From 87c2503571bd7f5e753bc16a05bd198fc58d7d7c Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore Date: Wed, 17 Jun 2015 17:11:40 -0400 Subject: Use Object.create(…) instead of new …() for inheritance (faster) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blocks.js | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index 67324ca..3613dae 100644 --- a/blocks.js +++ b/blocks.js @@ -240,7 +240,7 @@ WorldMorph.prototype.customMorphs = function () { // SyntaxElementMorph inherits from Morph: -SyntaxElementMorph.prototype = new Morph(); +SyntaxElementMorph.prototype = Object.create(Morph.prototype); SyntaxElementMorph.prototype.constructor = SyntaxElementMorph; SyntaxElementMorph.uber = Morph.prototype; @@ -1937,7 +1937,7 @@ SyntaxElementMorph.prototype.endLayout = function () { // BlockMorph inherits from SyntaxElementMorph: -BlockMorph.prototype = new SyntaxElementMorph(); +BlockMorph.prototype = Object.create(SyntaxElementMorph.prototype); BlockMorph.prototype.constructor = BlockMorph; BlockMorph.uber = SyntaxElementMorph.prototype; @@ -3262,7 +3262,7 @@ BlockMorph.prototype.snap = function () { // CommandBlockMorph inherits from BlockMorph: -CommandBlockMorph.prototype = new BlockMorph(); +CommandBlockMorph.prototype = Object.create(BlockMorph.prototype); CommandBlockMorph.prototype.constructor = CommandBlockMorph; CommandBlockMorph.uber = BlockMorph.prototype; @@ -3942,7 +3942,7 @@ CommandBlockMorph.prototype.drawBottomRightEdge = function (context) { // HatBlockMorph inherits from CommandBlockMorph: -HatBlockMorph.prototype = new CommandBlockMorph(); +HatBlockMorph.prototype = Object.create(CommandBlockMorph.prototype); HatBlockMorph.prototype.constructor = HatBlockMorph; HatBlockMorph.uber = CommandBlockMorph.prototype; @@ -4120,7 +4120,7 @@ HatBlockMorph.prototype.drawTopLeftEdge = function (context) { // ReporterBlockMorph inherits from BlockMorph: -ReporterBlockMorph.prototype = new BlockMorph(); +ReporterBlockMorph.prototype = Object.create(BlockMorph.prototype); ReporterBlockMorph.prototype.constructor = ReporterBlockMorph; ReporterBlockMorph.uber = BlockMorph.prototype; @@ -4644,7 +4644,7 @@ ReporterBlockMorph.prototype.drawDiamond = function (context) { // RingMorph inherits from ReporterBlockMorph: -RingMorph.prototype = new ReporterBlockMorph(); +RingMorph.prototype = Object.create(ReporterBlockMorph.prototype); RingMorph.prototype.constructor = RingMorph; RingMorph.uber = ReporterBlockMorph.prototype; @@ -4781,7 +4781,7 @@ RingMorph.prototype.fixBlockColor = function (nearest, isForced) { // ScriptsMorph inherits from FrameMorph: -ScriptsMorph.prototype = new FrameMorph(); +ScriptsMorph.prototype = Object.create(FrameMorph.prototype); ScriptsMorph.prototype.constructor = ScriptsMorph; ScriptsMorph.uber = FrameMorph.prototype; @@ -5321,7 +5321,7 @@ ScriptsMorph.prototype.reactToDropOf = function (droppedMorph, hand) { // ArgMorph inherits from SyntaxElementMorph: -ArgMorph.prototype = new SyntaxElementMorph(); +ArgMorph.prototype = Object.create(SyntaxElementMorph.prototype); ArgMorph.prototype.constructor = ArgMorph; ArgMorph.uber = SyntaxElementMorph.prototype; @@ -5434,7 +5434,7 @@ ArgMorph.prototype.isEmptySlot = function () { // CommandSlotMorph inherits from ArgMorph: -CommandSlotMorph.prototype = new ArgMorph(); +CommandSlotMorph.prototype = Object.create(ArgMorph.prototype); CommandSlotMorph.prototype.constructor = CommandSlotMorph; CommandSlotMorph.uber = ArgMorph.prototype; @@ -5884,7 +5884,7 @@ CommandSlotMorph.prototype.drawEdges = function (context) { // RingCommandSlotMorph inherits from CommandSlotMorph: -RingCommandSlotMorph.prototype = new CommandSlotMorph(); +RingCommandSlotMorph.prototype = Object.create(CommandSlotMorph.prototype); RingCommandSlotMorph.prototype.constructor = RingCommandSlotMorph; RingCommandSlotMorph.uber = CommandSlotMorph.prototype; @@ -6040,7 +6040,7 @@ RingCommandSlotMorph.prototype.drawFlat = function (context) { // CSlotMorph inherits from CommandSlotMorph: -CSlotMorph.prototype = new CommandSlotMorph(); +CSlotMorph.prototype = Object.create(CommandSlotMorph.prototype); CSlotMorph.prototype.constructor = CSlotMorph; CSlotMorph.uber = CommandSlotMorph.prototype; @@ -6463,7 +6463,7 @@ CSlotMorph.prototype.drawBottomEdge = function (context) { // InputSlotMorph inherits from ArgMorph: -InputSlotMorph.prototype = new ArgMorph(); +InputSlotMorph.prototype = Object.create(ArgMorph.prototype); InputSlotMorph.prototype.constructor = InputSlotMorph; InputSlotMorph.uber = ArgMorph.prototype; @@ -7399,7 +7399,7 @@ InputSlotMorph.prototype.drawRoundBorder = function (context) { // TemplateSlotMorph inherits from ArgMorph: -TemplateSlotMorph.prototype = new ArgMorph(); +TemplateSlotMorph.prototype = Object.create(ArgMorph.prototype); TemplateSlotMorph.prototype.constructor = TemplateSlotMorph; TemplateSlotMorph.uber = ArgMorph.prototype; @@ -7503,7 +7503,7 @@ TemplateSlotMorph.prototype.drawRounded = ReporterBlockMorph // BooleanSlotMorph inherits from ArgMorph: -BooleanSlotMorph.prototype = new ArgMorph(); +BooleanSlotMorph.prototype = Object.create(ArgMorph.prototype); BooleanSlotMorph.prototype.constructor = BooleanSlotMorph; BooleanSlotMorph.uber = ArgMorph.prototype; @@ -7660,7 +7660,7 @@ BooleanSlotMorph.prototype.isEmptySlot = function () { // ArrowMorph inherits from Morph: -ArrowMorph.prototype = new Morph(); +ArrowMorph.prototype = Object.create(Morph.prototype); ArrowMorph.prototype.constructor = ArrowMorph; ArrowMorph.uber = Morph.prototype; @@ -7730,7 +7730,7 @@ ArrowMorph.prototype.drawNew = function () { // TextSlotMorph inherits from InputSlotMorph: -TextSlotMorph.prototype = new InputSlotMorph(); +TextSlotMorph.prototype = Object.create(InputSlotMorph.prototype); TextSlotMorph.prototype.constructor = TextSlotMorph; TextSlotMorph.uber = InputSlotMorph.prototype; @@ -7813,7 +7813,7 @@ TextSlotMorph.prototype.layoutChanged = function () { // SymbolMorph inherits from Morph: -SymbolMorph.prototype = new Morph(); +SymbolMorph.prototype = Object.create(Morph.prototype); SymbolMorph.prototype.constructor = SymbolMorph; SymbolMorph.uber = Morph.prototype; @@ -9106,7 +9106,7 @@ SymbolMorph.prototype.drawSymbolRobot = function (canvas, color) { // ColorSlotMorph inherits from ArgMorph: -ColorSlotMorph.prototype = new ArgMorph(); +ColorSlotMorph.prototype = Object.create(ArgMorph.prototype); ColorSlotMorph.prototype.constructor = ColorSlotMorph; ColorSlotMorph.uber = ArgMorph.prototype; @@ -9214,7 +9214,7 @@ ColorSlotMorph.prototype.drawRectBorder = // BlockHighlightMorph inherits from Morph: -BlockHighlightMorph.prototype = new Morph(); +BlockHighlightMorph.prototype = Object.create(Morph.prototype); BlockHighlightMorph.prototype.constructor = BlockHighlightMorph; BlockHighlightMorph.uber = Morph.prototype; @@ -9239,7 +9239,7 @@ function BlockHighlightMorph() { // MultiArgMorph inherits from ArgMorph: -MultiArgMorph.prototype = new ArgMorph(); +MultiArgMorph.prototype = Object.create(ArgMorph.prototype); MultiArgMorph.prototype.constructor = MultiArgMorph; MultiArgMorph.uber = ArgMorph.prototype; @@ -9669,7 +9669,7 @@ MultiArgMorph.prototype.isEmptySlot = function () { // ArgLabelMorph inherits from ArgMorph: -ArgLabelMorph.prototype = new ArgMorph(); +ArgLabelMorph.prototype = Object.create(ArgMorph.prototype); ArgLabelMorph.prototype.constructor = ArgLabelMorph; ArgLabelMorph.uber = ArgMorph.prototype; @@ -9799,7 +9799,7 @@ ArgLabelMorph.prototype.isEmptySlot = function () { // FunctionSlotMorph inherits from ArgMorph: -FunctionSlotMorph.prototype = new ArgMorph(); +FunctionSlotMorph.prototype = Object.create(ArgMorph.prototype); FunctionSlotMorph.prototype.constructor = FunctionSlotMorph; FunctionSlotMorph.uber = ArgMorph.prototype; @@ -10180,7 +10180,7 @@ FunctionSlotMorph.prototype.drawDiamond = function (context) { // ReporterSlotMorph inherits from FunctionSlotMorph: -ReporterSlotMorph.prototype = new FunctionSlotMorph(); +ReporterSlotMorph.prototype = Object.create(FunctionSlotMorph.prototype); ReporterSlotMorph.prototype.constructor = ReporterSlotMorph; ReporterSlotMorph.uber = FunctionSlotMorph.prototype; @@ -10263,7 +10263,7 @@ ReporterSlotMorph.prototype.fixLayout = function () { // ReporterSlotMorph inherits from FunctionSlotMorph: -RingReporterSlotMorph.prototype = new ReporterSlotMorph(); +RingReporterSlotMorph.prototype = Object.create(ReporterSlotMorph.prototype); RingReporterSlotMorph.prototype.constructor = RingReporterSlotMorph; RingReporterSlotMorph.uber = ReporterSlotMorph.prototype; @@ -10651,7 +10651,7 @@ RingReporterSlotMorph.prototype.drawDiamond = function (context) { // CommentMorph inherits from BoxMorph: -CommentMorph.prototype = new BoxMorph(); +CommentMorph.prototype = Object.create(BoxMorph.prototype); CommentMorph.prototype.constructor = CommentMorph; CommentMorph.uber = BoxMorph.prototype; -- cgit v1.3.1 From 94687f8e630c5be6f2c82615c1aa1ec5cbee82b8 Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore Date: Wed, 17 Jun 2015 18:39:23 -0400 Subject: Optimize Block::thumbnail() Remove noShadow, because copying is really expensive--you could probably add this in-place with some more complicated logic, but it doesn't seem worth it. Also fix clipping logic so that fades look good on all background colors. --- blocks.js | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index 3613dae..d373cea 100644 --- a/blocks.js +++ b/blocks.js @@ -2225,7 +2225,7 @@ BlockMorph.prototype.userMenu = function () { ); if (this instanceof CommandBlockMorph && this.nextBlock()) { menu.addItem( - this.thumbnail(0.5, 60, false), + this.thumbnail(0.5, 60), function () { var cpy = this.fullCopy(), nb = cpy.nextBlock(), @@ -3103,38 +3103,34 @@ BlockMorph.prototype.mouseClickLeft = function () { // BlockMorph thumbnail -BlockMorph.prototype.thumbnail = function (scale, clipWidth, noShadow) { - var block = this.fullCopy(), - nb = block.nextBlock(), +BlockMorph.prototype.thumbnail = function (scale, clipWidth) { + var nb = this.nextBlock(), fadeout = 12, ext, trgt, ctx, gradient; - if (nb) {nb.destroy(); } - if (!noShadow) {block.addShadow(); } - ext = block.fullBounds().extent(); - if (!noShadow) { - ext = ext.subtract(this.shadowBlur * - (useBlurredShadows && !MorphicPreferences.isFlat ? 1 : 2)); - } + + if (nb) {nb.isVisible = false; } + ext = this.fullBounds().extent(); trgt = newCanvas(new Point( - Math.min(ext.x * scale, clipWidth || ext.x), + clipWidth ? Math.min(ext.x * scale, clipWidth) : ext.x * scale, ext.y * scale )); ctx = trgt.getContext('2d'); ctx.scale(scale, scale); - ctx.drawImage(block.fullImage(), 0, 0); + ctx.drawImage(this.fullImage(), 0, 0); // draw fade-out - if (trgt.width === clipWidth) { + if (clipWidth && ext.x * scale > clipWidth) { gradient = ctx.createLinearGradient( trgt.width / scale - fadeout, 0, trgt.width / scale, 0 ); - gradient.addColorStop(0, new Color(255, 255, 255, 0).toString()); - gradient.addColorStop(1, 'white'); + gradient.addColorStop(0, 'transparent'); + gradient.addColorStop(1, 'black'); + ctx.globalCompositeOperation = 'destination-out'; ctx.fillStyle = gradient; ctx.fillRect( trgt.width / scale - fadeout, @@ -3143,6 +3139,7 @@ BlockMorph.prototype.thumbnail = function (scale, clipWidth, noShadow) { trgt.height / scale ); } + if (nb) {nb.isVisible = true; } return trgt; }; -- cgit v1.3.1 From f54da26e8e4a9d92c93ac58f242ac521b6dbac66 Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore Date: Wed, 17 Jun 2015 20:05:35 -0400 Subject: Don't step SyntaxElementMorphs or their children ~1500 ms before => ~150 ms after (stepping world with large scripts) --- blocks.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index d373cea..d2a395a 100644 --- a/blocks.js +++ b/blocks.js @@ -621,6 +621,10 @@ SyntaxElementMorph.prototype.topBlock = function () { return this; }; +// SyntaxElementMorph stepping: + +SyntaxElementMorph.prototype.step = null; + // SyntaxElementMorph drag & drop: SyntaxElementMorph.prototype.reactToGrabOf = function (grabbedMorph) { -- cgit v1.3.1 From 95a815b6d63b57f46a72be25b9723366f4af76bd Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore Date: Wed, 17 Jun 2015 22:21:23 -0400 Subject: Don't redraw label parts unnecessarily --- blocks.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index d2a395a..6c10354 100644 --- a/blocks.js +++ b/blocks.js @@ -2062,7 +2062,7 @@ BlockMorph.prototype.setSpec = function (spec) { } part = myself.labelPart(word); myself.add(part); - if (!(part instanceof CommandSlotMorph)) { + if (!(part instanceof CommandSlotMorph || part instanceof StringMorph)) { part.drawNew(); } if (part instanceof RingMorph) { -- cgit v1.3.1 From 0245a81fc04cf787bae2f3467f850a07d9791ca7 Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore Date: Wed, 17 Jun 2015 23:05:34 -0400 Subject: Optimize loading projects a bit more --- blocks.js | 63 ++++++++++++++++++++++++++++++++------------------------------ morphic.js | 6 +++--- 2 files changed, 36 insertions(+), 33 deletions(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index 6c10354..8aad311 100644 --- a/blocks.js +++ b/blocks.js @@ -1421,16 +1421,19 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { new Point() : this.embossing; part.drawNew(); } else { - part = new StringMorph(spec); - part.fontName = this.labelFontName; - part.fontStyle = this.labelFontStyle; - part.fontSize = this.fontSize; - part.color = new Color(255, 255, 255); - part.isBold = true; - part.shadowColor = this.color.darker(this.labelContrast); - part.shadowOffset = MorphicPreferences.isFlat ? - new Point() : this.embossing; - part.drawNew(); + part = new StringMorph( + spec, // text + this.fontSize, // fontSize + this.labelFontStyle, // fontStyle + true, // bold + false, // italic + false, // isNumeric + MorphicPreferences.isFlat ? + new Point() : this.embossing, // shadowOffset + this.color.darker(this.labelContrast), // shadowColor + new Color(255, 255, 255), // color + this.labelFontName // fontName + ); } return part; }; @@ -6918,7 +6921,8 @@ InputSlotMorph.prototype.setChoices = function (dict, readonly) { // InputSlotMorph layout: InputSlotMorph.prototype.fixLayout = function () { - var contents = this.contents(), + var width, height, arrowWidth, + contents = this.contents(), arrow = this.arrow(); contents.isNumeric = this.isNumeric; @@ -6935,32 +6939,29 @@ InputSlotMorph.prototype.fixLayout = function () { arrow.setSize(this.fontSize); arrow.show(); } else { - arrow.setSize(0); arrow.hide(); } - this.setHeight( - contents.height() - + this.edge * 2 - // + this.typeInPadding * 2 - ); + arrowWidth = arrow.isVisible ? arrow.width() : 0; + + height = contents.height() + this.edge * 2; // + this.typeInPadding * 2 if (this.isNumeric) { - this.setWidth(contents.width() - + Math.floor(arrow.width() * 0.5) + width = contents.width() + + Math.floor(arrowWidth * 0.5) + this.height() - + this.typeInPadding * 2 - ); + + this.typeInPadding * 2; } else { - this.setWidth(Math.max( + width = Math.max( contents.width() - + arrow.width() + + arrowWidth + this.edge * 2 + this.typeInPadding * 2, contents.rawHeight ? // single vs. multi-line contents - contents.rawHeight() + arrow.width() - : contents.height() / 1.2 + arrow.width(), + contents.rawHeight() + arrowWidth + : contents.height() / 1.2 + arrowWidth, this.minWidth // for text-type slots - )); + ); } + this.setExtent(new Point(width, height)); if (this.isNumeric) { contents.setPosition(new Point( Math.floor(this.height() / 2), @@ -6973,10 +6974,12 @@ InputSlotMorph.prototype.fixLayout = function () { ).add(new Point(this.typeInPadding, 0)).add(this.position())); } - arrow.setPosition(new Point( - this.right() - arrow.width() - this.edge, - contents.top() - )); + if (arrow.isVisible) { + arrow.setPosition(new Point( + this.right() - arrowWidth - this.edge, + contents.top() + )); + } if (this.parent) { if (this.parent.fixLayout) { diff --git a/morphic.js b/morphic.js index 0b20eb5..1552d78 100644 --- a/morphic.js +++ b/morphic.js @@ -2199,7 +2199,7 @@ function Morph() { // Morph initialization: -Morph.prototype.init = function () { +Morph.prototype.init = function (noDraw) { Morph.uber.init.call(this); this.isMorph = true; this.bounds = new Rectangle(0, 0, 50, 40); @@ -2212,7 +2212,7 @@ Morph.prototype.init = function () { this.isTemplate = false; this.acceptsDrops = false; this.noticesTransparentClick = false; - this.drawNew(); + if (!noDraw) this.drawNew(); this.fps = 0; this.customContextMenu = null; this.lastTime = Date.now(); @@ -6999,7 +6999,7 @@ StringMorph.prototype.init = function ( this.markedBackgoundColor = new Color(60, 60, 120); // initialize inherited properties: - StringMorph.uber.init.call(this); + StringMorph.uber.init.call(this, true); // override inherited properites: this.color = color || new Color(0, 0, 0); -- cgit v1.3.1 From e1b104948b5162a014fa752f394d0e722664499c Mon Sep 17 00:00:00 2001 From: Nathan Dinsmore Date: Thu, 18 Jun 2015 16:05:27 -0400 Subject: Fix InputSlotMorph::fixLayout() --- blocks.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index 8aad311..d023db8 100644 --- a/blocks.js +++ b/blocks.js @@ -6947,7 +6947,7 @@ InputSlotMorph.prototype.fixLayout = function () { if (this.isNumeric) { width = contents.width() + Math.floor(arrowWidth * 0.5) - + this.height() + + height + this.typeInPadding * 2; } else { width = Math.max( @@ -6964,7 +6964,7 @@ InputSlotMorph.prototype.fixLayout = function () { this.setExtent(new Point(width, height)); if (this.isNumeric) { contents.setPosition(new Point( - Math.floor(this.height() / 2), + Math.floor(height / 2), this.edge ).add(new Point(this.typeInPadding, 0)).add(this.position())); } else { -- cgit v1.3.1