diff options
| author | Jens Mönig <jens@moenig.org> | 2015-06-25 13:07:57 +0200 |
|---|---|---|
| committer | Jens Mönig <jens@moenig.org> | 2015-06-25 13:07:57 +0200 |
| commit | 2a28dca75342eeffb013e0e2fc00ce29561e97ee (patch) | |
| tree | 9db5099e7540dd931e79a3aaf9083f5b4f70f85b | |
| parent | 3885ced35aee903f74d48c293bc3f0665a38dba5 (diff) | |
| parent | aef56afebf1504a9ce09ee5668d00c3c1df17565 (diff) | |
| download | snap-2a28dca75342eeffb013e0e2fc00ce29561e97ee.tar.gz snap-2a28dca75342eeffb013e0e2fc00ce29561e97ee.zip | |
Merge pull request #837 from nathan/optim
Optimizations
| -rw-r--r-- | blocks.js | 152 | ||||
| -rw-r--r-- | byob.js | 26 | ||||
| -rw-r--r-- | gui.js | 16 | ||||
| -rw-r--r-- | lists.js | 17 | ||||
| -rw-r--r-- | morphic.js | 442 | ||||
| -rw-r--r-- | objects.js | 26 | ||||
| -rw-r--r-- | paint.js | 10 | ||||
| -rw-r--r-- | store.js | 3 | ||||
| -rw-r--r-- | widgets.js | 16 | ||||
| -rw-r--r-- | xml.js | 121 |
10 files changed, 341 insertions, 488 deletions
@@ -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; @@ -621,6 +621,10 @@ SyntaxElementMorph.prototype.topBlock = function () { return this; }; +// SyntaxElementMorph stepping: + +SyntaxElementMorph.prototype.step = null; + // SyntaxElementMorph drag & drop: SyntaxElementMorph.prototype.reactToGrabOf = function (grabbedMorph) { @@ -1417,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; }; @@ -1937,7 +1944,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; @@ -2058,7 +2065,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) { @@ -2225,7 +2232,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 +3110,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 +3146,7 @@ BlockMorph.prototype.thumbnail = function (scale, clipWidth, noShadow) { trgt.height / scale ); } + if (nb) {nb.isVisible = true; } return trgt; }; @@ -3262,7 +3266,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 +3946,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 +4124,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 +4648,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 +4785,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 +5325,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 +5438,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 +5888,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 +6044,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 +6467,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; @@ -6917,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; @@ -6934,35 +6939,32 @@ 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) - + this.height() - + this.typeInPadding * 2 - ); + width = contents.width() + + Math.floor(arrowWidth * 0.5) + + height + + 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), + Math.floor(height / 2), this.edge ).add(new Point(this.typeInPadding, 0)).add(this.position())); } else { @@ -6972,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) { @@ -7399,7 +7403,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 +7507,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 +7664,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 +7734,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 +7817,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 +9110,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 +9218,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 +9243,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 +9673,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 +9803,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 +10184,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 +10267,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 +10655,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; @@ -379,7 +379,7 @@ CustomBlockDefinition.prototype.scriptsPicture = function () { // CustomCommandBlockMorph inherits from CommandBlockMorph: -CustomCommandBlockMorph.prototype = new CommandBlockMorph(); +CustomCommandBlockMorph.prototype = Object.create(CommandBlockMorph.prototype); CustomCommandBlockMorph.prototype.constructor = CustomCommandBlockMorph; CustomCommandBlockMorph.uber = CommandBlockMorph.prototype; @@ -896,7 +896,7 @@ CustomCommandBlockMorph.prototype.alternatives = function () { // CustomReporterBlockMorph inherits from ReporterBlockMorph: -CustomReporterBlockMorph.prototype = new ReporterBlockMorph(); +CustomReporterBlockMorph.prototype = Object.create(ReporterBlockMorph.prototype); CustomReporterBlockMorph.prototype.constructor = CustomReporterBlockMorph; CustomReporterBlockMorph.uber = ReporterBlockMorph.prototype; @@ -1028,7 +1028,7 @@ CustomReporterBlockMorph.prototype.alternatives // JaggedBlockMorph inherits from ReporterBlockMorph: -JaggedBlockMorph.prototype = new ReporterBlockMorph(); +JaggedBlockMorph.prototype = Object.create(ReporterBlockMorph.prototype); JaggedBlockMorph.prototype.constructor = JaggedBlockMorph; JaggedBlockMorph.uber = ReporterBlockMorph.prototype; @@ -1177,7 +1177,7 @@ JaggedBlockMorph.prototype.drawEdges = function (context) { // BlockDialogMorph inherits from DialogBoxMorph: -BlockDialogMorph.prototype = new DialogBoxMorph(); +BlockDialogMorph.prototype = Object.create(DialogBoxMorph.prototype); BlockDialogMorph.prototype.constructor = BlockDialogMorph; BlockDialogMorph.uber = DialogBoxMorph.prototype; @@ -1624,7 +1624,7 @@ BlockDialogMorph.prototype.fixLayout = function () { // BlockEditorMorph inherits from DialogBoxMorph: -BlockEditorMorph.prototype = new DialogBoxMorph(); +BlockEditorMorph.prototype = Object.create(DialogBoxMorph.prototype); BlockEditorMorph.prototype.constructor = BlockEditorMorph; BlockEditorMorph.uber = DialogBoxMorph.prototype; @@ -1936,7 +1936,7 @@ BlockEditorMorph.prototype.fixLayout = function () { // PrototypeHatBlockMorph inherits from HatBlockMorph: -PrototypeHatBlockMorph.prototype = new HatBlockMorph(); +PrototypeHatBlockMorph.prototype = Object.create(HatBlockMorph.prototype); PrototypeHatBlockMorph.prototype.constructor = PrototypeHatBlockMorph; PrototypeHatBlockMorph.uber = HatBlockMorph.prototype; @@ -2146,7 +2146,7 @@ BlockLabelFragment.prototype.setSingleInputType = function (type) { // BlockLabelFragmentMorph inherits from StringMorph: -BlockLabelFragmentMorph.prototype = new StringMorph(); +BlockLabelFragmentMorph.prototype = Object.create(StringMorph.prototype); BlockLabelFragmentMorph.prototype.constructor = BlockLabelFragmentMorph; BlockLabelFragmentMorph.uber = StringMorph.prototype; @@ -2268,7 +2268,7 @@ BlockLabelFragmentMorph.prototype.userMenu = function () { // BlockLabelPlaceHolderMorph inherits from StringMorph: -BlockLabelPlaceHolderMorph.prototype = new StringMorph(); +BlockLabelPlaceHolderMorph.prototype = Object.create(StringMorph.prototype); BlockLabelPlaceHolderMorph.prototype.constructor = BlockLabelPlaceHolderMorph; BlockLabelPlaceHolderMorph.uber = StringMorph.prototype; @@ -2396,7 +2396,7 @@ BlockLabelPlaceHolderMorph.prototype.updateBlockLabel // BlockInputFragmentMorph inherits from TemplateSlotMorph: -BlockInputFragmentMorph.prototype = new TemplateSlotMorph(); +BlockInputFragmentMorph.prototype = Object.create(TemplateSlotMorph.prototype); BlockInputFragmentMorph.prototype.constructor = BlockInputFragmentMorph; BlockInputFragmentMorph.uber = TemplateSlotMorph.prototype; @@ -2426,7 +2426,7 @@ BlockInputFragmentMorph.prototype.updateBlockLabel // InputSlotDialogMorph inherits from DialogBoxMorph: -InputSlotDialogMorph.prototype = new DialogBoxMorph(); +InputSlotDialogMorph.prototype = Object.create(DialogBoxMorph.prototype); InputSlotDialogMorph.prototype.constructor = InputSlotDialogMorph; InputSlotDialogMorph.uber = DialogBoxMorph.prototype; @@ -3026,7 +3026,7 @@ InputSlotDialogMorph.prototype.show = function () { // VariableDialogMorph inherits from DialogBoxMorph: -VariableDialogMorph.prototype = new DialogBoxMorph(); +VariableDialogMorph.prototype = Object.create(DialogBoxMorph.prototype); VariableDialogMorph.prototype.constructor = VariableDialogMorph; VariableDialogMorph.uber = DialogBoxMorph.prototype; @@ -3145,7 +3145,7 @@ VariableDialogMorph.prototype.fixLayout = function () { // BlockExportDialogMorph inherits from DialogBoxMorph: -BlockExportDialogMorph.prototype = new DialogBoxMorph(); +BlockExportDialogMorph.prototype = Object.create(DialogBoxMorph.prototype); BlockExportDialogMorph.prototype.constructor = BlockExportDialogMorph; BlockExportDialogMorph.uber = DialogBoxMorph.prototype; @@ -3327,7 +3327,7 @@ BlockExportDialogMorph.prototype.fixLayout // BlockImportDialogMorph inherits from DialogBoxMorph // and pseudo-inherits from BlockExportDialogMorph: -BlockImportDialogMorph.prototype = new DialogBoxMorph(); +BlockImportDialogMorph.prototype = Object.create(DialogBoxMorph.prototype); BlockImportDialogMorph.prototype.constructor = BlockImportDialogMorph; BlockImportDialogMorph.uber = DialogBoxMorph.prototype; @@ -88,7 +88,7 @@ var JukeboxMorph; // IDE_Morph inherits from Morph: -IDE_Morph.prototype = new Morph(); +IDE_Morph.prototype = Object.create(Morph.prototype); IDE_Morph.prototype.constructor = IDE_Morph; IDE_Morph.uber = Morph.prototype; @@ -4274,7 +4274,7 @@ IDE_Morph.prototype.prompt = function (message, callback, choices, key) { // ProjectDialogMorph inherits from DialogBoxMorph: -ProjectDialogMorph.prototype = new DialogBoxMorph(); +ProjectDialogMorph.prototype = Object.create(DialogBoxMorph.prototype); ProjectDialogMorph.prototype.constructor = ProjectDialogMorph; ProjectDialogMorph.uber = DialogBoxMorph.prototype; @@ -5181,7 +5181,7 @@ ProjectDialogMorph.prototype.fixLayout = function () { // SpriteIconMorph inherits from ToggleButtonMorph (Widgets) -SpriteIconMorph.prototype = new ToggleButtonMorph(); +SpriteIconMorph.prototype = Object.create(ToggleButtonMorph.prototype); SpriteIconMorph.prototype.constructor = SpriteIconMorph; SpriteIconMorph.uber = ToggleButtonMorph.prototype; @@ -5571,7 +5571,7 @@ SpriteIconMorph.prototype.copySound = function (sound) { // CostumeIconMorph inherits from ToggleButtonMorph (Widgets) // ... and copies methods from SpriteIconMorph -CostumeIconMorph.prototype = new ToggleButtonMorph(); +CostumeIconMorph.prototype = Object.create(ToggleButtonMorph.prototype); CostumeIconMorph.prototype.constructor = CostumeIconMorph; CostumeIconMorph.uber = ToggleButtonMorph.prototype; @@ -5782,7 +5782,7 @@ CostumeIconMorph.prototype.prepareToBeGrabbed = function () { // TurtleIconMorph inherits from ToggleButtonMorph (Widgets) // ... and copies methods from SpriteIconMorph -TurtleIconMorph.prototype = new ToggleButtonMorph(); +TurtleIconMorph.prototype = Object.create(ToggleButtonMorph.prototype); TurtleIconMorph.prototype.constructor = TurtleIconMorph; TurtleIconMorph.uber = ToggleButtonMorph.prototype; @@ -5965,7 +5965,7 @@ TurtleIconMorph.prototype.userMenu = function () { // WardrobeMorph inherits from ScrollFrameMorph -WardrobeMorph.prototype = new ScrollFrameMorph(); +WardrobeMorph.prototype = Object.create(ScrollFrameMorph.prototype); WardrobeMorph.prototype.constructor = WardrobeMorph; WardrobeMorph.uber = ScrollFrameMorph.prototype; @@ -6148,7 +6148,7 @@ WardrobeMorph.prototype.reactToDropOf = function (icon) { // SoundIconMorph inherits from ToggleButtonMorph (Widgets) // ... and copies methods from SpriteIconMorph -SoundIconMorph.prototype = new ToggleButtonMorph(); +SoundIconMorph.prototype = Object.create(ToggleButtonMorph.prototype); SoundIconMorph.prototype.constructor = SoundIconMorph; SoundIconMorph.uber = ToggleButtonMorph.prototype; @@ -6356,7 +6356,7 @@ SoundIconMorph.prototype.prepareToBeGrabbed = function () { // JukeboxMorph instance creation -JukeboxMorph.prototype = new ScrollFrameMorph(); +JukeboxMorph.prototype = Object.create(ScrollFrameMorph.prototype); JukeboxMorph.prototype.constructor = JukeboxMorph; JukeboxMorph.uber = ScrollFrameMorph.prototype; @@ -363,7 +363,7 @@ List.prototype.equalTo = function (other) { // ListWatcherMorph inherits from BoxMorph: -ListWatcherMorph.prototype = new BoxMorph(); +ListWatcherMorph.prototype = Object.create(BoxMorph.prototype); ListWatcherMorph.prototype.constructor = ListWatcherMorph; ListWatcherMorph.uber = BoxMorph.prototype; @@ -388,6 +388,13 @@ ListWatcherMorph.prototype.init = function (list, parentCell) { this.lastCell = null; this.parentCell = parentCell || null; // for circularity detection + ListWatcherMorph.uber.init.call( + this, + SyntaxElementMorph.prototype.rounding, + 1.000001, // shadow bug in Chrome, + new Color(120, 120, 120) + ); + // elements declarations this.label = new StringMorph( localize('length: ') + this.list.length(), @@ -436,13 +443,6 @@ ListWatcherMorph.prototype.init = function (list, parentCell) { this.plusButton.drawNew(); this.plusButton.fixLayout(); - ListWatcherMorph.uber.init.call( - this, - SyntaxElementMorph.prototype.rounding, - 1.000001, // shadow bug in Chrome, - new Color(120, 120, 120) - ); - this.color = new Color(220, 220, 220); this.isDraggable = true; this.setExtent(new Point(80, 70).multiplyBy( @@ -634,6 +634,7 @@ ListWatcherMorph.prototype.setStartIndex = function (index) { }; ListWatcherMorph.prototype.fixLayout = function () { + if (!this.label) return; Morph.prototype.trackChanges = false; if (this.frame) { this.arrangeCells(); @@ -528,7 +528,7 @@ whose "isTemplate" flag is false, in other words: a non-template. When creating a copy from a template, the copy's - + reactToTemplateCopy is invoked, if it is present. @@ -829,12 +829,11 @@ }; If your new morph stores or references other morphs outside of the - submorph tree in other properties, be sure to also override the - default + submorph tree in other properties, you may need to override the default - copyRecordingReferences() + updateReferences() - method accordingly if you want it to support duplication. + method if you want it to support duplication. (6) development and user modes @@ -1243,19 +1242,9 @@ function getDocumentPositionOf(aDOMelement) { return pos; } -function clone(target) { - // answer a new instance of target's type - if (typeof target === 'object') { - var Clone = function () {nop(); }; - Clone.prototype = target; - return new Clone(); - } - return target; -} - function copy(target) { // answer a shallow copy of target - var value, c, property; + var value, c, property, keys, l, i; if (typeof target !== 'object') { return target; @@ -1266,18 +1255,16 @@ function copy(target) { } if (target instanceof target.constructor && target.constructor !== Object) { - c = clone(target.constructor.prototype); - for (property in target) { - if (Object.prototype.hasOwnProperty.call(target, property)) { - c[property] = target[property]; - } + c = Object.create(target.constructor.prototype); + keys = Object.keys(target); + for (l = keys.length, i = 0; i < l; ++i) { + property = keys[i]; + c[property] = target[property]; } } else { c = {}; for (property in target) { - if (!c[property]) { - c[property] = target[property]; - } + c[property] = target[property]; } } return c; @@ -2171,7 +2158,7 @@ var TextMorph; // Morph inherits from Node: -Morph.prototype = new Node(); +Morph.prototype = Object.create(Node.prototype); Morph.prototype.constructor = Morph; Morph.uber = Node.prototype; @@ -2212,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); @@ -2225,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(); @@ -2411,19 +2398,16 @@ Morph.prototype.visibleBounds = function () { // Morph accessing - simple changes: Morph.prototype.moveBy = function (delta) { - this.changed(); - this.bounds = this.bounds.translateBy(delta); - this.children.forEach(function (child) { - child.moveBy(delta); - }); - this.changed(); + this.fullChanged(); + this.silentMoveBy(delta); + this.fullChanged(); }; Morph.prototype.silentMoveBy = function (delta) { this.bounds = this.bounds.translateBy(delta); - this.children.forEach(function (child) { - child.silentMoveBy(delta); - }); + for (var children = this.children, i = children.length; i--;) { + children[i].silentMoveBy(delta); + } }; Morph.prototype.setPosition = function (aPoint) { @@ -2899,7 +2883,7 @@ Morph.prototype.fullChanged = function () { }; Morph.prototype.childChanged = function () { - // react to a change in one of my children, + // react to a change in one of my children, // default is to just pass this message on upwards // override this method for Morphs that need to adjust accordingly if (this.parent) { @@ -3031,63 +3015,98 @@ Morph.prototype.isTransparentAt = function (aPoint) { // Morph duplicating: -Morph.prototype.copy = function () { - var c = copy(this); - c.parent = null; - c.children = []; - c.bounds = this.bounds.copy(); - return c; -}; +(function () { + // don't overwrite the global Map with AssociativeMap + var Map = window.Map || AssociativeMap; -Morph.prototype.fullCopy = function () { - /* - Produce a copy of me with my entire tree of submorphs. Morphs - mentioned more than once are all directed to a single new copy. - Other properties are also *shallow* copied, so you must override - to deep copy Arrays and (complex) Objects - */ - var dict = {}, c; - c = this.copyRecordingReferences(dict); - c.forAllChildren(function (m) { - m.updateReferences(dict); - }); - return c; -}; + Morph.prototype.copy = function () { + var c = copy(this); + c.parent = null; + c.children = []; + c.bounds = this.bounds.copy(); + return c; + }; -Morph.prototype.copyRecordingReferences = function (dict) { - /* - Recursively copy this entire composite morph, recording the - correspondence between old and new morphs in the given dictionary. - This dictionary will be used to update intra-composite references - in the copy. See updateReferences(). - Note: This default implementation copies ONLY morphs in the - submorph hierarchy. If a morph stores morphs in other properties - that it wants to copy, then it should override this method to do so. - The same goes for morphs that contain other complex data that - should be copied when the morph is duplicated. - */ - var c = this.copy(); - dict[this] = c; - this.children.forEach(function (m) { - c.add(m.copyRecordingReferences(dict)); - }); - return c; -}; + Morph.prototype.fullCopy = function () { + /* + Produce a copy of me with my entire tree of submorphs. Morphs + mentioned more than once are all directed to a single new copy. + Other properties are also *shallow* copied, so you must override + to deep copy Arrays and (complex) Objects + */ + var map = new Map(), c; + c = this.copyRecordingReferences(map); + c.forAllChildren(function (m) { + m.updateReferences(map); + }); + return c; + }; -Morph.prototype.updateReferences = function (dict) { - /* - Update intra-morph references within a composite morph that has - been copied. For example, if a button refers to morph X in the - orginal composite then the copy of that button in the new composite - should refer to the copy of X in new composite, not the original X. - */ - var property; - for (property in this) { - if (this[property] && this[property].isMorph && dict[property]) { - this[property] = dict[property]; + Morph.prototype.copyRecordingReferences = function (map) { + /* + Recursively copy this entire composite morph, recording the + correspondence between old and new morphs in the given dictionary. + This dictionary will be used to update intra-composite references + in the copy. See updateReferences(). + + Note: This default implementation copies ONLY morphs. If a morph + stores morphs in other properties that it wants to copy, then it + should override this method to do so. The same goes for morphs that + contain other complex data that should be copied when the morph is + duplicated. + */ + var c = this.copy(); + map.set(this, c); + this.children.forEach(function (m) { + c.add(m.copyRecordingReferences(map)); + }); + return c; + }; + + Morph.prototype.updateReferences = function (map) { + /* + Update intra-morph references within a composite morph that has + been copied. For example, if a button refers to morph X in the + orginal composite then the copy of that button in the new composite + should refer to the copy of X in new composite, not the original X. + */ + var property, value, reference; + for (var properties = Object.keys(this), l = properties.length, i = 0; i < l; ++i) { + property = properties[i]; + value = this[property]; + if (value && value.isMorph) { + reference = map.get(value); + if (reference) this[property] = reference; + } } + }; + + // associative array fallback for Map + + function AssociativeMap() { + this.keys = []; + this.values = []; } -}; + + AssociativeMap.prototype.get = function(key) { + for (var keys = this.keys, i = keys.length; i--;) { + if (keys[i] === key) return this.values[i]; + } + return undefined; + }; + + AssociativeMap.prototype.set = function(key, value) { + for (var keys = this.keys, i = keys.length; i--;) { + if (keys[i] === key) { + this.values[i] = value; + return; + } + } + keys.push(key); + this.values.push(value); + }; + +}()); // Morph dragging and dropping: @@ -3155,9 +3174,7 @@ Morph.prototype.slideBackTo = function (situation, inSteps) { this.fps = 0; this.step = function () { - myself.fullChanged(); - myself.silentMoveBy(new Point(xStep, yStep)); - myself.fullChanged(); + myself.moveBy(new Point(xStep, yStep)); stepCount += 1; if (stepCount === steps) { situation.origin.add(myself); @@ -3696,7 +3713,7 @@ Morph.prototype.overlappingImage = function (otherMorph) { // ShadowMorph inherits from Morph: -ShadowMorph.prototype = new Morph(); +ShadowMorph.prototype = Object.create(Morph.prototype); ShadowMorph.prototype.constructor = ShadowMorph; ShadowMorph.uber = Morph.prototype; @@ -3712,7 +3729,7 @@ function ShadowMorph() { // HandleMorph inherits from Morph: -HandleMorph.prototype = new Morph(); +HandleMorph.prototype = Object.create(Morph.prototype); HandleMorph.prototype.constructor = HandleMorph; HandleMorph.uber = Morph.prototype; @@ -3923,20 +3940,6 @@ HandleMorph.prototype.mouseLeave = function () { this.changed(); }; -// HandleMorph duplicating: - -HandleMorph.prototype.copyRecordingReferences = function (dict) { - // inherited, see comment in Morph - var c = HandleMorph.uber.copyRecordingReferences.call( - this, - dict - ); - if (c.target && dict[this.target]) { - c.target = (dict[this.target]); - } - return c; -}; - // HandleMorph menu: HandleMorph.prototype.attach = function () { @@ -3967,7 +3970,7 @@ var PenMorph; // PenMorph inherits from Morph: -PenMorph.prototype = new Morph(); +PenMorph.prototype = Object.create(Morph.prototype); PenMorph.prototype.constructor = PenMorph; PenMorph.uber = Morph.prototype; @@ -4199,7 +4202,7 @@ var ColorPaletteMorph; // ColorPaletteMorph inherits from Morph: -ColorPaletteMorph.prototype = new Morph(); +ColorPaletteMorph.prototype = Object.create(Morph.prototype); ColorPaletteMorph.prototype.constructor = ColorPaletteMorph; ColorPaletteMorph.uber = Morph.prototype; @@ -4260,20 +4263,6 @@ ColorPaletteMorph.prototype.updateTarget = function () { } }; -// ColorPaletteMorph duplicating: - -ColorPaletteMorph.prototype.copyRecordingReferences = function (dict) { - // inherited, see comment in Morph - var c = ColorPaletteMorph.uber.copyRecordingReferences.call( - this, - dict - ); - if (c.target && dict[this.target]) { - c.target = (dict[this.target]); - } - return c; -}; - // ColorPaletteMorph menu: ColorPaletteMorph.prototype.developersMenu = function () { @@ -4331,7 +4320,7 @@ var GrayPaletteMorph; // GrayPaletteMorph inherits from ColorPaletteMorph: -GrayPaletteMorph.prototype = new ColorPaletteMorph(); +GrayPaletteMorph.prototype = Object.create(ColorPaletteMorph.prototype); GrayPaletteMorph.prototype.constructor = GrayPaletteMorph; GrayPaletteMorph.uber = ColorPaletteMorph.prototype; @@ -4362,7 +4351,7 @@ GrayPaletteMorph.prototype.drawNew = function () { // ColorPickerMorph inherits from Morph: -ColorPickerMorph.prototype = new Morph(); +ColorPickerMorph.prototype = Object.create(Morph.prototype); ColorPickerMorph.prototype.constructor = ColorPickerMorph; ColorPickerMorph.uber = Morph.prototype; @@ -4431,7 +4420,7 @@ var BlinkerMorph; // BlinkerMorph inherits from Morph: -BlinkerMorph.prototype = new Morph(); +BlinkerMorph.prototype = Object.create(Morph.prototype); BlinkerMorph.prototype.constructor = BlinkerMorph; BlinkerMorph.uber = Morph.prototype; @@ -4464,7 +4453,7 @@ var CursorMorph; // CursorMorph inherits from BlinkerMorph: -CursorMorph.prototype = new BlinkerMorph(); +CursorMorph.prototype = Object.create(BlinkerMorph.prototype); CursorMorph.prototype.constructor = CursorMorph; CursorMorph.uber = BlinkerMorph.prototype; @@ -4884,7 +4873,7 @@ var BoxMorph; // BoxMorph inherits from Morph: -BoxMorph.prototype = new Morph(); +BoxMorph.prototype = Object.create(Morph.prototype); BoxMorph.prototype.constructor = BoxMorph; BoxMorph.uber = Morph.prototype; @@ -5092,7 +5081,7 @@ var SpeechBubbleMorph; // SpeechBubbleMorph inherits from BoxMorph: -SpeechBubbleMorph.prototype = new BoxMorph(); +SpeechBubbleMorph.prototype = Object.create(BoxMorph.prototype); SpeechBubbleMorph.prototype.constructor = SpeechBubbleMorph; SpeechBubbleMorph.uber = BoxMorph.prototype; @@ -5392,7 +5381,7 @@ var CircleBoxMorph; // CircleBoxMorph inherits from Morph: -CircleBoxMorph.prototype = new Morph(); +CircleBoxMorph.prototype = Object.create(Morph.prototype); CircleBoxMorph.prototype.constructor = CircleBoxMorph; CircleBoxMorph.uber = Morph.prototype; @@ -5512,7 +5501,7 @@ var SliderButtonMorph; // SliderButtonMorph inherits from CircleBoxMorph: -SliderButtonMorph.prototype = new CircleBoxMorph(); +SliderButtonMorph.prototype = Object.create(CircleBoxMorph.prototype); SliderButtonMorph.prototype.constructor = SliderButtonMorph; SliderButtonMorph.uber = CircleBoxMorph.prototype; @@ -5724,7 +5713,7 @@ SliderButtonMorph.prototype.mouseMove = function () { // SliderMorph inherits from CircleBoxMorph: -SliderMorph.prototype = new CircleBoxMorph(); +SliderMorph.prototype = Object.create(CircleBoxMorph.prototype); SliderMorph.prototype.constructor = SliderMorph; SliderMorph.uber = CircleBoxMorph.prototype; @@ -5840,23 +5829,6 @@ SliderMorph.prototype.updateTarget = function () { } }; -// SliderMorph duplicating: - -SliderMorph.prototype.copyRecordingReferences = function (dict) { - // inherited, see comment in Morph - var c = SliderMorph.uber.copyRecordingReferences.call( - this, - dict - ); - if (c.target && dict[this.target]) { - c.target = (dict[this.target]); - } - if (c.button && dict[this.button]) { - c.button = (dict[this.button]); - } - return c; -}; - // SliderMorph menu: SliderMorph.prototype.developersMenu = function () { @@ -6092,7 +6064,7 @@ var MouseSensorMorph; // MouseSensorMorph inherits from BoxMorph: -MouseSensorMorph.prototype = new BoxMorph(); +MouseSensorMorph.prototype = Object.create(BoxMorph.prototype); MouseSensorMorph.prototype.constructor = MouseSensorMorph; MouseSensorMorph.uber = BoxMorph.prototype; @@ -6166,7 +6138,7 @@ var TriggerMorph; // InspectorMorph inherits from BoxMorph: -InspectorMorph.prototype = new BoxMorph(); +InspectorMorph.prototype = Object.create(BoxMorph.prototype); InspectorMorph.prototype.constructor = InspectorMorph; InspectorMorph.uber = BoxMorph.prototype; @@ -6661,7 +6633,7 @@ var MenuItemMorph; // MenuMorph inherits from BoxMorph: -MenuMorph.prototype = new BoxMorph(); +MenuMorph.prototype = Object.create(BoxMorph.prototype); MenuMorph.prototype.constructor = MenuMorph; MenuMorph.uber = BoxMorph.prototype; @@ -6956,7 +6928,7 @@ MenuMorph.prototype.popUpCenteredInWorld = function (world) { // StringMorph inherits from Morph: -StringMorph.prototype = new Morph(); +StringMorph.prototype = Object.create(Morph.prototype); StringMorph.prototype.constructor = StringMorph; StringMorph.uber = Morph.prototype; @@ -7024,7 +6996,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); @@ -7402,6 +7374,7 @@ StringMorph.prototype.selectionStartSlot = function () { }; StringMorph.prototype.clearSelection = function () { + if (!this.currentlySelecting && this.startMark === 0 && this.endMark === 0) return; this.currentlySelecting = false; this.startMark = 0; this.endMark = 0; @@ -7491,7 +7464,7 @@ StringMorph.prototype.disableSelecting = function () { // TextMorph inherits from Morph: -TextMorph.prototype = new Morph(); +TextMorph.prototype = Object.create(Morph.prototype); TextMorph.prototype.constructor = TextMorph; TextMorph.uber = Morph.prototype; @@ -8016,7 +7989,7 @@ TextMorph.prototype.inspectIt = function () { // TriggerMorph inherits from Morph: -TriggerMorph.prototype = new Morph(); +TriggerMorph.prototype = Object.create(Morph.prototype); TriggerMorph.prototype.constructor = TriggerMorph; TriggerMorph.uber = Morph.prototype; @@ -8141,20 +8114,6 @@ TriggerMorph.prototype.createLabel = function () { this.add(this.label); }; -// TriggerMorph duplicating: - -TriggerMorph.prototype.copyRecordingReferences = function (dict) { - // inherited, see comment in Morph - var c = TriggerMorph.uber.copyRecordingReferences.call( - this, - dict - ); - if (c.label && dict[this.label]) { - c.label = (dict[this.label]); - } - return c; -}; - // TriggerMorph action: TriggerMorph.prototype.trigger = function () { @@ -8285,7 +8244,7 @@ var MenuItemMorph; // MenuItemMorph inherits from TriggerMorph: -MenuItemMorph.prototype = new TriggerMorph(); +MenuItemMorph.prototype = Object.create(TriggerMorph.prototype); MenuItemMorph.prototype.constructor = MenuItemMorph; MenuItemMorph.uber = TriggerMorph.prototype; @@ -8444,7 +8403,7 @@ MenuItemMorph.prototype.isSelectedListItem = function () { // Frames inherit from Morph: -FrameMorph.prototype = new Morph(); +FrameMorph.prototype = Object.create(Morph.prototype); FrameMorph.prototype.constructor = FrameMorph; FrameMorph.uber = Morph.prototype; @@ -8500,17 +8459,6 @@ FrameMorph.prototype.fullDrawOn = function (aCanvas, aRect) { }); }; -// FrameMorph scrolling optimization: - -FrameMorph.prototype.moveBy = function (delta) { - this.changed(); - this.bounds = this.bounds.translateBy(delta); - this.children.forEach(function (child) { - child.silentMoveBy(delta); - }); - this.changed(); -}; - // FrameMorph scrolling support: FrameMorph.prototype.submorphBounds = function () { @@ -8600,20 +8548,6 @@ FrameMorph.prototype.reactToGrabOf = function () { this.adjustBounds(); }; -// FrameMorph duplicating: - -FrameMorph.prototype.copyRecordingReferences = function (dict) { - // inherited, see comment in Morph - var c = FrameMorph.uber.copyRecordingReferences.call( - this, - dict - ); - if (c.frame && dict[this.scrollFrame]) { - c.frame = (dict[this.scrollFrame]); - } - return c; -}; - // FrameMorph menus: FrameMorph.prototype.developersMenu = function () { @@ -8638,7 +8572,7 @@ FrameMorph.prototype.keepAllSubmorphsWithin = function () { // ScrollFrameMorph //////////////////////////////////////////////////// -ScrollFrameMorph.prototype = new FrameMorph(); +ScrollFrameMorph.prototype = Object.create(FrameMorph.prototype); ScrollFrameMorph.prototype.constructor = ScrollFrameMorph; ScrollFrameMorph.uber = FrameMorph.prototype; @@ -8958,32 +8892,23 @@ ScrollFrameMorph.prototype.mouseScroll = function (y, x) { // ScrollFrameMorph duplicating: -ScrollFrameMorph.prototype.copyRecordingReferences = function (dict) { - // inherited, see comment in Morph - var c = ScrollFrameMorph.uber.copyRecordingReferences.call( - this, - dict - ); - if (c.contents && dict[this.contents]) { - c.contents = (dict[this.contents]); - } - if (c.hBar && dict[this.hBar]) { - c.hBar = (dict[this.hBar]); - c.hBar.action = function (num) { - c.contents.setPosition( - new Point(c.left() - num, c.contents.position().y) +ScrollFrameMorph.prototype.updateReferences = function (map) { + var self = this; + ScrollFrameMorph.uber.updateReferences.call(this, map); + if (this.hBar) { + this.hBar.action = function (num) { + self.contents.setPosition( + new Point(self.left() - num, self.contents.position().y) ); }; } - if (c.vBar && dict[this.vBar]) { - c.vBar = (dict[this.vBar]); - c.vBar.action = function (num) { - c.contents.setPosition( - new Point(c.contents.position().x, c.top() - num) + if (this.vBar) { + this.vBar.action = function (num) { + self.contents.setPosition( + new Point(self.contents.position().x, self.top() - num) ); }; } - return c; }; // ScrollFrameMorph menu: @@ -9013,7 +8938,7 @@ ScrollFrameMorph.prototype.toggleTextLineWrapping = function () { // ListMorph /////////////////////////////////////////////////////////// -ListMorph.prototype = new ScrollFrameMorph(); +ListMorph.prototype = Object.create(ScrollFrameMorph.prototype); ListMorph.prototype.constructor = ListMorph; ListMorph.uber = ScrollFrameMorph.prototype; @@ -9151,7 +9076,7 @@ ListMorph.prototype.setExtent = function (aPoint) { // StringFieldMorph inherit from FrameMorph: -StringFieldMorph.prototype = new FrameMorph(); +StringFieldMorph.prototype = Object.create(FrameMorph.prototype); StringFieldMorph.prototype.constructor = StringFieldMorph; StringFieldMorph.uber = FrameMorph.prototype; @@ -9243,20 +9168,6 @@ StringFieldMorph.prototype.mouseClickLeft = function (pos) { } }; -// StringFieldMorph duplicating: - -StringFieldMorph.prototype.copyRecordingReferences = function (dict) { - // inherited, see comment in Morph - var c = StringFieldMorph.uber.copyRecordingReferences.call( - this, - dict - ); - if (c.text && dict[this.text]) { - c.text = (dict[this.text]); - } - return c; -}; - // BouncerMorph //////////////////////////////////////////////////////// // I am a Demo of a stepping custom Morph @@ -9265,7 +9176,7 @@ var BouncerMorph; // Bouncers inherit from Morph: -BouncerMorph.prototype = new Morph(); +BouncerMorph.prototype = Object.create(Morph.prototype); BouncerMorph.prototype.constructor = BouncerMorph; BouncerMorph.uber = Morph.prototype; @@ -9352,7 +9263,7 @@ BouncerMorph.prototype.step = function () { // HandMorph inherits from Morph: -HandMorph.prototype = new Morph(); +HandMorph.prototype = Object.create(Morph.prototype); HandMorph.prototype.constructor = HandMorph; HandMorph.uber = Morph.prototype; @@ -9379,7 +9290,8 @@ HandMorph.prototype.init = function (aWorld) { this.contextMenuEnabled = false; }; -HandMorph.prototype.changed = function () { +HandMorph.prototype.changed = +HandMorph.prototype.fullChanged = function () { var b; if (this.world !== null) { b = this.fullBounds(); @@ -9387,33 +9299,31 @@ HandMorph.prototype.changed = function () { this.world.broken.push(this.fullBounds().spread()); } } - }; // HandMorph navigation: -HandMorph.prototype.morphAtPointer = function () { - var morphs = this.world.allChildren().slice(0).reverse(), - myself = this, - result = null; - - morphs.forEach(function (m) { - if (m.visibleBounds().containsPoint(myself.bounds.origin) && - result === null && - m.isVisible && - (m.noticesTransparentClick || - (!m.isTransparentAt(myself.bounds.origin))) && - (!(m instanceof ShadowMorph)) && - m.allParents().every(function (each) { - return each.isVisible; - })) { - result = m; - } - }); - if (result !== null) { - return result; +Morph.prototype.topMorphAt = function (p) { + if (!this.isVisible) return null; + for (var c = this.children, i = c.length; i--;) { + var result = c[i].topMorphAt(p); + if (result) return result; + } + return this.bounds.containsPoint(p) && (this.noticesTransparentClick || !this.isTransparentAt(p)) ? this : null; +}; +FrameMorph.prototype.topMorphAt = function (p) { + if (!(this.isVisible && this.bounds.containsPoint(p))) return null; + for (var c = this.children, i = c.length; i--;) { + var result = c[i].topMorphAt(p); + if (result) return result; } - return this.world; + return this.noticesTransparentClick || !this.isTransparentAt(p) ? this : null; +}; +ShadowMorph.prototype.topMorphAt = function () { + return null; +}; +HandMorph.prototype.morphAtPointer = function () { + return this.world.topMorphAt(this.bounds.origin) || this.world; }; /* @@ -9971,15 +9881,6 @@ HandMorph.prototype.destroyTemporaries = function () { }); }; -// HandMorph dragging optimization - -HandMorph.prototype.moveBy = function (delta) { - Morph.prototype.trackChanges = false; - HandMorph.uber.moveBy.call(this, delta); - Morph.prototype.trackChanges = true; - this.fullChanged(); -}; - // WorldMorph ////////////////////////////////////////////////////////// @@ -9987,7 +9888,7 @@ HandMorph.prototype.moveBy = function (delta) { // WorldMorph inherits from FrameMorph: -WorldMorph.prototype = new FrameMorph(); +WorldMorph.prototype = Object.create(FrameMorph.prototype); WorldMorph.prototype.constructor = WorldMorph; WorldMorph.uber = FrameMorph.prototype; @@ -10009,6 +9910,7 @@ WorldMorph.prototype.init = function (aCanvas, fillPage) { this.isDraggable = false; this.currentKey = null; // currently pressed key code this.worldCanvas = aCanvas; + this.noticesTransparentClick = true; // additional properties: this.stamp = Date.now(); // reference in multi-world setups @@ -105,7 +105,7 @@ InspectorMorph, ListMorph, Math, MenuItemMorph, MenuMorph, Morph, MorphicPreferences, MouseSensorMorph, Node, Object, PenMorph, Point, Rectangle, ScrollFrameMorph, ShadowMorph, SliderButtonMorph, SliderMorph, String, StringFieldMorph, StringMorph, TextMorph, -TriggerMorph, WorldMorph, clone, contains, copy, degrees, detect, +TriggerMorph, WorldMorph, contains, copy, degrees, detect, document, getDocumentPositionOf, isNaN, isObject, isString, newCanvas, nop, parseFloat, radians, standardSettings, touchScreenSettings, useBlurredShadows, version, window, modules, IDE_Morph, VariableDialogMorph, @@ -147,7 +147,7 @@ var SpriteHighlightMorph; // SpriteMorph inherits from PenMorph: -SpriteMorph.prototype = new PenMorph(); +SpriteMorph.prototype = Object.create(PenMorph.prototype); SpriteMorph.prototype.constructor = SpriteMorph; SpriteMorph.uber = PenMorph.prototype; @@ -583,7 +583,7 @@ SpriteMorph.prototype.initBlocks = function () { }, /* migrated to a newer block version: - + receiveClick: { type: 'hat', category: 'control', @@ -3008,7 +3008,7 @@ SpriteMorph.prototype.applyGraphicsEffects = function (canvas) { var i; if (value !== 0) { for (i = 0; i < p.length; i += 4) { - p[i] += value; //255 = 100% of this color + p[i] += value; //255 = 100% of this color p[i + 1] += value; p[i + 2] += value; } @@ -3290,7 +3290,7 @@ SpriteMorph.prototype.nestingBounds = function () { // SpriteMorph motion primitives -Morph.prototype.setPosition = function (aPoint, justMe) { +SpriteMorph.prototype.setPosition = function (aPoint, justMe) { // override the inherited default to make sure my parts follow // unless it's justMe var delta = aPoint.subtract(this.topLeft()); @@ -4289,7 +4289,7 @@ SpriteMorph.prototype.doScreenshot = function (imgSource, data) { // SpriteHighlightMorph inherits from Morph: -SpriteHighlightMorph.prototype = new Morph(); +SpriteHighlightMorph.prototype = Object.create(Morph.prototype); SpriteHighlightMorph.prototype.constructor = SpriteHighlightMorph; SpriteHighlightMorph.uber = Morph.prototype; @@ -4307,7 +4307,7 @@ function SpriteHighlightMorph() { // StageMorph inherits from FrameMorph: -StageMorph.prototype = new FrameMorph(); +StageMorph.prototype = Object.create(FrameMorph.prototype); StageMorph.prototype.constructor = StageMorph; StageMorph.uber = FrameMorph.prototype; @@ -5669,7 +5669,7 @@ StageMorph.prototype.replaceDoubleDefinitionsFor // SpriteBubbleMorph inherits from SpeechBubbleMorph: -SpriteBubbleMorph.prototype = new SpeechBubbleMorph(); +SpriteBubbleMorph.prototype = Object.create(SpeechBubbleMorph.prototype); SpriteBubbleMorph.prototype.constructor = SpriteBubbleMorph; SpriteBubbleMorph.uber = SpeechBubbleMorph.prototype; @@ -6168,7 +6168,7 @@ Costume.prototype.isTainted = function () { // SVG_Costume inherits from Costume: -SVG_Costume.prototype = new Costume(); +SVG_Costume.prototype = Object.create(Costume.prototype); SVG_Costume.prototype.constructor = SVG_Costume; SVG_Costume.uber = Costume.prototype; @@ -6219,7 +6219,7 @@ SVG_Costume.prototype.shrinkToFit = function (extentPoint) { // CostumeEditorMorph inherits from Morph: -CostumeEditorMorph.prototype = new Morph(); +CostumeEditorMorph.prototype = Object.create(Morph.prototype); CostumeEditorMorph.prototype.constructor = CostumeEditorMorph; CostumeEditorMorph.uber = Morph.prototype; @@ -6454,7 +6454,7 @@ Note.prototype.stop = function () { // CellMorph inherits from BoxMorph: -CellMorph.prototype = new BoxMorph(); +CellMorph.prototype = Object.create(BoxMorph.prototype); CellMorph.prototype.constructor = CellMorph; CellMorph.uber = BoxMorph.prototype; @@ -6794,7 +6794,7 @@ CellMorph.prototype.mouseClickLeft = function (pos) { // WatcherMorph inherits from BoxMorph: -WatcherMorph.prototype = new BoxMorph(); +WatcherMorph.prototype = Object.create(BoxMorph.prototype); WatcherMorph.prototype.constructor = WatcherMorph; WatcherMorph.uber = BoxMorph.prototype; @@ -7281,7 +7281,7 @@ WatcherMorph.prototype.drawNew = function () { // StagePrompterMorph inherits from BoxMorph: -StagePrompterMorph.prototype = new BoxMorph(); +StagePrompterMorph.prototype = Object.create(BoxMorph.prototype); StagePrompterMorph.prototype.constructor = StagePrompterMorph; StagePrompterMorph.uber = BoxMorph.prototype; @@ -81,7 +81,7 @@ var PaintColorPickerMorph; // A complete paint editor -PaintEditorMorph.prototype = new DialogBoxMorph(); +PaintEditorMorph.prototype = Object.create(DialogBoxMorph.prototype); PaintEditorMorph.prototype.constructor = PaintEditorMorph; PaintEditorMorph.uber = DialogBoxMorph.prototype; @@ -92,6 +92,7 @@ function PaintEditorMorph() { } PaintEditorMorph.prototype.init = function () { + PaintEditorMorph.uber.init.call(this); // additional properties: this.paper = null; // paint canvas this.oncancel = null; @@ -476,7 +477,7 @@ PaintEditorMorph.prototype.getUserColor = function () { // A large hsl color picker -PaintColorPickerMorph.prototype = new Morph(); +PaintColorPickerMorph.prototype = Object.create(Morph.prototype); PaintColorPickerMorph.prototype.constructor = PaintColorPickerMorph; PaintColorPickerMorph.uber = Morph.prototype; @@ -485,6 +486,7 @@ function PaintColorPickerMorph(extent, action) { } PaintColorPickerMorph.prototype.init = function (extent, action) { + PaintColorPickerMorph.uber.init.call(this); this.setExtent(extent || new Point(200, 100)); this.action = action || nop; this.drawNew(); @@ -552,7 +554,7 @@ PaintColorPickerMorph.prototype.mouseMove = modify its image, based on a 'tool' property. */ -PaintCanvasMorph.prototype = new Morph(); +PaintCanvasMorph.prototype = Object.create(Morph.prototype); PaintCanvasMorph.prototype.constructor = PaintCanvasMorph; PaintCanvasMorph.uber = Morph.prototype; @@ -561,6 +563,7 @@ function PaintCanvasMorph(shift) { } PaintCanvasMorph.prototype.init = function (shift) { + PaintCanvasMorph.uber.init.call(this); this.rotationCenter = new Point(240, 180); this.dragRect = null; this.previousDragPoint = null; @@ -961,6 +964,7 @@ PaintCanvasMorph.prototype.buildContents = function () { }; PaintCanvasMorph.prototype.drawNew = function () { + if (!this.background) return; var can = newCanvas(this.extent()); this.merge(this.background, can); this.merge(this.paper, can); @@ -246,7 +246,7 @@ var SnapSerializer; // SnapSerializer inherits from XML_Serializer: -SnapSerializer.prototype = new XML_Serializer(); +SnapSerializer.prototype = Object.create(XML_Serializer.prototype); SnapSerializer.prototype.constructor = SnapSerializer; SnapSerializer.uber = XML_Serializer.prototype; @@ -274,6 +274,7 @@ SnapSerializer.prototype.watcherLabels = { // SnapSerializer instance creation: function SnapSerializer() { + XML_Serializer.call(this); this.init(); } @@ -91,7 +91,7 @@ var InputFieldMorph; // PushButtonMorph inherits from TriggerMorph: -PushButtonMorph.prototype = new TriggerMorph(); +PushButtonMorph.prototype = Object.create(TriggerMorph.prototype); PushButtonMorph.prototype.constructor = PushButtonMorph; PushButtonMorph.uber = TriggerMorph.prototype; @@ -476,7 +476,7 @@ PushButtonMorph.prototype.createLabel = function () { // ToggleButtonMorph inherits from PushButtonMorph: -ToggleButtonMorph.prototype = new PushButtonMorph(); +ToggleButtonMorph.prototype = Object.create(PushButtonMorph.prototype); ToggleButtonMorph.prototype.constructor = ToggleButtonMorph; ToggleButtonMorph.uber = PushButtonMorph.prototype; @@ -900,7 +900,7 @@ ToggleButtonMorph.prototype.show = function () { // TabMorph inherits from ToggleButtonMorph: -TabMorph.prototype = new ToggleButtonMorph(); +TabMorph.prototype = Object.create(ToggleButtonMorph.prototype); TabMorph.prototype.constructor = TabMorph; TabMorph.uber = ToggleButtonMorph.prototype; @@ -1022,7 +1022,7 @@ TabMorph.prototype.drawEdges = function ( // ToggleMorph inherits from PushButtonMorph: -ToggleMorph.prototype = new PushButtonMorph(); +ToggleMorph.prototype = Object.create(PushButtonMorph.prototype); ToggleMorph.prototype.constructor = ToggleMorph; ToggleMorph.uber = PushButtonMorph.prototype; @@ -1270,7 +1270,7 @@ ToggleMorph.prototype.show = ToggleButtonMorph.prototype.show; // ToggleElementMorph inherits from TriggerMorph: -ToggleElementMorph.prototype = new TriggerMorph(); +ToggleElementMorph.prototype = Object.create(TriggerMorph.prototype); ToggleElementMorph.prototype.constructor = ToggleElementMorph; ToggleElementMorph.uber = TriggerMorph.prototype; @@ -1440,7 +1440,7 @@ ToggleElementMorph.prototype.mouseClickLeft // DialogBoxMorph inherits from Morph: -DialogBoxMorph.prototype = new Morph(); +DialogBoxMorph.prototype = Object.create(Morph.prototype); DialogBoxMorph.prototype.constructor = DialogBoxMorph; DialogBoxMorph.uber = Morph.prototype; @@ -2866,7 +2866,7 @@ DialogBoxMorph.prototype.outlinePathBody = function (context, radius) { // AlignmentMorph inherits from Morph: -AlignmentMorph.prototype = new Morph(); +AlignmentMorph.prototype = Object.create(Morph.prototype); AlignmentMorph.prototype.constructor = AlignmentMorph; AlignmentMorph.uber = Morph.prototype; @@ -2940,7 +2940,7 @@ AlignmentMorph.prototype.fixLayout = function () { // InputFieldMorph inherits from Morph: -InputFieldMorph.prototype = new Morph(); +InputFieldMorph.prototype = Object.create(Morph.prototype); InputFieldMorph.prototype.constructor = InputFieldMorph; InputFieldMorph.uber = Morph.prototype; @@ -61,7 +61,7 @@ */ -/*global modules, isString, detect, Node, isNil*/ +/*global modules, detect, Node, isNil*/ // Global stuff //////////////////////////////////////////////////////// @@ -85,7 +85,8 @@ function ReadStream(arrayOrString) { // ReadStream constants: -ReadStream.prototype.space = /[\s]/; +ReadStream.prototype.nonSpace = /\S|$/g; +ReadStream.prototype.nonWord = /[\s\>\/\=]|$/g; // ReadStream accessing: @@ -115,46 +116,26 @@ ReadStream.prototype.atEnd = function () { // ReadStream accessing String contents: -ReadStream.prototype.upTo = function (regex) { - var i, start; - if (!isString(this.contents)) {return ''; } - i = this.contents.substr(this.index).search(regex); - if (i === -1) { - return ''; - } - start = this.index; - this.index += i; - return this.contents.substring(start, this.index); +ReadStream.prototype.upTo = function (str) { + var i = this.contents.indexOf(str, this.index); + return i === -1 ? '' : this.contents.slice(this.index, this.index = i); }; -ReadStream.prototype.peekUpTo = function (regex) { - if (!isString(this.contents)) {return ''; } - var i = this.contents.substr(this.index).search(regex); - if (i === -1) { - return ''; - } - return this.contents.substring(this.index, this.index + i); +ReadStream.prototype.peekUpTo = function (str) { + var i = this.contents.indexOf(str, this.index); + return i === -1 ? '' : this.contents.slice(this.index, i); }; ReadStream.prototype.skipSpace = function () { - if (!isString(this.contents)) {return ''; } - var ch = this.peek(); - while (this.space.test(ch) && ch !== '') { - this.skip(); - ch = this.peek(); - } + this.nonSpace.lastIndex = this.index; + var result = this.nonSpace.exec(this.contents); + if (result) this.index = result.index; }; ReadStream.prototype.word = function () { - var i, start; - if (!isString(this.contents)) {return ''; } - i = this.contents.substr(this.index).search(/[\s\>\/\=]|$/); - if (i === -1) { - return ''; - } - start = this.index; - this.index += i; - return this.contents.substring(start, this.index); + this.nonWord.lastIndex = this.index; + var result = this.nonWord.exec(this.contents); + return result ? this.contents.slice(this.index, this.index = result.index) : ''; }; // XML_Element /////////////////////////////////////////////////////////// @@ -166,7 +147,7 @@ ReadStream.prototype.word = function () { // XML_Element inherits from Node: -XML_Element.prototype = new Node(); +XML_Element.prototype = Object.create(Node.prototype); XML_Element.prototype.constructor = XML_Element; XML_Element.uber = Node.prototype; @@ -190,9 +171,7 @@ XML_Element.prototype.init = function (tag, contents, parent) { XML_Element.uber.init.call(this); // override inherited properties - if (parent instanceof XML_Element) { - parent.addChild(this); - } + if (parent) parent.addChild(this); }; // XML_Element DOM navigation: (aside from what's inherited from Node) @@ -318,51 +297,18 @@ XML_Element.prototype.escape = function (string, ignoreQuotes) { }; XML_Element.prototype.unescape = function (string) { - var stream = new ReadStream(string), - result = '', - ch, - esc; - - function nextPut(str) { - result += str; - stream.upTo(';'); - stream.skip(); - } - - while (!stream.atEnd()) { - ch = stream.next(); - if (ch === '&') { - esc = stream.peekUpTo(';'); - switch (esc) { - case 'apos': - nextPut('\''); - break; - case 'quot': - nextPut('\"'); - break; - case 'lt': - nextPut('<'); - break; - case 'gt': - nextPut('>'); - break; - case 'amp': - nextPut('&'); - break; - case '#xD': - nextPut('\n'); - break; - case '#126': - nextPut('~'); - break; - default: - result += ch; - } - } else { - result += ch; + return string.replace(/&(amp|apos|quot|lt|gt|#xD|#126);/g, function(_, name) { + switch (name) { + case 'amp': return '&'; + case 'apos': return '\''; + case 'quot': return '"'; + case 'lt': return '<'; + case 'gt': return '>'; + case '#xD': return '\n'; + case '#126': return '~'; + default: console.warn('unreachable'); } - } - return result; + }); }; // XML_Element parsing: @@ -375,10 +321,7 @@ XML_Element.prototype.parseString = function (string) { }; XML_Element.prototype.parseStream = function (stream) { - var key, - value, - ch, - child; + var key, value, ch, child; // tag: this.tag = stream.word(); @@ -395,9 +338,7 @@ XML_Element.prototype.parseStream = function (stream) { stream.skipSpace(); ch = stream.next(); if (ch !== '"' && ch !== "'") { - throw new Error( - 'Expected single- or double-quoted attribute value' - ); + throw new Error('Expected single- or double-quoted attribute value'); } value = stream.upTo(ch); stream.skip(1); @@ -407,7 +348,7 @@ XML_Element.prototype.parseStream = function (stream) { } // empty tag: - if (stream.peek() === '/') { + if (ch === '/') { stream.skip(); if (stream.next() !== '>') { throw new Error('Expected ">" after "/" in empty tag'); |
