From 00db1cce3f3af9971984258528def240f1519f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20M=C3=B6nig?= Date: Mon, 10 Apr 2017 10:28:23 +0200 Subject: [PATCH] Revert to 4.0.10 to prepare for newly surfaced bug in the Chrome browser --- blocks.js | 218 ++++++++-------------------------------------------- byob.js | 98 +++-------------------- gui.js | 45 ++--------- history.txt | 16 +++- lang-de.js | 14 +--- lists.js | 4 +- locale.js | 4 +- morphic.js | 58 ++++---------- objects.js | 137 ++++++++------------------------- store.js | 26 ++----- threads.js | 29 ++----- 11 files changed, 126 insertions(+), 523 deletions(-) mode change 100644 => 100755 blocks.js mode change 100644 => 100755 byob.js mode change 100644 => 100755 lang-de.js mode change 100644 => 100755 lists.js mode change 100644 => 100755 locale.js mode change 100644 => 100755 morphic.js mode change 100644 => 100755 objects.js mode change 100644 => 100755 store.js mode change 100644 => 100755 threads.js diff --git a/blocks.js b/blocks.js old mode 100644 new mode 100755 index cbfe4a75..9b2a8281 --- a/blocks.js +++ b/blocks.js @@ -150,7 +150,7 @@ CustomCommandBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2017-March-01'; +modules.blocks = '2017-January-13'; var SyntaxElementMorph; var BlockMorph; @@ -567,20 +567,14 @@ SyntaxElementMorph.prototype.revertToDefaultInput = function (arg, noValues) { if (idx !== -1) { if (this instanceof BlockMorph) { deflt = this.labelPart(this.parseSpec(this.blockSpec)[idx]); - if (this.definition) { - if (deflt instanceof InputSlotMorph) { - deflt.setChoices.apply( - deflt, - this.definition.inputOptionsOfIdx(inp) - ); - } - if (deflt instanceof InputSlotMorph || - (deflt instanceof BooleanSlotMorph) - ) { - deflt.setContents( - this.definition.defaultValueOfInputIdx(inp) - ); - } + if (deflt instanceof InputSlotMorph && this.definition) { + deflt.setChoices.apply( + deflt, + this.definition.inputOptionsOfIdx(inp) + ); + deflt.setContents( + this.definition.defaultValueOfInputIdx(inp) + ); } } else if (this instanceof MultiArgMorph) { deflt = this.labelPart(this.slotSpec); @@ -1316,21 +1310,6 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { ); part.setContents(['number']); break; - case '%mapValue': - part = new InputSlotMorph( - null, - false, - { - String : ['String'], - Number : ['Number'], - 'true' : ['true'], - 'false' : ['false'] - }, - true - ); - part.setContents(['String']); - part.isStatic = true; - break; case '%var': part = new InputSlotMorph( null, @@ -1874,18 +1853,17 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic) { txt, img, morphToShow, - rcvr, isClickable = false, ide = this.parentThatIsA(IDE_Morph), + rcvr = this.receiver(), anchor = this, pos = this.rightCenter().add(new Point(2, 0)), sf = this.parentThatIsA(ScrollFrameMorph), wrrld = this.world(); - if ((value === undefined) || !wrrld || !this.receiver) { + if ((value === undefined) || !wrrld) { return null; } - rcvr = this.receiver(); if (value instanceof ListWatcherMorph) { morphToShow = value; morphToShow.update(true); @@ -2197,7 +2175,7 @@ BlockMorph.prototype.init = function (silently) { BlockMorph.uber.init.call(this, silently); this.color = new Color(0, 17, 173); - this.cachedInputs = null; + this.cashedInputs = null; }; BlockMorph.prototype.receiver = function () { @@ -2277,10 +2255,6 @@ BlockMorph.prototype.setSpec = function (spec, silently) { inputIdx += 1; } part = myself.labelPart(word); - if (isNil(part)) { - // console.log('could not create label part', word); - return; - } myself.add(part); if (!(part instanceof CommandSlotMorph || part instanceof StringMorph)) { @@ -2520,13 +2494,9 @@ BlockMorph.prototype.userMenu = function () { function () { var cpy = myself.fullCopy(), nb = cpy.nextBlock(), - ide = myself.parentThatIsA(IDE_Morph), - blockEditor = myself.parentThatIsA(BlockEditorMorph); + ide = myself.parentThatIsA(IDE_Morph); if (nb) {nb.destroy(); } cpy.pickUp(world); - if (!ide && blockEditor) { - ide = blockEditor.target.parentThatIsA(IDE_Morph); - } if (ide) { world.hand.grabOrigin = { origin: ide.palette, @@ -2569,16 +2539,6 @@ BlockMorph.prototype.userMenu = function () { ); }); } - proc.homeContext.variables.names().forEach(function (vn) { - if (!contains(vNames, vn)) { - menu.addItem( - vn + '...', - function () { - proc.doShowVar(vn); - } - ); - } - }); return menu; } if (this.parent.parentThatIsA(RingMorph)) { @@ -2864,10 +2824,7 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) { if (old instanceof ReporterBlockMorph) { leftOver.push(old); } else if (old instanceof CommandSlotMorph) { - nb = old.nestedBlock(); - if (nb) { - leftOver.push(nb); - } + leftOver.push(old.nestedBlock()); } } this.cachedInputs = null; @@ -3862,16 +3819,11 @@ BlockMorph.prototype.allComments = function () { }); }; -BlockMorph.prototype.destroy = function (justThis) { - if (justThis) { - if (!isNil(this.comment)) { - this.comment.destroy(); - } - } else { - this.allComments().forEach(function (comment) { - comment.destroy(); - }); - } +BlockMorph.prototype.destroy = function () { + this.allComments().forEach(function (comment) { + comment.destroy(); + }); + if (!this.parent || !this.parent.topBlock && this.activeProcess()) { this.activeProcess().stop(); @@ -4351,7 +4303,7 @@ CommandBlockMorph.prototype.userDestroyJustThis = function () { } else if (cs && (cs.nestedBlock() === this)) { above = cs; } - this.destroy(true); // just this block + this.destroy(); if (nb) { if (above instanceof CommandSlotMorph) { above.nestedBlock(nb); @@ -8348,20 +8300,13 @@ InputSlotMorph.prototype.freshTextEdit = function (aStringOrTextMorph) { InputSlotMorph.prototype.userMenu = function () { var menu = new MenuMorph(this); - if (!StageMorph.prototype.enableCodeMapping) { + if (!StageMorph.prototype.enableCodeMapping || this.isNumeric) { return this.parent.userMenu(); } - if (this.isNumeric) { - menu.addItem( - 'code number mapping...', - 'mapNumberToCode' - ); - } else { - menu.addItem( - 'code string mapping...', - 'mapStringToCode' - ); - } + menu.addItem( + 'code string mapping...', + 'mapToCode' + ); return menu; }; @@ -8373,7 +8318,7 @@ InputSlotMorph.prototype.userMenu = function () { it's not part of Snap's evaluator and not needed for Snap itself */ -InputSlotMorph.prototype.mapStringToCode = function () { +InputSlotMorph.prototype.mapToCode = function () { // private - open a dialog box letting the user map code via the GUI new DialogBoxMorph( this, @@ -8388,30 +8333,12 @@ InputSlotMorph.prototype.mapStringToCode = function () { ); }; -InputSlotMorph.prototype.mapNumberToCode = function () { - // private - open a dialog box letting the user map code via the GUI - new DialogBoxMorph( - this, - function (code) { - StageMorph.prototype.codeMappings.number = code; - }, - this - ).promptCode( - 'Code mapping - Number <#1>', - StageMorph.prototype.codeMappings.number || '', - this.world() - ); -}; - InputSlotMorph.prototype.mappedCode = function () { - var block = this.parentThatIsA(BlockMorph), - val = this.evaluate(), - code; + var code = StageMorph.prototype.codeMappings.string || '<#1>', + block = this.parentThatIsA(BlockMorph), + val = this.evaluate(); - if (this.isNumeric) { - code = StageMorph.prototype.codeMappings.number || '<#1>'; - return code.replace(/<#1>/g, val); - } + if (this.isNumeric) {return val; } if (!isNaN(parseFloat(val))) {return val; } if (!isString(val)) {return val; } if (block && contains( @@ -8420,7 +8347,6 @@ InputSlotMorph.prototype.mappedCode = function () { )) { return val; } - code = StageMorph.prototype.codeMappings.string || '<#1>'; return code.replace(/<#1>/g, val); }; @@ -8879,10 +8805,6 @@ BooleanSlotMorph.prototype = new ArgMorph(); BooleanSlotMorph.prototype.constructor = BooleanSlotMorph; BooleanSlotMorph.uber = ArgMorph.prototype; -// BooleanSlotMorph preferences settings - -BooleanSlotMorph.prototype.isTernary = true; - // BooleanSlotMorph instance creation: function BooleanSlotMorph(initialValue) { @@ -8909,12 +8831,6 @@ BooleanSlotMorph.prototype.isEmptySlot = function () { return this.value === null; }; -BooleanSlotMorph.prototype.isBinary = function () { - return !this.isTernary && - isNil(this.parentThatIsA(RingMorph)) && - !isNil(this.parentThatIsA(ScriptsMorph)); -}; - BooleanSlotMorph.prototype.setContents = function (boolOrNull, silently) { this.value = (typeof boolOrNull === 'boolean') ? boolOrNull : null; if (silently) {return; } @@ -8924,7 +8840,7 @@ BooleanSlotMorph.prototype.setContents = function (boolOrNull, silently) { BooleanSlotMorph.prototype.toggleValue = function () { var ide = this.parentThatIsA(IDE_Morph); - if (this.isStatic || this.isBinary()) { + if (this.isStatic) { this.setContents(!this.value, true); } else { switch (this.value) { @@ -8971,7 +8887,7 @@ BooleanSlotMorph.prototype.mouseClickLeft = function () { BooleanSlotMorph.prototype.mouseEnter = function () { if (this.isStatic) {return; } - if (this.value === false && !this.isBinary()) { + if (this.value === false) { var oldValue = this.value; this.value = null; this.drawNew(3); @@ -8989,72 +8905,6 @@ BooleanSlotMorph.prototype.mouseLeave = function () { this.changed(); }; -// BooleanSlotMorph menu: - -BooleanSlotMorph.prototype.userMenu = function () { - var menu = new MenuMorph(this); - if (!StageMorph.prototype.enableCodeMapping) { - return this.parent.userMenu(); - } - if (this.evaluate() === true) { - menu.addItem( - 'code true mapping...', - 'mapTrueToCode' - ); - } else { - menu.addItem( - 'code false mapping...', - 'mapFalseToCode' - ); - } - return menu; -}; - -// BooleanSlotMorph code mapping - -/* - code mapping lets you use blocks to generate arbitrary text-based - source code that can be exported and compiled / embedded elsewhere, - it's not part of Snap's evaluator and not needed for Snap itself -*/ - -BooleanSlotMorph.prototype.mapTrueToCode = function () { - // private - open a dialog box letting the user map code via the GUI - new DialogBoxMorph( - this, - function (code) { - StageMorph.prototype.codeMappings['true'] = code; - }, - this - ).promptCode( - 'Code mapping - true', - StageMorph.prototype.codeMappings['true'] || 'true', - this.world() - ); -}; - -BooleanSlotMorph.prototype.mapFalseToCode = function () { - // private - open a dialog box letting the user map code via the GUI - new DialogBoxMorph( - this, - function (code) { - StageMorph.prototype.codeMappings['false'] = code; - }, - this - ).promptCode( - 'Code mapping - false', - StageMorph.prototype.codeMappings['false'] || 'false', - this.world() - ); -}; - -BooleanSlotMorph.prototype.mappedCode = function () { - if (this.evaluate() === true) { - return StageMorph.prototype.codeMappings.boolTrue || 'true'; - } - return StageMorph.prototype.codeMappings.boolFalse || 'false'; -}; - // BooleanSlotMorph drawing: BooleanSlotMorph.prototype.drawNew = function (progress) { @@ -12900,10 +12750,6 @@ CommentMorph.prototype.startFollowing = function (topBlock, world) { this.addShadow(); this.stickyOffset = this.position().subtract(this.block.position()); this.step = function () { - if (!this.block) { // kludge - only needed for "redo" - this.stopFollowing(); - return; - } this.setPosition(this.block.position().add(this.stickyOffset)); }; }; diff --git a/byob.js b/byob.js old mode 100644 new mode 100755 index d896d7c8..8652e53e --- a/byob.js +++ b/byob.js @@ -103,12 +103,11 @@ StringMorph, nop, newCanvas, radians, BoxMorph, ArrowMorph, PushButtonMorph, contains, InputSlotMorph, ToggleButtonMorph, IDE_Morph, MenuMorph, copy, ToggleElementMorph, Morph, fontHeight, StageMorph, SyntaxElementMorph, SnapSerializer, CommentMorph, localize, CSlotMorph, MorphicPreferences, -SymbolMorph, isNil, CursorMorph, VariableFrame, WatcherMorph, Variable, -BooleanSlotMorph*/ +SymbolMorph, isNil, CursorMorph, VariableFrame, WatcherMorph, Variable*/ // Global stuff //////////////////////////////////////////////////////// -modules.byob = '2017-March-01'; +modules.byob = '2017-January-03'; // Declarations @@ -237,8 +236,6 @@ CustomBlockDefinition.prototype.blockSpec = function () { parts.forEach(function (part) { if (part[0] === '%' && part.length > 1) { spec = myself.typeOf(part.slice(1)); - } else if (part === '$nl') { - spec = '%br'; } else { spec = part; } @@ -546,7 +543,7 @@ CustomCommandBlockMorph.prototype.refreshDefaults = function () { var inputs = this.inputs(), idx = 0, myself = this; inputs.forEach(function (inp) { - if (inp instanceof InputSlotMorph || inp instanceof BooleanSlotMorph) { + if (inp instanceof InputSlotMorph) { inp.setContents(myself.definition.defaultValueOfInputIdx(idx)); } idx += 1; @@ -734,7 +731,7 @@ CustomCommandBlockMorph.prototype.mouseClickLeft = function () { }; CustomCommandBlockMorph.prototype.edit = function () { - var myself = this, editor, block, hat, rcvr; + var myself = this, editor, block, hat; if (this.isPrototype) { block = this.definition.blockInstance(); @@ -759,22 +756,8 @@ CustomCommandBlockMorph.prototype.edit = function () { myself.isInUse() ); } else { - // checking for custom block inheritance, highly experimental - rcvr = this.receiver(); - - /* // under construction, commented out for now - if (rcvr && contains( - Object.keys(rcvr.inheritedBlocks()), - this.definition.blockSpec() - ) - ) { - this.duplicateBlockDefinition(); - return; - } - */ - Morph.prototype.trackChanges = false; - editor = new BlockEditorMorph(this.definition, rcvr); + editor = new BlockEditorMorph(this.definition, this.receiver()); editor.popUp(); Morph.prototype.trackChanges = true; editor.changed(); @@ -840,7 +823,6 @@ CustomCommandBlockMorph.prototype.userMenu = function () { var hat = this.parentThatIsA(PrototypeHatBlockMorph), rcvr = this.receiver(), myself = this, - shiftClicked = this.world().currentKey === 16, menu; function monitor(vName) { @@ -919,15 +901,8 @@ CustomCommandBlockMorph.prototype.userMenu = function () { } else { menu.addLine(); } - if (shiftClicked) { - // menu.addItem("export definition...", 'exportBlockDefinition'); - menu.addItem( - "duplicate block definition...", - 'duplicateBlockDefinition', - null, - new Color(100, 0, 0) - ); - } + + // menu.addItem("export definition...", 'exportBlockDefinition'); menu.addItem("delete block definition...", 'deleteBlockDefinition'); this.variables.names().forEach(function (vName) { @@ -945,20 +920,6 @@ CustomCommandBlockMorph.prototype.exportBlockDefinition = function () { ide.saveXMLAs(xml, this.spec); }; -CustomCommandBlockMorph.prototype.duplicateBlockDefinition = function () { - var rcvr = this.receiver(), - dup = this.definition.copyAndBindTo(rcvr), - ide = this.parentThatIsA(IDE_Morph); - if (this.definition.isGlobal) { - ide.stage.globalBlocks.push(dup); - } else { - rcvr.customBlocks.push(dup); - } - ide.flushPaletteCache(); - ide.refreshPalette(); - new BlockEditorMorph(dup, rcvr).popUp(); -}; - CustomCommandBlockMorph.prototype.deleteBlockDefinition = function () { var idx, rcvr, stage, ide, myself = this, block; if (this.isPrototype) { @@ -1138,9 +1099,6 @@ CustomReporterBlockMorph.prototype.isInUse CustomReporterBlockMorph.prototype.userMenu = CustomCommandBlockMorph.prototype.userMenu; -CustomReporterBlockMorph.prototype.duplicateBlockDefinition - = CustomCommandBlockMorph.prototype.duplicateBlockDefinition; - CustomReporterBlockMorph.prototype.deleteBlockDefinition = CustomCommandBlockMorph.prototype.deleteBlockDefinition; @@ -2505,8 +2463,6 @@ BlockLabelFragmentMorph.prototype.userMenu = function () { name ); }); - menu.addLine(); - menu.addItem('\u23CE ' + localize('new line'), 'nl'); return menu; }; @@ -2851,13 +2807,7 @@ InputSlotDialogMorph.prototype.getInput = function () { } if (lbl) { this.fragment.labelString = lbl; - if (contains(['%b', '%boolUE'], this.fragment.type)) { - this.fragment.defaultValue = - this.slots.defaultSwitch.evaluate(); - } else { - this.fragment.defaultValue = - this.slots.defaultInputField.getValue(); - } + this.fragment.defaultValue = this.slots.defaultInputField.getValue(); return lbl; } else if (!this.noDelete) { this.fragment.isDeleted = true; @@ -2972,7 +2922,6 @@ InputSlotDialogMorph.prototype.symbolMenu = function () { '$' + symbol ]); }); - symbols.push(['\u23CE ' + localize('new line'), '$nl']); return symbols; }; @@ -2983,7 +2932,7 @@ InputSlotDialogMorph.prototype.deleteFragment = function () { InputSlotDialogMorph.prototype.createSlotTypeButtons = function () { // populate my 'slots' area with radio buttons, labels and input fields - var myself = this, defLabel, defInput, defSwitch, + var myself = this, defLabel, defInput, oldFlag = Morph.prototype.trackChanges; Morph.prototype.trackChanges = false; @@ -3025,7 +2974,7 @@ InputSlotDialogMorph.prototype.createSlotTypeButtons = function () { defLabel.setColor(new Color(255, 255, 255)); defLabel.refresh = function () { if (myself.isExpanded && contains( - ['%s', '%n', '%txt', '%anyUE', '%b', '%boolUE'], + ['%s', '%n', '%txt', '%anyUE'], myself.fragment.type )) { defLabel.show(); @@ -3042,10 +2991,7 @@ InputSlotDialogMorph.prototype.createSlotTypeButtons = function () { defInput.contents().drawNew(); defInput.setWidth(50); defInput.refresh = function () { - if (myself.isExpanded && contains( - ['%s', '%n', '%txt', '%anyUE'], - myself.fragment.type - )) { + if (defLabel.isVisible) { defInput.show(); if (myself.fragment.type === '%n') { defInput.setIsNumeric(true); @@ -3060,21 +3006,6 @@ InputSlotDialogMorph.prototype.createSlotTypeButtons = function () { this.slots.add(defInput); defInput.drawNew(); - defSwitch = new BooleanSlotMorph(this.fragment.defaultValue); - defSwitch.refresh = function () { - if (myself.isExpanded && contains( - ['%b', '%boolUE'], - myself.fragment.type - )) { - defSwitch.show(); - } else { - defSwitch.hide(); - } - }; - this.slots.defaultSwitch = defSwitch; - this.slots.add(defSwitch); - defSwitch.drawNew(); - Morph.prototype.trackChanges = oldFlag; }; @@ -3257,13 +3188,6 @@ InputSlotDialogMorph.prototype.fixSlotsLayout = function () { 0 )) ); - this.slots.defaultSwitch.setCenter( - this.slots.defaultInputLabel.center().add(new Point( - this.slots.defaultSwitch.width() / 2 - + this.slots.defaultInputLabel.width() / 2 + 5, - 0 - )) - ); Morph.prototype.trackChanges = oldFlag; this.slots.changed(); }; diff --git a/gui.js b/gui.js index 98e63ab9..f63a950f 100644 --- a/gui.js +++ b/gui.js @@ -70,11 +70,11 @@ fontHeight, hex_sha512, sb, CommentMorph, CommandBlockMorph, BlockLabelPlaceHolderMorph, Audio, SpeechBubbleMorph, ScriptFocusMorph, XML_Element, WatcherMorph, BlockRemovalDialogMorph, saveAs, TableMorph, isSnapObject, isRetinaEnabled, disableRetinaSupport, enableRetinaSupport, -isRetinaSupported, SliderMorph, Animation, BooleanSlotMorph*/ +isRetinaSupported, SliderMorph, Animation*/ // Global stuff //////////////////////////////////////////////////////// -modules.gui = '2017-March-01'; +modules.gui = '2017-January-13'; // Declarations @@ -2733,16 +2733,6 @@ IDE_Morph.prototype.settingsMenu = function () { 'uncheck for round ends of lines', 'check for flat ends of lines' ); - addPreference( - 'Ternary Boolean slots', - function () { - BooleanSlotMorph.prototype.isTernary = - !BooleanSlotMorph.prototype.isTernary; - }, - BooleanSlotMorph.prototype.isTernary, - 'uncheck to only\ntoggle true / false\noutside of rings', - 'check to enable toggling\nBoolean slots to empty' - ); addPreference( 'Codification support', function () { @@ -3197,7 +3187,7 @@ IDE_Morph.prototype.aboutSnap = function () { module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn, world = this.world(); - aboutTxt = 'Snap! 4.0.10.1 - dev -\nBuild Your Own Blocks\n\n' + aboutTxt = 'Snap! 4.0.10\nBuild Your Own Blocks\n\n' + 'Copyright \u24B8 2017 Jens M\u00F6nig and ' + 'Brian Harvey\n' + 'jens@moenig.org, bh@cs.berkeley.edu\n\n' @@ -3425,7 +3415,6 @@ IDE_Morph.prototype.newProject = function () { StageMorph.prototype.enableInheritance = false; StageMorph.prototype.enableSublistIDs = false; SpriteMorph.prototype.useFlatLineEnds = false; - BooleanSlotMorph.prototype.isTernary = true; Process.prototype.enableLiveCoding = false; this.setProjectName(''); this.projectNotes = ''; @@ -6277,7 +6266,7 @@ LibraryImportDialogMorph.prototype.init = function (ide, librariesData) { LibraryImportDialogMorph.uber.init.call( this, this, // target - this.importLibrary, // action + null, // function null // environment ); @@ -6394,7 +6383,7 @@ LibraryImportDialogMorph.prototype.installLibrariesList = function () { myself.displayBlocks(item.fileName); } else { myself.showMessage( - localize('Loading preview') + '\n' + localize(item.name) + localize('Loading') + '\n' + localize(item.name) ); myself.ide.getURL( myself.ide.resourceURL('libraries', item.fileName), @@ -7082,26 +7071,8 @@ CostumeIconMorph.prototype.init = function (aCostume, aTemplate) { this.fps = 1; }; -CostumeIconMorph.prototype.createThumbnail = function () { - var txt; - SpriteIconMorph.prototype.createThumbnail.call(this); - if (this.object instanceof SVG_Costume) { - txt = new StringMorph( - 'svg', - this.fontSize * 0.8, - this.fontStyle, - false, - false, - false, - this.labelShadowOffset, - this.labelShadowColor, - this.labelColor - ); - txt.setBottom(this.thumbnail.bottom()); - this.thumbnail.add(txt); - } -}; - +CostumeIconMorph.prototype.createThumbnail + = SpriteIconMorph.prototype.createThumbnail; CostumeIconMorph.prototype.createLabel = SpriteIconMorph.prototype.createLabel; @@ -7174,7 +7145,7 @@ CostumeIconMorph.prototype.renameCostume = function () { } } ).prompt( - ide.currentSprite instanceof SpriteMorph ? + this.currentSprite instanceof SpriteMorph ? 'rename costume' : 'rename background', costume.name, this.world() diff --git a/history.txt b/history.txt index 99ce4f4d..78ae5ebd 100755 --- a/history.txt +++ b/history.txt @@ -3304,7 +3304,7 @@ Fixes: * Translation updates (Russian, Polish, Danish, Portuguese, Catalan, German) -== v4.0.10.1 - in development - === +== v4.0.11 - in development - === 170119 ------ @@ -3389,3 +3389,17 @@ Fixes: 170307 ------ * Morphic, Objects, translation: let sprites’s rotation centers be adjusted onstage +* BYOB: added attributes for dynamic method definition lookup +* BYOB, Blocks, Objects, GUI: distinguish custom blocks by shared “isCustomBlock” attribute + +170321 +------ +* Change: Methods (sprite-local custom blocks) can no longer have block (instance) vars + +170322 +------ +* sprite-local custom block inheritance, first pass, still under heavy development + +170410 +------ +* Revert to 4.0.10 to prepare for newly surfaced bug in the Chrome browser diff --git a/lang-de.js b/lang-de.js old mode 100644 new mode 100755 index e46872f8..2398a072 --- a/lang-de.js +++ b/lang-de.js @@ -185,7 +185,7 @@ SnapTranslator.dict.de = { 'translator_e-mail': 'jens@moenig.org', // optional 'last_changed': - '2017-03-07', // this, too, will appear in the Translators tab + '2017-01-10', // this, too, will appear in the Translators tab // GUI // control bar: @@ -845,8 +845,6 @@ SnapTranslator.dict.de = { 'einschalten f\u00fcr flache\nPinselstrichenden', 'uncheck for round ends of lines': 'auschalten f\u00fcr runde\nPinselstrichenden', - 'Ternary Boolean slots': - 'Ternäre Bool\'sche Inputs', 'Inheritance support': 'Prototypische Vererbung', @@ -897,8 +895,6 @@ SnapTranslator.dict.de = { 'ausschalten, um den Inhalt\nim Projekt zu speichern', 'check to prevent contents\nfrom being saved': 'einschalten, um das Speichern des Inhalts\nim Projekt zu verhindern', - 'new line': - 'neue Zeile', // custom blocks: 'delete block definition...': @@ -911,10 +907,6 @@ SnapTranslator.dict.de = { 'Bearbeiten', 'move': 'Verschieben', - 'pivot': - 'Angelpunkt', - 'edit the costume\'s\nrotation center': - 'Drehpunkt des Kostüms\nanzeigen und verschieben', 'detach from': 'Abtrennen von', 'detach all parts': @@ -1364,10 +1356,6 @@ SnapTranslator.dict.de = { 'e^': 'e^', - // Boolean expressions keyboard entry - 'not': - 'nicht', - // delimiters 'letter': 'Buchstabe', diff --git a/lists.js b/lists.js old mode 100644 new mode 100755 index 799a9283..4db9272e --- a/lists.js +++ b/lists.js @@ -7,7 +7,7 @@ written by Jens Mönig and Brian Harvey jens@moenig.org, bh@cs.berkeley.edu - Copyright (C) 2017 by Jens Mönig and Brian Harvey + Copyright (C) 2016 by Jens Mönig and Brian Harvey This file is part of Snap!. @@ -62,7 +62,7 @@ CellMorph, ArrowMorph, MenuMorph, snapEquals, Morph, isNil, localize, MorphicPreferences, TableDialogMorph, SpriteBubbleMorph, SpeechBubbleMorph, TableFrameMorph, TableMorph, Variable, isSnapObject*/ -modules.lists = '2017-February-14'; +modules.lists = '2016-July-14'; var List; var ListWatcherMorph; diff --git a/locale.js b/locale.js old mode 100644 new mode 100755 index 75f2f038..f97ed708 --- a/locale.js +++ b/locale.js @@ -42,7 +42,7 @@ /*global modules, contains*/ -modules.locale = '2017-March-07'; +modules.locale = '2017-January-13'; // Global stuff @@ -160,7 +160,7 @@ SnapTranslator.dict.de = { 'translator_e-mail': 'jens@moenig.org', 'last_changed': - '2017-03-07' + '2017-01-10' }; SnapTranslator.dict.it = { diff --git a/morphic.js b/morphic.js old mode 100644 new mode 100755 index 029cdf79..7d76747e --- a/morphic.js +++ b/morphic.js @@ -1137,7 +1137,7 @@ /*global window, HTMLCanvasElement, FileReader, Audio, FileList*/ -var morphicVersion = '2017-March-07'; +var morphicVersion = '2017-January-09'; var modules = {}; // keep track of additional loaded modules var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug @@ -4432,14 +4432,11 @@ HandleMorph.prototype.init = function ( this.target = target || null; this.minExtent = new Point(minX || 0, minY || 0); this.inset = new Point(insetX || 0, insetY || insetX || 0); - this.type = type || 'resize'; // also: 'move', 'moveCenter', 'movePivot' + this.type = type || 'resize'; // can also be 'move', 'moveCenter' HandleMorph.uber.init.call(this); this.color = new Color(255, 255, 255); this.isDraggable = false; this.noticesTransparentClick = true; - if (this.type === 'movePivot') { - size *= 2; - } this.setExtent(new Point(size, size)); }; @@ -4448,27 +4445,20 @@ HandleMorph.prototype.init = function ( HandleMorph.prototype.drawNew = function () { this.normalImage = newCanvas(this.extent()); this.highlightImage = newCanvas(this.extent()); - if (this.type === 'movePivot') { - this.drawCrosshairsOnCanvas(this.normalImage, 0.6); - this.drawCrosshairsOnCanvas(this.highlightImage, 0.5); - } else { - this.drawOnCanvas( - this.normalImage, - this.color, - new Color(100, 100, 100) - ); - this.drawOnCanvas( - this.highlightImage, - new Color(100, 100, 255), - new Color(255, 255, 255) - ); - } + this.drawOnCanvas( + this.normalImage, + this.color, + new Color(100, 100, 100) + ); + this.drawOnCanvas( + this.highlightImage, + new Color(100, 100, 255), + new Color(255, 255, 255) + ); this.image = this.normalImage; if (this.target) { if (this.type === 'moveCenter') { this.setCenter(this.target.center()); - } else if (this.type === 'movePivot') { - this.setCenter(this.target.rotationCenter()); } else { // 'resize', 'move' this.setPosition( this.target.bottomRight().subtract( @@ -4481,25 +4471,6 @@ HandleMorph.prototype.drawNew = function () { } }; -HandleMorph.prototype.drawCrosshairsOnCanvas = function (aCanvas, fract) { - var ctx = aCanvas.getContext('2d'), - r = aCanvas.width / 2; - ctx.fillStyle = 'rgba(255, 255, 255, 0.5)'; - ctx.arc(r, r, r * 0.9, radians(0), radians(360), false); - ctx.fill(); - ctx.strokeStyle = 'black'; - ctx.lineWidth = 1; - ctx.beginPath(); - ctx.arc(r, r, r * fract, radians(0), radians(360), false); - ctx.stroke(); - ctx.moveTo(0, r); - ctx.lineTo(aCanvas.width, r); - ctx.stroke(); - ctx.moveTo(r, 0); - ctx.lineTo(r, aCanvas.height); - ctx.stroke(); -}; - HandleMorph.prototype.drawOnCanvas = function ( aCanvas, color, @@ -4603,7 +4574,7 @@ HandleMorph.prototype.mouseDownLeft = function (pos) { if (!this.target) { return null; } - if (this.type.indexOf('move') === 0) { + if (this.type === 'moveCenter') { offset = pos.subtract(this.center()); } else { offset = pos.subtract(this.bounds.origin); @@ -4626,9 +4597,6 @@ HandleMorph.prototype.mouseDownLeft = function (pos) { ); } else if (this.type === 'moveCenter') { myself.target.setCenter(newPos); - } else if (this.type === 'movePivot') { - myself.target.setPivot(newPos); - myself.setCenter(this.target.rotationCenter()); } else { // type === 'move' myself.target.setPosition( newPos.subtract(this.target.extent()) diff --git a/objects.js b/objects.js old mode 100644 new mode 100755 index a36fd03d..5c887d85 --- a/objects.js +++ b/objects.js @@ -80,9 +80,9 @@ document, isNaN, isString, newCanvas, nop, parseFloat, radians, window, modules, IDE_Morph, VariableDialogMorph, HTMLCanvasElement, Context, List, SpeechBubbleMorph, RingMorph, isNil, FileReader, TableDialogMorph, BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize, -TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph*/ +TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph*/ -modules.objects = '2017-March-07'; +modules.objects = '2017-January-13'; var SpriteMorph; var StageMorph; @@ -1185,20 +1185,12 @@ SpriteMorph.prototype.initBlocks = function () { category: 'other', spec: 'map %cmdRing to %codeKind %code' }, - doMapValueCode: { // experimental - type: 'command', - category: 'other', - spec: 'map %mapValue to code %code', - defaults: [['String'], '<#1>'] - }, - /* obsolete - superseded by 'doMapValue' doMapStringCode: { // experimental type: 'command', category: 'other', spec: 'map String to code %code', defaults: ['<#1>'] }, - */ doMapListCode: { // experimental type: 'command', category: 'other', @@ -1239,11 +1231,6 @@ SpriteMorph.prototype.initBlockMigrations = function () { reportFalse: { selector: 'reportBoolean', inputs: [false] - }, - doMapStringCode: { - selector: 'doMapValueCode', - inputs: [['String'], '<#1>'], - offset: 1 } }; }; @@ -2172,7 +2159,7 @@ SpriteMorph.prototype.blockTemplates = function (category) { if (StageMorph.prototype.enableCodeMapping) { blocks.push(block('doMapCodeOrHeader')); - blocks.push(block('doMapValueCode')); + blocks.push(block('doMapStringCode')); blocks.push(block('doMapListCode')); blocks.push('-'); blocks.push(block('reportMappedCode')); @@ -2288,7 +2275,7 @@ SpriteMorph.prototype.freshPalette = function (category) { menu.addPair( 'find blocks...', function () {myself.searchBlocks(); }, - '^F' + '⌘F' ); if (canHidePrimitives()) { menu.addItem( @@ -2417,30 +2404,6 @@ SpriteMorph.prototype.freshPalette = function (category) { } }); - // inherited custom blocks: (under construction...) - /* - // y += unit * 1.6; - if (this.exemplar) { - this.inheritedBlocks(true).forEach(function (definition) { - var block; - if (definition.category === category || - (category === 'variables' - && contains( - ['lists', 'other'], - definition.category - ))) { - block = definition.templateInstance(); - y += unit * 0.3; - block.setPosition(new Point(x, y)); - palette.addContents(block); - block.ghost(); - x = 0; - y += block.height(); - } - }); - } - */ - //layout palette.scrollX(palette.padding); @@ -2774,8 +2737,7 @@ SpriteMorph.prototype.reporterize = function (expressionString) { function blockFromAST(ast) { var block, selectors, monads, alias, key, sel, i, inps, - off = 1, - reverseDict = {}; + off = 1; selectors = { '+': 'reportSum', '-': 'reportDifference', @@ -2796,10 +2758,7 @@ SpriteMorph.prototype.reporterize = function (expressionString) { ceil: 'ceiling', '!' : 'not' }; - monads.concat(['true', 'false']).forEach(function (word) { - reverseDict[localize(word).toLowerCase()] = word; - }); - key = alias[ast[0]] || reverseDict[ast[0].toLowerCase()] || ast[0]; + key = alias[ast[0]] || ast[0]; if (contains(monads, key)) { // monadic sel = selectors[key]; if (sel) { // single input @@ -2819,14 +2778,11 @@ SpriteMorph.prototype.reporterize = function (expressionString) { if (ast[i] instanceof Array) { block.silentReplaceInput(inps[i - off], blockFromAST(ast[i])); } else if (isString(ast[i])) { - if (contains( - ['true', 'false'], reverseDict[ast[i]] || ast[i]) - ) { + if (contains(['true', 'false'], ast[i])) { block.silentReplaceInput( inps[i - off], SpriteMorph.prototype.blockForSelector( - (reverseDict[ast[i]] || ast[i]) === 'true' ? - 'reportTrue' : 'reportFalse' + ast[i] === 'true' ? 'reportTrue' : 'reportFalse' ) ); } else if (ast[i] !== '_') { @@ -3032,13 +2988,6 @@ SpriteMorph.prototype.userMenu = function () { } menu.addItem("delete", 'remove'); menu.addItem("move", 'moveCenter'); - if (this.costume) { - menu.addItem( - "pivot", - 'moveRotationCenter', - 'edit the costume\'s\nrotation center' - ); - } if (!this.isClone) { menu.addItem("edit", 'edit'); } @@ -4237,32 +4186,6 @@ SpriteMorph.prototype.setRotationCenter = function (absoluteCoordinate) { this.drawNew(); }; -SpriteMorph.prototype.moveRotationCenter = function () { - // make this a method of Snap >> SpriteMorph - this.world().activeHandle = new HandleMorph( - this, - null, - null, - null, - null, - 'movePivot' - ); -}; - -SpriteMorph.prototype.setPivot = function (worldCoordinate) { - var stage = this.parentThatIsA(StageMorph), - cntr; - if (stage) { - cntr = stage.center(); - this.setRotationCenter( - new Point( - (worldCoordinate.x - cntr.x) / stage.scale, - (cntr.y - worldCoordinate.y) / stage.scale - ) - ); - } -}; - SpriteMorph.prototype.xCenter = function () { var stage = this.parentThatIsA(StageMorph); @@ -4479,25 +4402,6 @@ SpriteMorph.prototype.reportThreadCount = function () { return 0; }; -// SpriteMorph variable refactoring - -SpriteMorph.prototype.refactorVariableInstances = function ( - oldName, - newName, - isGlobal -) { - if (isGlobal && this.hasSpriteVariable(oldName)) { - return; - } - - this.scripts.children.forEach(function (child) { - if (child instanceof BlockMorph) { - child.refactorVarInStack(oldName, newName); - } - }); - -}; - // SpriteMorph variable watchers (for palette checkbox toggling) SpriteMorph.prototype.findVariableWatcher = function (varName) { @@ -4963,10 +4867,30 @@ SpriteMorph.prototype.hasSpriteVariable = function (varName) { return contains(this.variables.names(), varName); }; +// Variable refactoring + +SpriteMorph.prototype.refactorVariableInstances = function ( + oldName, + newName, + isGlobal +) { + if (isGlobal && this.hasSpriteVariable(oldName)) { + return; + } + + this.scripts.children.forEach(function (child) { + if (child instanceof BlockMorph) { + child.refactorVarInStack(oldName, newName); + } + }); + +}; + // SpriteMorph inheritance - custom blocks -// under construction /* +// under construction, commented out for now + SpriteMorph.prototype.ownBlocks = function () { var dict = {}; this.customBlocks.forEach(function (def) { @@ -5006,6 +4930,7 @@ SpriteMorph.prototype.inheritedBlocks = function (valuesOnly) { } return dict; }; + */ // SpriteMorph thumbnail @@ -6467,7 +6392,7 @@ StageMorph.prototype.blockTemplates = function (category) { if (StageMorph.prototype.enableCodeMapping) { blocks.push(block('doMapCodeOrHeader')); - blocks.push(block('doMapValueCode')); + blocks.push(block('doMapStringCode')); blocks.push(block('doMapListCode')); blocks.push('-'); blocks.push(block('reportMappedCode')); diff --git a/store.js b/store.js old mode 100644 new mode 100755 index 8fdea4cd..659d1e17 --- a/store.js +++ b/store.js @@ -7,7 +7,7 @@ written by Jens Mönig jens@moenig.org - Copyright (C) 2017 by Jens Mönig + Copyright (C) 2016 by Jens Mönig This file is part of Snap!. @@ -57,11 +57,11 @@ BlockMorph, ArgMorph, InputSlotMorph, TemplateSlotMorph, CommandSlotMorph, FunctionSlotMorph, MultiArgMorph, ColorSlotMorph, nop, CommentMorph, isNil, localize, sizeOf, ArgLabelMorph, SVG_Costume, MorphicPreferences, SyntaxElementMorph, Variable, isSnapObject, console, BooleanSlotMorph, -normalizeCanvas, contains*/ +normalizeCanvas*/ // Global stuff //////////////////////////////////////////////////////// -modules.store = '2017-March-01'; +modules.store = '2016-December-27'; // XML_Serializer /////////////////////////////////////////////////////// @@ -412,8 +412,6 @@ SnapSerializer.prototype.rawLoadProjectModel = function (xmlNode) { project.stage.setExtent(StageMorph.prototype.dimensions); SpriteMorph.prototype.useFlatLineEnds = model.stage.attributes.lines === 'flat'; - BooleanSlotMorph.prototype.isTernary = - model.stage.attributes.ternary !== 'false'; project.stage.isThreadSafe = model.stage.attributes.threadsafe === 'true'; StageMorph.prototype.enableCodeMapping = @@ -838,9 +836,7 @@ SnapSerializer.prototype.loadCustomBlocks = function ( i += 1; definition.declarations[names[i]] = [ child.attributes.type, - contains(['%b', '%boolUE'], child.attributes.type) ? - (child.contents ? child.contents === 'true' : null) - : child.contents, + child.contents, options ? options.contents : undefined, child.attributes.readonly === 'true' ]; @@ -1011,8 +1007,7 @@ SnapSerializer.prototype.loadComment = function (model) { SnapSerializer.prototype.loadBlock = function (model, isReporter) { // private - var block, info, inputs, isGlobal, rm, receiver, migration, - migrationOffset = 0; + var block, info, inputs, isGlobal, rm, receiver; if (model.tag === 'block') { if (Object.prototype.hasOwnProperty.call( model.attributes, @@ -1033,10 +1028,6 @@ SnapSerializer.prototype.loadBlock = function (model, isReporter) { } */ block = SpriteMorph.prototype.blockForSelector(model.attributes.s); - migration = SpriteMorph.prototype.blockMigrations[model.attributes.s]; - if (migration) { - migrationOffset = migration.offset; - } } else if (model.tag === 'custom-block') { isGlobal = model.attributes.scope ? false : true; receiver = isGlobal ? this.project.stage @@ -1097,7 +1088,7 @@ SnapSerializer.prototype.loadBlock = function (model, isReporter) { } else if (child.tag === 'receiver') { nop(); // ignore } else { - this.loadInput(child, inputs[i + migrationOffset], block); + this.loadInput(child, inputs[i], block); } }, this); block.cachedInputs = null; @@ -1118,9 +1109,6 @@ SnapSerializer.prototype.obsoleteBlock = function (isReporter) { SnapSerializer.prototype.loadInput = function (model, input, block) { // private var inp, val, myself = this; - if (isNil(input)) { - return; - } if (model.tag === 'script') { inp = this.loadScript(model); if (inp) { @@ -1521,7 +1509,6 @@ StageMorph.prototype.toXML = function (serializer) { ''; - break; - case 'Number': - StageMorph.prototype.codeMappings.number = aString || '<#1>'; - break; - case 'true': - StageMorph.prototype.codeMappings.boolTrue = aString || 'true'; - break; - case 'false': - StageMorph.prototype.codeMappings.boolFalse = aString || 'true'; - break; - default: - throw new Error( - localize('unsupported data type') + ' ' + tp - ); - } - +Process.prototype.doMapStringCode = function (aString) { + StageMorph.prototype.codeMappings.string = aString || '<#1>'; }; Process.prototype.doMapListCode = function (part, kind, aString) { @@ -3660,7 +3641,7 @@ function Variable(value, isTransient) { } Variable.prototype.toString = function () { - return 'a ' + (this.isTransient ? 'transient ' : '') + 'Variable [' + + return 'a ' + this.isTransient ? 'transient ' : '' + 'Variable [' + this.value + ']'; };