diff --git a/snap.html b/snap.html index 7390e28..35bafa0 100644 --- a/snap.html +++ b/snap.html @@ -1,14 +1,16 @@ - - \ No newline at end of file +initial-scale=1"> + + + + \ No newline at end of file diff --git a/src/FileSaver.js b/src/FileSaver.js deleted file mode 100644 index 5167640..0000000 --- a/src/FileSaver.js +++ /dev/null @@ -1,142 +0,0 @@ -/* Set the file saver's Morphic module. */ -modules.FileSaver = '2023-November-02'; -/* The code of FileSaver.js starts here... */ -/* This code it's fundamental for Morphic and its other separated .js files. */ -var saveAs = saveAs || function(e) { - "use strict"; - if (typeof e === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { - return - } - var t = e.document - , n = function() { - return e.URL || e.webkitURL || e - } - , r = t.createElementNS("http://www.w3.org/1999/xhtml", "a") - , o = "download"in r - , a = function(e) { - var t = new MouseEvent("click"); - e.dispatchEvent(t) - } - , i = /constructor/i.test(e.HTMLElement) || e.safari - , f = /CriOS\/[\d]+/.test(navigator.userAgent) - , u = function(t) { - (e.setImmediate || e.setTimeout)(function() { - throw t - }, 0) - } - , s = "application/octet-stream" - , d = 1e3 * 40 - , c = function(e) { - var t = function() { - if (typeof e === "string") { - n().revokeObjectURL(e) - } else { - e.remove() - } - }; - setTimeout(t, d) - } - , l = function(e, t, n) { - t = [].concat(t); - var r = t.length; - while (r--) { - var o = e["on" + t[r]]; - if (typeof o === "function") { - try { - o.call(e, n || e) - } catch (a) { - u(a) - } - } - } - } - , p = function(e) { - if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)) { - return new Blob([String.fromCharCode(65279), e],{ - type: e.type - }) - } - return e - } - , v = function(t, u, d) { - if (!d) { - t = p(t) - } - var v = this, w = t.type, m = w === s, y, h = function() { - l(v, "writestart progress write writeend".split(" ")) - }, S = function() { - if ((f || m && i) && e.FileReader) { - var r = new FileReader; - r.onloadend = function() { - var t = f ? r.result : r.result.replace(/^data:[^;]*;/, "data:attachment/file;"); - var n = e.open(t, "_blank"); - if (!n) - e.location.href = t; - t = undefined; - v.readyState = v.DONE; - h() - } - ; - r.readAsDataURL(t); - v.readyState = v.INIT; - return - } - if (!y) { - y = n().createObjectURL(t) - } - if (m) { - e.location.href = y - } else { - var o = e.open(y, "_blank"); - if (!o) { - e.location.href = y - } - } - v.readyState = v.DONE; - h(); - c(y) - }; - v.readyState = v.INIT; - if (o) { - y = n().createObjectURL(t); - setTimeout(function() { - r.href = y; - r.download = u; - a(r); - h(); - c(y); - v.readyState = v.DONE - }); - return - } - S() - } - , w = v.prototype - , m = function(e, t, n) { - return new v(e,t || e.name || "download",n) - }; - if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { - return function(e, t, n) { - t = t || e.name || "download"; - if (!n) { - e = p(e) - } - return navigator.msSaveOrOpenBlob(e, t) - } - } - w.abort = function() {} - ; - w.readyState = w.INIT = 0; - w.WRITING = 1; - w.DONE = 2; - w.error = w.onwritestart = w.onprogress = w.onwrite = w.onabort = w.onerror = w.onwriteend = null; - return m -}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content); -if (typeof module !== "undefined" && module.exports) { - module.exports.saveAs = saveAs -} else if (typeof define !== "undefined" && define !== null && define.amd !== null) { - define("FileSaver.js", function() { - return saveAs - }) -} -; \ No newline at end of file diff --git a/src/api.js b/src/api.js index 0d8263d..4c4f262 100644 --- a/src/api.js +++ b/src/api.js @@ -7,7 +7,7 @@ written by Jens Mönig jens@moenig.org - Copyright (C) 2022 by Jens Mönig + Copyright (C) 2024 by Jens Mönig This file is part of Snap!. @@ -29,25 +29,12 @@ -------------- needs gui.js, lists.js, objects.js, threads.js and morphic.js - - documentation - ------------- - along with this file you should have received a copy of the Snap! API - documentation. If not, see - https://github.com/jmoenig/Snap/blob/master/API.md - or https://snap.berkeley.edu/snap/API.md - */ -/*global modules, IDE_Morph, isString, Map, List, world, isNil, Project, -detect, isSnapObject, VariableFrame*/ - -/*jshint esversion: 6*/ - /* # The Snap! API -Jens Mönig, Bernat Romagosa, January 24, 2024 +Jens Mönig, Bernat Romagosa This document describes how Snap! can be accessed from an outside program to start scripts, send and retrieve information. The model use case is embedding interactive Snap! projects in other websites such as MOOCs or other adaptive learning platforms. @@ -97,7 +84,7 @@ Currently the API consists of the following methods: Getting hold of an ide can usually be achieved by evaluating: - var ide = world.children[0]; + var ide = world.childThatIsA(IDE_Morph); The model case in mind is embedding Snap! in an iframe: @@ -161,7 +148,6 @@ The getScenes() method returns an array with the names of all scenes in the proj #### return value an Array of Strings, minimum length 1 - ### IDE_Morph.prototype.getCurrentScene() The getCurrentScene() method returns a string representing the name of the currently active scene in the project. If the scene is unnamed and empty string is returned. @@ -171,7 +157,6 @@ The getCurrentScene() method returns a string representing the name of the curre #### return value a String, can be an empty String - ### IDE_Morph.prototype.switchTo() The switchTo() method displays the specified scene. It suspends all processes and clones of the previously active scene and passes control to the new scene. @@ -185,7 +170,6 @@ The switchTo() method displays the specified scene. It suspends all processes an #### return value undefined - ### IDE_Morph.prototype.isRunning() The isRunning() method returns `true` if the active scene is currently running one or more threads, `false` if the scene is idle. @@ -195,7 +179,6 @@ The isRunning() method returns `true` if the active scene is currently running o #### return value a Boolean - ### IDE_Morph.prototype.stop() The stop() method immediately terminates all currently running threads in the active scene and removes all temporary clones. It does not trigger a "When I am stopped" event. @@ -205,7 +188,6 @@ The stop() method immediately terminates all currently running threads in the ac #### return value undefined - ### IDE_Morph.prototype.broadcast() The broadcast() method triggers all scripts whose hat block listens to the specified message. An optional callback can be added to be run after all triggered scripts have terminated. @@ -221,7 +203,6 @@ The broadcast() method triggers all scripts whose hat block listens to the speci #### return value undefined - ### IDE_Morph.prototype.addMessageListenerForAll() The addMessageListenerForAll() method sets up a function that will be called whenever a message is broadcast. The function takes one argument, the message being broadcast, and can be used to react to any message. Multiple message listeners can be set up, they all get executed in the order in which they were added. @@ -235,7 +216,6 @@ The addMessageListenerForAll() method sets up a function that will be called whe #### return value undefined - ### IDE_Morph.prototype.addMessageListener() The addMessageListener() method sets up a function that will be called whenever the specified message is broadcast. Multiple message listeners can be set up per message, they all the executed in the order in which they were added. @@ -251,7 +231,6 @@ The addMessageListener() method sets up a function that will be called whenever #### return value undefined - #### IDE_Morph.prototype.getMessages() The getMessage() method returns a new Array that contains all the message strings that occur in the project, both in hat blocks and in broadcast blocks. @@ -271,7 +250,6 @@ The getVarNames() method returns a new Array that contains all the global variab ### return value an Array of Strings, or an empty Array - ### IDE_Morph.prototype.getVar() The getVar() method returns the value of the global variable indicated by the specified name. @@ -281,7 +259,6 @@ The getVar() method returns the value of the global variable indicated by the sp #### return value whatever value the variable holds. - ### IDE_Morph.prototype.setVar() The setVar() methods assigns a value to the a global variable specified by name. @@ -291,7 +268,6 @@ The setVar() methods assigns a value to the a global variable specified by name. #### return value undefined - ### IDE_Morph.prototype.newList() The newList() methods returns a new Snap! list. Optionally a source array containing the list elements can be specified. @@ -301,7 +277,6 @@ The newList() methods returns a new Snap! list. Optionally a source array contai #### return value a new Snap! List - ### IDE_Morph.prototype.getProjectXML() the getProjectXML() method returns a string in XML format representing the serialized project currently loaded into the IDE. @@ -311,7 +286,6 @@ the getProjectXML() method returns a string in XML format representing the seria #### return value an XML String - ### IDE_Morph.prototype.loadProjectXML() the loadProjectXML() method replaces the current project of the IDE with another serialized one encoded in a string in XML format. Note that no user acknowledgement is required, all unsaved edits to the prior project are lost. @@ -325,7 +299,6 @@ the loadProjectXML() method replaces the current project of the IDE with another #### return value unefined - ### IDE_Morph.prototype.unsavedChanges() the unsavedChanges() method return a Boolean value indicating whether the currently edited project has been modifed since it was last saved. @@ -335,16 +308,11 @@ the unsavedChanges() method return a Boolean value indicating whether the curren #### return value a Boolean - ## Manipulating Lists Snap! lists can be accessed and manipulated through a set of methods described in the file `lists.js` */ -// Global stuff //////////////////////////////////////////////////////// - -modules.api = '2022-December-24'; - // IDE_Morph external communication API - experimental /* @@ -353,8 +321,8 @@ modules.api = '2022-December-24'; global variables */ -window.onmessage = function (event) {if (world) {var ide = world.childThatIsA(IDE_Morph); if (!isNil(event.data.selector)) {window.top.postMessage( -{selector: event.data.selector, response: ide[event.data.selector].apply(ide, event.data.params)}, '*');};};}; +window.onmessage = function (event) {if (world) {var ide = world.childThatIsA(IDE_Morph); if (!isNil(event.data.selector)) { +window.top.postMessage({selector: event.data.selector, response: ide[event.data.selector].apply(ide, event.data.params)}, '*');};};}; IDE_Morph.prototype.getScenes = function () {return this.scenes.itemsArray().map(each => each.name);}; @@ -365,8 +333,9 @@ if (scene === null) {throw new Error('cannot find scene ' + sceneName);}; this.s IDE_Morph.prototype.isRunning = function () {return this.stage.threads.processes.length > 0;}; -IDE_Morph.prototype.stop = function () {var stage = this.stage; stage.keysPressed = {}; stage.threads.stopAll(); stage.stopAllActiveSounds(); stage.children.forEach( -morph => {if (morph.stopTalking) {morph.stopTalking();}}); stage.removeAllClones(); stage.stopProjection(); this.controlBar.pauseButton.refresh();}; +IDE_Morph.prototype.stop = function () {var stage = this.stage; stage.keysPressed = {}; stage.threads.stopAll(); +stage.stopAllActiveSounds(); stage.children.forEach(morph => {if (morph.stopTalking) {morph.stopTalking();} +}); stage.removeAllClones(); stage.stopProjection(); this.controlBar.pauseButton.refresh();}; IDE_Morph.prototype.broadcast = function(message, callback) { // same as using the broadcast block - launch all scripts diff --git a/src/blocks.js b/src/blocks.js index 6c826f5..a6f4915 100644 --- a/src/blocks.js +++ b/src/blocks.js @@ -144,52 +144,20 @@ please also refer to the high-level comment at the beginning of each constructor for further details. + */ -/*global Array, BoxMorph, -Color, ColorPaletteMorph, FrameMorph, Function, HandleMorph, Math, MenuMorph, -Morph, MorphicPreferences, Object, ScrollFrameMorph, ShadowMorph, ZERO, Sound, -String, StringMorph, TextMorph, contains, degrees, detect, PianoMenuMorph, nop, -document, getDocumentPositionOf, isNaN, isString, newCanvas, parseFloat, isNil, -radians, useBlurredShadows, SpeechBubbleMorph, modules, StageMorph, SymbolMorph, -fontHeight, TableFrameMorph, SpriteMorph, Context, ListWatcherMorph, Rectangle, -DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, WHITE, BLACK, -Costume, IDE_Morph, BlockDialogMorph, BlockEditorMorph, localize, CLEAR, Point, -isSnapObject, PushButtonMorph, SpriteIconMorph, Process, AlignmentMorph, List, -CustomCommandBlockMorph, ToggleButtonMorph, DialMorph, SnapExtensions, -CostumeIconMorph, SoundIconMorph, SVG_Costume*/ - -var SyntaxElementMorph; -var BlockMorph; -var BlockLabelMorph; -var BlockSymbolMorph; -var CommandBlockMorph; -var DefinitorBlockMorph; -var ReporterBlockMorph; -var ScriptsMorph; -var ArgMorph; -var BlockSlotMorph -var CommandSlotMorph; -var CSlotMorph; -var InputSlotMorph; -var InputSlotStringMorph; -var InputSlotTextMorph; -var BooleanSlotMorph; -var ArrowMorph; -var ColorSlotMorph; -var HatBlockMorph; -var BlockHighlightMorph; -var MultiArgMorph; -var TemplateSlotMorph; -var FunctionSlotMorph; -var ReporterSlotMorph; -var RingMorph; -var RingCommandSlotMorph; -var RingReporterSlotMorph; -var CommentMorph; -var ArgLabelMorph; -var TextSlotMorph; -var ScriptFocusMorph; +var SyntaxElementMorph, BlockMorph, BlockLabelMorph, +BlockSymbolMorph, CommandBlockMorph, ScriptsMorph, +DefinitorBlockMorph, ReporterBlockMorph, ArgMorph, +BlockSlotMorph, CommandSlotMorph, InputSlotMorph, +CSlotMorph, InputSlotStringMorph, MultiArgMorph, +ArrowMorph, InputSlotTextMorph, BooleanSlotMorph, +ColorSlotMorph, HatBlockMorph, BlockHighlightMorph, +TemplateSlotMorph, FunctionSlotMorph, RingMorph, +ReporterSlotMorph, RingMorph, RingCommandSlotMorph, +RingReporterSlotMorph, CommentMorph, ArgLabelMorph, +TextSlotMorph, ScriptFocusMorph; // SyntaxElementMorph ////////////////////////////////////////////////// @@ -233,6 +201,7 @@ SyntaxElementMorph.uber = Morph.prototype; labelFontName - specific font family name labelFontStyle - generic font family name, cascaded + labelSize - duh, obviously the font's own size fontSize - duh, obviously the font's own size embossing - offset for embossing effect labelWidth - column width, used for word wrapping @@ -260,39 +229,37 @@ SyntaxElementMorph.prototype.rfColor = new Color(127.5, 127.5, 127.5); SyntaxElementMorph.prototype.contrast = 65; SyntaxElementMorph.prototype.listOfContractives = ['%rcv', '%scndN']; /* The contractives are inside of multiargs. */ -SyntaxElementMorph.prototype.setScale = function anonymous (num) { -var scale = Math.min(Math.max(num, 1), 10); this.scale = scale; -this.corner = 3 * scale; this.rounding = 9 * scale; -this.flatEdge = scale / 2; this.jag = 4.5 * scale; -this.inset = 6 * scale; this.hatHeight = 12 * scale; -this.hatWidth = 70 * scale; this.rfBorder = 3 * scale; -this.edge = scale; this.minWidth = 0; this.dent = 8 * scale; -this.bottomPadding = 3 * scale; this.cSlotPadding = 4 * scale; -this.typeInPadding = scale; this.labelPadding = 4 * scale; -this.labelFontName = ((localStorage['-snap-setting-language' -] === 'tok') ? 'blockTokiPonaFont' : 'blockGlobalFont'); -this.labelFontStyle = 'sans-serif'; this.fontSize = 11 * scale; -this.labelSize = (11 + (contains(['blockGlobalFont', +SyntaxElementMorph.prototype.setScale = function (num) { +var scale = Math.round(Math.min(Math.max(num, 1/2), 10 +) * 1000) / 1000; this.scale = scale; this.corner = ( +3 * scale); this.flatEdge = (scale / 2); (this.rounding +) = this.corner * 3; this.jag = this.rounding / 2; (this +).inset = 6 * scale; this.hatHeight = 12 * scale; (this +).hatWidth = 70 * scale; this.rfBorder = 3 * scale; (this +).edge = scale; this.minWidth = 0; this.dent = 8 * scale; +this.cSlotPadding = 4 * scale; this.labelPadding = (this +).cSlotPadding; this.fontSize = this.hatHeight; (this +).bottomPadding = this.rfBorder; (this.typeInPadding +) = scale; this.labelFontName = ((localStorage[ +'-snap-setting-language'] === 'tok') ? ( +'blockTokiPonaFont') : 'blockGlobalFont' +); this.labelFontStyle = 'sans-serif'; (this +).labelSize = (12 + (contains(['blockGlobalFont', 'blockTokiPonaFont'], this.labelFontName) ? ({ -'blockGlobalFont' : 1, 'blockTokiPonaFont' : 5 -})[this.labelFontName] : 0)) * scale; -this.embossing = new Point( --1 * Math.max(scale / 2, 1), --1 * Math.max(scale / 2, 1)); -this.labelWidth = 450 * scale; -this.labelWordWrap = true; -this.dynamicInputLabels = true; -this.feedbackMinHeight = 5; -this.minSnapDistance = 20; -this.reporterDropFeedbackPadding = 10 * scale; -this.labelContrast = 25; -this.activeHighlight = new Color(153, 255, 213); -this.errorHighlight = new Color(173, 15, 0); -this.activeBlur = 20; this.activeBorder = 4;}; - -SyntaxElementMorph.prototype.setScale(1); -SyntaxElementMorph.prototype.isCachingInputs = false; -SyntaxElementMorph.prototype.alpha = 1; +'blockGlobalFont' : 0, 'blockTokiPonaFont' : 4 +})[this.labelFontName] : 0)) * scale; (this +).embossing = new Point(-1 * Math.max(scale / 2, +1), -1 * Math.max(scale / 2, 1)); (this.labelWordWrap +) = true; this.labelWidth = (450 * scale); (this +).reporterDropFeedbackPadding = (10 * scale); (this +).dynamicInputLabels = true; (this.feedbackMinHeight +) = 5; this.minSnapDistance = 20; (this.activeHighlight +) = new Color(153, 255, 213); (this.errorHighlight +) = new Color(173, 15, 0); this.activeBorder = 4; +this.activeBlur = 20; this.labelContrast = 25;}; +SyntaxElementMorph.prototype.isCachingInputs = ( +false); SyntaxElementMorph.prototype.setScale( +1); SyntaxElementMorph.prototype.alpha = 1; // SyntaxElementMorph label part specs: @@ -454,9 +421,9 @@ SyntaxElementMorph.prototype.labelParts = { type: 'input', tags: 'read-only static', menu: { - 'commandize': ['commandize'], 'hatize': ['hatize'], 'definitize': ['definitize'], + 'commandize': ['commandize'], 'reporterize': ['reporterize'], 'predicatize': ['predicatize'], 'arrowize': ['arrowize'], @@ -1123,9 +1090,7 @@ SyntaxElementMorph.prototype.labelParts = { oldText: '', newText: 'without rounding' }, - '%b': { - type: 'boolean' - }, + '%b': {type: 'boolean'}, '%boolUE': { type: 'boolean', tags: 'unevaluated' @@ -1138,9 +1103,7 @@ SyntaxElementMorph.prototype.labelParts = { type: 'boolean', tags: 'unevaluated static' }, - '%cs': { - type: 'c', - }, + '%cs': {type: 'c'}, '%c': { type: 'c', tags: 'static' @@ -1179,35 +1142,6 @@ SyntaxElementMorph.prototype.labelParts = { tags: 'static', label: localize('Input Name'), }, - '%cmdRing': { - type: 'ring', - selector: 'reifyScript' - }, - '%repRing': { - type: 'ring', - tags: 'static', - selector: 'reifyReporter' - }, - '%predRing': { - type: 'ring', - tags: 'static', - selector: 'reifyPredicate' - }, - '%rc': { - type: 'ring slot', - tags: 'static', - kind: 'command' - }, - '%rr': { - type: 'ring slot', - tags: 'static', - kind: 'reporter' - }, - '%rp': { - type: 'ring slot', - tags: 'static', - kind: 'predicate' - }, '%cmd': { type: 'slot', kind: 'command' @@ -1230,6 +1164,21 @@ SyntaxElementMorph.prototype.labelParts = { tags: 'static', kind: 'instructions' }, + '%rc': { + type: 'ring slot', + tags: 'static', + kind: 'command' + }, + '%rr': { + type: 'ring slot', + tags: 'static', + kind: 'reporter' + }, + '%rp': { + type: 'ring slot', + tags: 'static', + kind: 'predicate' + }, '%obj': { type: 'slot', kind: 'object' @@ -1254,8 +1203,19 @@ SyntaxElementMorph.prototype.labelParts = { type: 'slot', kind: 'unknown' }, - '%comment': { - type: 'comment' + '%cmdRing': { + type: 'ring', + selector: 'reifyScript' + }, + '%repRing': { + type: 'ring', + tags: 'static', + selector: 'reifyReporter' + }, + '%predRing': { + type: 'ring', + tags: 'static', + selector: 'reifyPredicate' }, /* @@ -1306,7 +1266,7 @@ SyntaxElementMorph.prototype.labelParts = { '%loopArrow': { type: 'symbol', name: 'loop', - scale: 0.7, + scale: 0.54, tags: 'fading' }, @@ -1558,31 +1518,18 @@ SyntaxElementMorph.prototype.labelParts = { group: 'else if %b %c', dflt: [true, null], tags: 'static widget' - }, - '%throwReport': { - type: 'multi', - slots: '%s', - max: 1, - label: 'and report', - tags: 'static' - }, -}; + }}; // SyntaxElementMorph instance creation: function SyntaxElementMorph () {this.init();}; SyntaxElementMorph.prototype.init = function () { - this.cachedClr = null; - this.cachedClrBright = null; - this.cachedClrDark = null; - this.cachedNormalColor = null; // for single-stepping - this.isStatic = false; // if true, I cannot be exchanged - SyntaxElementMorph.uber.init.call(this); - this.defaults = []; - this.cachedInputs = null; - delete this.alpha; -}; +this.cachedClr = null; this.cachedClrBright = null; +this.cachedClrDark = null; (this.cachedNormalColor +) = null; this.isStatic = false; (SyntaxElementMorph +).uber.init.call(this); this.defaults = []; (this +).cachedInputs = null; delete this.alpha;}; // SyntaxElementMorph accessing: @@ -1591,24 +1538,16 @@ SyntaxElementMorph.prototype.parts = function () { var nb = null; if (this.nextBlock) { // if I am a CommandBlock or a HatBlock nb = this.nextBlock(); - } - return this.children.filter(child => - (child !== nb) && - !(child instanceof ShadowMorph) && - !(child instanceof BlockHighlightMorph) - ); -}; + }; return this.children.filter( + child => (child !== nb) && + !(child instanceof ShadowMorph) && !( + child instanceof BlockHighlightMorph));}; SyntaxElementMorph.prototype.inputs = function () { - // answer my arguments and nested reporters - if (isNil(this.cachedInputs) || !this.isCachingInputs) { - this.cachedInputs = this.parts().filter(part => - part instanceof SyntaxElementMorph - ); - } - // this.debugCachedInputs(); - return this.cachedInputs; -}; +if (isNil(this.cachedInputs) || !this.isCachingInputs +) {this.cachedInputs = this.parts().filter(part => ( +part instanceof SyntaxElementMorph));}; +return this.cachedInputs;}; SyntaxElementMorph.prototype.debugCachedInputs = function () { // private - only used for manually debugging inputs caching @@ -1617,12 +1556,10 @@ SyntaxElementMorph.prototype.debugCachedInputs = function () { realInputs = this.parts().filter(part => part instanceof SyntaxElementMorph ); - } - if (this.cachedInputs.length !== realInputs.length) { + }; if (this.cachedInputs.length !== realInputs.length) { throw new Error('cached inputs size do not match: ' + this.constructor.name); - } - for (i = 0; i < realInputs.length; i += 1) { + }; for (i = 0; i < realInputs.length; i += 1) { if (this.cachedInputs[i] !== realInputs[i]) { throw new Error('cached input does not match: ' + this.constructor.name + @@ -1632,9 +1569,7 @@ SyntaxElementMorph.prototype.debugCachedInputs = function () { this.cachedInputs[i].constructor.name + ' != ' + realInputs[i].constructor.name); - } - } -}; + };};}; SyntaxElementMorph.prototype.allInputs = function () { // answer arguments and nested reporters of all children @@ -1642,106 +1577,53 @@ SyntaxElementMorph.prototype.allInputs = function () { (child instanceof ArgMorph) || (child instanceof ReporterBlockMorph && child !== this) - ); -}; + );}; -SyntaxElementMorph.prototype.allEmptySlots = function anonymous () { - // answer empty input slots of all children excluding myself, - // but omit those in nested rings (lambdas) and JS-Function primitives. - // Used by the evaluator when binding implicit formal parameters - // to empty input slots - var empty = []; - if (!(this instanceof RingMorph) && - // disregard custom C-slots, because they should be treated as - // rings. Commented out for now... - // !(this instanceof CSlotMorph && !this.isStatic) && - (!(contains(['reportJSFunction', 'reportScript', 'reify', 'reifyScript', 'reifyReporter', 'reifyPredicate'], this.selector)))) { - this.children.forEach(morph => { - if (morph.isEmptySlot && morph.isEmptySlot()) { - empty.push(morph); - } else if (morph.allEmptySlots) { - empty = empty.concat(morph.allEmptySlots()); - } - }); - } - return empty; -}; +SyntaxElementMorph.prototype.allEmptySlots = function ( +) {var empty = []; if (!(this instanceof RingMorph) && ( +!(contains(['reportJSFunction', 'reportScript', 'reify', +'reifyScript', 'reifyReporter', 'reifyPredicate'], +this.selector)))) {this.children.forEach(morph => { +if (morph.isEmptySlot && morph.isEmptySlot()) { +empty.push(morph);} else if (morph.allEmptySlots) { +empty = empty.concat(morph.allEmptySlots());};});}; +return empty;}; /* Detect all replaceable slots. */ SyntaxElementMorph.prototype.tagExitBlocks = function (stopTag, isCommand) { - if (this.selector === 'doReport') { - this.partOfCustomCommand = isCommand; - } else if (this.selector === 'doStopThis') { - this.exitTag = stopTag; - } else { - if (!(this instanceof RingMorph)) { - this.children.forEach(morph => { - if (morph.tagExitBlocks) { - morph.tagExitBlocks(stopTag, isCommand); - } - }); - } - } -}; +if (this.selector === 'doReport') {this.partOfCustomCommand = isCommand; +} else if (this.selector === 'doStopThis') {this.exitTag = stopTag;} else { +if (!(this instanceof RingMorph)) {this.children.forEach(morph => {if ( +morph.tagExitBlocks) {morph.tagExitBlocks(stopTag, isCommand);};});};};}; SyntaxElementMorph.prototype.replaceInput = function (oldArg, newArg) { - var scripts = this.parentThatIsA(ScriptsMorph), - replacement = newArg, - idx = this.children.indexOf(oldArg), - i = 0; - - // try to find the ArgLabel embedding the newArg, - // used for the undrop() feature - if (idx === -1 && newArg instanceof MultiArgMorph) { - this.children.forEach(morph => { - if (morph instanceof ArgLabelMorph && - morph.argMorph() === oldArg - ) { - idx = i; - } - i += 1; - }); - } - - if (oldArg.cachedSlotSpec) {oldArg.cachedSlotSpec = null; } - if (newArg.cachedSlotSpec) {newArg.cachedSlotSpec = null; } - - this.changed(); - if (newArg.parent) { - newArg.parent.removeChild(newArg); - } - if (oldArg instanceof MultiArgMorph) { - oldArg.inputs().forEach(inp => // preserve nested reporters - oldArg.replaceInput(inp, new InputSlotMorph()) - ); - if ((this.dynamicInputLabels || oldArg.collapse) && - newArg instanceof ReporterBlockMorph) { - replacement = new ArgLabelMorph(newArg, oldArg.collapse); - } - } - replacement.parent = this; - this.children[idx] = replacement; - if (oldArg instanceof ReporterBlockMorph && scripts && - !oldArg.isPrototype - ) { - if (!(oldArg instanceof RingMorph) - || (oldArg instanceof RingMorph && oldArg.contents())) { - scripts.add(oldArg); - oldArg.moveBy(replacement.extent()); - oldArg.fixBlockColor(); - } - } - if (replacement instanceof MultiArgMorph - || replacement instanceof ArgLabelMorph - || replacement.constructor === CommandSlotMorph) { - replacement.fixLayout(); - if (this.fixLabelColor) { // special case for variadic continuations - this.fixLabelColor(); - } - } else { - this.fixLayout(); - } - this.cachedInputs = null; -}; +var scripts = this.parentThatIsA(ScriptsMorph), replacement = newArg, +idx = this.children.indexOf(oldArg), i = 0; if ((idx == -1) && (newArg +) instanceof MultiArgMorph) {this.children.forEach(morph => {if ( +morph instanceof ArgLabelMorph && morph.argMorph() === oldArg) { +idx = i;}; i += 1;});}; if (oldArg.cachedSlotSpec) {(oldArg +).cachedSlotSpec = null;}; if (newArg.cachedSlotSpec) {(newArg +).cachedSlotSpec = null;}; this.changed(); if (newArg.parent) { +newArg.parent.removeChild(newArg);}; if (oldArg instanceof ( +MultiArgMorph)) {oldArg.inputs().forEach(inp => (oldArg +).replaceInput(inp, new InputSlotMorph())); if (((this +).dynamicInputLabels || oldArg.collapse) && ((newArg +) instanceof ReporterBlockMorph)) {replacement = ( +new ArgLabelMorph(newArg, oldArg.collapse));};}; +replacement.parent = this; this.children[idx] = ( +replacement); if ((oldArg instanceof ( +ReporterBlockMorph)) && scripts && !( +oldArg.isPrototype)) {if (!((oldArg +) instanceof RingMorph) || ((oldArg +) instanceof RingMorph && (oldArg +).contents())) {scripts.add(oldArg); +oldArg.moveBy(replacement.extent() +); oldArg.fixBlockColor();};}; if ( +(replacement instanceof MultiArgMorph +) || (replacement instanceof ArgLabelMorph +) || (replacement.constructor === ( +CommandSlotMorph))) {replacement.fixLayout( +); if (this.fixLabelColor) {this.fixLabelColor();}; +} else {this.fixLayout();}; this.cachedInputs = null;}; SyntaxElementMorph.prototype.revertToDefaultInput = function (arg, noValues) { var deflt = this.revertToEmptyInput(arg), @@ -1749,9 +1631,8 @@ SyntaxElementMorph.prototype.revertToDefaultInput = function (arg, noValues) { def; if (noValues || inp < 0) { return deflt; - } - if (this instanceof BlockMorph) { - if (this.isCustomBlock) { + }; if (this instanceof BlockMorph + ) {if (this.isCustomBlock) { def = this.isGlobal ? this.definition : this.scriptTarget().getMethod(this.blockSpec); if (!noValues && @@ -1772,10 +1653,7 @@ SyntaxElementMorph.prototype.revertToDefaultInput = function (arg, noValues) { deflt.setContents(this.defaults[inp]); if (deflt instanceof MultiArgMorph) { deflt.defaults = this.defaults[inp]; - } - } - return deflt; -}; + };}; return deflt;}; SyntaxElementMorph.prototype.revertToEmptyInput = function (arg) { var idx = this.parts().indexOf(arg), @@ -1783,7 +1661,7 @@ SyntaxElementMorph.prototype.revertToEmptyInput = function (arg) { deflt = new InputSlotMorph, rcvr, def; - if (idx !== -1) { + if (idx > -1) { if (this instanceof BlockMorph) { deflt = this.labelPart(this.parseSpec(this.blockSpec)[idx]); if (this.isCustomBlock) { @@ -1793,9 +1671,8 @@ SyntaxElementMorph.prototype.revertToEmptyInput = function (arg) { rcvr = this.scriptTarget(true); if (rcvr) { def = rcvr.getMethod(this.blockSpec); - } - } - if (def) { + }; + }; if (def) { if (deflt instanceof InputSlotMorph) { deflt.setChoices.apply( deflt, @@ -1803,97 +1680,63 @@ SyntaxElementMorph.prototype.revertToEmptyInput = function (arg) { ); } else if (deflt instanceof MultiArgMorph) { deflt.setInfix(def.separatorOfInputIdx(inp)); - } - } - } + }; + }; + }; } else if (this instanceof MultiArgMorph) { deflt = this.labelPart(this.slotSpecFor(inp)); } else if (this instanceof ReporterSlotMorph) { deflt = this.emptySlot(); - } - } - if (deflt.icon || deflt instanceof BooleanSlotMorph) { - deflt.fixLayout(); - } - this.replaceInput(arg, deflt); + }; + }; if (deflt.icon || deflt instanceof BooleanSlotMorph + ) {deflt.fixLayout(); + }; this.replaceInput(arg, deflt); if (deflt instanceof MultiArgMorph) { deflt.refresh(); } else if (deflt instanceof RingMorph) { deflt.fixBlockColor(); - } - this.cachedInputs = null; - return deflt; -}; + }; this.cachedInputs = null; + return deflt;}; -SyntaxElementMorph.prototype.isLocked = function anonymous () {/* answer true if I can be exchanged by a dropped reporter */ return this.isStatic;}; +SyntaxElementMorph.prototype.isLocked = ( +function () {return this.isStatic;}); // SyntaxElementMorph enumerating: -SyntaxElementMorph.prototype.topBlock = function () { - if (this.parent && this.parent.topBlock) { - return this.parent.topBlock(); - } - return this; -}; +SyntaxElementMorph.prototype.topBlock = function ( +) {if (this.parent && ((this.parent).topBlock)) { +return this.parent.topBlock();}; return this;}; // SyntaxElementMorph reachable variables SyntaxElementMorph.prototype.getVarNamesDict = function () { - var block = this.parentThatIsA(BlockMorph), - rcvr, tempVars = [], dict; - - if (!block) { - return {}; - }; rcvr = block.scriptTarget(); - block.allParents().forEach(morph => { - if (morph instanceof PrototypeHatBlockMorph) { - tempVars.push.apply( - tempVars, - morph.variableNames() - ); - tempVars.push.apply( - tempVars, - morph.inputs()[0].inputFragmentNames() - ); - } else if (morph instanceof BlockMorph) { - morph.inputs().forEach(inp => { - inp.allChildren().forEach(child => { - if (child instanceof TemplateSlotMorph) { - tempVars.push(child.contents()); - } else if (child instanceof MultiArgMorph) { - child.children.forEach(m => { - if (m instanceof TemplateSlotMorph) { - tempVars.push(m.contents()); - }; - }); - }; - }); - }); - }; - }); if (rcvr) { - dict = rcvr.variables.allNamesDict(); - tempVars.forEach(name => - dict[name] = name - ); if (block.selector === 'doSetVar') { - // add settable object attributes - dict['~'] = null; - dict.my = [{// wrap the submenu into a 1-item array to translate it - 'anchor' : ['my anchor'], - 'parent' : ['my parent'], - 'name' : ['my name'], - 'temporary?' : ['my temporary?'], - 'dangling?' : ['my dangling?'], - 'draggable?' : ['my draggable?'], - 'rotation style' : ['my rotation style'], - 'rotation x' : ['my rotation x'], - 'rotation y' : ['my rotation y'] - }]; if (this.world().currentKey === 16) { // shift - dict.my[0]['~'] = null; // don't forget we're inside an array... - dict.my[0]['microphone modifier'] = ['microphone modifier']; - }; - }; return dict; - }; return {}; -}; +var block = this.parentThatIsA(BlockMorph), tempVars = [ +], rcvr, dict; if (!block) {return {};}; rcvr = (block +).scriptTarget(); block.allParents().forEach(morph => { +if (morph instanceof PrototypeHatBlockMorph) {(tempVars +).push.apply(tempVars, morph.variableNames()); (tempVars +).push.apply(tempVars, morph.inputs()[0].inputFragmentNames( +));} else if (morph instanceof BlockMorph) {(morph.inputs() +).forEach(inp => {inp.allChildren().forEach(child => {if (( +child) instanceof TemplateSlotMorph) {tempVars.push((child +).contents());} else if (child instanceof MultiArgMorph) { +(child.children).forEach(m => {if (m instanceof ( +TemplateSlotMorph)) {tempVars.push(m.contents());}; +});};});});};}); if (rcvr) {dict = (rcvr.variables +).allNamesDict(); tempVars.forEach(name => dict[name +] = name); if (block.selector === 'doSetVar') {dict[ +'~'] = null; dict.my = [{'anchor' : ['my anchor'], +'parent' : ['my parent'], 'name' : ['my name'], +'temporary?' : ['my temporary?'], 'dangling?' : [ +'my dangling?'], 'draggable?' : ['my draggable?' +], 'rotation style' : ['my rotation style' +], 'rotation x' : ['my rotation x'], +'rotation y' : ['my rotation y']}]; +if (world.currentKey === 16) {(dict +).my[0]['~'] = null; (dict.my[0] +)['microphone modifier'] = [ +'microphone modifier'];};}; +return dict;}; return {};}; // Variable refactoring @@ -1928,9 +1771,7 @@ SyntaxElementMorph.prototype.refactorVarInStack = function ( var nb = this.nextBlock(); if (nb) { nb.refactorVarInStack(oldName, newName); - }; - }; -}; + };};}; SyntaxElementMorph.prototype.definesScriptVariable = function (name) { // Returns true if this block is defining either a script local var or @@ -1946,80 +1787,52 @@ SyntaxElementMorph.prototype.definesScriptVariable = function (name) { // SyntaxElementMorph copy-on-write support: -SyntaxElementMorph.prototype.selectForEdit = function () { - var scripts = this.parentThatIsA(ScriptsMorph), - ide = this.parentThatIsA(IDE_Morph), - rcvr = ide ? ide.currentSprite : null, - selected; - if (scripts && rcvr && rcvr.inheritsAttribute('scripts')) { - // copy on write: - this.selectionID = true; - rcvr.shadowAttribute('scripts'); - selected = detect( - rcvr.scripts.allChildren(), - m => m.selectionID - ); delete this.selectionID; - delete selected.selectionID; - return selected; - }; return this; -}; +SyntaxElementMorph.prototype.selectForEdit = function ( +) {var scripts = this.parentThatIsA(ScriptsMorph), +ide = this.parentThatIsA(IDE_Morph), rcvr = (ide ? ( +ide.currentSprite) : null), selected; if ((scripts +) && rcvr && (rcvr.inheritsAttribute('scripts'))) { +this.selectionID = true; rcvr.shadowAttribute('scripts' +); selected = detect(rcvr.scripts.allChildren(), +(m => m.selectionID)); delete this.selectionID; +delete selected.selectionID; return selected; +}; return this;}; /* Select while editing. */ // SyntaxElementMorph drag & drop: SyntaxElementMorph.prototype.reactToGrabOf = function (grabbedMorph) { - var topBlock = this.topBlock(), - affected; - if (grabbedMorph instanceof CommandBlockMorph) { - affected = this.parentThatIsA(CommandSlotMorph, ReporterSlotMorph); - if (affected) { - affected.fixLayout(); - }; - }; if (topBlock) { - topBlock.allComments().forEach(comment => - comment.align(topBlock) - ); if (topBlock.getHighlight()) { - topBlock.addHighlight(topBlock.removeHighlight()); - }; - }; -}; +var topBlock = this.topBlock(), affected; if (grabbedMorph instanceof ( +CommandBlockMorph)) {affected = this.parentThatIsA(CommandSlotMorph, +ReporterSlotMorph); if (affected) {affected.fixLayout();};}; if ( +topBlock) {topBlock.allComments().forEach(comment => ((comment +).align(topBlock))); if (topBlock.getHighlight()) {(topBlock +).addHighlight(topBlock.removeHighlight());};};}; // SyntaxElementMorph 3D - border color rendering: -SyntaxElementMorph.prototype.bright = function () {return this.color.lighter(this.contrast).toString();}; - -SyntaxElementMorph.prototype.dark = function () {return this.color.darker(this.contrast).toString();}; +SyntaxElementMorph.prototype.bright = function () { +return this.color.lighter(this.contrast).toString(); +}; SyntaxElementMorph.prototype.dark = function () { +return this.color.darker(this.contrast).toString();}; // SyntaxElementMorph color changing: -SyntaxElementMorph.prototype.setColor = function (aColor) { - var block; - if (aColor) { - if (!this.color.eq(aColor)) { - block = this.parentThatIsA(BlockMorph); - this.color = aColor; - this.children.forEach(morph => { - if (block && (morph instanceof StringMorph || - morph instanceof SymbolMorph)) { - morph.shadowColor = block.color.darker( - block.labelContrast - ); - morph.rerender(); - } else if (morph instanceof CommandSlotMorph) { - morph.setColor(aColor); - }; - }); - if (block) {block.fixLabelColor();}; - this.rerender(); - }; - }; -}; +SyntaxElementMorph.prototype.setColor = function ( +aColor) {var block; if (aColor) {if (!((this.color +).eq(aColor))) {block = this.parentThatIsA(BlockMorph +); this.color = aColor; this.children.forEach(morph => { +if (block && ((morph instanceof StringMorph) || ((morph +) instanceof SymbolMorph))) {morph.shadowColor = (block +).color.darker(block.labelContrast); morph.rerender( +);} else if (morph instanceof CommandSlotMorph) { +morph.setColor(aColor);};}); if (block) {(block +).fixLabelColor();}; this.rerender();};};}; SyntaxElementMorph.prototype.setLabelColor = function ( textColor, shadowColor, shadowOffset -) { - this.children.forEach(morph => { +) {this.children.forEach(morph => { if (morph instanceof StringMorph && !morph.isProtectedLabel) { morph.shadowOffset = shadowOffset || morph.shadowOffset; morph.shadowColor = shadowColor || morph.shadowColor; @@ -2031,49 +1844,41 @@ SyntaxElementMorph.prototype.setLabelColor = function ( && morph.isReadOnly)) { morph.setLabelColor(textColor, shadowColor, shadowOffset); } else if (morph.isLoop) { // C-shaped slot with loop arrow symbol - morph.loop().setLabelColor(textColor, shadowColor, shadowOffset); - }; - }); -}; + (morph.loop()).setLabelColor(textColor, shadowColor, shadowOffset); + };});}; SyntaxElementMorph.prototype.flash = function () { if (!this.cachedNormalColor) { this.cachedNormalColor = this.color; this.setColor(this.activeHighlight); - }; -}; + };}; SyntaxElementMorph.prototype.unflash = function () { if (this.cachedNormalColor) { var clr = this.cachedNormalColor; this.cachedNormalColor = null; this.setColor(clr); - }; -}; + };}; -SyntaxElementMorph.prototype.doWithAlpha = function (alpha, callback) { - var current = SyntaxElementMorph.prototype.alpha, - result; - SyntaxElementMorph.prototype.alpha = alpha; - result = callback(); - SyntaxElementMorph.prototype.alpha = current; - return result; -}; +SyntaxElementMorph.prototype.doWithAlpha = function ( +alpha, callback) {var current = ((SyntaxElementMorph +).prototype.alpha), result; ((SyntaxElementMorph +).prototype.alpha) = alpha; result = callback(); +SyntaxElementMorph.prototype.alpha = ( +current); return result;}; // SyntaxElementMorph zebra coloring SyntaxElementMorph.prototype.fixBlockColor = function ( - nearestBlock, - isForced -) { - this.children.forEach(morph => { - if (morph instanceof SyntaxElementMorph) { - morph.fixBlockColor(nearestBlock, isForced); - }; - }); -}; +nearestBlock, isForced) {this.children.forEach((morph +) => {if (morph instanceof SyntaxElementMorph) {(morph +).fixBlockColor(nearestBlock, isForced);};});}; -SyntaxElementMorph.prototype.pictureLabelExceptions = {'%obj' : '%turtle', '%clr' : '%pipette', '%l' : '%verticalEllipsis'}; +(SyntaxElementMorph.prototype +).pictureLabelExceptions = { +'%l' : '%verticalEllipsis', +'%clr' : '%pipette', +'%obj' : '%turtle'}; // SyntaxElementMorph label parts: @@ -2081,7 +1886,7 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { var part, info, tokens, cnts, i; if (spec[0] === '%' && spec.length > 1 && - (this.selector !== 'reportGetVar' || + (!(this.selector == 'reportGetVar') || (contains(Object.values(SyntaxElementMorph.prototype.pictureLabelExceptions), spec) && this.isObjInputFragment()))) { // check for variable multi-arg-slot: @@ -2112,18 +1917,17 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { part = new InputSlotMorph(0, true); break; case 'degrees number': - part = new InputSlotMorph(90, true, - { - '§_dir': null, - '(90) right' : 90, - '(270) left' : -90, - '(0) up' : 0, - '(180) down' : 180, - 'random' : ['random'] + part = new InputSlotMorph( + 90, true, {'§_dir': null, + '(90) right' : 90, + '(270) left' : -90, + '(0) up' : 0, + '(180) down' : 180, + 'random' : ['random'] }); break; case 'another number': - part = new InputSlotMorph(50, true); - break; + part = new InputSlotMorph( + 50, true); break; case 'text entry': part = new TextSlotMorph; break; @@ -2131,44 +1935,25 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { switch (info.kind) { case 'command': part = new CommandSlotMorph; - break; - case 'reporter': + break; case 'reporter': part = new ReporterSlotMorph; - part.render = function (ctx) { - var borderColor; if (this.parent) {borderColor = this.parent.color; - } else {borderColor = new Color(120, 120, 120);}; // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast).toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - if (this.nestedBlock() instanceof ReporterBlockMorph) { - if (this.nestedBlock().isPredicate || this.nestedBlock( - ).isArrow) {this.drawModifiedDiamond(ctx); - } else {this.drawModifiedRounded(ctx);}; - } else {this.drawModifiedRounded(ctx);}; - }; break; case 'predicate': - part = new ReporterSlotMorph(true); - part.render = function (ctx) { - var borderColor; if (this.parent) {borderColor = this.parent.color; - } else {borderColor = new Color(120, 120, 120);}; // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast).toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - if (this.nestedBlock() instanceof ReporterBlockMorph) { - if (this.nestedBlock().isPredicate || this.nestedBlock( - ).isArrow) {this.drawModifiedDiamond(ctx); - } else {this.drawModifiedRounded(ctx);}; - } else {this.drawModifiedDiamond(ctx);}; - }; break; - case 'function': part = new RingReporterSlotMorph; - part.getSpec = (() => '%f'); break; case 'instructions': - part = new BlockSlotMorph; break; case 'color': - part = new ColorSlotMorph; if (this instanceof BlockMorph - ) {if (this.selector === 'getColor') {part.isStatic = true;};}; - part.bounds.setExtent(new Point((14 * part.edge), (14 * part.edge - ))); break; default: part = new ArgMorph(info.kind);}; break; - case 'boolean': part = new BooleanSlotMorph; break; case 'symbol': - part = new BlockSymbolMorph(info.name); - part.size = this.fontSize * (info.scale || 1); + break; case 'predicate': + part = new ReporterSlotMorph( + true); break; case 'function': + part = new RingReporterSlotMorph; + part.getSpec = (() => '%f'); + break; case 'instructions': + part = new BlockSlotMorph; + break; case 'color': part = ( + new ColorSlotMorph); if ((this + ) instanceof BlockMorph) {if ( + this.selector === 'getColor') { + part.isStatic = true;};}; break; + default: part = new ArgMorph( + info.kind);}; break; + case 'boolean': part = new BooleanSlotMorph; break; + case 'symbol': part = new BlockSymbolMorph(info.name + ); part.size = this.fontSize * (info.scale || 1); part.color = info.color || WHITE; part.shadowColor = this.color.darker(this.labelContrast); part.shadowOffset = MorphicPreferences.isFlat ? @@ -2201,26 +1986,18 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { case 'break': part = new Morph; part.setExtent( ZERO); part.isBlockLabelBreak = true; - part.getSpec = () => '%br'; break; + part.getSpec = (() => '%br'); break; case 'multi': part = new MultiArgMorph( - info.slots, - info.label, - info.min || 0, - spec, - null, null, null, null, null, - info.infix, - info.collapse, - info.dflt, - info.group, - info.hidden - ); - part.maxInputs = (info.hidden ? 1 : info.max); - for (i = 0; i < (info.hidden ? 1 : (info.defaults || 0)); i += 1) { - part.addInput(); - }; - break; - default: + info.slots, info.label, + info.min || 0, spec, + null, null, null, null, + null, info.infix, (info + ).collapse, info.dflt, + info.group, info.hidden + ); part.maxInputs = (info.hidden ? 1 : info.max + ); for (i = 0; i < (info.hidden ? 1 : ((info.defaults + ) || 0)); i += 1) {part.addInput();}; break; default: throw new Error('unknown label part type: "' + info.type + '"'); }; @@ -2249,7 +2026,7 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { break; case 'read-only': part.isReadOnly = true; - if (!MorphicPreferences.isFlat) { + if (!(MorphicPreferences.isFlat)) { cnts = part.contents(); cnts.shadowOffset = new Point(1, 1); cnts.fixLayout(); @@ -2283,7 +2060,6 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { case 'widget': part.canBeEmpty = false; break; - default: }; }; }); part.fixLayout(); @@ -2341,15 +2117,12 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { WHITE, // color this.labelFontName // fontName ); - }; return part; -}; + }; return part;}; SyntaxElementMorph.prototype.isObjInputFragment = function () { - // private - for displaying a symbol in a variable block template - return (this.selector === 'reportGetVar') && - (this.getSlotSpec() === '%t') && - contains(Object.keys(SyntaxElementMorph.prototype.pictureLabelExceptions), this.parent.fragment.type); -}; +return (((this.selector === 'reportGetVar') && (this.getSlotSpec( +) === '%t')) && contains(Object.keys((SyntaxElementMorph.prototype +).pictureLabelExceptions), this.parent.fragment.type));}; // SyntaxElementMorph layout: @@ -2366,7 +2139,7 @@ SyntaxElementMorph.prototype.fixLayout = function () { l = [], lines = [], space = this.isPrototype ? - 1 : Math.floor(fontHeight(this.labelSize) / 3), + 1 : Math.floor(fontHeight(this.fontSize) / 3), ico = this instanceof BlockMorph && this.hasLocationPin() ? this.methodIconExtent().x + space : 0, bottomCorrection, @@ -2383,45 +2156,32 @@ SyntaxElementMorph.prototype.fixLayout = function () { + (this.edge * 2) + (this.inset * 3) + this.dent; - } - - if (this.nextBlock) { + }; if (this.nextBlock) { nb = this.nextBlock(); - } + }; // determine lines parts.forEach(part => { if ((part instanceof CSlotMorph) || (part instanceof MultiArgMorph && extraContains(['%cl', '%c', '%cs', '%cla', '%loop', '%ca'], part.slotSpec)) - ) { - if (l.length > 0) { + ) {if (l.length > 0) { lines.push(l); lines.push([part]); l = []; x = 0; } else { lines.push([part]); - } - } else if (this.isVertical() && !(part instanceof FrameMorph)) { - // variadic ring-inputs are arranged vertically - // except the arrows for expanding and collapsing them - if (l.length > 0) { - lines.push(l); - } - l = [part]; - x = part.fullBounds().width() + space; + }; + } else if (this.isVertical() && !(part instanceof FrameMorph + )) {if (l.length > 0) {lines.push(l);}; l = [part]; + x = part.fullBounds().width() + space; } else { if (part.isVisible) { x += part.fullBounds().width() + space; - } - if ((x > this.labelWidth) || part.isBlockLabelBreak) { - if (l.length > 0) { - lines.push(l); - l = []; + }; if ((x > this.labelWidth) || part.isBlockLabelBreak) { + if (l.length > 0) {lines.push(l); l = []; x = part.fullBounds().width() + space; - } - } - l.push(part); + };}; l.push(part); if (part.isBlockLabelBreak) { x = 0; }; @@ -2429,26 +2189,23 @@ SyntaxElementMorph.prototype.fixLayout = function () { }); if (l.length > 0) { lines.push(l); - }; // distribute parts on lines + }; // distribute parts on lines if (this instanceof CommandBlockMorph) { y = this.top() + this.corner + this.edge; - if (this instanceof HatBlockMorph) { - y += this.hatHeight; - if (((this.constructor.name === 'HatBlockMorph' - ) && asABool(this.isPrototypeLike)) || ( - this.constructor.name === 'PrototypeHatBlockMorph' - )) { - y += this.hatHeight; - };}; + if (this instanceof DefinitorBlockMorph + ) {y += this.hatHeight;}; + if (this instanceof HatBlockMorph + ) {y += this.hatHeight; + if (this.isPrototypeLike) { + y += this.hatHeight;};}; } else if (this instanceof ReporterBlockMorph) { y = this.top() + (this.edge * 2); } else if (this instanceof MultiArgMorph || this instanceof ArgLabelMorph) { y = this.top(); if (contains(['%cl', '%c', '%cs', '%cla', '%loop', '%ca' - ], asAnArray(this.slotSpec)[0]) && (this.inputs().length > 0)) { - y -= this.rounding; - }; + ], asAnArray(this.slotSpec)[0]) && (((this.inputs( + )).length) > 0)) {y -= this.rounding;}; }; lines.forEach(line => { if (hasLoopCSlot) { hasLoopArrow = true; @@ -2461,7 +2218,7 @@ SyntaxElementMorph.prototype.fixLayout = function () { x = this.left() + ico + this.rounding; };} else if (this instanceof MultiArgMorph || this instanceof ArgLabelMorph - ) {x = this.left(); + ) {x = this.left(); }; y += lineHeight; lineHeight = 0; line.forEach(part => { @@ -2518,9 +2275,7 @@ SyntaxElementMorph.prototype.fixLayout = function () { Math.floor((lineHeight - part.height()) / 2) )); }); - }); - - // determine my height: + }); // determine my height: y += lineHeight; if (this.children.some(any => any instanceof CSlotMorph)) { bottomCorrection = this.bottomPadding; @@ -2531,8 +2286,8 @@ SyntaxElementMorph.prototype.fixLayout = function () { this.bottomPadding, this.rounding - this.bottomPadding ); - }; y += bottomCorrection; - }; if (this instanceof CommandBlockMorph) { + }; y += bottomCorrection; + }; if (this instanceof CommandBlockMorph) { blockHeight = y - this.top() + (this.corner * 2); } else if (this instanceof ReporterBlockMorph) { blockHeight = y - this.top() + (this.edge * 2); @@ -2555,15 +2310,16 @@ SyntaxElementMorph.prototype.fixLayout = function () { blockWidth = Math.max( blockWidth, maxX - this.left() + this.labelPadding - this.edge - ); // adjust right padding if rightmost input has arrows + ); // adjust right padding if rightmost input has arrows rightMost = parts[parts.length - 1]; if (rightMost instanceof MultiArgMorph && rightMost.isVisible && (lines.length === 1)) { blockWidth -= space; - }; // adjust width to hat width - if (this instanceof HatBlockMorph) { - blockWidth = Math.max(blockWidth, this.hatWidth * 1.5); - }; + }; // adjust width to hat width + if ((this instanceof HatBlockMorph + ) || (this instanceof DefinitorBlockMorph + )) {blockWidth = Math.max(blockWidth, + this.hatWidth * 3/2);}; }; // set my extent (silently, because we'll redraw later anyway): this.bounds.setWidth(blockWidth); this.bounds.setHeight(blockHeight); @@ -2621,16 +2377,16 @@ SyntaxElementMorph.prototype.fixLayout = function () { if (this.parent instanceof SyntaxElementMorph) { return; }; - }; this.fixHighlight(); + }; this.fixHighlight(); }; -SyntaxElementMorph.prototype.fixHighlight = function () { -var top = this.topBlock(); if (top.getHighlight && top.getHighlight()) { -top.addHighlight(top.removeHighlight());};}; - SyntaxElementMorph.prototype.methodIconExtent = function ( -) {var ico = this.fontSize * 1.2; return this.hasLocationPin( -) ? new Point(ico * (2 / 3), ico) : new Point(0, 0);}; +) {var ico = this.fontSize * 6/5; return this.hasLocationPin( +) ? new Point(ico * 2/3, ico) : ZERO;}; + +SyntaxElementMorph.prototype.fixHighlight = function ( +) {var top = this.topBlock(); if (top.getHighlight && (top +).getHighlight()) {top.addHighlight(top.removeHighlight());};}; SyntaxElementMorph.prototype.isVertical = (() => false); @@ -2647,12 +2403,9 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, ide = this.parentThatIsA(IDE_Morph) || ((target instanceof Morph ) ? target.parentThatIsA(IDE_Morph) : world.childThatIsA(IDE_Morph )), anchor = this, pos = this.rightCenter().add(new Point(2, 0)), - sf = this.parentThatIsA(ScrollFrameMorph), - wrrld = this.world() || target.world(); - - if ((value === undefined) || !wrrld) { - return null; - }; if (value instanceof ListWatcherMorph) { + sf = this.parentThatIsA(ScrollFrameMorph), wrrld = world; + if (value === undefined) {return null;}; + if (value instanceof ListWatcherMorph) { morphToShow = value; morphToShow.update(true); morphToShow.step = value.update; @@ -2679,16 +2432,14 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, this.cachedImage = img; this.version = value.version; this.changed(); - }; - }; + };}; } else { img = value.fullImage(); morphToShow = new Morph; morphToShow.isCachingImage = true; morphToShow.bounds.setWidth(img.width); - morphToShow.bounds.setHeight(img.height); - morphToShow.cachedImage = img; - }; + morphToShow.bounds.setHeight(img.height + ); morphToShow.cachedImage = img;}; } else if (value instanceof Costume) { img = value.thumbnail(new Point(40, 40)); morphToShow = new Morph; @@ -2713,8 +2464,8 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, hand.grabOrigin = { origin: ide.palette, position: ide.palette.center() - }; this.prepareToBeGrabbed = prepare; - }; icon.setCenter(this.center()); + }; this.prepareToBeGrabbed = prepare; + }; icon.setCenter(this.center()); return icon; }; @@ -2756,10 +2507,9 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, hand.grabOrigin = { origin: ide.palette, position: ide.palette.center() - }; this.prepareToBeGrabbed = prepare; - }; icon.setCenter(this.center()); - return icon; - }; + }; this.prepareToBeGrabbed = prepare; + }; icon.setCenter(this.center()); + return icon;}; // support exporting sounds directly from result bubbles: morphToShow.userMenu = function () { @@ -2790,7 +2540,7 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, origin: ide.palette, position: ide.palette.center() }; this.prepareToBeGrabbed = prepare; - }; if (ide.isAppMode) {return;}; + }; if (ide.isAppMode) {return;}; script.setPosition(this.position()); return script; }; @@ -2818,7 +2568,7 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, hand.grabOrigin = { origin: ide.palette, position: ide.palette.center() - }; this.prepareToBeGrabbed = prepare; + }; this.prepareToBeGrabbed = prepare; }; if (ide.isAppMode) {return;}; script.setPosition(this.position()); return script; @@ -2842,10 +2592,10 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, hand.grabOrigin = { origin: ide.palette, position: ide.palette.center() - }; this.prepareToBeGrabbed = prepare; - }; if (ide.isAppMode) {return;}; - script.setPosition(this.position()); - return script; + }; this.prepareToBeGrabbed = prepare; + }; if (ide.isAppMode) {return;}; + script.setPosition(this.position( + )); return script; }; } else if (isString(value)) { txt = value.length > 500 ? value.slice(0, 500) + '...' : value; @@ -2861,47 +2611,44 @@ SyntaxElementMorph.prototype.showBubble = function (value, exportPic, 'text/plain;charset=utf-8', localize('data') ) - ); return menu; + ); return menu; }; } else if (value === null) { morphToShow = new TextMorph( '', this.fontSize); } else if (value.toString) { morphToShow = new TextMorph( - ((value.textRepresentation === undefined) ? value.toString() : value.textRepresentation), - this.fontSize); - }; if (ide && (ide.currentSprite !== target)) { + ((value.textRepresentation === undefined + ) ? value.toString() : getText( + value.textRepresentation, + value)), this.fontSize); + }; if (ide && !(ide.currentSprite === target)) { if (target instanceof StageMorph) { anchor = ide.corral.stageIcon; } else if (target) { if (target.isTemporary) { - target = detect( - target.allExemplars(), - each => !each.isTemporary - ); - }; anchor = detect( - ide.corral.frame.contents.children, - icon => icon.object === target - ); + target = detect(target.allExemplars(), + each => !(each.isTemporary)); + }; anchor = detect( + ide.corral.frame.contents.children, + icon => icon.object === target); } else { target = ide; }; pos = anchor.center(); }; bubble = new SpeechBubbleMorph( - morphToShow, null, - Math.max(this.rounding - 2, 6), - 0 + morphToShow, null, Math.max( + this.rounding - 2, 6), 0 ); bubble.popUp( wrrld, pos, isClickable - ); if (exportPic) { + ); if (exportPic) { this.exportPictureWithResult(bubble); - }; if (anchor instanceof SpriteIconMorph) { - bubble.keepWithin(ide.corral); - } else if (sf) { + }; if (anchor instanceof SpriteIconMorph + ) {bubble.keepWithin(ide.corral); + } else if (sf) { bubble.keepWithin(sf); - }; -}; + };}; SyntaxElementMorph.prototype.exportPictureWithResult = function (aBubble) { var ide = this.parentThatIsA(IDE_Morph) || @@ -2916,12 +2663,8 @@ SyntaxElementMorph.prototype.exportPictureWithResult = function (aBubble) { )), ctx = pic.getContext('2d'); ctx.drawImage(scr, 0, pic.height - scr.height); ctx.drawImage(bub, scr.width + 2, 0); - // request to open pic in new window. - ide.saveCanvasAs( - pic, - (ide.projectName || localize('Untitled')) + ' ' + localize('script pic') - ); -}; + ide.saveCanvasAs(pic, (ide.projectName || ( + localize('Untitled'))) + ' ' + localize('script pic'));}; // SyntaxElementMorph code mapping @@ -2938,6 +2681,27 @@ SyntaxElementMorph.prototype.mappedCode = function (definitions) { }; return result; }; +SyntaxElementMorph.prototype.cSlots = function () { + var result = []; + this.parts().forEach(part => { + if (part instanceof CSlotMorph) { + result.push(part); + } else if (part instanceof MultiArgMorph + ) {part.cSlots().forEach( + slot => result.push(slot)); + };}); return result;}; + +SyntaxElementMorph.prototype.clearSlots = function () { + var result = []; + this.parts().forEach(part => { + if ((part instanceof RingCommandSlotMorph) || ( + part instanceof RingReporterSlotMorph)) { + result.push(part); + } else if (part instanceof MultiArgMorph + ) {part.clearSlots().forEach( + slot => result.push(slot)); + };}); return result;}; + // BlockLabelMorph /////////////////////////////////////////////// /* @@ -3018,37 +2782,29 @@ BlockSymbolMorph.prototype.getRenderColor = function () { if (MorphicPreferences.isFlat) { if (this.isFading) { return this.color.mixed(block.alpha, WHITE); - } - if (this.color.eq(WHITE)) { + }; if (this.color.eq(WHITE)) { return this.parent.alpha > 0.5 ? this.color : block.color.solid().darker(Math.max(block.alpha * 200, 0.1)); - } - if (this.color.eq(BLACK)) { + }; if (this.color.eq(BLACK)) { return this.parent.alpha > 0.5 ? this.color : block.color.solid().darker(Math.max(block.alpha * 200, 0.1)); - } - return this.color; - } - if (this.isFading) { + }; return this.color; + }; if (this.isFading) { return this.color.mixed( block.alpha, SpriteMorph.prototype.paletteColor ); - } - if (this.color.eq(BLACK)) { + }; if (this.color.eq(BLACK)) { return block.alpha > 0.5 ? this.color : block.color.solid().lighter(Math.max(block.alpha * 200, 0.1)); - } - if (this.color.eq(WHITE)) { + }; if (this.color.eq(WHITE)) { return this.parent.alpha > 0.5 ? this.color : block.color.solid().lighter(Math.max(block.alpha * 200, 0.1)); - } - return this.color; + }; return this.color; }; BlockSymbolMorph.prototype.getShadowRenderColor = function () { - return this.parent.alpha > 0.5 ? this.shadowColor : CLEAR; -}; +return ((this.parent).alpha > 0.5 ? this.shadowColor : CLEAR);}; // BlockMorph ////////////////////////////////////////////////////////// @@ -3178,19 +2934,19 @@ BlockMorph.prototype.zebraContrast = 40; // alternating color brightness // BlockMorph sound feedback: -BlockMorph.prototype.getSpec = function anonymous () {return this.blockSpec.toString() || '';}; +BlockMorph.prototype.getSpec = function () { +return (this.blockSpec.toString() || '');}; BlockMorph.prototype.snapSound = null; -BlockMorph.prototype.toggleSnapSound = function () { - if (this.snapSound !== null) { - this.snapSound = null; - } else { - BlockMorph.prototype.snapSound = document.createElement('audio'); - BlockMorph.prototype.snapSound.src = 'src/click.wav'; - }; CommentMorph.prototype.snapSound = BlockMorph.prototype.snapSound; - BlockSlotMorph.prototype.snapSound = BlockMorph.prototype.snapSound; -}; +BlockMorph.prototype.toggleSnapSound = function ( +) {if (isNil(this.snapSound)) {(BlockMorph.prototype +).snapSound = document.createElement('audio'); +BlockMorph.prototype.snapSound.src = ( +'src/click.wav');} else {(this.snapSound +) = null;}; (CommentMorph.prototype.snapSound +) = BlockMorph.prototype.snapSound; (BlockSlotMorph +).prototype.snapSound = BlockMorph.prototype.snapSound;}; // BlockMorph instance creation: @@ -3238,12 +2994,9 @@ BlockMorph.prototype.scriptTarget = function (noError) { if (dlg) { if (isSnapObject(dlg.target)) { return dlg.target; - }; - if (dlg.target instanceof IDE_Morph) { - return dlg.target.currentSprite; - }; - }; - if (noError) {return null; } + }; if (dlg.target instanceof IDE_Morph + ) {return dlg.target.currentSprite;}; + }; if (noError) {return null;}; throw new Error('script target cannot be found for orphaned block'); }; @@ -3265,12 +3018,9 @@ BlockMorph.prototype.parseSpec = function (spec) { words = isString(spec) ? spec.split(' ') : []; if (words.length === 0) { words = [spec]; - } - if (this.labelWordWrap) { + }; if (this.labelWordWrap) { return words; - } - - function addWord(w) { + }; function addWord(w) { if ((w[0] === '%') && (w.length > 1)) { if (word !== '') { result.push(word); @@ -3282,15 +3032,13 @@ BlockMorph.prototype.parseSpec = function (spec) { word += ' ' + w; } else { word = w; - } - } - } - - words.forEach(each => addWord(each)); - if (word !== '') { + }; + }; + }; words.forEach( + each => addWord(each + )); if (word !== '') { result.push(word); - } - return result; + }; return result; }; BlockMorph.prototype.setSpec = function (spec, definition) { @@ -3328,31 +3076,28 @@ BlockMorph.prototype.setSpec = function (spec, definition) { (definition || this.definition).inputOptionsOfIdx(inputIdx) ); }; - }); this.blockSpec = spec; if (contains(['reportScript', - 'zoomLambdaTest'], this.selector) && (this instanceof - ReporterBlockMorph)) {this.rounding = 4.5 * this.scale; - } else if ((contains(['getColor', 'makeColor', - 'mixColors', 'mixClrsAt', 'clrFlags'], - this.selector)) && (this instanceof ReporterBlockMorph - )) {this.rounding = 0;} else { - this.rounding = 9 * this.scale; - }; this.fixLayout(); - this.rerender(); - this.cachedInputs = null; + }); this.blockSpec = spec; if (contains([ + 'reportScript', 'zoomLambdaTest'], this.selector + ) && (this instanceof ReporterBlockMorph)) { + this.rounding = 4.5 * this.scale;} else if (( + contains(['getColor', 'makeColor', 'mixColors', + 'mixClrsAt', 'clrFlags'], this.selector)) && ( + this instanceof ReporterBlockMorph)) {(this + ).rounding = 0;} else {this.rounding = (9 * ( + this).scale);}; this.fixLayout(); (this + ).rerender(); this.cachedInputs = null; }; -BlockMorph.prototype.userSetSpec = function (spec) { - var tb = this.topBlock(); - tb.fullChanged(); - this.setSpec(spec); - tb.fullChanged(); -}; +BlockMorph.prototype.userSetSpec = function ( +spec) {var tb = this.topBlock(); tb.fullChanged( +); this.setSpec(spec); tb.fullChanged();}; -BlockMorph.prototype.buildSpec = function () {this.blockSpec = ''; this.parts().forEach(part => {if (part instanceof StringMorph) {this.blockSpec += part.text;} else if (part instanceof ArgMorph) { -this.blockSpec += part.getSpec();} else if (part.isBlockLabelBreak) {this.blockSpec += part.getSpec();} else {this.blockSpec += '[undefined]';}; this.blockSpec += ' ';}); this.blockSpec = this.blockSpec.trim();}; +BlockMorph.prototype.buildSpec = function () {this.blockSpec = ''; this.parts().forEach(part => {if (part instanceof StringMorph) { +this.blockSpec += part.text;} else if (part instanceof ArgMorph) {this.blockSpec += part.getSpec();} else if (part.isBlockLabelBreak) { +this.blockSpec += part.getSpec();} else {this.blockSpec += '[undefined]';}; this.blockSpec += ' ';}); this.blockSpec = this.blockSpec.trim();}; -BlockMorph.prototype.rebuild = function (contrast) {this.setSpec(this.blockSpec); if (contrast) {this.inputs().forEach(input => {if (input instanceof ReporterBlockMorph) { -input.setColor(input.color.lighter(contrast)); input.setSpec(input.blockSpec);};});};}; +BlockMorph.prototype.rebuild = function (contrast) {this.setSpec(this.blockSpec); if (contrast) {this.inputs().forEach(input => { +if (input instanceof ReporterBlockMorph) {input.setColor(input.color.lighter(contrast)); input.setSpec(input.blockSpec);};});};}; BlockMorph.prototype.abstractBlockSpec = function () { // answer the semantic block spec substituting each input @@ -3397,30 +3142,23 @@ BlockMorph.prototype.localizeBlockSpec = function (spec) { // BlockMorph menu: -BlockMorph.prototype.userMenu = function anonymous () { - var menu = new MenuMorph(this), - world = this.world(), - myself = this, - hasLine = false, - proc = this.activeProcess(), - top = this.topBlock(), +BlockMorph.prototype.userMenu = function () { + var menu = new MenuMorph(this), myself = this, + hasLine = false, proc = this.activeProcess( + ), top = this.topBlock(), vNames = proc && proc.context && proc.context.outerContext ? proc.context.outerContext.variables.names() : [], - slot, - mult, - alternatives, - field, - rcvr; + slot, mult, alternatives, field, rcvr; function addOption(label, toggle, test, onHint, offHint) { menu.addItem( [ test ? new SymbolMorph( 'checkedBox', - MorphicPreferences.menuFontSize * 0.75 + MorphicPreferences.menuFontSize * 3/4 ) : new SymbolMorph( 'rectangle', - MorphicPreferences.menuFontSize * 0.75 + MorphicPreferences.menuFontSize * 3/4 ), localize(label) ], @@ -3446,13 +3184,6 @@ BlockMorph.prototype.userMenu = function anonymous () { } menu.addItem("help...", 'showHelp'); - /* if (!this.isCustomBlock) {menu.addItem("edit...", function () {var block = this; text = ''; function findArgs (input) { - input = input.toString(), i = 0, result = ''; while (input.charAt(i - 1) !== '\(') {i++;}; i++; while (input.charAt(i - 1) !== '\)') { - if (input.charAt(i - 1) !== String.fromCharCode(10)) {if (input.charAt(i - 1) !== String.fromCharCode(9)) {if (input.charAt(i - 1) !== String.fromCharCode(32)) { - result = result.concat('', input.charAt(i - 1));};};};}; return result;}; function findCode (input) {input = input.toString(), i = 0, result = ''; - while (input.charAt(i - 1) !== '\{') {i++;}; i++; i++; while (i < (input.length - 1)) {result = result.concat('', input.charAt(i - 1)); i++;}; - return result;}; new DialogBoxMorph(this, text => eval('Process.prototype.' + block.selector + ' = new Function\(findArgs\(text\), findCode\(text\)\);'), this).promptCode( - 'Code Editor', eval('Process.prototype.' + block.selector).toString(), this.world(), block.fullImage(), 'Editing the block code \(only for process\) will not be saved.');});}; */ if (this.isTemplate) { if (this.parent instanceof SyntaxElementMorph) { if (this.selector === 'reportGetVar') { // script var definition @@ -3641,22 +3372,22 @@ BlockMorph.prototype.userMenu = function anonymous () { if (this.selector === 'mixColors') { if (this.inputs()[0].constructor.name === 'MultiArgMorph') { if (this.inputs()[0].inputs().length === 2) { - menu.addItem('relabel...', function anonymous () { + menu.addItem('relabel...', (() => { var clr1 = this.inputs()[0].inputs()[0].color; var clr2 = this.inputs()[0].inputs()[1].color; this.setSelector('mixClrsAt'); this.inputs()[0].setColor(clr1); this.inputs()[1].setColor(clr2); this.fixLayout(); - });};};}; if (this.selector === 'mixClrsAt') { + }));};};}; if (this.selector === 'mixClrsAt') { if (this.inputs()[2].constructor.name === 'InputSlotMorph') { if (this.inputs()[2].evaluate() === 50) { - menu.addItem('relabel...', function anonymous () { + menu.addItem('relabel...', (() => { var clr1 = this.inputs()[0]; var clr2 = this.inputs()[1]; this.setSelector('mixColors'); this.inputs()[0].children[0] = clr1; this.inputs()[0].children[2] = clr2; - this.fixLayout();});};};}; if (this.selector === 'receiveGo') {menu.addItem('be inner', (( + this.fixLayout();}));};};}; if (this.selector === 'receiveGo') {menu.addItem('be inner', (( ) => {var block = this.nextBlock(); Object.setPrototypeOf(this, DefinitorBlockMorph.prototype ); this.selector = 'runScript'; this.setSpec('when $flag-1.5-0-200-0 clicked %c'); if ( block instanceof Morph) {this.inputs()[0].nestedBlock(block); this.inputs()[0].nestedBlock( @@ -4386,28 +4117,9 @@ BlockMorph.prototype.restoreInputs = function (oldInputs, offset = 0) { } else if ((old.constructor.name === 'ReporterSlotMorph' ) && (inp.constructor.name === 'ReporterSlotMorph')) { old.isPredicate = inp.isPredicate; if (inp.isPredicate - ) {oldSlot.render = function (ctx) { - var borderColor; if (this.parent) {borderColor = this.parent.color; - } else {borderColor = new Color(120, 120, 120);}; // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast).toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - if (this.nestedBlock() instanceof ReporterBlockMorph) { - if (this.nestedBlock().isPredicate) {this.drawDiamond(ctx); - } else {this.drawRounded(ctx);}; - } else {this.drawDiamond(ctx);}; - };} else {oldSlot.render = function (ctx) { - var borderColor; if (this.parent) {borderColor = this.parent.color; - } else {borderColor = new Color(120, 120, 120);}; // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast).toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - if (this.nestedBlock() instanceof ReporterBlockMorph) { - if (this.nestedBlock().isPredicate) {this.drawDiamond(ctx); - } else {this.drawRounded(ctx);}; - } else {this.drawRounded(ctx);}; - };}; oldSlot.rerender(); - oldSlot.fullChanged();}; + ) {oldSlot.render = oldSlot.renderPredicate;} else { + oldSlot.render = oldSlot.renderReporter;}; + oldSlot.rerender(); oldSlot.fullChanged();}; if (!isReplaced) {element.replaceInput(inp, oldSlot);}; } else if ((old instanceof MultiArgMorph) && (inp instanceof MultiArgMorph)) { @@ -4687,17 +4399,16 @@ BlockMorph.prototype.copyWithInputs = function (inputs) { data.length > 2 && data[0] === '[' && data[data.length - 1] === ']'; - } + }; if (dta.length === 0) { return cpy.reify(); - } - if (cpy.selector === 'reportGetVar' && ( + }; if (cpy.selector === 'reportGetVar' && ( (dta.length === 1) || (cpy.blockSpec === '\xa0' && dta.length > 1)) ) { cpy.setSpec(dta[0]); return cpy.reify(dta.slice(1)); - } + }; // restore input slots slots.forEach(slt => { @@ -4739,10 +4450,9 @@ BlockMorph.prototype.copyWithInputs = function (inputs) { ); } else { slot.addInput(cnt); - } - } - } - count += 1; + }; + }; + }; count += 1; } else if (slot instanceof MultiArgMorph && slot.inputs().length) { // fill the visible slots of the polyadic input as if they were // permanent inputs each @@ -4753,8 +4463,7 @@ BlockMorph.prototype.copyWithInputs = function (inputs) { entry.nestedBlock(inp); } else if (inp instanceof ReporterBlockMorph && (!entry.isStatic || entry instanceof RingMorph)) { - slot.replaceInput(entry, inp); - } + slot.replaceInput(entry, inp);}; } else { if (inp instanceof List && inp.length() === 0) { nop(); // ignore, i.e. leave slot as is @@ -4762,10 +4471,7 @@ BlockMorph.prototype.copyWithInputs = function (inputs) { entry instanceof TemplateSlotMorph || entry instanceof BooleanSlotMorph) { entry.setContents(inp); - } - } - count += 1; - }); + };}; count += 1;}); } else { // fill the visible slot, treat collapsed variadic slots as single // input (to be replaced by a reporter), @@ -4781,7 +4487,7 @@ BlockMorph.prototype.copyWithInputs = function (inputs) { } else if (inp instanceof ReporterBlockMorph && slot.nestedBlock) { slot.nestedBlock(inp); - } + }; } else { if (inp instanceof List && inp.length() === 0) { nop(); // ignore, i.e. leave slot as is @@ -4792,53 +4498,32 @@ BlockMorph.prototype.copyWithInputs = function (inputs) { } else if (slot instanceof TemplateSlotMorph || slot instanceof BooleanSlotMorph) { slot.setContents(inp); - } - } - count += 1; - } - }); - - // create a function to return - return cpy.reify(dta.slice(count)); + }; + }; count += 1; + }; + }); return cpy.reify(dta.slice(count)); }; -BlockMorph.prototype.copyWithNext = function (next, parameterNames) { - var expr = this.fullCopy(), - top; - if (this instanceof ReporterBlockMorph) { - return expr.reify(); - } - top = next.fullCopy().topBlock(); - if (top instanceof CommandBlockMorph) { - expr.bottomBlock().nextBlock(top); - } - return expr.reify(parameterNames); -}; +BlockMorph.prototype.copyWithNext = function ( +next, parameterNames) {var expr = this.fullCopy( +), top; if (this instanceof ReporterBlockMorph) { +return expr.reify();}; top = (next.fullCopy() +).topBlock(); if (top instanceof CommandBlockMorph +) {expr.bottomBlock().nextBlock(top);}; return ( +expr.reify(parameterNames));}; BlockMorph.prototype.reify = function (inputNames) { - var context = new Context; - context.expression = this; - context.inputs = (inputNames || []); - context.emptySlots = this.markEmptySlots(); - return context; -}; - -BlockMorph.prototype.markEmptySlots = function () { - var count = 0; - - this.allInputs().forEach(input => - delete input.bindingID - ); - this.allEmptySlots().forEach(slot => { - count += 1; - if (slot instanceof MultiArgMorph) { - slot.bindingID = Symbol.for('arguments'); - } else { - slot.bindingID = count; - } - }); - return count; -}; +var context = new Context; context.expression = this; +context.inputs = (inputNames || []); (context.emptySlots +) = this.markEmptySlots(); return context;}; + +BlockMorph.prototype.markEmptySlots = function ( +) {var count = 0; this.allInputs().forEach((input +) => (delete input.bindingID)); (this.allEmptySlots( +)).forEach(slot => {count += 1; if ((slot +) instanceof MultiArgMorph) {(slot.bindingID +) = Symbol.for('arguments');} else {(slot +).bindingID = count;};}); return count;}; // BlockMorph code mapping @@ -4849,15 +4534,10 @@ BlockMorph.prototype.markEmptySlots = function () { */ BlockMorph.prototype.mapToHeader = function () { - // open a dialog box letting the user map header code via the GUI - var key = ((this.selector.substr(0, 5) === 'reify') || (this.selector === 'reportScript')) ? - 'reify' : this.selector, - block = this.codeDefinitionHeader(), - help, - pic; - block.addShadow(new Point(3, 3)); - pic = block.doWithAlpha(1, () => block.fullImage()); - if (this.isCustomBlock) { + var key = (((this.selector.substr(0, 5) === 'reify') || (this.selector === 'reportScript' + )) ? 'reify' : this.selector), block = this.codeDefinitionHeader(), help, pic; + block.addShadow(new Point(3, 3)); pic = block.doWithAlpha(1, ( + ) => block.fullImage()); if (this.isCustomBlock) { help = 'Enter code that corresponds to the block\'s definition. ' + 'Use the formal parameter\nnames as shown and to ' + 'reference the definition body\'s generated text code.'; @@ -4865,17 +4545,15 @@ BlockMorph.prototype.mapToHeader = function () { help = 'Enter code that corresponds to the block\'s definition. ' + 'Choose your own\nformal parameter names (ignoring the ones ' + 'shown).'; - } - new DialogBoxMorph( + }; new DialogBoxMorph( this, code => { if (key === 'evaluateCustomBlock') { this.definition.codeHeader = code; } else { StageMorph.prototype.codeHeaders[key] = code; - } - }, - this + }; + }, this ).promptCode( 'Header mapping', key === 'evaluateCustomBlock' ? this.definition.codeHeader || '' @@ -4887,29 +4565,22 @@ BlockMorph.prototype.mapToHeader = function () { }; BlockMorph.prototype.mapToCode = function () { - // open a dialog box letting the user map code via the GUI - var key = ((this.selector.substr(0, 5) === 'reify') || (this.selector === 'reportScript')) ? - 'reify' : this.selector, - block = this.codeMappingHeader(), - pic; - block.addShadow(new Point(3, 3)); - pic = block.doWithAlpha(1, () => block.fullImage()); - new DialogBoxMorph( + var key = (((this.selector.substr(0, 5) === 'reify') || (this.selector === 'reportScript' + )) ? 'reify' : this.selector), block = this.codeMappingHeader(), pic; block.addShadow( + new Point(3, 3)); pic = block.doWithAlpha(1, () => block.fullImage()); new DialogBoxMorph( this, code => { if (key === 'evaluateCustomBlock') { this.definition.codeMapping = code; } else { StageMorph.prototype.codeMappings[key] = code; - } - }, - this + }; + }, this ).promptCode( 'Code mapping', key === 'evaluateCustomBlock' ? this.definition.codeMapping || '' : StageMorph.prototype.codeMappings[key] || '', - this.world(), - pic, + this.world(), pic, 'Enter code that corresponds to the block\'s operation ' + '(usually a single\nfunction invocation). Use <#n> to ' + 'reference actual arguments as shown.' @@ -4925,8 +4596,8 @@ BlockMorph.prototype.mapHeader = function (aString, key) { this.definition.codeHeader = aString; } else { StageMorph.prototype.codeHeaders[sel] = aString; - } - } + }; + }; }; BlockMorph.prototype.mapCode = function (aString, key) { @@ -4938,22 +4609,18 @@ BlockMorph.prototype.mapCode = function (aString, key) { this.definition.codeMapping = aString; } else { StageMorph.prototype.codeMappings[sel] = aString; - } - } + }; + }; }; BlockMorph.prototype.mappedCode = function (definitions) { - var key = ((this.selector.substr(0, 5) === 'reify') || (this.selector === 'reportScript')) ? - 'reify' : this.selector, - code, - codeLines, - count = 1, - header, - headers, - headerLines, - body, - bodyLines, - defKey = this.isCustomBlock ? this.definition.spec : key, + var key = (((this.selector.substr(0, 5) === 'reify') || ((this + ).selector === 'reportScript')) ? 'reify' : this.selector), + code, codeLines, count = 1, + header, headers, headerLines, + body, bodyLines, defKey = ( + this.isCustomBlock ? (this + ).definition.spec : key), defs = definitions || {}, parts = []; code = key === 'reportGetVar' ? this.blockSpec @@ -4969,8 +4636,7 @@ BlockMorph.prototype.mappedCode = function (definitions) { body = ''; if (this.definition.body) { body = this.definition.body.expression.mappedCode(defs); - } - bodyLines = body.split('\n'); + }; bodyLines = body.split('\n'); headerLines = header.split('\n'); headerLines.forEach((headerLine, idx) => { var prefix = '', @@ -4978,25 +4644,19 @@ BlockMorph.prototype.mappedCode = function (definitions) { if (headerLine.trimLeft().indexOf(''), bodyLines.join('\n' + prefix) - ); - headerLines[idx] = headerLines[idx].replace( + ); headerLines[idx] = headerLines[idx].replace( new RegExp('', 'g'), bodyLines.join('\n') ); - }); - header = headerLines.join('\n'); - } - defs[defKey] = header; + }); header = headerLines.join('\n'); + }; defs[defKey] = header; } else { defs[defKey] = StageMorph.prototype.codeHeaders[defKey]; - } - } - - codeLines = code.split('\n'); + }; + }; codeLines = code.split('\n'); this.inputs().forEach(input => parts.push(input.mappedCode(defs).toString()) ); @@ -5010,21 +4670,16 @@ BlockMorph.prototype.mappedCode = function (definitions) { if (codeLine.trimLeft().indexOf(placeHolder) === 0) { indent = codeLine.indexOf(placeHolder); prefix = codeLine.slice(0, indent); - } - codeLines[idx] = codeLine.replace( + }; codeLines[idx] = codeLine.replace( new RegExp(placeHolder), partLines.join('\n' + prefix) - ); - codeLines[idx] = codeLines[idx].replace(rx, partLines.join('\n')); + ); codeLines[idx] = codeLines[idx].replace(rx, partLines.join('\n')); }); count += 1; - }); - code = codeLines.join('\n'); + }); code = codeLines.join('\n'); if (this.nextBlock && this.nextBlock()) { // Command code += ('\n' + this.nextBlock().mappedCode(defs)); - } - if (!definitions) { // top-level, add headers - headers = []; + }; if (!definitions) {headers = []; Object.keys(defs).forEach(each => { if (defs[each]) { headers.push(defs[each]); @@ -5449,9 +5104,12 @@ BlockMorph.prototype.clearAlpha = function () { // BlockMorph drawing BlockMorph.prototype.render = function (ctx) { - this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); + this.cachedClr = (this.color).toString(); + this.cachedClrBright = (((this.color).lighter( + this.contrast)).withAlpha((1 + (MorphicPreferences + ).isFlat) / 2)).toString(); this.cachedClrDark = ( + ((this.color).darker(this.contrast)).withAlpha(( + 1 + (MorphicPreferences).isFlat) / 2)).toString(); if (MorphicPreferences.isFlat) { // draw the outline @@ -5469,7 +5127,17 @@ BlockMorph.prototype.render = function (ctx) { ctx.fill(); } else { // draw the flat shape - ctx.fillStyle = this.cachedClr; + var gradient = (ctx + ).createLinearGradient( + 0, 0, 0, this.height()); + + // Add three color stops + gradient.addColorStop(0, + (this.color).toString()); + gradient.addColorStop(1, + ((this.color).darker( + )).toString()); (ctx + ).fillStyle = gradient; ctx.beginPath(); this.outlinePath(ctx, 0); ctx.closePath(); @@ -5496,7 +5164,7 @@ BlockMorph.prototype.drawMethodIcon = function (ctx) { x = this.rounding; }; if (this instanceof CommandBlockMorph) { y += this.corner; - }; ctx.fillStyle = isNormal ? this.cachedClrBright : this.cachedClrDark; + }; ctx.fillStyle = isNormal ? this.bright() : this.dark(); // pin ctx.beginPath(); ctx.arc(x + r, y + r, r, radians(-210), radians(30), false); @@ -5506,26 +5174,11 @@ BlockMorph.prototype.drawMethodIcon = function (ctx) { // hole ctx.fillStyle = this.cachedClr; ctx.beginPath(); - ctx.arc(x + r, y + r, r * 0.4, radians(0), radians(360), false); + ctx.arc(x + r, y + r, r * 2/5, 0, Math.PI * 2, false); ctx.closePath(); ctx.fill(); }; -BlockMorph.prototype.cSlots = function () { - var result = []; - this.parts().forEach(part => { - if (part instanceof CSlotMorph) { - result.push(part); - } else if (part instanceof MultiArgMorph) { - part.parts().forEach(slot => { - if (slot instanceof CSlotMorph) { - result.push(slot); - }; - }); - }; - }); return result; -}; - BlockMorph.prototype.hasLocationPin = function () {return (this.isCustomBlock && !this.isGlobal) || this.isLocalVarTemplate;}; // BlockMorph highlighting @@ -6090,48 +5743,33 @@ CommandBlockMorph.prototype.init = function () { // CommandBlockMorph enumerating: CommandBlockMorph.prototype.blockSequence = function () { - var sequence = [this], - nb = this.nextBlock(); - while (nb) { - sequence.push(nb); - nb = nb.nextBlock(); - } - return sequence; -}; +var sequence = [this], nb = this.nextBlock(); while (nb) { +sequence.push(nb); nb = nb.nextBlock();}; return sequence;}; -CommandBlockMorph.prototype.bottomBlock = function () { - // topBlock() also exists - inherited from SyntaxElementMorph - if (this.nextBlock()) { - return this.nextBlock().bottomBlock(); - } - return this; -}; +CommandBlockMorph.prototype.bottomBlock = function () {if ((this +).nextBlock()) {return this.nextBlock().bottomBlock();}; return this;}; CommandBlockMorph.prototype.nextBlock = function (block) { - // set / get the block attached to my bottom if (block) { var nb = this.nextBlock(), affected = this.parentThatIsA(CommandSlotMorph, ReporterSlotMorph); this.add(block); if (nb) { block.bottomBlock().nextBlock(nb); - } - block.setPosition( + }; block.setPosition( new Point( this.left(), this.bottom() - (this.corner) ) - ); - if (affected) { + ); if (affected) { affected.fixLayout(); - } + }; } else { return detect( this.children, child => child instanceof CommandBlockMorph && !child.isPrototype ); - } -}; +};}; // CommandBlockMorph attach targets: @@ -6326,7 +5964,7 @@ CommandBlockMorph.prototype.snap = function (hand) { next = this.nextBlock(); if (next) { scripts.add(next); - next.moveBy(this.extent().floorDivideBy(2)); + next.moveBy(this.extent().divideBy(2)); affected = this.parentThatIsA( CommandSlotMorph, ReporterSlotMorph @@ -6588,355 +6226,113 @@ CommandBlockMorph.prototype.outlinePath = function(ctx, inset) { ); }; -CommandBlockMorph.prototype.drawEdges = function (ctx) { - this.drawTopDentEdge(ctx, 0, 0); - this.drawBottomDentEdge(ctx, 0, this.height() - this.corner); - this.drawLeftEdge(ctx); - this.drawRightEdge(ctx); - this.drawTopLeftEdge(ctx); - this.drawBottomRightEdge(ctx); -}; - -CommandBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { - var shift = this.edge * 0.5, - indent = x + this.corner * 2 + this.inset, - upperGradient, - lowerGradient, - leftGradient, - lgx; - +CommandBlockMorph.prototype.drawEdges = function ( + ctx) {var shift = this.edge * 1/2, x = 0, y = 0, + indent = x + this.corner * 2 + this.inset, + top = this.top(), lgx = (x + this.corner + ) + this.inset, cslots = this.cSlots(); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - upperGradient = ctx.createLinearGradient( - 0, - y, - 0, - y + this.edge - ); - upperGradient.addColorStop(0, this.cachedClrBright); - upperGradient.addColorStop(1, this.cachedClr); - - ctx.strokeStyle = upperGradient; - ctx.beginPath(); - ctx.moveTo(this.corner, y + shift); - ctx.lineTo(x + this.corner + this.inset, - y + shift); ctx.stroke(); + ctx.lineCap = 'butt'; - ctx.strokeStyle = upperGradient; - ctx.beginPath(); - ctx.moveTo( + ctx.strokeStyle = this.cachedClrBright; ctx.beginPath(); + ctx.moveTo(shift, this.height() - this.corner * 2 - shift + ); ctx.lineTo(shift, this.corner); + ctx.arc( + this.corner, + this.corner, + this.corner - shift, + radians(-180), + radians(-90), + false + ); ctx.lineTo(this.corner + this.inset, shift); + ctx.lineTo(indent, y + this.corner + shift); ctx.lineTo( + indent + this.dent, y + this.corner + shift); ctx.moveTo( x + this.corner * 3 + this.inset + this.dent + shift, y + shift - ); - ctx.lineTo(this.width() - this.corner, y + shift); - ctx.stroke(); + ); ctx.lineTo(this.width() - this.corner, + shift); ctx.stroke(); x = this.width(); - lgx = x + this.corner + this.inset; - leftGradient = ctx.createLinearGradient( - lgx - this.edge, - y + this.edge, - lgx, - y - ); - leftGradient.addColorStop(0, this.cachedClr); - leftGradient.addColorStop(1, this.cachedClrBright); + ctx.strokeStyle = this.cachedClrDark; + ctx.beginPath(); ctx.moveTo((x + ) - shift, this.corner + shift); + if (cslots.length > 0) { + ctx.beginPath(); + ctx.moveTo(x - shift, (this.corner + ) + shift); cslots.forEach( + slot => {y = slot.top( + ) - top; ctx.lineTo(( + x - shift), y); (ctx + ).stroke(); ctx.beginPath( + ); ctx.moveTo(x - shift, + y + slot.height());}); + }; y = this.height() - this.corner; + ctx.arc(this.width() - this.corner, + this.height() - this.corner * 2, + this.corner - shift, 0, Math.PI / 2 + ); if (!(this.isStop())) {ctx.lineTo( + this.corner * 3 + this.inset + this.dent, + y - shift); ctx.lineTo(indent + this.dent, + y + this.corner - shift); ctx.lineTo( + indent + shift, y + this.corner - shift); + ctx.stroke(); ctx.beginPath(); ctx.moveTo( + this.corner + this.inset - shift, y - shift + );}; ctx.lineTo(this.corner, y - shift); ctx.stroke();}; - ctx.strokeStyle = leftGradient; - ctx.beginPath(); - ctx.moveTo(x + this.corner + this.inset, y + shift); - ctx.lineTo(indent, y + this.corner + shift); - ctx.stroke(); + CommandBlockMorph.prototype.userCut = function() { - lowerGradient = ctx.createLinearGradient( - 0, - y + this.corner, - 0, - y + this.corner + this.edge - ); - lowerGradient.addColorStop(0, this.cachedClrBright); - lowerGradient.addColorStop(1, this.cachedClr); + window.blockCopy = this.fullCopy() + var nb = window.blockCopy.nextBlock() + if (nb) {nb.destroy(); + }; var target = this.selectForEdit(); + if (target !== this) { + return this.userDestroy.call(target); + }; if (this.nextBlock()) { + this.userDestroyJustThis(); + return; + }; var scripts = this.parentThatIsA(ScriptsMorph + ), ide = this.parentThatIsA(IDE_Morph), + parent = this.parentThatIsA(SyntaxElementMorph), + cslot = this.parentThatIsA(CSlotMorph); - ctx.strokeStyle = lowerGradient; - ctx.beginPath(); - ctx.moveTo(indent, y + this.corner + shift); - ctx.lineTo(indent + this.dent, - y + this.corner + shift); ctx.stroke(); -}; + // for undrop / redrop + if (scripts) { + scripts.clearDropInfo(); + scripts.lastDroppedBlock = this; + scripts.recordDrop(this.situation()); + scripts.dropRecord.action = 'delete'; + }; this.prepareToBeGrabbed(); -CommandBlockMorph.prototype.drawBottomDentEdge = function (ctx, x, y) { - var shift = this.edge * 0.5, - indent = x + this.corner * 2 + this.inset, - upperGradient, - lowerGradient, - rightGradient; + if (ide) { + // also stop all active processes hatted by this block + ide.removeBlock(this); + } else { + this.destroy(); + }; if (cslot) { + cslot.fixLayout(); + }; if (parent) { + parent.reactToGrabOf(this); // fix highlight + }; + }; - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; +// HatBlockMorph /////////////////////////////////////////////////////// - upperGradient = ctx.createLinearGradient( - 0, - y - this.edge, - 0, - y - ); - upperGradient.addColorStop(0, this.cachedClr); - upperGradient.addColorStop(1, this.cachedClrDark); +/* + I am a script's top most block. I can attach command blocks at my + bottom, but not on top. - ctx.strokeStyle = upperGradient; - ctx.beginPath(); - ctx.moveTo(this.corner, y - shift); - if (this.isStop()) { - ctx.lineTo(this.width() - this.corner, y - shift); - } else { - ctx.lineTo(x + this.corner + this.inset - shift, y - shift); - } - ctx.stroke(); +*/ - if (this.isStop()) { // draw straight bottom edge - return null; - } +// HatBlockMorph inherits from CommandBlockMorph: - lowerGradient = ctx.createLinearGradient( - 0, - y + this.corner - this.edge, - 0, - y + this.corner - ); - lowerGradient.addColorStop(0, this.cachedClr); - lowerGradient.addColorStop(1, this.cachedClrDark); +HatBlockMorph.prototype = new CommandBlockMorph; +HatBlockMorph.prototype.constructor = HatBlockMorph; +HatBlockMorph.uber = CommandBlockMorph.prototype; - ctx.strokeStyle = lowerGradient; - ctx.beginPath(); - ctx.moveTo(indent + shift, y + this.corner - shift); - ctx.lineTo(indent + this.dent, y + this.corner - shift); - ctx.stroke(); +// HatBlockMorph instance creation: - rightGradient = ctx.createLinearGradient( - x + indent + this.dent - this.edge, - y + this.corner - this.edge, - x + indent + this.dent, - y + this.corner - ); - rightGradient.addColorStop(0, this.cachedClr); - rightGradient.addColorStop(1, this.cachedClrDark); - - ctx.strokeStyle = rightGradient; - ctx.beginPath(); - ctx.moveTo(x + indent + this.dent, y + this.corner - shift); - ctx.lineTo( - x + this.corner * 3 + this.inset + this.dent, - y - shift - ); - ctx.stroke(); - - ctx.strokeStyle = upperGradient; - ctx.beginPath(); - ctx.moveTo( - x + this.corner * 3 + this.inset + this.dent, - y - shift - ); - ctx.lineTo(this.width() - this.corner, y - shift); - ctx.stroke(); -}; - -CommandBlockMorph.prototype.drawFlatBottomDentEdge = function (ctx) { - if (!this.isStop()) { - ctx.fillStyle = this.color.darker(this.contrast / 2).toString(); - ctx.beginPath(); - this.drawDent(ctx, 0, this.height() - this.corner); - ctx.closePath(); - ctx.fill(); - } -}; - -CommandBlockMorph.prototype.drawLeftEdge = function (ctx) { - var shift = this.edge * 0.5, - gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); - - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, this.corner); - ctx.lineTo(shift, this.height() - this.corner * 2 - shift); - ctx.stroke(); -}; - -CommandBlockMorph.prototype.drawRightEdge = function (ctx) { - var shift = this.edge * 0.5, - cslots = this.cSlots(), - top = this.top(), - x = this.width(), - y, - gradient; - - gradient = ctx.createLinearGradient(x - this.edge, 0, x, 0); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - ctx.strokeStyle = gradient; - - if (cslots.length) { - ctx.beginPath(); - ctx.moveTo(x - shift, this.corner + shift); - cslots.forEach(slot => { - y = slot.top() - top; - ctx.lineTo(x - shift, y); - ctx.stroke(); - ctx.beginPath(); - ctx.moveTo(x - shift, y + slot.height()); - }); - } else { - ctx.beginPath(); - ctx.moveTo(x - shift, this.corner + shift); - } - ctx.lineTo(x - shift, this.height() - this.corner * 2); - ctx.stroke(); -}; - -CommandBlockMorph.prototype.drawTopLeftEdge = function (ctx) { - var shift = this.edge * 0.5, - gradient; - - gradient = ctx.createRadialGradient( - this.corner, - this.corner, - this.corner, - this.corner, - this.corner, - this.corner - this.edge - ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); - - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - ctx.strokeStyle = gradient; - - ctx.beginPath(); - ctx.arc( - this.corner, - this.corner, - this.corner - shift, - radians(-180), - radians(-90), - false - ); - ctx.stroke(); -}; - -CommandBlockMorph.prototype.drawBottomRightEdge = function (ctx) { - var shift = this.edge * 0.5, - x = this.width() - this.corner, - y = this.height() - this.corner * 2, - gradient; - - gradient = ctx.createRadialGradient( - x, - y, - this.corner, - x, - y, - this.corner - this.edge - ); - gradient.addColorStop(0, this.cachedClrDark); - gradient.addColorStop(1, this.cachedClr); - - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - ctx.strokeStyle = gradient; - - ctx.beginPath(); - ctx.arc( - x, - y, - this.corner - shift, - radians(90), - radians(0), - true - ); - ctx.stroke(); -}; - - CommandBlockMorph.prototype.userCut = function() { - - window.blockCopy = this.fullCopy() - var nb = window.blockCopy.nextBlock() - if (nb) { - nb.destroy(); - } - - var target = this.selectForEdit(); // enable copy-on-edit - if (target !== this) { - return this.userDestroy.call(target); - } - if (this.nextBlock()) { - this.userDestroyJustThis(); - return; - } - - var scripts = this.parentThatIsA(ScriptsMorph), - ide = this.parentThatIsA(IDE_Morph), - parent = this.parentThatIsA(SyntaxElementMorph), - cslot = this.parentThatIsA(CSlotMorph); - - // for undrop / redrop - if (scripts) { - scripts.clearDropInfo(); - scripts.lastDroppedBlock = this; - scripts.recordDrop(this.situation()); - scripts.dropRecord.action = 'delete'; - } - - this.prepareToBeGrabbed(); // fix outer ring reporter slot - - if (ide) { - // also stop all active processes hatted by this block - ide.removeBlock(this); - } else { - this.destroy(); - } - if (cslot) { - cslot.fixLayout(); - } - if (parent) { - parent.reactToGrabOf(this); // fix highlight - } - }; - -// HatBlockMorph /////////////////////////////////////////////////////// - -/* - I am a script's top most block. I can attach command blocks at my - bottom, but not on top. - -*/ - -// HatBlockMorph inherits from CommandBlockMorph: - -HatBlockMorph.prototype = new CommandBlockMorph; -HatBlockMorph.prototype.constructor = HatBlockMorph; -HatBlockMorph.uber = CommandBlockMorph.prototype; - -// HatBlockMorph instance creation: - -function HatBlockMorph (isPrototypeLike) {this.init(isPrototypeLike);}; +function HatBlockMorph (isPrototypeLike) {this.init(isPrototypeLike);}; HatBlockMorph.prototype.init = function (isPrototypeLike) {HatBlockMorph.uber.init.call(this); if (asABool(isPrototypeLike)) {this.category = 'custom'; this.setSpec(localize('define').concat( @@ -7009,6 +6405,11 @@ this, ctx, inset);} else { false ); + // C-Slots + this.cSlots().forEach(slot => { + slot.outlinePath(ctx, inset, slot.position().subtract(pos)); + }); + // bottom right: ctx.arc( this.width() - this.corner, @@ -7038,100 +6439,55 @@ this, ctx, inset);} else { ); };}; -HatBlockMorph.prototype.drawLeftEdge = function (ctx) { -if (this.isPrototypeLike) {PrototypeHatBlockMorph.prototype.drawLeftEdge.call( -this, ctx);} else { - var shift = this.edge * 0.5, - gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); - - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, this.hatHeight + shift); - ctx.lineTo(shift, this.height() - this.corner * 2 - shift); - ctx.stroke(); -};}; - -HatBlockMorph.prototype.drawTopDentEdge = nop; - -HatBlockMorph.prototype.drawTopLeftEdge = function (ctx) { -if (this.isPrototypeLike) {PrototypeHatBlockMorph.prototype.drawTopLeftEdge.call( -this, ctx, true);} else { - var shift = this.edge * 0.5, - s = this.hatWidth, - h = this.hatHeight, - r = ((4 * h * h) + (s * s)) / (8 * h), - a = degrees(4 * Math.atan(2 * h / s)), - sa = a / 2, - sp = Math.min(s * 1.7, this.width() - this.corner), - gradient; - - gradient = ctx.createRadialGradient( - s / 2, - r, - r - this.edge, - s / 2, - r, - r - ); - gradient.addColorStop(1, this.cachedClrBright); - gradient.addColorStop(0, this.cachedClr); - - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - Math.round(s / 2), - r, - r - shift, - radians(-sa - 90), - radians(-90), - false - ); - ctx.moveTo(s / 2, shift); - ctx.bezierCurveTo( - s, - shift, - s, - h + shift, - sp, - h + shift - ); - ctx.lineTo(this.width() - this.corner, h + shift); - ctx.stroke(); -};}; - -HatBlockMorph.prototype.drawRightEdge = function (ctx) { -if (this.isPrototypeLike) {PrototypeHatBlockMorph.prototype.drawRightEdge.call( -this, ctx);} else { - var shift = this.edge * 0.5, - x = this.width(), - y, - gradient; - - gradient = ctx.createLinearGradient(x - this.edge, 0, x, 0); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); +HatBlockMorph.prototype.drawEdges = function (ctx) { + if (this.isPrototypeLike) { + PrototypeHatBlockMorph.prototype.drawEdges.call(this, ctx); + } else {var shift = this.edge / 2, x = 0, y = 0, + indent = x + this.corner * 2 + this.inset, + top = this.top(), lgx = (x + this.corner + ) + this.inset, cslots = this.cSlots(), + r = ((4 * (this.hatHeight ** 2)) + (this.hatWidth ** 2)) / (8 * this.hatHeight); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - ctx.strokeStyle = gradient; - - ctx.beginPath(); - ctx.moveTo(x - shift, this.corner + this.hatHeight + shift); - ctx.lineTo(x - shift, this.height() - this.corner * 2); - ctx.stroke(); -};}; + ctx.lineCap = 'butt'; + + ctx.strokeStyle = this.cachedClrBright; ctx.beginPath(); + ctx.moveTo(shift, this.height() - this.corner * 2 - shift + ); ctx.lineTo(shift, this.hatHeight + shift); + ctx.arc(this.hatWidth / 2, shift + r, r, + radians((degrees(4 * Math.atan(2 * ( + this.hatHeight / this.hatWidth)) + ) / -2) - 90), Math.PI / -2 + ); ctx.bezierCurveTo((this + ).hatWidth, shift, (this + ).hatWidth, this.hatHeight + shift, + Math.min(this.hatWidth * 1.7, + this.width() - this.corner), + this.hatHeight + shift + ); ctx.lineTo(this.width() - this.corner, + this.hatHeight + shift); ctx.stroke(); x = this.width(); + + ctx.strokeStyle = this.cachedClrDark; ctx.beginPath(); + ctx.moveTo(x - shift, (this.corner + this.hatHeight + ) + shift); if (cslots.length > 0 + ) {cslots.forEach(slot => { + y = slot.top() - top; + ctx.lineTo(x - shift, + y); ctx.stroke(); + ctx.beginPath(); + ctx.moveTo(x - shift, y + slot.height( + ));});}; y = this.height() - this.corner; + ctx.arc(this.width() - this.corner, + this.height() - this.corner * 2, + this.corner - shift, 0, Math.PI / 2 + ); if (!(this.isStop())) {ctx.lineTo( + this.corner * 3 + this.inset + this.dent, + y - shift ); ctx.lineTo(indent + this.dent, + y + this.corner - shift); ctx.lineTo(indent + shift, + y + this.corner - shift); ctx.stroke(); ctx.beginPath( + ); ctx.moveTo(this.corner + this.inset - shift, y - shift +);};}; ctx.lineTo(this.corner, y - shift); ctx.stroke();}; // DefinitorBlockMorph /////////////////////////////////////////////////////// @@ -7147,100 +6503,15 @@ DefinitorBlockMorph.prototype = new CommandBlockMorph; DefinitorBlockMorph.prototype.constructor = DefinitorBlockMorph; DefinitorBlockMorph.uber = CommandBlockMorph.prototype; -// DefinitorBlockMorph instance creation: - -function DefinitorBlockMorph() {this.init();}; - -DefinitorBlockMorph.prototype.init = function () {DefinitorBlockMorph.uber.init.call(this); this.fixLayout(); this.rerender();}; - -DefinitorBlockMorph.prototype.outlinePath = function(ctx, inset) { - var indent = this.corner * 2 + this.inset, - bottom = this.height() - this.corner, - bottomCorner = this.height() - this.corner * 2, - radius = Math.max(this.corner - inset, 0), - pos = this.position(); - - // top left: - ctx.arc( - this.corner, - this.corner, - radius, - radians(-180), - radians(-90), - false - ); - - // top right: - ctx.arc( - this.width() - this.corner, - this.corner, - radius, - radians(-90), - radians(-0), - false - ); - - // C-Slots - this.cSlots().forEach(slot => { - slot.outlinePath(ctx, inset, slot.position().subtract(pos)); - }); - - // bottom right: - ctx.arc( - this.width() - this.corner, - bottomCorner, - radius, - radians(0), - radians(90), - false - ); - - if (!this.isStop()) { - ctx.lineTo(this.width() - this.corner, bottom - inset); - ctx.lineTo(this.corner * 3 + this.inset + this.dent, bottom - inset); - ctx.lineTo(indent + this.dent, bottom + this.corner - inset); - ctx.lineTo(indent, bottom + this.corner - inset); - ctx.lineTo(this.corner + this.inset, bottom - inset); - }; - - // bottom left: - ctx.arc( - this.corner, - bottomCorner, - radius, - radians(90), - radians(180), - false - ); -}; - -DefinitorBlockMorph.prototype.drawTopDentEdge = function (ctx, x, y) { - var shift = this.edge * 0.5, - indent = x + this.corner * 2 + this.inset, - upperGradient, - lowerGradient, - leftGradient, - lgx; +// DefinitorBlockMorph instance creation: - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; +function DefinitorBlockMorph() {this.init();}; - upperGradient = ctx.createLinearGradient( - 0, - y, - 0, - y + this.edge - ); - upperGradient.addColorStop(0, this.cachedClrBright); - upperGradient.addColorStop(1, this.cachedClr); +DefinitorBlockMorph.prototype.init = function () {(DefinitorBlockMorph +).uber.init.call(this); this.fixLayout(); this.rerender();}; - ctx.strokeStyle = upperGradient; - ctx.beginPath(); - ctx.moveTo(this.corner, y + shift); - ctx.lineTo(this.width() - this.corner, y + shift); - ctx.stroke(); -}; +DefinitorBlockMorph.prototype.outlinePath = HatBlockMorph.prototype.outlinePath; +DefinitorBlockMorph.prototype.drawEdges = HatBlockMorph.prototype.drawEdges; // ReporterBlockMorph ////////////////////////////////////////////////// @@ -7315,9 +6586,8 @@ ReporterBlockMorph.prototype.prepareToBeGrabbed = function (handMorph) { || (this.parent instanceof ReporterSlotMorph)) { this.parent.revertToDefaultInput(this); this.setPosition(oldPos); - } - ReporterBlockMorph.uber.prepareToBeGrabbed.call(this, handMorph); - handMorph.alpha = this.alpha < 1 ? 1 : 0.85; + }; ReporterBlockMorph.uber.prepareToBeGrabbed.call(this, handMorph); + handMorph.alpha = this.alpha < 1 ? 1 : 17/20; this.cachedSlotSpec = null; }; @@ -7329,7 +6599,7 @@ ReporterBlockMorph.prototype.blockSequence = function anonymous () {return this; ReporterBlockMorph.prototype.isUnevaluated = function () {var spec = this.getSlotSpec(); return contains(['%anyUE', '%numericUE', '%textingUE', '%linesUE', '%codeUE', '%boolUE', '%bUE'], spec);}; -ReporterBlockMorph.prototype.isLocked = function anonymous () {return this.isStatic || (this.getSlotSpec() === '%t');}; +ReporterBlockMorph.prototype.isLocked = function () {return this.isStatic || (this.getSlotSpec() === '%t');}; ReporterBlockMorph.prototype.getSlotSpec = function () { // answer the spec of the slot I'm in, if any @@ -7349,8 +6619,7 @@ ReporterBlockMorph.prototype.getSlotSpec = function () { ); } */ - } - return this.cachedSlotSpec; + }; return this.cachedSlotSpec; }; ReporterBlockMorph.prototype.determineSlotSpec = function () { @@ -7359,21 +6628,18 @@ ReporterBlockMorph.prototype.determineSlotSpec = function () { if (this.parent instanceof BlockMorph) { parts = this.parent.parts().filter(part => !(part instanceof BlockHighlightMorph) - ); - idx = parts.indexOf(this); + ); idx = parts.indexOf(this); if (idx !== -1) { if (this.parent.blockSpec) { return this.parseSpec(this.parent.blockSpec)[idx]; - } - } - } + }; + }; + }; if (this.parent instanceof MultiArgMorph) { return this.parent.slotSpec; - } - if (this.parent instanceof TemplateSlotMorph) { + }; if (this.parent instanceof TemplateSlotMorph) { return this.parent.getSpec(); - } - return ''; + }; return ''; }; // ReporterBlockMorph events @@ -7391,15 +6657,14 @@ ReporterBlockMorph.prototype.mouseClickLeft = function (pos) { label = "Block variable name"; } else { label = "Script variable name"; - } - new DialogBoxMorph( + }; new DialogBoxMorph( this, this.userSetSpec, this ).prompt( label, this.blockSpec, - this.world() + world ); } else { ReporterBlockMorph.uber.mouseClickLeft.call(this, pos); @@ -7511,8 +6776,9 @@ ReporterBlockMorph.prototype.outlinePathDiamond = function (ctx, inset) { ctx.lineTo(r, inset); ctx.lineTo(right - inset, inset); + // C-Slots if (cslots.length) { - this.cSlots().forEach(slot => { + cslots.forEach(slot => { slot.outlinePath(ctx, inset, slot.position().subtract(pos)); }); } else { @@ -7537,8 +6803,9 @@ ReporterBlockMorph.prototype.outlinePathArrow = function (ctx, inset) { ctx.lineTo(0, inset); ctx.lineTo(right - inset, inset); + // C-Slots if (cslots.length) { - this.cSlots().forEach(slot => { + cslots.forEach(slot => { slot.outlinePath(ctx, inset, slot.position().subtract(pos)); }); } else { @@ -7556,183 +6823,54 @@ ReporterBlockMorph.prototype.drawEdges = function (ctx) { this.drawEdgesArrow(ctx); } else { this.drawEdgesOval(ctx); - }; -}; + };}; -ReporterBlockMorph.prototype.drawEdgesOval = function (ctx) { - // add 3D-Effect - var h = this.height(), - r = Math.max(Math.min(this.rounding, (h / 2)), this.edge), - w = this.width(), - shift = this.edge / 2, - y, - top = this.top(), - cslots = this.cSlots(), - gradient; +ReporterBlockMorph.prototype.drawEdgesOval = function ( + ctx) {var h = this.height(), + r = Math.max(Math.min( + this.rounding, (h / 2 + )), this.edge), w = ( + this).width(), shift = ( + this.edge / 2), y, top = ( + this.top()), cslots = ( + this.cSlots()); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - // half-tone edges - // bottem left corner - gradient = ctx.createRadialGradient( - r, - h - r, - r - this.edge, - r, - h - r, - r + this.edge - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - r, - h - r, - r - shift, - radians(90), - radians(180), - false - ); - ctx.stroke(); - - // top right corner - gradient = ctx.createRadialGradient( - w - r, - r, - r - this.edge, - w - r, - r, - r + this.edge - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - w - r, - r, - r - shift, - radians(-90), - radians(0), - false - ); - ctx.stroke(); - - // normal gradient edges - - // top edge: straight line - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r - shift, shift); - ctx.lineTo(w - r + shift, shift); - ctx.stroke(); - - // top edge: left corner - gradient = ctx.createRadialGradient( - r, - r, - r - this.edge, - r, - r, - r - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - r, - r, - r - shift, - radians(180), - radians(270), - false - ); - ctx.stroke(); + ctx.lineCap = 'butt'; - // bottom edge: right corner - gradient = ctx.createRadialGradient( - w - r, - h - r, - r - this.edge, - w - r, - h - r, - r - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - ctx.strokeStyle = gradient; + ctx.strokeStyle = this.cachedClrBright; ctx.beginPath(); - ctx.arc( - w - r, + ctx.arc(r, h - r, r - shift, - radians(0), - radians(90), + Math.PI / 2, + Math.PI, false - ); - ctx.stroke(); - - // bottom edge: straight line - gradient = ctx.createLinearGradient( - 0, - h - this.edge, - 0, - h - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r - shift, h - shift); - ctx.lineTo(w - r + shift, h - shift); - ctx.stroke(); - - // left edge: straight vertical line - gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, r); - ctx.lineTo(shift, h - r); - ctx.stroke(); - - // right edge: straight vertical line - gradient = ctx.createLinearGradient(w - this.edge, 0, w, 0); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - ctx.strokeStyle = gradient; + ); ctx.arc(r, + r, r - shift, + Math.PI, + Math.PI / -2, + false); (ctx + ).lineTo(w - r, + shift); ctx.stroke(); - if (cslots.length) { - ctx.beginPath(); - ctx.moveTo(w - shift, r + shift); + ctx.strokeStyle = this.cachedClrDark; + ctx.beginPath(); ctx.arc(w - r, r, + r - shift, Math.PI / -2, 0 + ); if (cslots.length > 0) { cslots.forEach(slot => { y = slot.top() - top; - ctx.lineTo(w - shift, y); - ctx.stroke(); + ctx.lineTo(w - shift, + y); ctx.stroke(); ctx.beginPath(); - ctx.moveTo(w - shift, y + slot.height()); - }); - } else { - ctx.beginPath(); - ctx.moveTo(w - shift, r + shift); - } - - ctx.lineTo(w - shift, h - r); - ctx.stroke(); -}; + ctx.moveTo(w - shift, + y + slot.height()); + });}; ctx.lineTo(w - shift, + h - r); ctx.arc(w - r, h - r, + r - shift, 0, Math.PI / 2, + false); ctx.lineTo(r, h - ( + shift)); ctx.stroke();}; ReporterBlockMorph.prototype.drawEdgesDiamond = function (ctx) { // add 3D-Effect @@ -7741,10 +6879,9 @@ ReporterBlockMorph.prototype.drawEdgesDiamond = function (ctx) { h2 = Math.floor(h / 2), r = this.rounding, shift = this.edge / 2, - cslots = this.cSlots(), - top = this.top(), - y, - gradient; + cslots = this.cSlots( + ), top = this.top(), + y, gradient; ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -7888,10 +7025,9 @@ ReporterBlockMorph.prototype.drawEdgesArrow = function (ctx) { h2 = Math.floor(h / 2), r = this.rounding, shift = this.edge / 2, - cslots = this.cSlots(), - top = this.top(), - y, - gradient; + cslots = this.cSlots( + ), top = this.top(), + y, gradient; ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; @@ -8028,165 +7164,80 @@ ReporterBlockMorph.prototype.drawEdgesArrow = function (ctx) { ctx.stroke(); }; - ReporterBlockMorph.prototype.userCut = function() { +ReporterBlockMorph.prototype.userCut = function() { - window.blockCopy = this.fullCopy() + window.blockCopy = this.fullCopy() - // make sure to restore default slot of parent block - var target = this.selectForEdit(); // enable copy-on-edit - if (target !== this) { - return this.userDestroy.call(target); - } + // make sure to restore default slot of parent block + var target = this.selectForEdit(); // enable copy-on-edit + if (target !== this) { + return this.userDestroy.call(target); + } - // for undrop / redrop - var scripts = this.parentThatIsA(ScriptsMorph); - if (scripts) { - scripts.clearDropInfo(); - scripts.lastDroppedBlock = this; - scripts.recordDrop(this.situation()); - scripts.dropRecord.action = 'delete'; - } + // for undrop / redrop + var scripts = this.parentThatIsA(ScriptsMorph); + if (scripts) { + scripts.clearDropInfo(); + scripts.lastDroppedBlock = this; + scripts.recordDrop(this.situation()); + scripts.dropRecord.action = 'delete';}; - this.topBlock().fullChanged(); - this.prepareToBeGrabbed(this.world().hand); - this.destroy(); + this.topBlock().fullChanged(); + this.prepareToBeGrabbed(world.hand); + this.destroy(); - var nb = window.blockCopy.fullCopy() - nb = nb.nextBlock() - if (nb) { - nb.destroy(); - } - }; + var nb = window.blockCopy.fullCopy( + ); nb = nb.nextBlock(); if ( + nb) {nb.destroy();};}; // RingMorph ///////////////////////////////////////////////////////////// /* - I am a reporter block which lambdifies it's contents todo outputs, - my outer shape will be sometimes roundish, diamondish or arrowish. -*/ - -// RingMorph inherits from ReporterBlockMorph: - -RingMorph.prototype = new ReporterBlockMorph; -RingMorph.prototype.constructor = RingMorph; -RingMorph.uber = ReporterBlockMorph.prototype; - -// RingMorph preferences settings: - -RingMorph.prototype.isCachingInputs = false; - -// RingMorph instance creation: - -function RingMorph () {this.init();}; - -RingMorph.prototype.init = function anonymous () {RingMorph.uber.init.call(this); -this.contrast = RingMorph.prototype.contrast; this.bounds.setExtent(new Point(50, -22).multiplyBy(this.scale)); this.rerender();}; /* Init the block for fun. :~) */ - -// RingMorph drawing - -RingMorph.prototype.render = function (ctx, inset) { - var slots = this.inputs().filter(slot => (slot instanceof RingCommandSlotMorph - ) || (slot instanceof RingReporterSlotMorph)), pos = this.position(); - - this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); - - if (MorphicPreferences.isFlat) { - // draw the outer filled shape - // draw the outline - ctx.fillStyle = this.cachedClrDark; - ctx.beginPath(); - this.outlinePath(ctx, 0); - - // render the holes: - slots.forEach(function anonymous (slot) { - slot.outlinePath(ctx, slot.position().subtract(pos)); - }); - - // ctx.closePath(); - ctx.clip('evenodd'); - ctx.fill(); - - // draw the inner filled shaped - // draw the outline - ctx.fillStyle = this.cachedClr; - ctx.beginPath(); - this.outlinePath(ctx, this.flatEdge); + I am a reporter block which lambdifies it's contents todo outputs, + my outer shape will be sometimes roundish, diamondish or arrowish. +*/ - // render the holes: - slots.forEach(function anonymous (slot) { - slot.outlinePath(ctx, slot.position().subtract(pos)); - }); +// RingMorph inherits from ReporterBlockMorph: - // ctx.closePath(); - ctx.clip('evenodd'); - ctx.fill(); - } else { - ctx.fillStyle = this.cachedClr; - // draw the 'flat' shape: - // draw the outline - ctx.beginPath(); - this.outlinePath(ctx, 0); - if (this.isPredicate) { - var w = this.width(), - h = this.height(), - r = this.rounding, - right = w - r, - pos = this.position(); +RingMorph.prototype = new ReporterBlockMorph; +RingMorph.prototype.constructor = RingMorph; +RingMorph.uber = ReporterBlockMorph.prototype; - ctx.moveTo(inset, h2); - ctx.lineTo(r, inset); - ctx.lineTo(right - inset, inset); +// RingMorph preferences settings: - // render the holes: - slots.forEach(function anonymous (slot) { - slot.outlinePath(ctx, slot.position().subtract(pos)); - }); +RingMorph.prototype.isCachingInputs = false; - ctx.lineTo(right - inset, h - inset); - ctx.lineTo(r, h - inset); - } else { - // render the holes: - slots.forEach(function anonymous (slot) { - slot.outlinePath(ctx, slot.position().subtract(pos)); - }); - }; - ctx.closePath(); - ctx.clip('evenodd'); - ctx.fill(); +// RingMorph instance creation: - // add 3D-Effect: - this.drawEdges(ctx); - }; -}; +function RingMorph () {this.init();}; + +RingMorph.prototype.init = function () {RingMorph.uber.init.call(this); (this +).contrast = RingMorph.prototype.contrast; this.bounds.setExtent(new Point(50, +22).multiplyBy(this.scale)); this.rerender();}; /* Init the block for fun. */ // RingMorph dragging and dropping -RingMorph.prototype.rootForGrab = function () { -if (this.isDraggable) {return this;} else { +RingMorph.prototype.rootForGrab = function ( +) {if (this.isDraggable) {return this;} else { return BlockMorph.uber.rootForGrab.call(this);};}; // RingMorph ops - Note: these assume certain layouts defined elsewhere - -RingMorph.prototype.embed = function anonymous (aBlock, inputNames, noVanish) { +RingMorph.prototype.embed = function (aBlock, inputNames, noVanish) { var slot; this.isDraggable = true; this.category = asABool( localStorage['-snap-setting-oldLambdaOn']) ? 'operators' : 'other'; this.color = SpriteMorph.prototype.blockColorFor(this.category); // set my type, selector, and nested block: this.isStatic = false; if (aBlock instanceof CommandBlockMorph) { - this.selector = asABool(localStorage['-snap-setting-oldLambdaOn']) ? 'reportScript' : 'reifyScript'; - this.setSpec(localize(asABool(localStorage['-snap-setting-oldLambdaOn']) ? 'the script %parms %c' : '%rc %ringparms')); - slot = this.parts().filter(part => ((part instanceof CommandSlotMorph) || (part instanceof FunctionSlotMorph)))[0]; - slot.nestedBlock(aBlock); - } else { - this.selector = ('reify').concat(asABool(localStorage['-snap-setting-oldLambdaOn']) ? '' : (aBlock.isPredicate ? 'Predicate' : 'Reporter' - )); this.setSpec(localize(asABool(localStorage['-snap-setting-oldLambdaOn']) ? 'the %f block %parms' : (aBlock.isPredicate ? '%rp' : '%rr').concat(' %ringparms'))); slot = this.parts().filter(part => (( - part instanceof CommandSlotMorph) || (part instanceof FunctionSlotMorph)))[0]; if (slot instanceof Morph) { - slot.replaceInput(slot.contents(), aBlock, noVanish);}; - }; + this.selector = asABool(localStorage['-snap-setting-oldLambdaOn']) ? 'reportScript' : 'reifyScript'; + this.setSpec(localize(asABool(localStorage['-snap-setting-oldLambdaOn']) ? 'the script %parms %c' : '%rc %ringparms')); + slot = this.parts().filter(part => ((part instanceof CommandSlotMorph) || (part instanceof FunctionSlotMorph)))[0]; + slot.nestedBlock(aBlock);} else { + this.selector = ('reify').concat(asABool(localStorage['-snap-setting-oldLambdaOn']) ? '' : (aBlock.isPredicate ? 'Predicate' : 'Reporter' + )); this.setSpec(localize(asABool(localStorage['-snap-setting-oldLambdaOn']) ? 'the %f block %parms' : (aBlock.isPredicate ? '%rp' : '%rr' + ).concat(' %ringparms'))); slot = this.parts().filter(part => ((part instanceof CommandSlotMorph) || (part instanceof FunctionSlotMorph + )))[0]; if (slot instanceof Morph) {slot.replaceInput(slot.contents(), aBlock, noVanish);};}; // set my inputs, if any slot = this.children.filter(part => (part instanceof MultiArgMorph))[0]; @@ -8223,7 +7274,7 @@ RingMorph.prototype.blockSlot = function anonymous () {var slots = this.parts(). thatSlot instanceof Morph) ? thatSlot.nestedBlock() : null);}; RingMorph.prototype.inputNamesElement = function () {var inputs = this.children.filter(part => ( part instanceof MultiArgMorph))[0]; if (inputs instanceof MultiArgMorph) {return inputs;} else {return null;};}; RingMorph.prototype.inputNames = function ( ) {var inputs = this.inputNamesElement(); if (inputs instanceof MultiArgMorph) {return inputs.evaluate();} else {return []; -};}; RingMorph.prototype.dataType = function anonymous () {return contains(['reportScript', 'reifyScript'], this.selector +};}; RingMorph.prototype.dataType = function () {return contains(['reportScript', 'reifyScript'], this.selector ) ? 'command' : ((this.contents() instanceof ReporterBlockMorph) ? (this.contents().isPredicate ? 'predicate' : 'reporter' ) : (this.blockSlot().isPredicate ? 'predicate' : 'reporter'));}; RingMorph.prototype.isEmptySlot = function ( ) {return ((this.contents() === null) && (this.getSlotSpec().indexOf('Ring') > 0));}; @@ -8287,7 +7338,7 @@ ScriptsMorph.prototype.init = function () { // ScriptsMorph deep copying: ScriptsMorph.prototype.fullCopy = function () { - var cpy = new ScriptsMorph(), + var cpy = new ScriptsMorph, pos = this.position(), child; if (this.focus) { @@ -8317,7 +7368,7 @@ ScriptsMorph.prototype.render = function (aContext) { if (this.cachedTexture) { this.renderCachedTexture(aContext); } else if (this.texture) { - this.renderTexture(this.texture, aContext); + this.renderTexture(this.texture); } }; @@ -9205,18 +8256,16 @@ ScriptsMorph.prototype.reactToDropOf = function (droppedMorph, hand) { if (droppedMorph instanceof BlockMorph || droppedMorph instanceof CommentMorph) { droppedMorph.snap(hand); - } - this.adjustBounds(); + }; this.adjustBounds(); }; // ScriptsMorph events ScriptsMorph.prototype.mouseClickLeft = function (pos) { - var shiftClicked = this.world().currentKey === 16; + var shiftClicked = world.currentKey === 16; if (shiftClicked) { return this.edit(pos); - } - if (this.focus) {this.focus.stopEditing(); } + }; if (this.focus) {this.focus.stopEditing();}; }; ScriptsMorph.prototype.selectForEdit = function () { @@ -9227,32 +8276,22 @@ ScriptsMorph.prototype.selectForEdit = function () { this.feedbackMorph.destroy(); rcvr.shadowAttribute('scripts'); return rcvr.scripts; - } - return this; -}; + }; return this;}; // ScriptsMorph keyboard support -ScriptsMorph.prototype.edit = function (pos) { - var target, - world = this.world(); - if (this.focus) {this.focus.stopEditing(); } - world.stopEditing(); - if (!ScriptsMorph.prototype.enableKeyboard) {return; } - target = this.selectForEdit(); // enable copy-on-edit - target.focus = new ScriptFocusMorph(target, target, pos); - target.focus.getFocus(world); -}; +ScriptsMorph.prototype.edit = function (pos) {var target; if ( +this.focus) {this.focus.stopEditing();}; world.stopEditing(); +if (!ScriptsMorph.prototype.enableKeyboard) {return;}; (target +) = this.selectForEdit(); target.focus = new ScriptFocusMorph( +target, target, pos); target.focus.getFocus(world);}; ScriptsMorph.prototype.toggleKeyboardEntry = function () { // when the user clicks the keyboard button in the toolbar - var target, sorted, - world = this.world(); + var target, sorted; if (this.focus) { this.focus.stopEditing(); - return; - } - world.stopEditing(); + return;}; world.stopEditing(); if (ScriptsMorph.prototype.enableKeyboard) { target = this.selectForEdit(); // enable copy-on-edit target.focus = new ScriptFocusMorph(target, target, target.position()); @@ -9289,10 +8328,7 @@ ScriptsMorph.prototype.scriptTarget = function () { editor = this.parentThatIsA(BlockEditorMorph); if (editor) { return editor.target; - }; - throw new Error('script target cannot be found for orphaned scripts'); -}; - + }; throw new Error('script target cannot be found for orphaned scripts');}; // ArgMorph ////////////////////////////////////////////////////////// @@ -9315,20 +8351,13 @@ ArgMorph.uber = SyntaxElementMorph.prototype; // ArgMorph instance creation: -function ArgMorph(type) { - this.init(type); -} +function ArgMorph(type) {this.init(type);}; ArgMorph.prototype.init = function (type) { - this.type = type || null; - this.icon = null; - ArgMorph.uber.init.call(this); - this.color = new Color(0, 17, 173); - this.createIcon(); - if (type === 'list') { - this.alpha = 1; - } -}; +this.type = type || null; this.icon = null; +ArgMorph.uber.init.call(this); (this.color +) = new Color(0, 17, 173); this.createIcon( +); if (type === 'list') {this.alpha = 1;};}; // ArgMorph preferences settings: @@ -9351,31 +8380,26 @@ ArgMorph.prototype.reactToSliderEdit = function () { receiver = top.scriptTarget(); if (top instanceof PrototypeHatBlockMorph) { return; - } - if (receiver) { + }; if (receiver) { stage = receiver.parentThatIsA(StageMorph); if (stage && (stage.isThreadSafe || Process.prototype.enableSingleStepping)) { stage.threads.startProcess(top, receiver, stage.isThreadSafe); } else { top.mouseClickLeft(); - } - } - } -}; + }; + }; + };}; // ArgMorph drag & drop: for demo puposes only -ArgMorph.prototype.justDropped = function () { - if (!(this instanceof CommandSlotMorph)) { - this.fixLayout(); - this.rerender(); - } -}; +ArgMorph.prototype.justDropped = function ( +) {if (!(this instanceof CommandSlotMorph) +) {this.fixLayout(); this.rerender();};}; // ArgMorph spec extrapolation (for demo purposes) -ArgMorph.prototype.getSpec = function anonymous () {return '%s'; /* default */}; +ArgMorph.prototype.getSpec = (() => '%s'); // ArgMorph menu @@ -9384,8 +8408,7 @@ ArgMorph.prototype.userMenu = function () { menu; if (!sm && !(this.parent instanceof MultiArgMorph)) { return this.parent.userMenu(); - } - menu = sm || new MenuMorph(this); + }; menu = sm || new MenuMorph(this); if (this.parent instanceof MultiArgMorph && this.parentThatIsA(ScriptsMorph)) { if (!this.parent.maxInputs || @@ -9394,58 +8417,42 @@ ArgMorph.prototype.userMenu = function () { 'insert a slot', () => this.parent.insertNewInputBefore(this) ); - } - if (this.parent.inputs().length > this.parent.minInputs) { + }; if (this.parent.inputs().length > this.parent.minInputs) { menu.addItem( 'delete slot', () => this.parent.deleteSlot(this) ); - } - } - return menu; -}; + }; + }; return menu;}; -ArgMorph.prototype.slotMenu = function anonymous () {/* subclass responsibility */ return null;}; +ArgMorph.prototype.slotMenu = function () {return null;}; // ArgMorph drawing -ArgMorph.prototype.createIcon = function () {switch (this.type) {case 'costume': this.icon = this.labelPart('%wardrobe'); this.add(this.icon); break; -case 'sound': this.icon = this.labelPart('%notes'); this.add(this.icon); break; case 'object': this.icon = this.labelPart('%turtleOutline'); this.add(this.icon); break; -case 'list': this.icon = this.labelPart('%list'); this.add(this.icon); break; case 'unknown': this.icon = this.labelPart('%unknown'); this.add(this.icon); break; default: nop();}}; +ArgMorph.prototype.createIcon = function () {switch (this.type) {case 'costume': this.icon = this.labelPart('%wardrobe'); this.add(this.icon); break; case 'sound': +this.icon = this.labelPart('%notes'); this.add(this.icon); break; case 'object': this.icon = this.labelPart('%turtleOutline'); this.add(this.icon); break; case 'list': +this.icon = this.labelPart('%list'); this.add(this.icon); break; case 'unknown': this.icon = this.labelPart('%unknown'); this.add(this.icon); break; default: nop();};}; ArgMorph.prototype.fixLayout = function () { - if (this.icon) { - this.icon.setPosition(this.position()); - this.bounds.setExtent(this.icon.extent()); - } else { - ArgMorph.uber.fixLayout.call(this); - }; -}; - -ArgMorph.prototype.render = function (ctx) { - // make sure my icon's shadow color matches my block's color - var block; - if (this.icon) { - block = this.parentThatIsA(BlockMorph); - if (block) { - this.icon.shadowColor = block.color.darker(this.labelContrast); - }; - switch (this.type) { - case 'list': - this.color = new Color(255, 140, 0); // list color - break; - default: - return; // don't draw anything except the icon - }; - }; - ArgMorph.uber.render.call(this, ctx); -}; +if (this.icon) {this.icon.setPosition((this +).position()); this.bounds.setExtent(((this +).icon).extent());} else {(ArgMorph +).uber.fixLayout.call(this);};}; + +ArgMorph.prototype.render = function (ctx) {var block; +if (this.icon) {block = this.parentThatIsA(BlockMorph +); if (block) {this.icon.shadowColor = (block.color +).darker(this.labelContrast);}; switch (this.type +) {case 'list': this.color = new Color(255, 140, +0); break; default: return;};}; (ArgMorph +).uber.render.call(this, ctx);}; // ArgMorph evaluation -ArgMorph.prototype.evaluate = function anonymous () {return ((this.type === 'list') ? new List : null);}; +ArgMorph.prototype.evaluate = function () { +return ((this.type === 'list') ? new List : null);}; -ArgMorph.prototype.isEmptySlot = function anonymous () {return this.type !== null;}; +ArgMorph.prototype.isEmptySlot = function () {return !isNil(this.type);}; // BlockSlotMorph ////////////////////////////////////////////////////// @@ -9461,26 +8468,23 @@ ArgMorph.prototype.isEmptySlot = function anonymous () {return this.type !== nul // BlockSlotMorph inherits form SyntaxElementMorph: -BlockSlotMorph.prototype = new SyntaxElementMorph; BlockSlotMorph.prototype.constructor = BlockSlotMorph; BlockSlotMorph.uber = SyntaxElementMorph.prototype; function BlockSlotMorph () { -this.init();}; BlockSlotMorph.prototype.init = function anonymous () {this.touchingMouse = false; BlockSlotMorph.uber.init.call(this); this.fixLayout(); this.cursorStyle = 'default';}; -BlockSlotMorph.prototype.render = function anonymous (ctx) {var borderColor; if (this.parent) {borderColor = this.parent.color.darker();} else {borderColor = new Color(120, 120, 120);}; -if (this.touchingMouse && (this.world().hand.children[0] instanceof BlockMorph)) {borderColor = borderColor.copy(); borderColor = borderColor.lighter();}; this.cachedClr = borderColor.toString( +BlockSlotMorph.prototype = new SyntaxElementMorph; BlockSlotMorph.prototype.constructor = BlockSlotMorph; BlockSlotMorph.uber = SyntaxElementMorph.prototype; function BlockSlotMorph ( +) {this.init();}; BlockSlotMorph.prototype.init = function () {this.touchingMouse = false; BlockSlotMorph.uber.init.call(this); this.fixLayout(); this.cursorStyle = 'default';}; +BlockSlotMorph.prototype.render = function (ctx) {var borderColor; if (this.parent) {borderColor = this.parent.color.darker();} else {borderColor = new Color(120, 120, 120);}; if ( +this.touchingMouse && (world.hand.children[0] instanceof BlockMorph)) {borderColor = borderColor.copy(); borderColor = borderColor.lighter();}; this.cachedClr = borderColor.toString( ); this.cachedClrBright = borderColor.lighter(this.contrast).toString(); var h = this.height(), w = this.width(); this.cachedClrDark = borderColor.darker(this.contrast).toString(); ctx.fillStyle = this.cachedClr; ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(w,0); ctx.lineTo(w,h); ctx.lineTo(0,h); ctx.lineTo(0,0); ctx.fill(); if (!(MorphicPreferences.isFlat)) { -ctx.strokeStyle = (new Color(64, 64, 64)).toString(); ctx.lineWidth = this.scale; ctx.lineCap = 'round'; ctx.lineJoin = 'miter'; ctx.lineTo(w,0); ctx.lineTo(w,h); ctx.lineTo(0,h); -ctx.lineTo(0,0); ctx.stroke();}; ctx.closePath();}; BlockSlotMorph.prototype.fixLayout = function anonymous () {var myBlock = this.children[0]; if (myBlock instanceof BlockMorph -) {this.bounds.setExtent(myBlock.bounds.extent().add(this.edge * 2 + this.rfBorder * 2));} else {this.bounds.setExtent(new Point((40 * this.edge), (20 * this.edge)));}; if ( -this.parent instanceof Morph) {this.parent.fixLayout();};}; BlockSlotMorph.prototype.step = nop; BlockSlotMorph.prototype.wantsDropOf = function (aMorph) {if ( -aMorph instanceof BlockMorph) {if (aMorph.parent === world.hand) {if (this.snapSound) {this.snapSound.play();};}; return true;} else {return false;};}; -BlockSlotMorph.prototype.reactToDropOf = function (aMorph) {if (aMorph instanceof BlockMorph) {this.add(aMorph); aMorph.fixBlockColor(); -this.fixLayout(); aMorph.setCenter(this.bounds.center()); if (this.parent instanceof Morph) {this.parent.fixLayout();};};}; -BlockSlotMorph.prototype.evaluate = function anonymous () {var myBlock = this.children[0]; return (( -myBlock instanceof BlockMorph) ? myBlock : null);}; BlockSlotMorph.prototype.getSpec = (() => '%instr' -); BlockSlotMorph.prototype.mouseEnter = function anonymous () {this.touchingMouse = true; -this.rerender();}; BlockSlotMorph.prototype.mouseLeave = function anonymous () { -this.touchingMouse = false; this.rerender();}; BlockSlotMorph.prototype.reactToGrabOf = function ( -) {if (this.parent instanceof SyntaxElementMorph) {if (!(this.evaluate() instanceof BlockMorph)) { -this.parent.revertToDefaultInput(this);};}; this.rerender();}; /* Included the flat design mode for this. */ +ctx.strokeStyle = (new Color(64, 64, 64)).toString(); ctx.lineWidth = this.scale; ctx.lineCap = 'square'; ctx.lineJoin = 'miter'; ctx.lineTo(w,0); ctx.lineTo(w,h); ctx.lineTo(0, +h); ctx.lineTo(0,0); ctx.stroke();}; ctx.closePath();}; BlockSlotMorph.prototype.fixLayout = function () {var myBlock = this.children[0]; if (myBlock instanceof BlockMorph) { +this.bounds.setExtent(myBlock.bounds.extent().add(this.edge * 2 + this.rfBorder * 2));} else {this.bounds.setExtent(new Point((40 * this.edge), (20 * this.edge)));}; if ( +this.parent instanceof Morph) {this.parent.fixLayout();};}; BlockSlotMorph.prototype.step = nop; BlockSlotMorph.prototype.wantsDropOf = function (aMorph) {if ((aMorph +) instanceof BlockMorph) {if (aMorph.parent === world.hand) {if (this.snapSound) {this.snapSound.play();};}; return true;} else {return false;};}; (BlockSlotMorph +).prototype.reactToDropOf = function (aMorph) {if (aMorph instanceof BlockMorph) {this.add(aMorph); aMorph.fixBlockColor(); this.fixLayout(); aMorph.setCenter( +this.bounds.center()); if (this.parent instanceof Morph) {this.parent.fixLayout();};};}; BlockSlotMorph.prototype.evaluate = function () {var myBlock = (this +).children[0]; return ((myBlock instanceof BlockMorph) ? myBlock : null);}; BlockSlotMorph.prototype.getSpec = (() => '%instr'); (BlockSlotMorph.prototype +).mouseEnter = function () {this.touchingMouse = true; this.rerender();}; BlockSlotMorph.prototype.mouseLeave = function () {this.touchingMouse = false; +this.rerender();}; BlockSlotMorph.prototype.reactToGrabOf = function () {if (this.parent instanceof SyntaxElementMorph) {if (!((this.evaluate() +) instanceof BlockMorph)) {this.parent.revertToDefaultInput(this);};}; this.rerender();}; /* Included the flat design mode for this. */ // CommandSlotMorph //////////////////////////////////////////////////// @@ -9507,21 +8511,20 @@ CommandSlotMorph.uber = ArgMorph.prototype; function CommandSlotMorph () {this.init();}; -CommandSlotMorph.prototype.init = function anonymous () { +CommandSlotMorph.prototype.init = function () { this.fillingColor = this.rfColor.lighter().lighter(10); this.borderColor = BLACK; CommandSlotMorph.uber.init.call( -this); this.setExtent(new Point(230, (this.corner * 4 -) + this.cSlotPadding)); this.fixLayout(); this.setColor( -this.fillerColor); this.cursorStyle = 'default';}; -CommandSlotMorph.prototype.getSpec = (() => '%cmd'); +this); this.fixLayout(); this.setColor(this.fillerColor +); this.cursorStyle = 'default'; this.cachedClr = ( +this.fillingColor).toString();}; (CommandSlotMorph +).prototype.getSpec = (() => '%cmd'); // CommandSlotMorph enumerating: CommandSlotMorph.prototype.topBlock = function () { if (this.parent.topBlock) { return this.parent.topBlock(); - } - return this.nestedBlock(); + }; return this.nestedBlock(); }; // CommandSlotMorph nesting: @@ -9532,14 +8535,13 @@ CommandSlotMorph.prototype.nestedBlock = function (block) { this.add(block); if (nb) { block.bottomBlock().nextBlock(nb); - } - this.fixLayout(); + }; this.fixLayout(); } else { return detect( this.children, child => child instanceof CommandBlockMorph ); - } + }; }; // CommandSlotMorph attach targets: @@ -9570,43 +8572,36 @@ CommandSlotMorph.prototype.attachTargets = function () { element: this, loc: 'bottom', type: 'slot' - }); - return answer; + }); return answer; }; // CommandSlotMorph layout: -CommandSlotMorph.prototype.fixLayout = function () { - var nb = this.nestedBlock(); +CommandSlotMorph.prototype.fixLayout = function ( + ) {var nb = this.nestedBlock(); if (this.borderColor && this.parent) { - if (!this.borderColor.eq(this.parent.color)) { - this.borderColor = this.parent.color; - }; - }; - if (nb) { + if (!this.borderColor.eq(this.parent.color + )) {this.borderColor = this.parent.color;}; + }; if (nb) { nb.setPosition( - new Point( + new Point( this.left() + this.edge + this.rfBorder, this.top() + this.edge + this.rfBorder - ) - ); - this.bounds.setWidth(nb.fullBounds().width() - + (this.edge + this.rfBorder) * 2 - ); + ) + ); this.bounds.setWidth(nb.fullBounds().width( + ) + (this.edge + this.rfBorder) * 2); this.bounds.setHeight(nb.fullBounds().height() - + this.edge + (this.rfBorder * 2) - (this.corner - this.edge) - ); - } else { - this.bounds.setHeight(this.corner * 4); - this.bounds.setWidth( - this.corner * 4 - + this.inset - + this.dent - ); - } - if (this.parent && this.parent.fixLayout) { - this.parent.fixLayout(); - } + + this.edge + (this.rfBorder * 2) - ( + this.corner - this.edge)); + } else {var shrink = ((this.rfBorder * 2) + ( + this.edge * 2)); this.bounds.setExtent((new Point( + (this.fontSize + this.edge * 2) * 2 - shrink, + this.fontSize + this.edge * 2 - shrink + )).add(this.edge * 2 + this.rfBorder * 2 + ));}; if (this.parent && ( + this.parent.fixLayout)) { + this.parent.fixLayout(); + }; }; // CommandSlotMorph evaluating: @@ -9627,301 +8622,129 @@ CommandSlotMorph.prototype.attach = function () { var choices = this.overlappedMorphs(), menu = new MenuMorph(this, 'choose new parent:'); - choices.forEach(each => - menu.addItem( - each.toString().slice(0, 50), - () => { - each.add(this); - this.isDraggable = false; - if (each.fixLayout) { - each.fixLayout(); - } - } - ) - ); - if (choices.length > 0) { - menu.popUpAtHand(this.world()); - } -}; - -// CommandSlotMorph drawing: - -CommandSlotMorph.prototype.render = function anonymous ( -ctx) {this.cachedClr = this.fillingColor.toString(); -this.cachedClrBright = this.borderColor.lighter( -this.contrast).toString(); -this.cachedClrDark = this.borderColor.darker( -this.contrast).toString(); -ctx.fillStyle = this.cachedClr; -this.drawFlat(ctx); if ( -!MorphicPreferences.isFlat -) {this.drawEdges(ctx);};}; - -CommandSlotMorph.prototype.drawFlat = function (ctx) { - var isFilled = this.nestedBlock() !== null, - ins = (isFilled ? this.inset : this.inset / 2), - dent = (isFilled ? this.dent : this.dent / 2), - indent = this.corner * 2 + ins, - edge = this.edge, - rf = (isFilled ? this.rfBorder : 0), - y = this.height() - this.corner - edge; - - ctx.beginPath(); - - // top left: - ctx.arc( - this.corner + edge, - this.corner + edge, - this.corner, - radians(-180), - radians(-90), - false - ); - - // dent: - ctx.lineTo(this.corner + ins + edge + rf * 2, edge); - ctx.lineTo(indent + edge + rf * 2, this.corner + edge); - ctx.lineTo( - indent + edge + rf * 2 + (dent - rf * 2), - this.corner + edge - ); - ctx.lineTo( - indent + edge + rf * 2 + (dent - rf * 2) + this.corner, - edge - ); - ctx.lineTo(this.width() - this.corner - edge, edge); - - // top right: - ctx.arc( - this.width() - this.corner - edge, - this.corner + edge, - this.corner, - radians(-90), - radians(-0), - false - ); - - // bottom right: - ctx.arc( - this.width() - this.corner - edge, - y, - this.corner, - radians(0), - radians(90), - false - ); - - // bottom left: - ctx.arc( - this.corner + edge, - y, - this.corner, - radians(90), - radians(180), - false - ); - - ctx.closePath(); - ctx.fill(); - -}; - -CommandSlotMorph.prototype.drawEdges = function (ctx) { - var isFilled = this.nestedBlock() !== null, - ins = (isFilled ? this.inset : this.inset / 2), - dent = (isFilled ? this.dent : this.dent / 2), - indent = this.corner * 2 + ins, - edge = this.edge, - rf = (isFilled ? this.rfBorder : 0), - shift = this.edge * 0.5, - gradient, - upperGradient, - lowerGradient, - rightGradient; - - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - // bright: - // bottom horizontal line - gradient = ctx.createLinearGradient( - 0, - this.height(), - 0, - this.height() - this.edge - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrBright); - - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(this.corner + edge, this.height() - shift); - ctx.lineTo( - this.width() - this.corner - edge, - this.height() - shift - ); - ctx.stroke(); - - // bottom right corner - gradient = ctx.createRadialGradient( - this.width() - (this.corner + edge), - this.height() - (this.corner + edge), - this.corner, - this.width() - (this.corner + edge), - this.height() - (this.corner + edge), - this.corner + edge - ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); - - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - this.width() - (this.corner + edge), - this.height() - (this.corner + edge), - this.corner + shift, - radians(0), - radians(90), - false - ); - ctx.stroke(); - - // right vertical line - gradient = ctx.createLinearGradient( - this.width(), - 0, - this.width() - this.edge, - 0 - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrBright); - - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo( - this.width() - shift, - this.height() - this.corner - this.edge - ); - ctx.lineTo(this.width() - shift, edge + this.corner); - ctx.stroke(); - - if (useBlurredShadows) { - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } - - // left vertical side - gradient = ctx.createLinearGradient( - 0, - 0, - edge, - 0 - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, edge + this.corner); - ctx.lineTo(shift, this.height() - edge - this.corner); - ctx.stroke(); - - // upper left corner - gradient = ctx.createRadialGradient( - this.corner + edge, - this.corner + edge, - this.corner, - this.corner + edge, - this.corner + edge, - this.corner + edge - ); - gradient.addColorStop(0, this.cachedClrDark); - gradient.addColorStop(1, this.cachedClr); + choices.forEach(each => + menu.addItem( + each.toString().slice(0, 50), + () => { + each.add(this); + this.isDraggable = false; + if (each.fixLayout) { + each.fixLayout(); + }; + } + ) + ); if (choices.length > 0) { + menu.popUpAtHand(world); + }; +}; - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - this.corner + edge, - this.corner + edge, - this.corner + shift, - radians(-180), - radians(-90), - false - ); - ctx.stroke(); +// CommandSlotMorph drawing: - // upper edge (left side) - upperGradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - upperGradient.addColorStop(0, this.cachedClr); - upperGradient.addColorStop(1, this.cachedClrDark); +CommandSlotMorph.prototype.render = function (ctx) {this.cachedClrBright = ( +((this.borderColor).lighter(this.contrast)).withAlpha(0.5)).toString(); (this +).cachedClrDark = (((this.borderColor).darker(this.contrast)).withAlpha(1/2) +).toString(); var gradient = ctx.createLinearGradient(0, 0, 0, this.height()); +if (!(MorphicPreferences.isFlat)) {gradient.addColorStop(0, (this.fillingColor +).toString()); gradient.addColorStop(1, (this.fillingColor.darker()).toString( +)); ctx.fillStyle = gradient; this.drawFlat(ctx); this.drawEdges(ctx); +} else {ctx.fillStyle = this.cachedClr; this.drawFlat(ctx);};}; + +CommandSlotMorph.prototype.drawFlat = function ( + ctx) {var isFilled = !isNil(this.nestedBlock()), + ins = (isFilled ? this.inset : this.inset / 2), + dent = (isFilled ? this.dent : this.dent / 2), + edge = this.edge, indent = (this.corner * 2 + ) + ins, rf = (isFilled ? this.rfBorder : 0), + filledForCornedEdge = (this.corner + edge + ( + (isFilled * (this.rfBorder > 0)) * edge * 3/2 + )), cornerWithFilling = this.corner + ( + isFilled * edge * 3/2); ctx.beginPath(); - ctx.strokeStyle = upperGradient; - ctx.beginPath(); - ctx.moveTo(this.corner + edge, shift); + // top left: + ctx.arc( + filledForCornedEdge, + filledForCornedEdge, + cornerWithFilling, + -Math.PI, + -Math.PI / 2, + false); // dent: + ctx.lineTo(this.corner + ins + edge + rf * 2, edge); + ctx.lineTo(indent + edge + rf * 2, this.corner + edge); ctx.lineTo( - this.corner + ins + edge + rf * 2 - shift, - shift - ); - ctx.stroke(); - - // dent bottom - lowerGradient = ctx.createLinearGradient( - 0, - this.corner, - 0, + indent + edge + rf * 2 + (dent - rf * 2), this.corner + edge - ); - lowerGradient.addColorStop(0, this.cachedClr); - lowerGradient.addColorStop(1, this.cachedClrDark); + ); ctx.lineTo( + indent + edge + rf * 2 + (dent - rf * 2) + this.corner, + edge + ); ctx.lineTo(this.width() - this.corner - edge, edge); - ctx.strokeStyle = lowerGradient; - ctx.beginPath(); - ctx.moveTo(indent + edge + rf * 2 + shift, this.corner + shift); - ctx.lineTo( - indent + edge + rf * 2 + (dent - rf * 2), - this.corner + shift - ); - ctx.stroke(); + // top right: + ctx.arc( + this.width() - filledForCornedEdge, + filledForCornedEdge, + cornerWithFilling, + -Math.PI / 2, 0, + false); // bottom right: + ctx.arc( + this.width() - filledForCornedEdge, + this.height() - filledForCornedEdge, + cornerWithFilling, 0, Math.PI / 2, + false); // bottom left: + ctx.arc( + filledForCornedEdge, + this.height() - filledForCornedEdge, + cornerWithFilling, Math.PI / 2, + Math.PI, false); ctx.closePath(); ctx.fill();}; - // dent right edge - rightGradient = ctx.createLinearGradient( - indent + edge + rf * 2 + (dent - rf * 2) - shift, - this.corner, - indent + edge + rf * 2 + (dent - rf * 2) + shift * 0.7, - this.corner + shift + shift * 0.7 - ); - rightGradient.addColorStop(0, this.cachedClr); - rightGradient.addColorStop(1, this.cachedClrDark); +CommandSlotMorph.prototype.drawEdges = function (ctx + ) {var isFilled = !isNil(this.nestedBlock()), + ins = (isFilled ? this.inset : this.inset / 2), + dent = (isFilled ? this.dent : this.dent / 2), + indent = this.corner * 2 + ins, edge = (this + ).edge, shift = this.edge / 2, filledForCornedEdge = ( + this.corner + edge + ((isFilled * (this.rfBorder > 0 + )) * edge * 3/2)), rf = (isFilled ? this.rfBorder : 0), + shift = this.edge / 2, cornerWithFilling = Math.max( + (this.corner + shift + ((isFilled * ((this.rfBorder + ) > 0)) * edge * 3/2)), 0); ctx.lineWidth = this.edge; + ctx.lineJoin = 'round'; ctx.lineCap = 'butt'; + ctx.strokeStyle = this.cachedClrBright; + ctx.beginPath(); ctx.moveTo( + this.width() - shift, (edge * 2) + this.corner + ); ctx.lineTo(this.width() - shift, + this.height() - filledForCornedEdge + ); ctx.arc(this.width() - filledForCornedEdge, + this.height() - filledForCornedEdge, + cornerWithFilling, 0, + Math.PI / 2, false); + ctx.lineTo(filledForCornedEdge, + this.height() - shift); ctx.stroke(); - ctx.strokeStyle = rightGradient; - ctx.beginPath(); - ctx.moveTo( - indent + edge + rf * 2 + (dent - rf * 2), - this.corner + shift - ); - ctx.lineTo( - indent + edge + rf * 2 + (dent - rf * 2) + this.corner, - shift - ); - ctx.stroke(); + if (useBlurredShadows) { + ctx.shadowOffsetY = shift; + ctx.shadowBlur = edge; + ctx.shadowColor = "black"; + }; ctx.strokeStyle = this.cachedClrDark; + + ctx.beginPath(); ctx.moveTo(shift, (this + ).height() - filledForCornedEdge); ctx.arc( + filledForCornedEdge, + filledForCornedEdge, + cornerWithFilling, + -Math.PI, -Math.PI / 2, false + ); ctx.lineTo((this.corner + ins) + ( + edge + rf * 2), shift); ctx.stroke(); - // upper edge (right side) - ctx.strokeStyle = upperGradient; ctx.beginPath(); - ctx.moveTo( - indent + edge + rf * 2 + (dent - rf * 2) + this.corner, - shift - ); - ctx.lineTo(this.width() - this.corner - edge, shift); - ctx.stroke(); -}; + ctx.moveTo(indent + edge + rf * 2, + this.corner + shift); ctx.lineTo( + indent + edge + rf * 2 + (dent - rf * 2), + this.corner + shift + ); ctx.lineTo( + indent + edge + rf * 2 + (dent - rf * 2 + ) + this.corner, shift + ); ctx.lineTo(this.width( + ) - filledForCornedEdge, shift); ctx.stroke();}; // RingCommandSlotMorph /////////////////////////////////////////////////// @@ -9947,36 +8770,35 @@ RingCommandSlotMorph.prototype.rfBorder = 0; // RingCommandSlotMorph instance creation: -function RingCommandSlotMorph() {this.init();}; +function RingCommandSlotMorph () {this.init();}; RingCommandSlotMorph.prototype.init = function anonymous ( -) { - RingCommandSlotMorph.uber.init.call(this); - this.fillingColor = CLEAR; - this.contrast = RingMorph.prototype.contrast; - this.setColor(this.fillerColor); - this.rerender(); -}; +) {RingCommandSlotMorph.uber.init.call( + this); this.fillingColor = CLEAR; + this.cachedClr = (this.fillingColor + ).toString(); this.contrast = ( + RingMorph.prototype.contrast); + this.setColor(this.fillerColor + ); this.rerender();}; RingCommandSlotMorph.prototype.getSpec = function () {return '%rc';}; // RingCommandSlotMorph drawing: -RingCommandSlotMorph.prototype.render = function anonymous ( -ctx) {this.cachedClr = this.fillingColor.toString(); -this.cachedClrBright = this.borderColor.lighter( -this.contrast).toString(); -this.cachedClrDark = this.borderColor.darker( -this.contrast).toString(); -ctx.fillStyle = this.cachedClr; -this.drawFlat(ctx); if ( -!MorphicPreferences.isFlat -) {this.drawEdges(ctx);};}; - -RingCommandSlotMorph.prototype.outlinePath = function (ctx, offset) { - var ox = offset.x, - oy = offset.y, - isFilled = (this.nestedBlock() !== null), +RingCommandSlotMorph.prototype.render = function (ctx) { +this.cachedClrBright = (((this.borderColor).lighter((this +).contrast)).withAlpha(0.5)).toString(); (this.cachedClrDark +) = (((this.borderColor).darker(this.contrast)).withAlpha(0.5 +)).toString(); ctx.fillStyle = this.cachedClr; this.drawFlat( +ctx); if (!MorphicPreferences.isFlat) {this.drawEdges(ctx);};}; + +RingCommandSlotMorph.prototype.fixHolesLayout = function ( +) {var edge = this.edge; this.holes = [new Rectangle(edge, +edge, this.width() - edge, this.height() - edge)];}; + +RingCommandSlotMorph.prototype.outlinePath = function ( + ctx, inset, offset) {var ox = offset.x, oy = offset.y, + isFilled = !isNil(this.nestedBlock()), ins = this.inset / (2 - isFilled), dent = this.dent / (2 - isFilled), indent = this.corner * 2 + ins, @@ -9991,8 +8813,8 @@ RingCommandSlotMorph.prototype.outlinePath = function (ctx, offset) { this.corner + edge + ox, this.corner + edge + oy, this.corner, - radians(-180), - radians(-90), + -Math.PI, + -Math.PI / 2, false ); @@ -10044,7 +8866,6 @@ RingCommandSlotMorph.prototype.outlinePath = function (ctx, offset) { this.corner + edge + ox - this.corner, // this needs to be adjusted this.corner + edge + oy ); - }; // CSlotMorph //////////////////////////////////////////////////// @@ -10064,27 +8885,20 @@ RingCommandSlotMorph.prototype.outlinePath = function (ctx, offset) { // CSlotMorph inherits from CommandSlotMorph: -CSlotMorph.prototype = new CommandSlotMorph; +CSlotMorph.prototype = new RingCommandSlotMorph; CSlotMorph.prototype.constructor = CSlotMorph; CSlotMorph.uber = CommandSlotMorph.prototype; // CSlotMorph instance creation: -function CSlotMorph() { - this.init(); -} - -CSlotMorph.prototype.init = function () { - CommandSlotMorph.uber.init.call(this); - this.isLambda = false; // see Process.prototype.evaluateInput - this.isLoop = false; // has a loop arrow symbol - this.color = new Color(0, 17, 173); - this.setExtent(new Point(230, this.corner * 4 + this.cSlotPadding)); -}; +function CSlotMorph () {this.init();}; +CSlotMorph.prototype.init = function ( +) {CommandSlotMorph.uber.init.call(this); +this.isLambda = false; this.isLoop = (false +); this.color = BLACK; this.fixLayout();}; -CSlotMorph.prototype.getSpec = function () { - return this.isLoop? '%loop' : '%c'; -}; +CSlotMorph.prototype.getSpec = function ( +) {return this.isLoop ? '%loop' : '%c';}; CSlotMorph.prototype.mappedCode = function (definitions) { var code = StageMorph.prototype.codeMappings.reify || '<#1>', @@ -10094,51 +8908,39 @@ CSlotMorph.prototype.mappedCode = function (definitions) { partLines = (part.toString()).split('\n'), rx = new RegExp('<#1>', 'g'); - codeLines.forEach((codeLine, idx) => { - var prefix = '', - indent; + codeLines.forEach((codeLine, idx + ) => {var prefix = '', indent; if (codeLine.trimLeft().indexOf('<#1>') === 0) { indent = codeLine.indexOf('<#1>'); prefix = codeLine.slice(0, indent); - } - codeLines[idx] = codeLine.replace( + }; codeLines[idx] = codeLine.replace( new RegExp('<#1>'), partLines.join('\n' + prefix) - ); - codeLines[idx] = codeLines[idx].replace(rx, partLines.join('\n')); - }); - - return codeLines.join('\n'); + ); codeLines[idx] = codeLines[idx + ].replace(rx, partLines.join('\n')); + }); return codeLines.join('\n'); }; // CSlotMorph layout: CSlotMorph.prototype.fixLayout = function () { - var nb = this.nestedBlock(); - if (nb) { + var nb = this.nestedBlock(); if (nb) { nb.setPosition( new Point( this.left() + this.inset, this.top() + this.corner ) - ); - this.bounds.setHeight(nb.fullBounds().height() + this.corner); - this.bounds. setWidth( + ); this.bounds.setHeight(nb.fullBounds( + ).height() + this.corner); this.bounds.setWidth( nb.fullBounds().width() + (this.cSlotPadding * 2) ); - } else { - this.bounds.setHeight(this.corner * 4 + this.cSlotPadding); // default - this.bounds.setWidth( - this.corner * 4 - + (this.inset * 2) - + this.dent - + (this.cSlotPadding * 2) - ); - } - - if (this.parent && this.parent.fixLayout) { - this.parent.fixLayout(); - } + } else {var shrink = ((this.rfBorder * 2) + ( + this.edge * 2)); this.bounds.setExtent((new Point( + (this.fontSize + this.edge * 2) * 2 - shrink, + this.fontSize + this.edge * 2 - shrink + this.cSlotPadding + )).add(this.edge * 2 + this.rfBorder * 2));}; + if (this.parent && this.parent.fixLayout + ) {this.parent.fixLayout();}; }; CSlotMorph.prototype.fixLoopLayout = function () { @@ -10148,8 +8950,8 @@ CSlotMorph.prototype.fixLoopLayout = function () { if (loop) { loop.setRight(this.right() - this.corner); loop.setBottom(this.bottom() + this.cSlotPadding + this.edge); - } - } + }; + }; }; CSlotMorph.prototype.loop = function () { @@ -10158,50 +8960,67 @@ CSlotMorph.prototype.loop = function () { this.children, child => child instanceof SymbolMorph ); - } - return null; -}; - -CSlotMorph.prototype.fixHolesLayout = function () { - this.holes = [ - new Rectangle( - this.inset, - this.corner, - this.width(), - this.height() - this.corner - ) - ]; + }; return null; }; -CSlotMorph.prototype.isLocked = function anonymous () {return this.isStatic || (this.parent instanceof MultiArgMorph);}; +CSlotMorph.prototype.isLocked = function () {return (( +this.isStatic) || (this.parent instanceof MultiArgMorph));}; // CSlotMorph drawing: CSlotMorph.prototype.render = function (ctx) { - - // init - this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); - ctx.fillStyle = this.cachedClr; + if (this.parent instanceof SyntaxElementMorph) { + this.color = this.parent.color;}; this.cachedClr = ( + this.color).toString(); this.cachedClrBright = ((( + this.color).lighter(this.contrast)).withAlpha((1 + ( + MorphicPreferences).isFlat) / 2)).toString(); (this + ).cachedClrDark = (((this.color).darker(this.contrast + )).withAlpha((1 + (MorphicPreferences).isFlat) / 2) + ).toString(); ctx.fillStyle = this.cachedClr; // only add 3D-Effect here, rendering of the flat shape happens at the // encompassing block level if (!MorphicPreferences.isFlat) {this.drawEdges(ctx);}; }; -CSlotMorph.prototype.drawEdges = function (ctx) { - this.drawTopRightEdge(ctx); - this.drawTopEdge(ctx, this.inset, this.corner); - this.drawTopLeftEdge(ctx); - this.drawBottomEdge(ctx); - this.drawRightEdge(ctx); -}; - -CSlotMorph.prototype.outlinePath = function (ctx, inset, offset) { - var ox = offset.x, - oy = offset.y, - radius = Math.max(this.corner - inset, 0); +CSlotMorph.prototype.fixHolesLayout = function () { +this.holes = [new Rectangle(this.inset, this.corner, +this.width(), (this.height() - this.corner))];}; + +CSlotMorph.prototype.drawEdges = function ( +ctx) {var shift = this.edge / 2, x = (this +).width() - this.corner, y = 0, indent = ( +x + this.corner * 2 + this.inset); (ctx +).lineWidth = this.edge; ctx.lineJoin = ( +'round'); ctx.lineCap = 'butt'; (ctx +).strokeStyle = this.cachedClrDark; ( +ctx).beginPath(); ctx.arc(x, y, (this +).corner - shift, radians(0), radians( +90)); x = this.inset; y = this.corner; +ctx.lineTo(x + (this.corner * 3) + ( +this.inset + this.dent), y - shift); +ctx.lineTo(x + this.inset + ((this +).corner * 2) + this.dent, y + ( +this.corner - shift)); ctx.lineTo( +x + this.inset + (this.corner * 2), +y + this.corner - shift); ctx.stroke( +); ctx.beginPath(); ctx.moveTo(x + (this +).corner + this.inset - shift, y - shift +); ctx.arc(this.corner + this.inset, +this.corner * 2, this.corner + shift, +radians(270), Math.PI, true); ctx.lineTo( +x - shift, this.height() - this.corner * 2 +); ctx.stroke(); ctx.strokeStyle = (this +).cachedClrBright; ctx.beginPath(); ctx.arc( +this.corner + this.inset, this.height() - ( +this.corner * 2), this.corner + shift, +Math.PI, Math.PI / 2, true); ctx.lineTo( +this.width() - this.corner, this.height( +) - this.corner + shift); ctx.stroke();}; + +CSlotMorph.prototype.outlinePath = function (ctx, +inset, offset) {var ox = offset.x, oy = (offset +).y, radius = Math.max(this.corner - inset, 0); // top corner: ctx.lineTo(this.width() + ox - inset, oy); @@ -10528,86 +9347,57 @@ InputSlotMorph.uber = ArgMorph.prototype; // InputSlotMorph instance creation: -function InputSlotMorph(text, isNumeric, choiceDict, isReadOnly) { - this.init(text, isNumeric, choiceDict, isReadOnly); -} +function InputSlotMorph(text, isNumeric, +choiceDict, isReadOnly) {this.init(text, +isNumeric, choiceDict, isReadOnly);}; InputSlotMorph.prototype.init = function ( - text, - isNumeric, - choiceDict, - isReadOnly -) { - var contents = new InputSlotStringMorph(''), - arrow = new ArrowMorph( - 'down', - 0, - Math.max(Math.floor(this.fontSize / 6), 1), - BLACK, - true - ); - - contents.fontSize = this.fontSize; - contents.isShowingBlanks = asABool(localStorage['-snap-setting-isShowingBlanks']); - - this.selectedBlock = null; - this.symbol = null; - - this.isUnevaluated = false; - this.choices = choiceDict || null; - this.oldContentsExtent = contents.extent(); - this.isNumeric = isNumeric || false; - this.isReadOnly = isReadOnly || false; - this.minWidth = 0; // can be chaged for text-type inputs ("landscape") - this.constant = null; - this.onSetContents = null; - - InputSlotMorph.uber.init.call(this, null, true); - this.color = WHITE; - this.add(contents); - this.add(arrow); - contents.isEditable = true; - contents.isDraggable = false; - contents.enableSelecting(); - this.setContents(text); -}; +text, isNumeric, choiceDict, isReadOnly) { +var contents = new InputSlotStringMorph( +''), arrow = new ArrowMorph('down', 0, +Math.max(Math.floor(this.fontSize / 6), +1), BLACK, true); contents.fontSize = ( +this.fontSize); (contents.isShowingBlanks +) = asABool(localStorage[('-snap-setting' +) + '-isShowingBlanks']); this.symbol = ( +null); this.selectedBlock = null; (this +).oldContentsExtent = contents.extent(); +this.isUnevaluated = false; (this.choices +) = choiceDict || null; (this.isNumeric +) = isNumeric || false; (this.isReadOnly +) = isReadOnly || false; (this.minWidth +) = 0; this.onSetContents = null; (this +).constant = null; (InputSlotMorph.uber +).init.call(this, null, true); (this.color +) = WHITE; this.add(contents); this.add( +arrow); contents.isEditable = true; +contents.isDraggable = false; +contents.enableSelecting(); +this.setContents(text);}; // InputSlotMorph accessing: -InputSlotMorph.prototype.getSpec = function () { - if (this.isNumeric) { - return '%n'; - } - return '%s'; // default -}; +InputSlotMorph.prototype.getSpec = function ( +) {return (this.isNumeric ? '%n' : '%s');}; -InputSlotMorph.prototype.contents = function () { - return detect( - this.children, - child => child instanceof StringMorph - ); -}; +InputSlotMorph.prototype.contents = function ( +) {return detect(this.children, (child => ( +child instanceof StringMorph)));}; -InputSlotMorph.prototype.arrow = function () { - return detect( - this.children, - child => child instanceof ArrowMorph - ); -}; +InputSlotMorph.prototype.arrow = function ( +) {return detect(this.children, ((child +) => child instanceof ArrowMorph));}; InputSlotMorph.prototype.setContents = function (data) { // data can be a String, Float, or "wish" Block - var cnts = this.contents(), - dta = data, - isConstant = dta instanceof Array; + var cnts = this.contents(), dta = data, + isConstant = dta instanceof Array; if (this.selectedBlock) { - this.selectedBlock = null; - } - if (this.symbol) { - this.symbol.destroy(); - this.symbol = null; - } + this.selectedBlock = null; + }; if (this.symbol) { + this.symbol.destroy(); + this.symbol = null;}; if (isConstant) { dta = localize(dta[0]); @@ -10618,19 +9408,14 @@ InputSlotMorph.prototype.setContents = function (data) { } else { // assume dta is a localizable choice if it's a key in my choices cnts.isItalic = false; if (!isNil(this.choices) && this.choices[dta] instanceof Array) { - return this.setContents(this.choices[dta]); - } - } - cnts.text = dta; + return this.setContents(this.choices[dta]);};}; cnts.text = dta; if (isNil(dta)) { cnts.text = ''; } else if (dta.toString) { cnts.text = dta.toString(); - } - if (this.isReadOnly && !MorphicPreferences.isFlat) { + }; if (this.isReadOnly && !(MorphicPreferences.isFlat)) { cnts.shadowOffset = new Point(1, 1); // correct initial dimensions - } - cnts.fixLayout(); + }; cnts.fixLayout(); // remember the constant, if any this.constant = isConstant ? data : null; @@ -10638,13 +9423,12 @@ InputSlotMorph.prototype.setContents = function (data) { // adjust to zebra coloring: if (this.isReadOnly && (this.parent instanceof BlockMorph)) { this.parent.fixLabelColor(); - } + }; // run onSetContents if any if (this.onSetContents) { this[this.onSetContents](data); - } -}; + };}; InputSlotMorph.prototype.userSetContents = function (aStringOrFloat) { // enable copy-on-edit for inherited scripts @@ -10662,45 +9446,34 @@ InputSlotMorph.prototype.dropDownMenu = function (enableKeyboard) { var menu = this.menuFromDict(this.choices, false, enableKeyboard); if (!menu) { // has already happened return; - } - if (menu.items.length > 0) { + }; if (menu.items.length > 0) { if (enableKeyboard) { - menu.popup(this.world(), this.bottomLeft()); + menu.popup(world, this.bottomLeft()); menu.getFocus(); } else { - menu.popUpAtHand(this.world()); - } - } -}; + menu.popUpAtHand(world); + }; + };}; InputSlotMorph.prototype.menuFromDict = function ( choices, noEmptyOption, - enableKeyboard) -{ - var key, dial, flag, - myself = this, - selector, + enableKeyboard +) {var key, dial, flag, myself = this, selector, block = this.parentThatIsA(BlockMorph), ide = this.parentThatIsA(IDE_Morph), menu = new MenuMorph( - this.userSetContents, - null, - this, - this.fontSize - ); + this.userSetContents, + null, this, (this + ).fontSize); function update(num) { myself.setContents(num); myself.reactToSliderEdit(); if (ide && !block.isTemplate) { - ide.recordUnsavedChanges(); - } - } + ide.recordUnsavedChanges();};}; - function getImg(block) { - return () => block.fullImage(); - } + function getImg(block) {return (() => block.fullImage());}; menu.addItem(' ', null); if (choices instanceof Function) { @@ -10748,7 +9521,7 @@ InputSlotMorph.prototype.menuFromDict = function ( // appear when the user holds down the shift-key // use with care because mobile devices might only // have a "soft" keyboard that isn't always there - if (this.world().currentKey === 16) { // shift + if (world.currentKey === 16) { // shift menu.addItem( key.slice(2), choices[key], @@ -10884,8 +9657,7 @@ InputSlotMorph.prototype.keysMenu = function () { }; InputSlotMorph.prototype.messagesMenu = function (searching) { - if (searching) {return {}; } - + if (!searching) { var dict = {}, rcvr = this.parentThatIsA(BlockMorph).scriptTarget(), stage = rcvr.parentThatIsA(StageMorph), @@ -10894,15 +9666,12 @@ InputSlotMorph.prototype.messagesMenu = function (searching) { stage.children.concat(stage).forEach(morph => { if (isSnapObject(morph)) { allNames = allNames.concat(morph.allMessageNames()); - } - }); - allNames.sort().forEach(name => - dict[name] = name - ); + }; + }); allNames.sort().forEach( + name => dict[name] = name); if (allNames.length > 0) { dict['~'] = null; - } - dict['new...'] = () => + }; dict['new...'] = () => new DialogBoxMorph( this, this.setContents, @@ -10910,10 +9679,9 @@ InputSlotMorph.prototype.messagesMenu = function (searching) { ).prompt( 'Message name', null, - this.world() + world ); - return dict; -}; + return dict;};}; InputSlotMorph.prototype.messagesReceivedMenu = function (searching) { var dict = {'any message': ['any message']}, @@ -10946,7 +9714,7 @@ InputSlotMorph.prototype.messagesReceivedMenu = function (searching) { ).prompt( 'Message name', null, - this.world() + world ); return dict; }; @@ -11134,36 +9902,32 @@ dict['brightness effect'] = ['brightness effect']; dict['color effect'] = ['colo ] = null; dict['pen RGBA'] = ['pen RGBA']; dict['pen down?'] = ['pen down?']; dict['pen size'] = ['pen size']; dict['~5'] = null; if (nest) {dict.anchor = ['anchor'];}; if (oop) {dict.children = ['children']; dict.parent = ['parent'];}; if (nest) {dict.parts = ['parts'];}; return dict;}; -InputSlotMorph.prototype.myPropertiesMenu = function () {var dict = {}; - dict.neighbors = ['neighbors']; - dict.self = ['self']; - dict['other sprites'] = ['other sprites']; - dict.clones = ['clones']; - dict['other clones'] = ['other clones']; - dict.stage = ['stage']; - if (StageMorph.prototype.enableInheritance) {dict['temporary?'] = ['temporary?'];}; - dict['current costume'] = ['current costume']; - dict.scripts = ['scripts']; - dict.blocks = ['blocks']; - dict['dangling?'] = ['dangling?']; - dict.width = ['width']; - dict.height = ['height']; - dict.left = ['left']; - dict.right = ['right']; - dict.top = ['top']; - dict.bottom = ['bottom']; - dict['rotation x'] = ['rotation x']; - dict['rotation y'] = ['rotation y']; - dict['center x'] = ['center x']; - dict['center y'] = ['center y']; - return dict; -}; - -InputSlotMorph.prototype.scriptsMenu = function anonymous () {var dict = {}, root = this.parentThatIsA(HatBlockMorph); if (this.parent) {var scripts = world.children[0].currentSprite.scripts.children; var i = 0; +InputSlotMorph.prototype.myPropertiesMenu = function ( +) {var dict = {}; dict.neighbors = ['neighbors']; +dict.self = ['self']; dict['other sprites'] = [ +'other sprites']; dict.clones = ['clones']; +dict['other clones'] = ['other clones']; +dict.stage = ['stage']; if ((StageMorph +).prototype.enableInheritance) {dict[ +'temporary?'] = ['temporary?'];}; dict[ +'current costume'] = ['current costume' +]; dict.scripts = ['scripts']; (dict +).blocks = ['blocks']; dict['dangling?' +] = ['dangling?']; dict.width = ['width' +]; dict.height = ['height']; (dict.left +) = ['left']; dict.right = ['right']; +dict.top = ['top']; dict.bottom = [ +'bottom']; dict['rotation x'] = [ +'rotation x']; dict['rotation y' +] = ['rotation y']; dict['center x' +] = ['center x']; dict['center y' +] = ['center y']; return dict;}; + +InputSlotMorph.prototype.scriptsMenu = function () {var dict = {}, root = this.parentThatIsA(HatBlockMorph); if (this.parent) {var scripts = world.children[0].currentSprite.scripts.children; var i = 0; while (i < scripts.length) {if (((scripts[i] instanceof HatBlockMorph) || (scripts[i] instanceof DefinitorBlockMorph)) && !(scripts[i] === root)) {dict['§_def' + i] = scripts[i];}; i++;};}; return dict;}; -InputSlotMorph.prototype.constantsMenu = function anonymous () {var dict = {}, ide = world.childThatIsA(IDE_Morph -); if (ide instanceof IDE_Morph) {ide.mathConstants().forEach(con => {dict[con[0]] = con[0];});}; return dict;}; +InputSlotMorph.prototype.constantsMenu = function () {var dict = {}, ide = world.childThatIsA(IDE_Morph); +if (ide instanceof IDE_Morph) {ide.mathConstants().forEach(con => {dict[con[0]] = con[0];});}; return dict;}; InputSlotMorph.prototype.attributesMenu = function anonymous ( searching) {var dict = { @@ -11205,8 +9969,7 @@ searching) {var dict = { stage.children, morph => morph.name === objName ); - }; - if (obj instanceof StageMorph) { + }; if (obj instanceof StageMorph) { dict = { 'costume #' : ['costume #'], 'costume name' : ['costume name'], @@ -11219,8 +9982,7 @@ searching) {var dict = { 'top' : ['top'], 'bottom' : ['bottom'] }; - }; - dict['~'] = null; + }; dict['~'] = null; dict.variables = ['variables']; if (obj) { varNames = obj.variables.names(); @@ -11228,13 +9990,9 @@ searching) {var dict = { varNames.forEach(name => dict[name] = name ); - }; - obj.allBlocks(true).forEach((def, i) => + }; obj.allBlocks(true).forEach((def, i) => dict['§_def' + i] = def.blockInstance(true) // include translations - ); - }; - return dict; -}; + );}; return dict;}; InputSlotMorph.prototype.costumesMenu = function (searching) { if (searching) {return {};}; @@ -11248,22 +10006,16 @@ InputSlotMorph.prototype.costumesMenu = function (searching) { dict = {Empty : ['Empty']}; } else { dict = {Turtle : ['Turtle']}; - }; - } else {dict = {};}; + };} else {dict = {};}; if (!contains(['doSwitchToCostume', 'doSwitchToBackground'], block.selector)) { dict.current = ['current']; - } - rcvr.costumes.asArray().forEach(costume => + }; rcvr.costumes.asArray().forEach(costume => allNames = allNames.concat(costume.name) - ); - if (allNames.length > 0) { + ); if (allNames.length > 0) { dict['~'] = null; allNames.forEach(name => dict[name] = name - ); - } - return dict; -}; + );}; return dict;}; InputSlotMorph.prototype.soundsMenu = function (searching) { if (searching) {return {}; } @@ -11274,23 +10026,17 @@ InputSlotMorph.prototype.soundsMenu = function (searching) { rcvr.sounds.asArray().forEach(sound => allNames = allNames.concat(sound.name) - ); - if (allNames.length > 0) { + ); if (allNames.length > 0) { allNames.sort().forEach(name => dict[name] = name ); - } - return dict; -}; + }; return dict;}; InputSlotMorph.prototype.shadowedVariablesMenu = function (searching) { - if (searching) {return {}; } + if (searching) {return {};}; - var block = this.parentThatIsA(BlockMorph), - vars, - attribs, - rcvr, - dict = {}; + var block = this.parentThatIsA(BlockMorph + ), vars, attribs, rcvr, dict = {}; if (!block) {return dict; } rcvr = block.scriptTarget(); @@ -11320,100 +10066,70 @@ InputSlotMorph.prototype.shadowedVariablesMenu = function (searching) { attribs = rcvr.shadowedAttributes(); /* if (vars.length && attribs.length) { - dict['~'] = null; // add line - } - */ - attribs.forEach(name => - dict[name] = [name] - ); - } - return dict; -}; - -InputSlotMorph.prototype.speakingPitchMenu = function anonymous (searching) { -if (searching) {return {};}; var dict = {}; dict[localize('alto')] = localize( -'alto'); dict[localize('tenor')] = localize('tenor'); dict[localize('squeak') -] = localize('squeak'); dict[localize('giant')] = localize('giant'); dict[ -localize('kitten')] = localize('kitten'); return dict;}; - -InputSlotMorph.prototype.speakingSpeedMenu = function anonymous (searching) { -if (searching) {return {};}; var dict = {}; dict[localize('very fast')] = localize( -'very fast'); dict[localize('fast')] = localize('fast'); dict[localize('normal') -] = localize('normal'); dict[localize('slow')] = localize('slow'); dict[ + dict['~'] = null; // add line + } + */ + attribs.forEach(name => + dict[name] = [name] + );}; return dict;}; + +InputSlotMorph.prototype.speakingPitchMenu = function (searching) { +if (searching) {return {};}; var dict = {}; dict[localize('alto') +] = localize('alto'); dict[localize('tenor')] = localize('tenor' +); dict[localize('squeak')] = localize('squeak'); dict[localize( +'giant')] = localize('giant'); dict[localize('kitten' +)] = localize('kitten'); return dict;}; + +InputSlotMorph.prototype.speakingSpeedMenu = function (searching +) {if (searching) {return {};}; var dict = {}; dict[localize( +'very fast')] = localize('very fast'); dict[localize('fast') +] = localize('fast'); dict[localize('normal')] = localize( +'normal'); dict[localize('slow')] = localize('slow'); dict[ localize('very slow')] = localize('very slow'); return dict;}; -InputSlotMorph.prototype.speakingLanguageMenu = function anonymous (searching) { -if (searching) {return {};}; var dict = {}; -dict[localize('Arabic')] = localize('Arabic'); -dict[localize('Chinese \(Mandarin\)')] = localize('Chinese \(Mandarin\)'); -dict[localize('Danish')] = localize('Danish'); -dict[localize('Dutch')] = localize('Dutch'); -dict[localize('English')] = localize('English'); -dict[localize('English \(United States\)')] = localize('English \(United States\)'); -dict[localize('French')] = localize('French'); -dict[localize('German')] = localize('German'); -dict[localize('Greek')] = localize('Greek'); -dict[localize('Hindi')] = localize('Hindi'); -dict[localize('Icelandic')] = localize('Icelandic'); -dict[localize('Italian')] = localize('Italian'); -dict[localize('Japanese')] = localize('Japanese'); -dict[localize('Korean')] = localize('Korean'); -dict[localize('Norwegian')] = localize('Norwegian'); -dict[localize('Polish')] = localize('Polish'); -dict[localize('Portuguese')] = localize('Portuguese'); -dict[localize('Portuguese \(Brazilian\)')] = localize('Portuguese \(Brazilian\)'); -dict[localize('Romanian')] = localize('Romanian'); -dict[localize('Russian')] = localize('Russian'); -dict[localize('Spanish')] = localize('Spanish'); -dict[localize('Spanish \(Latin American\)')] = localize('Spanish \(Latin American\)'); -dict[localize('Swedish')] = localize('Swedish'); -dict[localize('Turkish')] = localize('Turkish'); -dict[localize('Welsh')] = localize('Welsh'); -return dict;}; - -InputSlotMorph.prototype.pianoKeyboardMenu = function (searching) { - if (searching) {return {}; } - - var menu, block, instrument; - block = this.parentThatIsA(BlockMorph); - if (block) { - instrument = block.scriptTarget().instrument; - } - menu = new PianoMenuMorph( - this.setContents, - this, - this.fontSize, - instrument - ); - menu.popup(this.world(), new Point( - this.right() - (menu.width() / 2), - this.bottom() - )); - menu.selectKey(+this.evaluate()); -}; - -InputSlotMorph.prototype.directionDialMenu = function anonymous ( -searching) {return (searching ? {} : {'§_dir': null});}; - -InputSlotMorph.prototype.audioMenu = function (searching) { - var dict = { - 'volume' : ['volume'], - 'note' : ['note'], - 'frequency' : ['frequency'], - 'samples' : ['samples'], - 'sample rate' : ['sample rate'], - 'spectrum' : ['spectrum'], - 'resolution' : ['resolution'] - }; - if (searching) {return dict; } - - if (this.world().currentKey === 16) { // shift - dict['~'] = null; - dict.modifier = ['modifier']; - dict.output = ['output']; - } - return dict; -}; +InputSlotMorph.prototype.speakingLanguageMenu = function (searching) { +var dict = {}; dict[localize('Arabic')] = localize('Arabic'); dict[ +localize('Chinese \(Mandarin\)')] = localize('Chinese \(Mandarin\)'); +dict[localize('Danish')] = localize('Danish'); dict[localize('Dutch') +] = localize('Dutch'); dict[localize('English')] = localize('English'); +dict[localize('English \(United States\)')] = localize('English ' + ( +'\(United States\)')); dict[localize('French')] = localize('French'); +dict[localize('German')] = localize('German'); dict[localize('Greek') +] = localize('Greek'); dict[localize('Hindi')] = localize('Hindi'); +dict[localize('Icelandic')] = localize('Icelandic'); dict[localize( +'Italian')] = localize('Italian'); dict[localize('Japanese')] = ( +localize('Japanese')); dict[localize('Korean')] = localize('Korean'); +dict[localize('Norwegian')] = localize('Norwegian'); dict[localize( +'Polish')] = localize('Polish'); dict[localize('Portuguese')] = ( +localize('Portuguese')); dict[localize('Portuguese \(Brazilian\)' +)] = localize('Portuguese \(Brazilian\)'); dict[localize('Romanian' +)] = localize('Romanian'); dict[localize('Russian')] = localize( +'Russian'); dict[localize('Spanish')] = localize('Spanish'); dict[ +localize('Spanish \(Latin American\)')] = localize(('Spanish \(' +) + 'Latin American\)'); dict[localize('Swedish')] = localize( +'Swedish'); dict[localize('Turkish')] = localize('Turkish' +); dict[localize('Welsh')] = localize('Welsh'); +return (searching ? dict : {});}; + +InputSlotMorph.prototype.pianoKeyboardMenu = function (searching +) {if (searching) {return {};}; var instrument, menu, block = ( +this.parentThatIsA(BlockMorph)); if (block) {instrument = ( +block.scriptTarget()).instrument;}; menu = new PianoMenuMorph( +this.setContents, this, this.fontSize, instrument); menu.popup( +world, new Point((this.right() - (menu.width() / 2)), (this +).bottom())); menu.selectKey(+(this.evaluate()));}; + +InputSlotMorph.prototype.directionDialMenu = ( +searching => (searching ? {} : {'§_dir': null})); + +InputSlotMorph.prototype.audioMenu = function (searching +) {var dict = {'volume' : ['volume'], 'note' : ['note'], +'frequency' : ['frequency'], 'samples' : ['samples'], +'sample rate' : ['sample rate'], 'spectrum' : ['spectrum' +], 'resolution' : ['resolution']}; if (searching) { +return dict;}; if (world.currentKey === 16) {dict[ +'~'] = null; dict.modifier = ['modifier']; +dict.output = ['output'];}; return dict;}; InputSlotMorph.prototype.scenesMenu = function (searching) { var dict = {}, @@ -11424,18 +10140,16 @@ InputSlotMorph.prototype.scenesMenu = function (searching) { scenes.itemsArray().forEach(scn => { if (scn.name) { dict[scn.name] = scn.name; - } + }; }); - } - } - dict['~'] = null; + }; + }; dict['~'] = null; dict.next = ['next']; dict.previous = ['previous']; // dict['1 '] = 1; // trailing space needed to prevent undesired sorting // dict.last = ['last']; dict.random = ['random']; - return dict; -}; + return dict;}; InputSlotMorph.prototype.setChoices = function (dict, readonly, static) { // externally specify choices, read-only status and static, @@ -11450,10 +10164,8 @@ InputSlotMorph.prototype.setChoices = function (dict, readonly, static) { cnts.shadowOffset = ZERO; cnts.shadowColor = null; cnts.setColor(BLACK); - } - } - this.fixLayout(); -}; + }; + }; this.fixLayout();}; // InputSlotMorph layout: @@ -11472,12 +10184,12 @@ InputSlotMorph.prototype.fixLayout = function () { } else { contents.enableSelecting(); contents.color = BLACK; - }; if (this.choices) { + }; if (this.choices) { arrow.setSize(this.fontSize); arrow.show(); } else { arrow.hide(); - }; arrowWidth = arrow.isVisible ? arrow.width() : 0; + }; arrowWidth = arrow.isVisible ? arrow.width() : 0; // determine slot dimensions if (this.selectedBlock) { // a "wish" in the OF-block's left slot @@ -11514,7 +10226,7 @@ InputSlotMorph.prototype.fixLayout = function () { this.minWidth // for text-type slots ); }; - }; this.bounds.setExtent(new Point(width, height)); + }; this.bounds.setExtent(new Point(width, height)); if (this.isNumeric) { contents.setPosition(new Point( @@ -11539,8 +10251,7 @@ InputSlotMorph.prototype.fixLayout = function () { this.cursorStyle = 'default'; } else { this.cursorStyle = 'text'; - }; -}; + };}; // InputSlotMorph events: @@ -11550,8 +10261,7 @@ InputSlotMorph.prototype.mouseDownLeft = function (pos) { this.escalateEvent('mouseDownLeft', pos); } else { this.selectForEdit().contents().edit(); - } -}; + };}; InputSlotMorph.prototype.mouseClickLeft = function (pos) { if (this.arrow().bounds.containsPoint(pos)) { @@ -11560,53 +10270,30 @@ InputSlotMorph.prototype.mouseClickLeft = function (pos) { this.dropDownMenu(); } else { this.contents().edit(); - } -}; + };}; -InputSlotMorph.prototype.reactToKeystroke = function () { - var cnts; - if (this.constant) { - cnts = this.contents(); - this.constant = null; - cnts.isItalic = false; - cnts.rerender(); - } -}; +InputSlotMorph.prototype.reactToKeystroke = ( +function () {var cnts; if (this.constant) { +cnts = this.contents(); this.constant = null; +cnts.isItalic = false; cnts.rerender();};}); InputSlotMorph.prototype.reactToEdit = function () { - var block = this.parentThatIsA(BlockMorph), - ide = this.parentThatIsA(IDE_Morph); - this.contents().clearSelection(); - if (ide && !block.isTemplate) { - ide.recordUnsavedChanges(); - } -}; +var block = this.parentThatIsA(BlockMorph), ide = ( +this.parentThatIsA(IDE_Morph)); (this.contents() +).clearSelection(); if (ide && !(block.isTemplate +)) {ide.recordUnsavedChanges();};}; -InputSlotMorph.prototype.freshTextEdit = function (aStringOrTextMorph) { - this.onNextStep = () => aStringOrTextMorph.selectAll(); -}; +InputSlotMorph.prototype.freshTextEdit = function (aStringOrTextMorph +) {this.onNextStep = (() => aStringOrTextMorph.selectAll());}; // InputSlotMorph menu: InputSlotMorph.prototype.slotMenu = function () { - var menu; - if (StageMorph.prototype.enableCodeMapping) { - menu = new MenuMorph(this); - if (this.isNumeric) { - menu.addItem( - 'code number mapping...', - 'mapNumberToCode' - ); - } else { - menu.addItem( - 'code string mapping...', - 'mapStringToCode' - ); - } - return menu; - } - return null; -}; +var menu; if (StageMorph.prototype.enableCodeMapping +) {menu = new MenuMorph(this); if (this.isNumeric) { +menu.addItem('code number mapping...', 'mapNumberToCode' +);} else {menu.addItem('code string mapping...', +'mapStringToCode');}; return menu;}; return null;}; // InputSlotMorph reacting to user choices @@ -11618,396 +10305,170 @@ InputSlotMorph.prototype.slotMenu = function () { */ InputSlotMorph.prototype.updateEventUpvar = function (data) { - // assumes a second multi-arg input slot to my right that is - // either shown or hidden and collapsed based on whether - // "any ..." is selected as choice. - - var trg = this.parent.inputs()[1]; - if (data instanceof Array && data[0].indexOf('any') === 0) { - trg.show(); - } else { - trg.removeInput(); - trg.hide(); - } - this.parent.fixLayout(); -}; - +var trg = (this.parent.inputs())[1]; if ((data instanceof Array +) && data[0].indexOf('any') === 0) {trg.show();} else {(trg +).removeInput(); trg.hide();}; this.parent.fixLayout();}; // InputSlotMorph 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 -*/ - -InputSlotMorph.prototype.mapStringToCode = function () { - // private - open a dialog box letting the user map code via the GUI - new DialogBoxMorph( - this, - code => StageMorph.prototype.codeMappings.string = code, - this - ).promptCode( - 'Code mapping - String <#1>', - StageMorph.prototype.codeMappings.string || '', - this.world() - ); -}; - -InputSlotMorph.prototype.mapNumberToCode = function () { - // private - open a dialog box letting the user map code via the GUI - new DialogBoxMorph( - this, - 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; - - if (this.isNumeric) { - code = StageMorph.prototype.codeMappings.number || '<#1>'; - return code.replace(/<#1>/g, val); - } - if (!isNaN(parseFloat(val))) {return val; } - if (!isString(val)) {return val; } - if (block && contains( - ['doSetVar', 'doChangeVar', 'doShowVar', 'doHideVar'], - block.selector - )) { - return val; - } - code = StageMorph.prototype.codeMappings.string || '<#1>'; - return code.replace(/<#1>/g, val); -}; - -// InputSlotMorph evaluating: - -InputSlotMorph.prototype.evaluate = function () { -/* - answer my contents, which can be a "wish", i.e. a block that refers to - another sprite's local method, or a text string. If I am numerical convert - that string to a number. If the conversion fails answer the string - (e.g. for special choices like 'any', 'all' or 'last') otherwise - the numerical value. -*/ - var num, contents; - - if (this.selectedBlock) { - return this.selectedBlock; - } - if (this.symbol) { - if (this.symbol.name === 'flag') { - return ['__shout__go__']; - } - return ''; - } - if (this.constant) { - return this.constant; - } - contents = this.contents(); - if (this.isNumeric) { - num = parseFloat(contents.text || '0'); - if (!isNaN(num)) { - return num; - } - } - return contents.text; -}; - -InputSlotMorph.prototype.isEmptySlot = function () { - return this.contents().text === '' && !this.selectedBlock && !this.symbol; -}; - -// InputSlotMorph single-stepping: - -InputSlotMorph.prototype.flash = function () { - // don't redraw the label b/c zebra coloring - if (!this.cachedNormalColor) { - this.cachedNormalColor = this.color; - this.color = this.activeHighlight; - this.rerender(); - } -}; - -InputSlotMorph.prototype.unflash = function () { - // don't redraw the label b/c zebra coloring - if (this.cachedNormalColor) { - var clr = this.cachedNormalColor; - this.cachedNormalColor = null; - this.color = clr; - this.rerender(); - } -}; - -// InputSlotMorph drawing: - -InputSlotMorph.prototype.render = function (ctx) { - var borderColor, r; - - // initialize my surface property - if (this.cachedNormalColor) { // if flashing - borderColor = this.color; - } else if (this.parent) { - borderColor = this.parent.color; - } else { - borderColor = new Color(120, 120, 120); - } - ctx.fillStyle = this.color.toString(); - if (this.isReadOnly && !this.cachedNormalColor) { // unless flashing - ctx.fillStyle = borderColor.darker().toString(); - } - - // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast) - .toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - - if (!this.isNumeric) { - ctx.fillRect( - this.edge, - this.edge, - this.width() - this.edge * 2, - this.height() - this.edge * 2 - ); - if (!MorphicPreferences.isFlat) { - this.drawRectBorder(ctx); - } - } else { - r = Math.max((this.height() - (this.edge * 2)) / 2, 0); - ctx.beginPath(); - ctx.arc( - r + this.edge, - r + this.edge, - r, - radians(90), - radians(-90), - false - ); - ctx.arc( - this.width() - r - this.edge, - r + this.edge, - r, - radians(-90), - radians(90), - false - ); - ctx.closePath(); - ctx.fill(); - if (!MorphicPreferences.isFlat) { - this.drawRoundBorder(ctx); - } - } - - // draw my "wish" block, if any - if (this.selectedBlock) { - ctx.drawImage( - this.doWithAlpha(1, () => this.selectedBlock.fullImage()), - this.edge + this.typeInPadding, - this.edge - ); - } -}; - -InputSlotMorph.prototype.drawRectBorder = function (ctx) { - var shift = this.edge * 0.5, - gradient; - - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - if (useBlurredShadows) { - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } - - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(this.edge, shift); - ctx.lineTo(this.width() - this.edge - shift, shift); - ctx.stroke(); - - ctx.shadowOffsetY = 0; - - gradient = ctx.createLinearGradient( - 0, - 0, - this.edge, - 0 - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, this.edge); - ctx.lineTo(shift, this.height() - this.edge - shift); - ctx.stroke(); - - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; - - gradient = ctx.createLinearGradient( - 0, - this.height() - this.edge, - 0, - this.height() - ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(this.edge, this.height() - shift); - ctx.lineTo(this.width() - this.edge, this.height() - shift); - ctx.stroke(); - - gradient = ctx.createLinearGradient( - this.width() - this.edge, - 0, - this.width(), - 0 - ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(this.width() - shift, this.edge); - ctx.lineTo(this.width() - shift, this.height() - this.edge); - ctx.stroke(); - -}; - -InputSlotMorph.prototype.drawRoundBorder = function (ctx) { - var shift = this.edge * 0.5, - r = Math.max((this.height() - (this.edge * 2)) / 2, 0), - start, - end, - gradient; +/* + 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 +*/ - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; +InputSlotMorph.prototype.mapStringToCode = function () { +(new DialogBoxMorph(this, code => (StageMorph.prototype +).codeMappings.string = code, this)).promptCode( +'Code mapping - String <#1>', (StageMorph +).prototype.codeMappings.string || '', world);}; - // straight top edge: - start = r + this.edge; - end = this.width() - r - this.edge; - if (end > start) { +InputSlotMorph.prototype.mapNumberToCode = function () { +(new DialogBoxMorph(this, code => (StageMorph.prototype +).codeMappings.number = code, this)).promptCode( +'Code mapping - Number <#1>', (StageMorph +).prototype.codeMappings.number || '', world);}; + +InputSlotMorph.prototype.mappedCode = function ( +) {var block = this.parentThatIsA(BlockMorph), +val = this.evaluate(), code; if (this.isNumeric +) {code = ((StageMorph.prototype.codeMappings +).number || '<#1>'); return code.replace(/<#1>/g, +val);}; if (!isNaN(parseFloat(val))) {return val; +}; if (!isString(val)) {return val;}; if ((block +) && contains(['doSetVar', 'doChangeVar', +'doShowVar', 'doHideVar'], block.selector)) { +return val;}; code = ((StageMorph.prototype +).codeMappings.string || '<#1>'); return ( +code.replace(/<#1>/g, val));}; - if (useBlurredShadows) { - ctx.shadowOffsetX = shift; - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } +// InputSlotMorph evaluating: - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - ctx.strokeStyle = gradient; - ctx.beginPath(); +InputSlotMorph.prototype.evaluate = function ( +) {var num, contents; if (this.selectedBlock) { +return this.selectedBlock;}; if (this.symbol +) {if (this.symbol.name === 'flag') {return [ +'__shout__go__'];}; return '';}; if ( +this.constant) {return this.constant;}; +contents = this.contents(); if ((this +).isNumeric) {num = asANum((contents +).text);}; return contents.text;}; - ctx.moveTo(start, shift); - ctx.lineTo(end, shift); - ctx.stroke(); +InputSlotMorph.prototype.isEmptySlot = function () {return ((this +).contents().text === '' && !(this.selectedBlock) && !(this.symbol));}; - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; - } +// InputSlotMorph single-stepping: - // straight bottom edge: - gradient = ctx.createLinearGradient( - 0, - this.height() - this.edge, - 0, - this.height() - ); - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r + this.edge, this.height() - shift); - ctx.lineTo(this.width() - r - this.edge, this.height() - shift); - ctx.stroke(); +InputSlotMorph.prototype.unflash = function () { +if (this.cachedNormalColor) {var clr = (this +).cachedNormalColor; this.color = clr; (this +).cachedNormalColor = null; this.rerender();}; +}; InputSlotMorph.prototype.flash = function ( +) {if (!(this.cachedNormalColor)) {(this.color +) = this.activeHighlight; (this.cachedNormalColor +) = this.color; this.rerender();};}; - r = Math.max(this.height() / 2, this.edge); +// InputSlotMorph drawing: - if (useBlurredShadows) { - ctx.shadowOffsetX = shift; - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } +InputSlotMorph.prototype.render = function (ctx) { + var borderColor; - // top edge: left corner - gradient = ctx.createRadialGradient( - r, - r, - r - this.edge, - r, - r, - r - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrDark); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - r, - r, - r - shift, - radians(180), - radians(270), - false - ); ctx.stroke(); - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; + // initialize my surface property + if (this.cachedNormalColor) { + borderColor = this.color; + } else if (this.parent) { + borderColor = this.parent.color; + } else { + borderColor = new Color(120, 120, 120 + );}; ctx.fillStyle = this.color.toString(); + if (this.isReadOnly && !this.cachedNormalColor) { + if (MorphicPreferences.isFlat) {(ctx.fillStyle + ) = borderColor.darker().toString();} else { + var gradient = ctx.createLinearGradient(0, 0, + 0, this.height()); gradient.addColorStop(0, + borderColor.darker().toString()); (gradient + ).addColorStop(1, (borderColor.darker( + ).darker()).toString()); (ctx.fillStyle + ) = gradient;};}; this.cachedClr = ( + borderColor.toString()); (this.cachedClrBright + ) = borderColor.lighter(this.contrast).toString( + ); this.cachedClrDark = borderColor.darker( + this.contrast).toString(); - // bottom edge: right corner - gradient = ctx.createRadialGradient( - this.width() - r, - r, - r - this.edge, - this.width() - r, - r, - r - ); gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - this.width() - r, - r, - r - shift, - radians(0), - radians(90), - false - ); ctx.stroke(); -}; + if (this.isNumeric) { + var r = Math.max((this.height() - (this.edge * 2)) / 2, 0); + ctx.beginPath(); + ctx.arc( + r + this.edge, + r + this.edge, + r, + Math.PI / 2, + Math.PI / -2, + false + ); ctx.arc( + this.width() - r - this.edge, + r + this.edge, + r, + Math.PI / -2, + Math.PI / 2, + false + ); ctx.closePath(); + ctx.fill(); + if (!(MorphicPreferences.isFlat)) { + this.drawRoundBorder(ctx, borderColor); + }; + } else { + ctx.fillRect( + this.edge, + this.edge, + this.width() - this.edge * 2, + this.height() - this.edge * 2 + ); if (!(MorphicPreferences.isFlat)) { + this.drawRectBorder(ctx, borderColor);}; + }; // draw my "wish" block, if any + if (this.selectedBlock) { + ctx.drawImage( + this.doWithAlpha(1, + () => this.selectedBlock.fullImage()), + this.edge + this.typeInPadding, + this.edge);};}; + +InputSlotMorph.prototype.drawRoundBorder = function (ctx, +borderColor) {var shift = this.edge / 2, r = Math.max(( +this.height() - (this.edge * 2)) / 2, 0); ctx.lineCap = ( +'round'); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; +if (useBlurredShadows) {ctx.shadowOffsetX = shift; (ctx +).shadowOffsetY = shift; ctx.shadowBlur = this.edge; +ctx.shadowColor = (this.color.darker(80).withAlpha( +1/2)).toString();}; ctx.strokeStyle = ((borderColor +).darker(this.contrast).withAlpha(1/2)).toString(); +ctx.beginPath(); ctx.lineTo(shift, this.height() - ( +r + this.edge)); ctx.arc(r, r, r - shift, Math.PI, +Math.PI / -2, false); ctx.lineTo(this.width() - ( +r + this.edge), shift); ctx.stroke(); r = Math.max( +this.height() / 2, this.edge); (ctx.shadowOffsetX +) = 0; ctx.shadowOffsetY = 0; ctx.shadowBlur = 0; +ctx.strokeStyle = (borderColor.lighter(this.contrast +).withAlpha(1/2)).toString(); ctx.beginPath(); (ctx +).arc(this.width() - r, r, r - shift, 0, Math.PI / 2, +false); ctx.lineTo(r, this.height() - shift); (ctx +).stroke();}; (InputSlotMorph.prototype.drawRectBorder +) = function (ctx, borderColor) {var shift = ((this.edge +) / 2); ctx.lineJoin = 'round'; ctx.lineWidth = this.edge; +if (useBlurredShadows) {ctx.shadowOffsetX = shift; (ctx +).shadowOffsetY = shift; ctx.shadowBlur = this.edge; +ctx.shadowColor = (this.color.darker(80).withAlpha( +1/2)).toString();}; ctx.strokeStyle = ((borderColor +).darker(this.contrast).withAlpha(1/2)).toString(); +ctx.lineCap = 'butt'; ctx.beginPath(); ctx.moveTo( +this.width() - this.edge, shift); ctx.lineTo(shift, +shift); ctx.lineTo(shift, this.height() - this.edge); +ctx.stroke(); ctx.shadowBlur = 0; ctx.shadowOffsetX = 0; +ctx.shadowOffsetY = 0; ctx.strokeStyle = ((borderColor +).lighter(this.contrast).withAlpha(1/2)).toString(); +ctx.beginPath(); ctx.moveTo(0, this.height() - shift); +ctx.lineTo(this.width() - shift, this.height() - shift +); ctx.lineTo(this.width() - shift, 0); ctx.stroke();}; // InputSlotStringMorph /////////////////////////////////////////////// @@ -12091,10 +10552,10 @@ function InputSlotTextMorph( shadowOffset, shadowColor ); -}; InputSlotTextMorph.prototype.getRenderColor = - InputSlotStringMorph.prototype.getRenderColor; - InputSlotTextMorph.prototype.getShadowRenderColor = - InputSlotStringMorph.prototype.getShadowRenderColor; +}; InputSlotTextMorph.prototype.getRenderColor = ( + InputSlotStringMorph.prototype.getRenderColor); + InputSlotTextMorph.prototype.getShadowRenderColor = ( + InputSlotStringMorph.prototype.getShadowRenderColor); // TemplateSlotMorph /////////////////////////////////////////////////// @@ -12115,16 +10576,16 @@ TemplateSlotMorph.uber = ArgMorph.prototype; // TemplateSlotMorph instance creation: -function TemplateSlotMorph(name) {this.init(name);}; +function TemplateSlotMorph (name) {this.init(name);}; -TemplateSlotMorph.prototype.init = function (name) {var template = new ReporterBlockMorph; this.labelString = name || ''; template.isDraggable = false; template.isTemplate = true; -template.color = SpriteMorph.prototype.blockColor.variables; template.category = 'variables'; template.setSpec(this.labelString); template.selector = 'reportGetVar'; +TemplateSlotMorph.prototype.init = function (name) {var template = new ReporterBlockMorph; this.labelString = name || ''; template.isDraggable = false; (template.isTemplate +) = true; template.color = SpriteMorph.prototype.blockColor.variables; template.category = 'variables'; template.setSpec(this.labelString); template.selector = 'reportGetVar'; TemplateSlotMorph.uber.init.call(this); this.add(template); this.fixLayout(); this.isDraggable = false; this.isStatic = true; template.cursorStyle = 'pointer';}; // TemplateSlotMorph accessing: TemplateSlotMorph.prototype.getSpec = (() => '%t'); TemplateSlotMorph.prototype.template = function () { -return this.children[0];}; TemplateSlotMorph.prototype.contents = function () {return this.template().blockSpec;}; +return this.children[0];}; TemplateSlotMorph.prototype.contents = function () {return (this.template()).blockSpec;}; TemplateSlotMorph.prototype.setContents = function (aString) {var tmp = this.template(); tmp.setSpec(( aString instanceof Array) ? localize(aString[0]) : aString); tmp.fixBlockColor(); tmp.fixLabelColor();}; @@ -12141,18 +10602,26 @@ if (this.parent) {if (this.parent.fixLayout) {this.parent.fixLayout();};};}; // TemplateSlotMorph drop behavior: -TemplateSlotMorph.prototype.wantsDropOf = function (aMorph) {return aMorph.selector === 'reportGetVar';}; -TemplateSlotMorph.prototype.reactToDropOf = function (droppedMorph) {if (droppedMorph.selector === 'reportGetVar') {droppedMorph.destroy();};}; +TemplateSlotMorph.prototype.wantsDropOf = function ( +aMorph) {return aMorph.selector === 'reportGetVar';}; +TemplateSlotMorph.prototype.reactToDropOf = function ( +droppedMorph) {if (droppedMorph.selector === ( +'reportGetVar')) {droppedMorph.destroy();};}; // TemplateSlotMorph drawing: -TemplateSlotMorph.prototype.render = function (ctx) {if (this.parent instanceof Morph) {this.color = this.parent.color.copy();}; BlockMorph.prototype.render.call(this, ctx);}; -TemplateSlotMorph.prototype.outlinePath = ReporterBlockMorph.prototype.outlinePathOval; TemplateSlotMorph.prototype.drawEdges = ReporterBlockMorph.prototype.drawEdgesOval; -TemplateSlotMorph.prototype.hasLocationPin = function () {return false;}; TemplateSlotMorph.prototype.cSlots = function anonymous () {return [];}; +TemplateSlotMorph.prototype.render = function (ctx) {if (this.parent instanceof Morph) { +this.color = this.parent.color.copy();}; BlockMorph.prototype.render.call(this, ctx);}; +TemplateSlotMorph.prototype.outlinePath = ReporterBlockMorph.prototype.outlinePathOval; +TemplateSlotMorph.prototype.drawEdges = ReporterBlockMorph.prototype.drawEdgesOval; +TemplateSlotMorph.prototype.hasLocationPin = function () {return false;}; +TemplateSlotMorph.prototype.cSlots = (() => []); (TemplateSlotMorph +).prototype.clearSlots = TemplateSlotMorph.prototype.cSlots; // TemplateSlotMorph single-stepping -TemplateSlotMorph.prototype.flash = function () {this.template().flash();}; TemplateSlotMorph.prototype.unflash = function () {this.template().unflash();}; +TemplateSlotMorph.prototype.flash = function () {(this.template()).flash();}; +TemplateSlotMorph.prototype.unflash = function () {(this.template()).unflash();}; // BooleanSlotMorph //////////////////////////////////////////////////// @@ -12188,49 +10657,43 @@ BooleanSlotMorph.prototype.isTernary = false; function BooleanSlotMorph(initialValue) {this.init(initialValue);} -BooleanSlotMorph.prototype.init = function (initialValue) { - this.value = ((typeof initialValue === 'boolean') ? initialValue : null); - this.isUnevaluated = false; this.progress = 0; BooleanSlotMorph.uber.init.call( - this); this.alpha = 1; this.fixLayout(); // progress for animation state, not persisted - this.cursorStyle = 'pointer'; -}; +BooleanSlotMorph.prototype.init = function (initialValue +) {this.value = ((typeof initialValue === 'boolean' +) ? initialValue : null); this.isUnevaluated = ( +false); this.progress = 0; (BooleanSlotMorph.uber +).init.call(this); this.alpha = 1; this.fixLayout( +); this.cursorStyle = 'pointer';}; BooleanSlotMorph.prototype.getSpec = function () { return (this.isUnevaluated ? '%boolUE' : '%b');}; // BooleanSlotMorph accessing: -BooleanSlotMorph.prototype.evaluate = function ( -) {return this.value;}; +BooleanSlotMorph.prototype.evaluate = ( +function () {return this.value;}); -BooleanSlotMorph.prototype.isEmptySlot = function ( -) {return this.value === null;}; +BooleanSlotMorph.prototype.isEmptySlot = ( +function () {return isNil(this.value);}); -BooleanSlotMorph.prototype.isBinary = function () { - return !this.isTernary && - isNil(this.parentThatIsA(RingMorph)) && - !isNil(this.parentThatIsA(ScriptsMorph)); -}; +BooleanSlotMorph.prototype.isBinary = function () {return ( +!(this.isTernary) && isNil(this.parentThatIsA(RingMorph +)) && !isNil(this.parentThatIsA(ScriptsMorph)));}; -BooleanSlotMorph.prototype.setContents = function (boolOrNull) { - this.value = (typeof boolOrNull === 'boolean') ? boolOrNull : null; - this.rerender(); -}; +BooleanSlotMorph.prototype.setContents = function ( +boolOrNull) {this.value = (typeof boolOrNull === ( +'boolean')) ? boolOrNull : null; this.rerender();}; -BooleanSlotMorph.prototype.toggleValue = function () { - var target = this.selectForEdit(), - block = this.parentThatIsA(BlockMorph), - ide; if (target !== this) { +BooleanSlotMorph.prototype.toggleValue = function ( + ) {var target = this.selectForEdit(), + block = this.parentThatIsA(BlockMorph + ), ide; if (target !== this) { return this.toggleValue.call(target); - }; ide = this.parentThatIsA(IDE_Morph); - this.value = this.nextValue(); - if (ide) { - if (!block.isTemplate) { - ide.recordUnsavedChanges(); - }; if (!ide.isAnimating) { - this.rerender(); - return; - }; + }; ide = this.parentThatIsA(IDE_Morph + ); this.value = this.nextValue(); + if (ide) {if (!block.isTemplate) { + ide.recordUnsavedChanges( + );}; if (!ide.isAnimating) { + this.rerender(); return;}; }; this.nextSteps([ () => { this.progress = 2; @@ -12267,20 +10730,11 @@ BooleanSlotMorph.prototype.toggleValue = function () { () => { this.progress = 0; this.rerender(); - }, - ]); -}; + },]);}; -BooleanSlotMorph.prototype.nextValue = function () { - switch (this.value) { - case true: - return false; - case false: - return null; - default: - return true; - }; -}; +BooleanSlotMorph.prototype.nextValue = function ( +) {switch (this.value) {case true: return false; +case false: return null; default: return true;};}; // BooleanSlotMorph events: @@ -12297,8 +10751,8 @@ BooleanSlotMorph.prototype.mouseLeave = function ( // BooleanSlotMorph menu: -BooleanSlotMorph.prototype.slotMenu = function () { - var menu; +BooleanSlotMorph.prototype.slotMenu = function ( +) {var menu; if (StageMorph.prototype.enableCodeMapping) { menu = new MenuMorph(this); if (this.evaluate() === true) { @@ -12311,11 +10765,8 @@ BooleanSlotMorph.prototype.slotMenu = function () { 'code false mapping...', 'mapFalseToCode' ); - } - return menu; - } - return null; -}; + }; return menu; + }; return null;}; // BooleanSlotMorph code mapping @@ -12327,36 +10778,33 @@ BooleanSlotMorph.prototype.slotMenu = function () { BooleanSlotMorph.prototype.mapTrueToCode = function () { // private - open a dialog box letting the user map code via the GUI - new DialogBoxMorph( + (new DialogBoxMorph( this, code => StageMorph.prototype.codeMappings['true'] = code, this - ).promptCode( + )).promptCode( 'Code mapping - true', StageMorph.prototype.codeMappings['true'] || 'true', - this.world() + world ); }; BooleanSlotMorph.prototype.mapFalseToCode = function () { // private - open a dialog box letting the user map code via the GUI - new DialogBoxMorph( + (new DialogBoxMorph( this, code => StageMorph.prototype.codeMappings['false'] = code, this - ).promptCode( + )).promptCode( 'Code mapping - false', StageMorph.prototype.codeMappings['false'] || 'false', - this.world() - ); -}; + world + );}; -BooleanSlotMorph.prototype.mappedCode = function () { - if (this.evaluate() === true) { - return StageMorph.prototype.codeMappings.boolTrue || 'true'; - } - return StageMorph.prototype.codeMappings.boolFalse || 'false'; -}; +BooleanSlotMorph.prototype.mappedCode = function ( +) {if (this.evaluate() === true) {return (StageMorph +).prototype.codeMappings.boolTrue || 'true';}; return ( +StageMorph.prototype.codeMappings.boolFalse || 'false');}; // BooleanSlotMorph layout: @@ -12366,177 +10814,71 @@ BooleanSlotMorph.prototype.fixLayout = function () { if (this.isStatic) { text = this.textLabelExtent(); h = text.y + (this.edge * 3); - this.bounds.setWidth(text.x + (h * 1.5) + (this.edge * 2)); + this.bounds.setWidth(text.x + (h * 3/2) + (this.edge * 2)); this.bounds.setHeight(h); } else { this.bounds.setWidth((this.fontSize + this.edge * 2) * 2); this.bounds.setHeight(this.fontSize + this.edge * 2); - }; -}; + };}; // BooleanSlotMorph drawing: BooleanSlotMorph.prototype.render = function (ctx) { if (!(this.cachedNormalColor)) { // unless flashing this.color = this.parent ? - this.parent.color : new Color(200, 200, 200); - } - this.cachedClr = this.color.toString(); - this.cachedClrBright = this.bright(); - this.cachedClrDark = this.dark(); + this.parent.color : new Color(200, 200, + 200);}; this.cachedClr = this.color.toString(); + this.cachedClrBright = ((this.color.lighter( + this.contrast)).withAlpha(1/2)).toString(); + this.cachedClrDark = ((this.color.darker( + this.contrast)).withAlpha(1/2)).toString(); this.drawDiamond(ctx, this.progress); this.drawLabel(ctx); this.drawKnob(ctx, this.progress); }; -BooleanSlotMorph.prototype.drawDiamond = function (ctx, progress) { - var w = this.width(), h = this.height(), r = h / 2, - w2 = (w * ((this.value ? (3 - progress) : progress) + 0.5)) / 4, - shift = this.edge / 2, - gradient; - - // draw the 'flat' shape: - if (this.cachedNormalColor) { // if flashing - ctx.fillStyle = this.color.toString(); - } else if (progress < 0 ) { // 'fade' - ctx.fillStyle = this.color.darker(25).toString(); - } else { - switch (this.value) { - case true: - ctx.fillStyle = 'rgb(0, 200, 0)'; - break; - case false: - ctx.fillStyle = 'rgb(200, 0, 0)'; - break; - default: - ctx.fillStyle = this.color.darker(25).toString(); - } - } - - if (progress > 0 && !this.isEmptySlot()) { - // left half: - ctx.fillStyle = 'rgb(0, 200, 0)'; - ctx.beginPath(); - ctx.moveTo(0, r); - ctx.lineTo(r, 0); - ctx.lineTo(w2, 0); - ctx.lineTo(w2, h); - ctx.lineTo(r, h); - ctx.closePath(); - ctx.fill(); - - // right half: - ctx.fillStyle = 'rgb(200, 0, 0)'; - ctx.beginPath(); - ctx.moveTo(w2, 0); - ctx.lineTo(w - r, 0); - ctx.lineTo(w, r); - ctx.lineTo(w - r, h); - ctx.lineTo(w2, h); - ctx.closePath(); - ctx.fill(); - } else { - ctx.beginPath(); - ctx.moveTo(0, r); - ctx.lineTo(r, 0); - ctx.lineTo(w - r, 0); - ctx.lineTo(w, r); - ctx.lineTo(w - r, h); - ctx.lineTo(r, h); - ctx.closePath(); - ctx.fill(); - } - - if (MorphicPreferences.isFlat) {return;}; - - // add 3D-Effect: - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - if (useBlurredShadows) { - ctx.shadowOffsetX = shift; - ctx.shadowBlur = shift; - ctx.shadowColor = 'black'; - } - - // top edge: left corner - gradient = ctx.createLinearGradient( - 0, - r, - this.edge * 0.6, - r + (this.edge * 0.6) - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, r); - ctx.lineTo(r, shift); - ctx.closePath(); - ctx.stroke(); - - // top edge: straight line - if (useBlurredShadows) { - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - } - - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r, shift); - ctx.lineTo(w - r, shift); - ctx.closePath(); - ctx.stroke(); - - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; - - // bottom edge: right corner - gradient = ctx.createLinearGradient( - w - r - (this.edge * 0.6), - h - (this.edge * 0.6), - w - r, - h - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(w - r, h - shift); - ctx.lineTo(w - shift, r); - ctx.closePath(); - ctx.stroke(); - - // bottom edge: straight line - gradient = ctx.createLinearGradient( - 0, - h - this.edge, - 0, - h - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r, h - shift); - ctx.lineTo(w - r - shift, h - shift); - ctx.closePath(); - ctx.stroke(); -}; - -BooleanSlotMorph.prototype.drawLabel = function anonymous (ctx +BooleanSlotMorph.prototype.drawDiamond = function (ctx, +progress) {var w = this.width(), h = this.height(), r = ( +h / 2), w2 = (w * ((this.value ? (3 - progress) : progress +) + 1/2)) / 4, shift = this.edge / 2, gradient; if ((this +).cachedNormalColor) {ctx.fillStyle = this.color.toString(); +} else if (progress < 0 ) {ctx.fillStyle = this.color.darker( +25).toString();} else {switch (this.value) {case true: (ctx +).fillStyle = 'rgb(0, 200, 0)'; break; case false: (ctx +).fillStyle = 'rgb(200, 0, 0)'; break; default: (ctx +).fillStyle = this.color.darker(25).toString();}; +}; if (progress > 0 && !(this.isEmptySlot())) { +ctx.fillStyle = 'rgb(0, 200, 0)'; ctx.beginPath( +); ctx.moveTo(0, r); ctx.lineTo(r, 0); ctx.lineTo( +w2, 0); ctx.lineTo(w2, h); ctx.lineTo(r, h); (ctx +).closePath(); ctx.fill(); ctx.fillStyle = (('rgb(' +) + '200, 0, 0)'); ctx.beginPath(); ctx.moveTo( +w2, 0); ctx.lineTo(w - r, 0); ctx.lineTo(w, r); +ctx.lineTo(w - r, h); ctx.lineTo(w2, h); (ctx +).closePath(); ctx.fill();} else {ctx.beginPath( +); ctx.moveTo(0, r); ctx.lineTo(r, 0); ctx.lineTo( +w - r, 0); ctx.lineTo(w, r); ctx.lineTo(w - r, h); +ctx.lineTo(r, h); ctx.closePath(); ctx.fill();}; +if (MorphicPreferences.isFlat) {return;}; (ctx +).lineWidth = this.edge; ctx.lineJoin = 'round'; +ctx.lineCap = 'butt'; if (useBlurredShadows) { +ctx.shadowOffsetX = shift; (ctx.shadowOffsetY +) = shift; ctx.shadowBlur = this.edge; (ctx +).shadowColor = (new Color(0, 0, 0, 1/2) +).toString();}; ctx.strokeStyle = (this +).cachedClrDark; ctx.beginPath(); (ctx +).moveTo(shift, r); ctx.lineTo(r, shift +); ctx.lineTo(w - r, shift); ctx.stroke( +); ctx.closePath(); ctx.shadowOffsetX = ( +0); ctx.shadowOffsetY = 0; (ctx.strokeStyle +) = this.cachedClrBright; ctx.beginPath(); +ctx.moveTo(w - shift, r); ctx.lineTo(w - ( +r), h - shift); ctx.lineTo(r, h - shift +); ctx.stroke(); ctx.closePath();}; + +BooleanSlotMorph.prototype.drawLabel = function (ctx ) {var w = this.width(), r = (this.height() / 2) - this.edge, -r2 = r / 2, shift = this.edge / 2, text, R = r * 0.4, +r2 = r / 2, shift = this.edge / 2, text, R = r * 2/5, x, y = this.height() / 2; if (this.isEmptySlot() || ( this.progress < 0)) {return;}; if (this.isStatic) { text = this.textLabelExtent(); @@ -12787,10 +11129,9 @@ ArrowMorph.prototype.getRenderColor = function () { if (this.isBlockLabel) { if (MorphicPreferences.isFlat) { return this.color; - } - return SyntaxElementMorph.prototype.alpha > 0.25 ? this.color : WHITE; - } - return this.color; + }; return ((SyntaxElementMorph.prototype + ).alpha > 0.25 ? this.color : WHITE); + }; return this.color; }; // TextSlotMorph ////////////////////////////////////////////////////// @@ -12853,12 +11194,7 @@ TextSlotMorph.prototype.init = function ( // TextSlotMorph accessing: -TextSlotMorph.prototype.getSpec = function () { - if (this.isNumeric) { - return '%mlt'; - } - return '%mlt'; // default -}; +TextSlotMorph.prototype.getSpec = (() => '%mlt'); TextSlotMorph.prototype.contents = function () { return detect( @@ -12869,9 +11205,8 @@ TextSlotMorph.prototype.contents = function () { // TextSlotMorph events: -TextSlotMorph.prototype.layoutChanged = function () { - this.fixLayout(); -}; +TextSlotMorph.prototype.layoutChanged = ( +function () {this.fixLayout();}); // ColorSlotMorph ////////////////////////////////////////////////////// @@ -12897,14 +11232,14 @@ ColorSlotMorph.uber = ArgMorph.prototype; function ColorSlotMorph(clr) {this.init(clr);}; -ColorSlotMorph.prototype.init = function anonymous (clr) {ColorSlotMorph.uber.init.call(this); this.alpha = 1; this.setColor(clr || new Color( -Math.round((Math.random() * 255)), Math.round((Math.random() * 255)), Math.round((Math.random() * 255)), 1)); this.cursorStyle = 'pointer';}; +ColorSlotMorph.prototype.init = function (clr) {ColorSlotMorph.uber.init.call(this); this.alpha = 1; this.setColor(clr || new Color(Math.round(( +Math.random() * 255)), Math.round((Math.random() * 255)), Math.round((Math.random() * 255)), 1)); this.fixLayout(); this.cursorStyle = 'pointer';}; -ColorSlotMorph.prototype.getSpec = function () {return '%clr';}; +ColorSlotMorph.prototype.getSpec = (() => '%clr'); // ColorSlotMorph color sensing: -ColorSlotMorph.prototype.getUserColor = function anonymous () {this.spawnRGBAEditorDialog(this);}; +ColorSlotMorph.prototype.getUserColor = function () {this.spawnRGBAEditorDialog(this);}; // ColorSlotMorph events: @@ -12912,40 +11247,33 @@ ColorSlotMorph.prototype.mouseClickLeft = function () {this.selectForEdit().getU // ColorSlotMorph evaluating: -ColorSlotMorph.prototype.evaluate = function () {return this.color;}; +ColorSlotMorph.prototype.evaluate = ( +function () {return this.color;}); // ColorSlotMorph drawing: -ColorSlotMorph.prototype.fixLayout = function () {var side = this.fontSize + this.edge * 2 + this.typeInPadding * 2; this.bounds.setWidth(side); this.bounds.setHeight(side);}; - -ColorSlotMorph.prototype.render = function (ctx) { - var borderColor; - - if (this.parent) { - borderColor = this.parent.color; - } else { - borderColor = new Color(120, 120, 120); - } - ctx.fillStyle = this.color.toString(); - - // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast) - .toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - - ctx.fillRect( - this.edge, - this.edge, - this.width() - this.edge * 2, - this.height() - this.edge * 2 - ); - if (!MorphicPreferences.isFlat) { - this.drawRectBorder(ctx); - } -}; - -ColorSlotMorph.prototype.drawRectBorder = InputSlotMorph.prototype.drawRectBorder; +ColorSlotMorph.prototype.fixLayout = function () { +var side = (this.fontSize + this.edge * 2 + (this +).typeInPadding * 2); this.bounds.setWidth(side); +this.bounds.setHeight(side);}; (ColorSlotMorph +).prototype.render = function (ctx) { +var borderColor; if (this.parent) { +borderColor = this.parent.color.withAlpha( +1/2);} else {borderColor = new Color(120, +120, 120, 1/2);}; ctx.fillStyle = (this.color +).toString(); this.cachedClr = (borderColor +).toString(); this.cachedClrBright = ( +borderColor.withAlpha(1/2)).lighter((this +).contrast).toString(); (this.cachedClrDark +) = (borderColor.withAlpha(1/2)).darker((this +).contrast).toString(); ctx.fillRect(this.edge, +this.edge, this.width() - this.edge * 2, +this.height() - (this.edge * 2)); if (!( +MorphicPreferences).isFlat) {(this +).drawRectBorder(ctx, borderColor +);};}; (ColorSlotMorph.prototype +).drawRectBorder = (InputSlotMorph +).prototype.drawRectBorder; // BlockHighlightMorph ///////////////////////////////////////////////// @@ -13029,18 +11357,18 @@ StringSyntaxMorph.uber = SyntaxElementMorph.prototype; function StringSyntaxMorph(oldText, newText, spec) {this.init(oldText, newText, spec);}; -StringSyntaxMorph.prototype.init = function anonymous (oldText, newText, spec) { +StringSyntaxMorph.prototype.init = function (oldText, newText, spec) { StringSyntaxMorph.uber.init.call(this); this.arrow = new ArrowMorph('right', (this.labelSize * 1.125), Math.max(Math.floor(this.labelSize / 6), 1), BLACK, true); this.oldText = oldText; this.newText = newText; this.label = new BlockLabelMorph(oldText, this.labelSize, this.labelFontStyle, true, false, false, -MorphicPreferences.isFlat ? ZERO : this.embossing, BLACK, WHITE, this.labelFontName); -this.setExtent(new Point(this.label.bounds.width(), this.labelSize * 1.125)); -this.add(this.label); this.label.setPosition(new Point(0, 0)); this.add( +MorphicPreferences.isFlat ? ZERO : this.embossing, BLACK, WHITE, this.labelFontName +); this.setExtent(new Point(this.label.bounds.width(), this.labelSize * 1.125) +); this.add(this.label); this.label.setPosition(ZERO); this.add( this.arrow); this.arrow.setPosition(new Point(this.label.bounds.corner.x, -0)); this.arrow.mouseClickLeft = function anonymous () { -this.parent.toggleText();}; this.labelSpec = spec;}; +0)); this.arrow.mouseClickLeft = function () {this.parent.toggleText(); +}; this.labelSpec = spec;}; StringSyntaxMorph.prototype.render = nop; -StringSyntaxMorph.prototype.fixLayout = function anonymous (aColor) {if ((this.label instanceof Morph) && ( +StringSyntaxMorph.prototype.fixLayout = function (aColor) {if ((this.label instanceof Morph) && ( this.parent instanceof Morph)) {this.color = this.parentThatIsA(BlockMorph).color; if (aColor instanceof Color ) {this.label.color = aColor;}; if ((this.label.color).eq(WHITE)) {this.label.shadowOffset = ( MorphicPreferences.isFlat ? ZERO : this.embossing); this.label.shadowColor = this.color.darker( @@ -13048,7 +11376,7 @@ this.labelContrast);} else if ((this.label.color).eq(BLACK)) {this.label.shadowO MorphicPreferences.isFlat ? ZERO : (this.embossing).neg()); this.label.shadowColor = this.color.lighter( this.zebraContrast).lighter(this.labelContrast * 2);};};}; /* They are only showing their labels. :-) */ -StringSyntaxMorph.prototype.toggleText = function anonymous () {if (this.label.text === this.oldText) { +StringSyntaxMorph.prototype.toggleText = function () {if (this.label.text === this.oldText) { this.label.text = this.newText; this.arrow.direction = 'left'; this.label.fixLayout(); this.arrow.setPosition(new Point(this.label.bounds.corner.x + (this.arrow.bounds.width() / 2), this.label.bounds.corner.y - this.label.bounds.extent().y)); this.setExtent(new Point( @@ -13632,7 +11960,7 @@ MultiArgMorph.prototype.hideThatInput = function () { this.hiddenInput.fixBlockColor(); this.hiddenInput.isHidden = true; this.hiddenInput.hiddenExtent = this.hiddenInput.extent(); - this.hiddenInput.bounds.setExtent(new Point(0, 0)); + this.hiddenInput.bounds.setExtent(ZERO); this.hiddenInput.hide(); this.fixLayout(); if (len > 0) { this.removePostfix(len); @@ -13940,415 +12268,103 @@ ArgLabelMorph.prototype.fixLayout = function () { if (this.parent) { this.parent.fixLayout(); } -}; - -ArgLabelMorph.prototype.refresh = function () { - this.inputs().forEach(input => { - input.fixLayout(); - input.rerender(); - }); -}; - -// ArgLabelMorph label color: - -ArgLabelMorph.prototype.setLabelColor = function ( - textColor, - shadowColor, - shadowOffset -) { - if (this.labelText !== '') { - var label = this.label(); - label.color = textColor; - label.shadowColor = shadowColor; - label.shadowOffset = shadowOffset; - label.rerender(); - } -}; - -// ArgLabelMorph events: - -ArgLabelMorph.prototype.reactToGrabOf = function () { - if (this.parent instanceof SyntaxElementMorph) { - this.parent.revertToDefaultInput(this); - } -}; - -// ArgLabelMorph evaluating: - -ArgLabelMorph.prototype.evaluate = function () { - // this is usually overridden by the interpreter. This method is only - // called (and needed) for the variables menu. - - return this.argMorph().evaluate(); -}; - -ArgLabelMorph.prototype.isEmptySlot = function () { - return false; -}; - -// FunctionSlotMorph /////////////////////////////////////////////////// - -/* - I am an unevaluated, non-editable, rf-colored, rounded or diamond - input slot. My current (only) use is in the THE BLOCK block. - - My command spec is %f -*/ - -// FunctionSlotMorph inherits from ArgMorph: - -FunctionSlotMorph.prototype = new ArgMorph; -FunctionSlotMorph.prototype.constructor = FunctionSlotMorph; -FunctionSlotMorph.uber = ArgMorph.prototype; - -// FunctionSlotMorph instance creation: - -function FunctionSlotMorph(isPredicate) {this.init(isPredicate);}; - -FunctionSlotMorph.prototype.init = function (isPredicate) { -FunctionSlotMorph.uber.init.call(this); this.isPredicate = -asABool(isPredicate); this.color = this.rfColor.lighter( -).lighter(10); this.cursorStyle = 'default';}; -FunctionSlotMorph.prototype.getSpec = (() => '%f'); - -// FunctionSlotMorph drawing: - -FunctionSlotMorph.prototype.render = function (ctx) { - var borderColor; - - if (this.parent) { - borderColor = this.parent.color; - } else { - borderColor = new Color(120, 120, 120); - }; - - // cache my border colors - this.cachedClr = borderColor.toString(); - this.cachedClrBright = borderColor.lighter(this.contrast).toString(); - this.cachedClrDark = borderColor.darker(this.contrast).toString(); - - if (this.isPredicate) { - this.drawDiamond(ctx); - } else { - this.drawRounded(ctx); - }; -}; - -FunctionSlotMorph.prototype.drawRounded = function (ctx) { - var h = this.height(), - r = Math.min(this.rounding, h / 2), - w = this.width(), - shift = this.edge / 2, - gradient; - - // draw the 'flat' shape: - ctx.fillStyle = this.color.toString(); - ctx.beginPath(); - - // top left: - ctx.arc( - r, - r, - r, - radians(-180), - radians(-90), - false - ); - - // top right: - ctx.arc( - w - r, - r, - r, - radians(-90), - radians(-0), - false - ); - - // bottom right: - ctx.arc( - w - r, - h - r, - r, - radians(0), - radians(90), - false - ); - - // bottom left: - ctx.arc( - r, - h - r, - r, - radians(90), - radians(180), - false - ); - - ctx.closePath(); - ctx.fill(); - - if (MorphicPreferences.isFlat) {return; } - - // add 3D-Effect: - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - // bottom left corner - ctx.strokeStyle = this.cachedClr; //gradient; - ctx.beginPath(); - ctx.arc( - r, - h - r, - r - shift, - radians(90), - radians(180), - false - ); - ctx.stroke(); - - // top right corner - ctx.strokeStyle = this.cachedClr; // this.gradient; - ctx.beginPath(); - ctx.arc( - w - r, - r, - r - shift, - radians(-90), - radians(0), - false - ); - ctx.stroke(); - - // normal gradient edges - - if (useBlurredShadows) { - ctx.shadowOffsetX = shift; - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } - - // top edge: straight line - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r - shift, shift); - ctx.lineTo(w - r + shift, shift); - ctx.stroke(); - - // top edge: left corner - gradient = ctx.createRadialGradient( - r, - r, - r - this.edge, - r, - r, - r - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrDark); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - r, - r, - r - shift, - radians(180), - radians(270), - false - ); - ctx.stroke(); - - // left edge: straight vertical line - gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, r); - ctx.lineTo(shift, h - r); - ctx.stroke(); +}; - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; +ArgLabelMorph.prototype.refresh = function () { + this.inputs().forEach(input => { + input.fixLayout(); + input.rerender(); + }); +}; - // bottom edge: right corner - gradient = ctx.createRadialGradient( - w - r, - h - r, - r - this.edge, - w - r, - h - r, - r - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.arc( - w - r, - h - r, - r - shift, - radians(0), - radians(90), - false - ); - ctx.stroke(); +// ArgLabelMorph label color: - // bottom edge: straight line - gradient = ctx.createLinearGradient( - 0, - h - this.edge, - 0, - h - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r - shift, h - shift); - ctx.lineTo(w - r + shift, h - shift); - ctx.stroke(); +ArgLabelMorph.prototype.setLabelColor = function ( + textColor, + shadowColor, + shadowOffset +) { + if (this.labelText !== '') { + var label = this.label(); + label.color = textColor; + label.shadowColor = shadowColor; + label.shadowOffset = shadowOffset; + label.rerender(); + } +}; - // right edge: straight vertical line - gradient = ctx.createLinearGradient(w - this.edge, 0, w, 0); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(w - shift, r + shift); - ctx.lineTo(w - shift, h - r); - ctx.stroke(); +// ArgLabelMorph events: + +ArgLabelMorph.prototype.reactToGrabOf = function () { + if (this.parent instanceof SyntaxElementMorph) { + this.parent.revertToDefaultInput(this); + } }; -FunctionSlotMorph.prototype.drawDiamond = function (ctx) { - var w = this.width(), - h = this.height(), - h2 = Math.floor(h / 2), - r = Math.min(this.rounding, h2), - shift = this.edge / 2, - gradient; +// ArgLabelMorph evaluating: - // draw the 'flat' shape: - ctx.fillStyle = this.color.toString(); - ctx.beginPath(); +ArgLabelMorph.prototype.evaluate = function () { + // this is usually overridden by the interpreter. This method is only + // called (and needed) for the variables menu. - ctx.moveTo(0, h2); - ctx.lineTo(r, 0); - ctx.lineTo(w - r, 0); - ctx.lineTo(w, h2); - ctx.lineTo(w - r, h); - ctx.lineTo(r, h); + return this.argMorph().evaluate(); +}; - ctx.closePath(); - ctx.fill(); +ArgLabelMorph.prototype.isEmptySlot = function () { + return false; +}; - if (MorphicPreferences.isFlat) {return; } +// FunctionSlotMorph /////////////////////////////////////////////////// - // add 3D-Effect: - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; +/* + I am an unevaluated, non-editable, rf-colored, rounded or diamond + input slot. My current (only) use is in the THE BLOCK block. - // half-tone edges - // bottom left corner - ctx.strokeStyle = this.cachedClr; - ctx.beginPath(); - ctx.moveTo(shift, h2); - ctx.lineTo(r, h - shift); - ctx.stroke(); + My command spec is %f +*/ - // top right corner - ctx.strokeStyle = this.cachedClr; - ctx.beginPath(); - ctx.moveTo(w - shift, h2); - ctx.lineTo(w - r, shift); - ctx.stroke(); +// FunctionSlotMorph inherits from ArgMorph: - // normal gradient edges - // top edge: left corner +FunctionSlotMorph.prototype = new ArgMorph; +FunctionSlotMorph.prototype.constructor = FunctionSlotMorph; +FunctionSlotMorph.uber = ArgMorph.prototype; - if (useBlurredShadows) { - ctx.shadowOffsetX = shift; - ctx.shadowOffsetY = shift; - ctx.shadowBlur = this.edge; - ctx.shadowColor = this.color.darker(80).toString(); - } +// FunctionSlotMorph instance creation: - gradient = ctx.createLinearGradient( - 0, - 0, - r, - 0 - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, h2); - ctx.lineTo(r, shift); - ctx.stroke(); +function FunctionSlotMorph(isPredicate) {this.init(isPredicate);}; - // top edge: straight line - gradient = ctx.createLinearGradient( - 0, - 0, - 0, - this.edge - ); - gradient.addColorStop(1, this.cachedClrDark); - gradient.addColorStop(0, this.cachedClr); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r, shift); - ctx.lineTo(w - r, shift); - ctx.stroke(); +FunctionSlotMorph.prototype.init = function (isPredicate) { +FunctionSlotMorph.uber.init.call(this); this.isPredicate = +asABool(isPredicate); this.color = this.rfColor.lighter( +).lighter(10); this.cursorStyle = 'default';}; +FunctionSlotMorph.prototype.getSpec = (() => '%f'); - ctx.shadowOffsetX = 0; - ctx.shadowOffsetY = 0; - ctx.shadowBlur = 0; +// FunctionSlotMorph drawing: - // bottom edge: right corner - gradient = ctx.createLinearGradient( - w - r, - 0, - w, - 0 - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(w - r, h - shift); - ctx.lineTo(w - shift, h2); - ctx.stroke(); +FunctionSlotMorph.prototype.render = function (ctx) { + var borderColor; - // bottom edge: straight line - gradient = ctx.createLinearGradient( - 0, - h - this.edge, - 0, - h - ); - gradient.addColorStop(1, this.cachedClr); - gradient.addColorStop(0, this.cachedClrBright); - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(r + shift, h - shift); - ctx.lineTo(w - r - shift, h - shift); - ctx.stroke(); + if (this.parent) { + borderColor = this.parent.color; + } else { + borderColor = new Color(120, 120, 120); + }; + + // cache my border colors + this.cachedClr = borderColor.toString(); + this.cachedClrBright = borderColor.lighter(this.contrast).toString(); + this.cachedClrDark = borderColor.darker(this.contrast).toString(); + + if (this.isPredicate) { + this.drawDiamond(ctx); + } else { + this.drawRounded(ctx); + }; }; +FunctionSlotMorph.prototype.drawRounded = nop; +FunctionSlotMorph.prototype.drawDiamond = nop; + // ReporterSlotMorph /////////////////////////////////////////////////// /* @@ -14373,13 +12389,14 @@ ReporterSlotMorph.uber = FunctionSlotMorph.prototype; // ReporterSlotMorph instance creation: -function ReporterSlotMorph(isPredicate) {this.init(isPredicate);}; +function ReporterSlotMorph(isPredicate +) {this.init(isPredicate);}; // init -ReporterSlotMorph.prototype.init = function (isPredicate) { - ReporterSlotMorph.uber.init.call(this, isPredicate, true); - this.add(this.emptySlot()); - this.fixLayout(); -}; +ReporterSlotMorph.prototype.init = function (isPredicate +) {ReporterSlotMorph.uber.init.call(this, isPredicate, +true); this.add(this.emptySlot()); if (isPredicate +) {this.render = this.renderPredicate;} else {(this +).render = this.renderReporter;}; this.fixLayout();}; ReporterSlotMorph.prototype.drawModifiedRounded = function (ctx) { if (this.nestedBlock() instanceof ReporterBlockMorph) { @@ -14439,7 +12456,7 @@ var rounding = this.rounding;}; ctx.closePath(); ctx.fill(); - if (MorphicPreferences.isFlat) {return; } + if (MorphicPreferences.isFlat) {return;}; // add 3D-Effect: ctx.lineWidth = this.edge; @@ -14479,7 +12496,7 @@ var rounding = this.rounding;}; ctx.shadowOffsetY = shift; ctx.shadowBlur = this.edge; ctx.shadowColor = this.color.darker(80).toString(); - } + }; // top edge: straight line gradient = ctx.createLinearGradient( @@ -14616,7 +12633,7 @@ var isArrow = false;}; ctx.closePath(); ctx.fill(); - if (MorphicPreferences.isFlat) {return; } + if (MorphicPreferences.isFlat) {return;}; // add 3D-Effect: ctx.lineWidth = this.edge; @@ -14649,7 +12666,7 @@ var isArrow = false;}; ctx.shadowOffsetY = shift; ctx.shadowBlur = this.edge; ctx.shadowColor = this.color.darker(80).toString(); - } + }; gradient = ctx.createLinearGradient( 0, @@ -14716,46 +12733,66 @@ var isArrow = false;}; ctx.stroke(); }; +ReporterSlotMorph.prototype.render = nop; + +ReporterSlotMorph.prototype.renderReporter = function (ctx) { +var borderColor; if (this.parent) {borderColor = this.parent.color; +} else {borderColor = new Color(120, 120, 120);}; // cache my border colors +this.cachedClr = borderColor.toString(); this.cachedClrBright = (borderColor +).lighter(this.contrast).toString(); this.cachedClrDark = borderColor.darker( +this.contrast).toString(); if (this.nestedBlock() instanceof ReporterBlockMorph +) {if (this.nestedBlock().isPredicate || this.nestedBlock().isArrow) {(this +).drawModifiedDiamond(ctx);} else {this.drawModifiedRounded(ctx);};} else { +this.drawModifiedRounded(ctx);};}; + +ReporterSlotMorph.prototype.renderPredicate = function (ctx) { +var borderColor; if (this.parent) {borderColor = this.parent.color; +} else {borderColor = new Color(120, 120, 120);}; // cache my border colors +this.cachedClr = borderColor.toString(); this.cachedClrBright = (borderColor +).lighter(this.contrast).toString(); this.cachedClrDark = borderColor.darker( +this.contrast).toString(); if (this.nestedBlock() instanceof ReporterBlockMorph +) {if (this.nestedBlock().isPredicate || this.nestedBlock().isArrow) {(this +).drawModifiedDiamond(ctx);} else {this.drawModifiedRounded(ctx);};} else { +this.drawModifiedDiamond(ctx);};}; + ReporterSlotMorph.prototype.emptySlot = function () { var empty = new ArgMorph, shrink = this.rfBorder * 2 + this.edge * 2; - empty.color = this.color.lighter(); - empty.alpha = 0; + empty.color = this.color.lighter( + ); empty.alpha = 0; empty.bounds.setExtent(new Point( (this.fontSize + this.edge * 2) * 2 - shrink, this.fontSize + this.edge * 2 - shrink - )); - return empty; + )); return empty; }; // ReporterSlotMorph accessing: -ReporterSlotMorph.prototype.getSpec = function () {return '%r';}; +ReporterSlotMorph.prototype.getSpec = function ( +) {return (this.isPredicate ? '%p' : '%r');}; ReporterSlotMorph.prototype.contents = function () {return this.children[0];}; -ReporterSlotMorph.prototype.nestedBlock = function anonymous () { -var contents = this.contents(); return ((contents instanceof BlockMorph -) ? contents : null);}; /* For evaluation in the "Fatal Error" virus. >:-) */ +ReporterSlotMorph.prototype.nestedBlock = function ( +) {var contents = this.contents(); return (((contents +) instanceof BlockMorph) ? contents : null);}; // ReporterSlotMorph evaluating: ReporterSlotMorph.prototype.evaluate = function () {return this.nestedBlock();}; - -ReporterSlotMorph.prototype.isEmptySlot = function () {return this.nestedBlock() === null;}; +ReporterSlotMorph.prototype.isEmptySlot = function () {return isNil(this.evaluate());}; // ReporterSlotMorph layout: ReporterSlotMorph.prototype.fixLayout = function () { var contents = this.contents(); - this.bounds.setExtent(contents.extent().add( - this.edge * 2 + this.rfBorder * 2 - )); - contents.setCenter(this.center()); + this.bounds.setExtent(contents.extent( + ).add(this.edge * 2 + this.rfBorder * 2 + )); contents.setCenter(this.center()); if (this.parent) { if (this.parent.fixLayout) { this.parent.fixLayout(); - } + }; }; }; @@ -14788,10 +12825,10 @@ RingReporterSlotMorph.prototype.rfBorder function RingReporterSlotMorph(isPredicate) {this.init(isPredicate);} -RingReporterSlotMorph.prototype.init = function (isPredicate) { - RingReporterSlotMorph.uber.init.call(this, isPredicate, true); - this.contrast = RingMorph.prototype.contrast; -}; +RingReporterSlotMorph.prototype.init = function (isPredicate +) {ReporterSlotMorph.uber.init.call(this, isPredicate, true +); this.add(this.emptySlot()); this.contrast = (RingMorph +).prototype.contrast; this.fixLayout();}; // RingReporterSlotMorph accessing: @@ -14849,53 +12886,32 @@ RingReporterSlotMorph.prototype.render = function (ctx var state = ((this.nestedBlock() instanceof ReporterBlockMorph) ? ( -this.nestedBlock().isPredicate ? 'predicate' : (this.nestedBlock().isArrow ? 'arrow' : 'reporter')) : 'reporter'); -if (this.getSpec() === '%rp') { -if ((state === 'predicate') || (this.nestedBlock() === null)) { -this.drawEdgesDiamond(ctx); -} else if (state === 'arrow') { -this.drawEdgesArrow( -ctx);} else { -this.drawEdgesOval( -ctx, ((this.nestedBlock( -) instanceof ReporterBlockMorph -) ? this.nestedBlock().rounding : null -));};} else {if (state === 'predicate') { -this.drawEdgesDiamond(ctx); -} else if (state === 'arrow') { -this.drawEdgesArrow( -ctx);} else { -this.drawEdgesOval( -ctx, ((this.nestedBlock( -) instanceof ReporterBlockMorph -) ? this.nestedBlock().rounding : null -));};}; - -}; - -RingReporterSlotMorph.prototype.outlinePath = function (ctx, offset) { +this.nestedBlock().isPredicate ? 'predicate' : (this.nestedBlock( +).isArrow ? 'arrow' : 'reporter')) : 'reporter'); if (this.getSpec( +) === '%rp') {if ((state === 'predicate') || isNil(this.nestedBlock( +))) {this.drawEdgesDiamond(ctx);} else if (state === 'arrow') { +this.drawEdgesArrow(ctx);} else {this.drawEdgesOval(ctx, ( +(this.nestedBlock() instanceof ReporterBlockMorph) ? (this +).nestedBlock().rounding : null));};} else {if ((state +) === 'predicate') {this.drawEdgesDiamond(ctx);} else if ( +state === 'arrow') {this.drawEdgesArrow(ctx);} else { +this.drawEdgesOval(ctx, ((this.nestedBlock( +) instanceof ReporterBlockMorph) ? (this +).nestedBlock().rounding : null));};};}; + +RingReporterSlotMorph.prototype.outlinePath = function (ctx, inset, offset) { var state = ((this.nestedBlock() instanceof ReporterBlockMorph) ? ( -this.nestedBlock().isPredicate ? 'predicate' : (this.nestedBlock().isArrow ? 'arrow' : 'reporter')) : 'reporter'); -if (this.getSpec() === '%rp') { -if ((state === 'predicate') || (this.nestedBlock() === null)) { -this.outlinePathDiamond(ctx, offset); -} else if (state === 'arrow') { -this.outlinePathArrow( -ctx, offset);} else { -this.outlinePathOval( -ctx, offset, ((this.nestedBlock( -) instanceof ReporterBlockMorph -) ? this.nestedBlock().rounding : null -));};} else {if (state === 'predicate') { -this.outlinePathDiamond(ctx, offset); -} else if (state === 'arrow') { -this.outlinePathArrow( -ctx, offset);} else { -this.outlinePathOval( -ctx, offset, ((this.nestedBlock( -) instanceof ReporterBlockMorph -) ? this.nestedBlock().rounding : null -));};};}; +this.nestedBlock().isPredicate ? 'predicate' : (this.nestedBlock( +).isArrow ? 'arrow' : 'reporter')) : 'reporter'); if (this.getSpec( +) === '%rp') {if ((state === 'predicate') || isNil(this.nestedBlock() +)) {this.outlinePathDiamond(ctx, offset);} else if (state === 'arrow' +) {this.outlinePathArrow(ctx, offset);} else {this.outlinePathOval( +ctx, offset, ((this.nestedBlock() instanceof ReporterBlockMorph) ? ( +this).nestedBlock().rounding : null));};} else {if (state === 'predicate' +) {this.outlinePathDiamond(ctx, offset);} else if (state === 'arrow') { +this.outlinePathArrow(ctx, offset);} else {this.outlinePathOval(ctx, +offset, ((this.nestedBlock() instanceof ReporterBlockMorph +) ? this.nestedBlock().rounding : null));};};}; RingReporterSlotMorph.prototype.outlinePathOval = function (ctx, offset, rounding) { var ox = offset.x, @@ -15387,7 +13403,8 @@ CommentMorph.prototype.refreshScale(); // CommentMorph instance creation: -function CommentMorph(contents) {this.init(contents);}; +function CommentMorph (contents +) {this.init(contents);}; CommentMorph.prototype.init = function (contents) { var scale = SyntaxElementMorph.prototype.scale; @@ -15396,18 +13413,16 @@ CommentMorph.prototype.init = function (contents) { this.stickyOffset = null; // not to be persisted this.isCollapsed = false; this.titleBar = new BoxMorph( - this.rounding, - scale, + this.rounding, scale, new Color(255, 255, 180) - ); this.titleBar.color = new Color(255, 255, 180); + ); this.titleBar.color = new Color(255, 255, 160); this.titleBar.setHeight(fontHeight( SyntaxElementMorph.prototype.fontSize ) + this.padding); this.title = null; - this.arrow = new ArrowMorph( - 'down', - this.fontSize - ); this.arrow.mouseClickLeft = () => this.toggleExpand(); - this.contents = new TextMorph( + this.arrow = new ArrowMorph('down', + this.fontSize, 0, new Color(130, 130, + 105)); this.arrow.mouseClickLeft = (() => ( + this).toggleExpand()); this.contents = new TextMorph( contents || localize('Please edit\nthis comment.'), SyntaxElementMorph.prototype.fontSize, 'sans-serif', @@ -15419,15 +13434,15 @@ CommentMorph.prototype.init = function (contents) { 0, null ); this.contents.isEditable = true; this.contents.enableSelecting(); - this.contents.maxWidth = 90 * scale; - this.contents.fixLayout(); + this.contents.maxWidth = ((this + ).contents.width() + (2 * scale + )); this.contents.fixLayout(); this.handle = new HandleMorph( - this.contents, - 80, + this.contents, 80, this.fontSize * 2, - -2, - -2 - ); this.handle.setExtent( + 4, 4, 'moveHorizontal' + ); this.handle.color = (this.arrow + ).color; (this.handle).setExtent( new Point(11 * scale, 11 * scale )); this.anchor = null; @@ -15435,9 +13450,9 @@ CommentMorph.prototype.init = function (contents) { this, this.rounding, scale, - new Color(255, 255, 180) + new Color(255, 255, 160) ); - this.color = new Color(255, 255, 220); + this.color = new Color(255, 255, 210); this.isDraggable = true; this.cursorStyle = 'grab'; this.titleBar.cursorStyle = 'grab'; @@ -15553,7 +13568,9 @@ CommentMorph.prototype.fixLayout = function () { this.handle.fixLayout(); }; -CommentMorph.prototype.userCut = function() {window.blockCopy = this.fullCopy(); this.selectForEdit().destroy();}; +CommentMorph.prototype.userCut = function ( +) {window.blockCopy = this.fullCopy(); +this.selectForEdit().destroy();}; // CommentMorph menu: @@ -15611,9 +13628,8 @@ CommentMorph.prototype.userMenu = function () { return menu; }; -CommentMorph.prototype.userDestroy = function () { - this.selectForEdit().destroy(); // enable copy-on-edit -}; +CommentMorph.prototype.userDestroy = ( +function () {this.selectForEdit().destroy();}); // CommentMorph hiding and showing: @@ -15624,14 +13640,10 @@ CommentMorph.prototype.userDestroy = function () { */ CommentMorph.prototype.hide = function () { - this.isVisible = false; - this.changed(); -}; +this.isVisible = false; this.changed();}; CommentMorph.prototype.show = function () { - this.isVisible = true; - this.changed(); -}; +this.isVisible = true; this.changed();}; // CommentMorph dragging & dropping @@ -15640,11 +13652,10 @@ CommentMorph.prototype.prepareToBeGrabbed = function (hand) { if (this.block) { this.block.comment = null; this.block = null; - } - if (this.anchor) { + }; if (this.anchor) { this.anchor.destroy(); this.anchor = null; - } + }; }; CommentMorph.prototype.selectForEdit = @@ -15657,22 +13668,19 @@ CommentMorph.prototype.snap = function (hand) { if (!(scripts instanceof ScriptsMorph)) { return null; - } - scripts.clearDropInfo(); + }; scripts.clearDropInfo(); target = scripts.closestBlock(this, hand); if (target !== null) { target.comment = this; this.block = target; if (this.snapSound) { this.snapSound.play(); - } - scripts.lastDropTarget = {element: target}; - } - this.align(); + }; scripts.lastDropTarget = {element: target}; + }; this.align(); scripts.lastDroppedBlock = this; if (hand) { scripts.recordDrop(hand.grabOrigin); - } + }; }; @@ -15693,8 +13701,7 @@ CommentMorph.prototype.align = function (topBlock, ignoreLayer) { child instanceof BlockMorph && child.bottom() > tp && child.top() < bottom - ); - rightMost = Math.max.apply( + ); rightMost = Math.max.apply( null, affectedBlocks.map(block => block.right()) ); diff --git a/src/bpmn.js b/src/bpmn.js index a0f3887..3d64aa3 100644 --- a/src/bpmn.js +++ b/src/bpmn.js @@ -70,13 +70,6 @@ BPM_DataFlowMorph */ -/*global modules, WorldMorph, BoxMorph, TextMorph, Point, Color, MenuMorph, -isNil, Morph, newCanvas, radians, nop, detect, StringMorph*/ - -// Global stuff //////////////////////////////////////////////////////// - -modules.bpmn = '2021-February-22'; - var BPM_AnchorMorph; var BPM_EventMorph; var BPM_GatewayMorph; diff --git a/src/byob.js b/src/byob.js index 988cb01..e5c984c 100644 --- a/src/byob.js +++ b/src/byob.js @@ -95,23 +95,6 @@ */ -/*global modules, CommandBlockMorph, SpriteMorph, TemplateSlotMorph, Map, Morph, -StringMorph, Color, DialogBoxMorph, ScriptsMorph, ScrollFrameMorph, WHITE, copy, -Point, HandleMorph, HatBlockMorph, BlockMorph, detect, List, Process, isString, -AlignmentMorph, ToggleMorph, InputFieldMorph, ReporterBlockMorph, StringMorph, -nop, radians, BoxMorph, ArrowMorph, PushButtonMorph, contains, InputSlotMorph, -ToggleButtonMorph, IDE_Morph, MenuMorph, ToggleElementMorph, fontHeight, isNil, -StageMorph, SyntaxElementMorph, CommentMorph, localize, CSlotMorph, Variable, -MorphicPreferences, SymbolMorph, CursorMorph, VariableFrame, BooleanSlotMorph, -WatcherMorph, XML_Serializer, SnapTranslator, SnapExtensions, MultiArgMorph, -ArgLabelMorph*/ - -/*jshint esversion: 6*/ - -// Global stuff //////////////////////////////////////////////////////// - -modules.byob = '2023-October-22'; - // Declarations var CustomBlockDefinition; @@ -171,10 +154,10 @@ CustomBlockDefinition.prototype.blockInstance = function (storeTranslations) { false, this.type === 'arrow' ); - }; block.isDraggable = true; + }; block.isDraggable = true; if (storeTranslations) { // only for "wishes" - block.storedTranslations = this.translationsAsText(); - }; return block; + block.storedTranslations = this.translationsAsText(); + }; return block; }; CustomBlockDefinition.prototype.templateInstance = function () { @@ -216,15 +199,13 @@ CustomBlockDefinition.prototype.prototypeInstance = function () { part.fragment.separator = slot[5] || null; }; }; - }); - - return block; + }); return block; }; // CustomBlockDefinition duplicating -CustomBlockDefinition.prototype.copyAndBindTo = function (sprite, headerOnly) { - var c = copy(this); +CustomBlockDefinition.prototype.copyAndBindTo = ( +function (sprite, headerOnly) {var c = copy(this); delete c[XML_Serializer.prototype.idProperty]; c.receiver = sprite; // only for (kludgy) serialization @@ -233,34 +214,28 @@ CustomBlockDefinition.prototype.copyAndBindTo = function (sprite, headerOnly) { c.declarations = new Map; for (var [key, val] of this.declarations) { c.declarations.set(key, val); - } - - if (headerOnly) { // for serializing inherited method signatures + }; if (headerOnly) {// for serializing inherited method signatures c.body = null; return c; - } - if (c.body) { + }; if (c.body) { c.body = Process.prototype.reify.call( null, this.body.expression, new List(this.inputNames()) - ); - c.body.outerContext = null; - } - return c; -}; + ); c.body.outerContext = null; + }; // deep copy scripts + c.scripts = (this.scripts).map( + each => each.fullCopy()); return c; +}); // CustomBlockDefinition accessing -CustomBlockDefinition.prototype.blockSpec = function () { - if (this.storedSemanticSpec) { - return this.storedSemanticSpec; // for "wishes" - } - - var ans = [], +CustomBlockDefinition.prototype.blockSpec = function ( + ) {if (this.storedSemanticSpec) { + return this.storedSemanticSpec; + /* for "wishes" */}; var ans = [], parts = this.parseSpec(this.spec), - spec; - parts.forEach(part => { + spec; parts.forEach(part => { if (part[0] === '%' && part.length > 1 ) {spec = this.typeOf(part.slice(1)); } else if (part.includes('$nl')) { @@ -270,29 +245,22 @@ CustomBlockDefinition.prototype.blockSpec = function () { }; CustomBlockDefinition.prototype.helpSpec = function () { - var ans = [], - parts = this.parseSpec(this.spec); + var ans = [], parts = this.parseSpec(this.spec); parts.forEach(part => { if (part[0] !== '%') { - ans.push(part); - } - }); - return ''.concat.apply('', ans).replace(/\?/g, ''); + ans.push(part);}; + }); return ''.concat.apply( + '', ans).replace(/\?/g, ''); }; CustomBlockDefinition.prototype.typeOf = function (inputName) { if (this.declarations.has(inputName)) { - return this.declarations.get(inputName)[0]; - } - return '%s'; + return this.declarations.get( + inputName)[0];}; return '%s'; }; -CustomBlockDefinition.prototype.defaultValueOf = function (inputName) { - if (this.declarations.has(inputName)) { - return this.declarations.get(inputName)[1]; - } - return ''; -}; +CustomBlockDefinition.prototype.defaultValueOf = function (inputName) {return ( +this.declarations.has(inputName) ? this.declarations.get(inputName)[1] : '');}; CustomBlockDefinition.prototype.defaultValueOfInputIdx = function (idx) { var inputName = this.inputNames()[idx]; @@ -333,7 +301,7 @@ CustomBlockDefinition.prototype.dropDownMenuOf = function (inputName) { if (contains( [ 'messagesMenu', - 'messagesReceivedMenu', //for backward (5.0.0 - 5.0.3) support + 'messagesReceivedMenu', 'objectsMenu', 'costumesMenu', 'soundsMenu', @@ -344,11 +312,12 @@ CustomBlockDefinition.prototype.dropDownMenuOf = function (inputName) { 'midsMenu' ], fname - ) || fname.indexOf('ext_') === 0) { - return fname; - }; - }; return this.parseChoices(this.declarations.get(inputName)[2]); - }; return null; + ) || fname.indexOf( + 'ext_') === 0) { + return fname;}; + }; return this.parseChoices( + this.declarations.get(inputName + )[2]);}; return null; }; CustomBlockDefinition.prototype.parseChoices = function (string) { @@ -505,12 +474,10 @@ CustomBlockDefinition.prototype.localizedSpec = function () { if (str === '_') { i += 1; return inputs[i]; - } - return str; - }); - this.cachedTranslation = locParts.join(' '); - } - return this.cachedTranslation; + }; + return str; + }); this.cachedTranslation = locParts.join(' '); + }; return this.cachedTranslation; }; CustomBlockDefinition.prototype.abstractBlockSpec = function () { @@ -525,8 +492,7 @@ CustomBlockDefinition.prototype.translationsAsText = function () { var txt = ''; Object.keys(this.translations).forEach(lang => txt += (lang + ':' + this.translations[lang] + '\n') - ); - return txt; + ); return txt; }; CustomBlockDefinition.prototype.updateTranslations = function (text) { @@ -538,7 +504,7 @@ CustomBlockDefinition.prototype.updateTranslations = function (text) { val = txt.slice(idx + 1).trim(); if (idx) { this.translations[key] = val; - } + }; }); }; @@ -565,11 +531,9 @@ CustomBlockDefinition.prototype.scriptsModel = function () { comment = this.comment.fullCopy(); proto.comment = comment; comment.block = proto; - } - if (this.body !== null) { + }; if (!isNil(this.body)) { proto.nextBlock(this.body.expression.fullCopy()); - } - scripts.add(proto); + }; scripts.add(proto); proto.fixBlockColor(null, true); this.scripts.forEach(element => { block = element.fullCopy(); @@ -579,13 +543,11 @@ CustomBlockDefinition.prototype.scriptsModel = function () { block.allComments().forEach(comment => comment.align(block) ); - } - }); - proto.allComments().forEach(comment => + }; + }); proto.allComments().forEach(comment => comment.align(proto) - ); - template = proto.parts()[1]; - template.fixLayout(); + ); template = proto.parts( + )[1]; template.fixLayout(); template.forceNormalColoring(); template.fixBlockColor(proto, true); scripts.fixMultiArgs(); @@ -662,7 +624,7 @@ CustomCommandBlockMorph.prototype.isCustomBlock = true; function CustomCommandBlockMorph(definition, isProto) { this.init(definition, isProto); -} +}; CustomCommandBlockMorph.prototype.init = function (definition, isProto) { this.definition = definition; @@ -1030,15 +992,11 @@ CustomCommandBlockMorph.prototype.labelPart = function (spec) { ); }; -CustomCommandBlockMorph.prototype.placeHolder = function () { - var part; - - part = new BlockLabelPlaceHolderMorph(); - part.fontSize = this.fontSize * 1.4; - part.color = new Color(45, 45, 45); - part.fixLayout(); - return part; -}; +CustomCommandBlockMorph.prototype.placeHolder = function ( +) {var part = new BlockLabelPlaceHolderMorph; +part.fontSize = this.fontSize * 1.4; +part.color = new Color(45, 45, 45); +part.fixLayout(); return part;}; CustomCommandBlockMorph.prototype.attachTargets = function () { if (this.isPrototype) { @@ -1353,11 +1311,11 @@ menu.addItem( if (this.isGlobal) { let newPos = ide.stage.globalBlocks.indexOf(def); ide.stage.globalBlocks = ide.stage.globalBlocks.filter(item => item !== def); - ide.stage.globalBlocks.splice(newPos-1,0,def); + ide.stage.globalBlocks.splice(newPos - 1, 0, def); } else { let newPos = rcvr.customBlocks.indexOf(def); rcvr.customBlocks = rcvr.customBlocks.filter(item => item !== def); - rcvr.customBlocks.splice(newPos-1,0,def); + rcvr.customBlocks.splice(newPos - 1, 0, def); } ide.flushPaletteCache(); @@ -1377,11 +1335,11 @@ menu.addItem( if (this.isGlobal) { let newPos = ide.stage.globalBlocks.indexOf(def); ide.stage.globalBlocks = ide.stage.globalBlocks.filter(item => item !== def); - ide.stage.globalBlocks.splice(newPos+1,0,def); + ide.stage.globalBlocks.splice(newPos + 1, 0, def); } else { let newPos = rcvr.customBlocks.indexOf(def); rcvr.customBlocks = rcvr.customBlocks.filter(item => item !== def); - rcvr.customBlocks.splice(newPos+1,0,def); + rcvr.customBlocks.splice(newPos + 1, 0, def); rcvr.customBlocks.shift(def); } @@ -1714,17 +1672,10 @@ if (contains(['%cl', '%c', '%cs', '%cla', '%loop', '%ca'], spec)) {this.minWidth // JaggedBlockMorph drawing: -JaggedBlockMorph.prototype.outlinePath = function (ctx, inset) { - var w = this.width(), - h, - jags, - delta, - pos = this.position(), - y = 0, - i; - - ctx.moveTo(inset, inset); - ctx.lineTo(w - inset, inset); +JaggedBlockMorph.prototype.outlinePath = function ( +ctx, inset) {var w = this.width(), h, jags, delta, +i, pos = this.position(), y = 0; ctx.moveTo(inset, +inset); ctx.lineTo(w - inset, inset); // C-Slots this.cSlots().forEach(slot => { @@ -1786,8 +1737,7 @@ JaggedBlockMorph.prototype.drawEdges = function (ctx) { ctx.lineTo(w - shift, shift); ctx.stroke(); - if (!this.cSlots().length) { // omit right jagged outline for c-slots - y = 0; + if (!(this.clearSlots().length)) {y = 0; for (i = 0; i < jags; i += 1) { ctx.strokeStyle = this.cachedClrDark; ctx.beginPath(); @@ -2559,154 +2509,90 @@ PrototypeHatBlockMorph.uber = HatBlockMorph.prototype; function PrototypeHatBlockMorph(definition) {this.init(definition);}; -PrototypeHatBlockMorph.prototype.init = function (definition) { - var proto = definition.prototypeInstance(), - vars; - - this.definition = definition; - - // additional attributes to store edited data - this.blockCategory = definition ? definition.category : null; - this.type = definition ? definition.type : null; - this.isHelper = definition ? definition.isHelper : false; - - // init inherited stuff - PrototypeHatBlockMorph.uber.init.call(this, false); - this.category = 'custom'; this.setSpec(localize('define')); - this.add(proto); if (definition.variableNames.length) { - vars = this.labelPart('%blockVars'); - this.add(this.labelPart('%br')); - this.add(vars); - definition.variableNames.forEach(name => - vars.addInput(name) - ); - }; proto.refreshPrototypeSlotTypes(); // show slot type indicators - this.fixLayout(); this.fixBlockColor(); - proto.fixBlockColor(this, true); - - this.cursorStyle = 'default'; - this.cursorGrabStyle = null; -}; - -PrototypeHatBlockMorph.prototype.outlinePath = function (ctx, inset) { - var indent = this.corner * 2 + this.inset, - bottom = this.height() - this.corner, - bottomCorner = this.height() - this.corner * 2, - radius = Math.max(this.corner - inset, 0), - s = this.hatWidth, - h = this.hatHeight, - r = ((4 * h * h) + (s * s)) / (8 * h), - a = degrees(4 * Math.atan(2 * h / s)), - sa = a / 2, - sp = Math.min(s * 1.7, this.width() - this.corner), - pos = this.position(); - - // top left: - ctx.moveTo(0, (h * 1.5) + this.corner); - - // top arc: - ctx.bezierCurveTo(this.width() * (0.5 / 3), 0, this.width() * (2.5 / 3), 0, this.width(), (h * 1.5) + this.corner); - this.drawTopLeftEdge(ctx, true); - - // bottom right: - ctx.arc( - this.width() - this.corner, - bottomCorner, - radius, - radians(0), - radians(90), - false - ); - - if (!this.isStop()) { - ctx.lineTo(this.width() - this.corner, bottom - inset); - ctx.lineTo(this.corner * 3 + this.inset + this.dent, bottom - inset); - ctx.lineTo(indent + this.dent, bottom + this.corner - inset); - ctx.lineTo(indent, bottom + this.corner - inset); - ctx.lineTo(this.corner + this.inset, bottom - inset); - }; - - // bottom left: - ctx.arc( - this.corner, - bottomCorner, - radius, - radians(90), - radians(180), - false - ); -}; - -PrototypeHatBlockMorph.prototype.drawLeftEdge = function (ctx) { - var shift = this.edge * 0.5, - gradient = ctx.createLinearGradient(0, 0, this.edge, 0); - - gradient.addColorStop(0, this.cachedClrBright); - gradient.addColorStop(1, this.cachedClr); +PrototypeHatBlockMorph.prototype.init = function (definition +) {var proto = definition.prototypeInstance(), vars; (this +).definition = definition; this.blockCategory = ((definition +) ? definition.category : null); this.type = (definition ? ( +definition.type) : null); this.isHelper = (definition ? ( +definition.isHelper) : false); (PrototypeHatBlockMorph.uber +).init.call(this, true); this.category = 'custom'; (this +).setSpec(localize('define')); this.add(proto); if ( +definition.variableNames.length) {vars = this.labelPart( +'%blockVars'); this.add(this.labelPart('%br')); this.add( +vars); definition.variableNames.forEach(name => (vars.addInput( +name)));}; proto.refreshPrototypeSlotTypes(); this.fixLayout(); +this.fixBlockColor(); proto.fixBlockColor(this, true); (this +).cursorStyle = 'default'; this.cursorGrabStyle = null;}; + +PrototypeHatBlockMorph.prototype.outlinePath = function ( +ctx, inset) {var indent = this.corner * 2 + this.inset, +bottom = this.height() - this.corner, bottomCorner = ( +this.height() - (this.corner * 2)), radius = Math.max( +this.corner - inset, 0), s = this.hatWidth, h = (this +).hatHeight, r = ((4 * h * h) + (s * s)) / (8 * h), +a = degrees(4 * Math.atan(2 * h / s)), sa = a / 2, +x = this.width(), gradient, sp = Math.min(s * 1.7, +this.width() - this.corner), pos = this.position( +), shift = this.edge / 2; ctx.lineJoin = 'round'; +ctx.lineCap = 'round'; ctx.strokeStyle = (this.color +).toString(); ctx.lineWidth = this.edge * 5; (ctx +).beginPath(); ctx.moveTo(0, (h * 3/2) + this.corner +); ctx.bezierCurveTo((x / 6), 0, (x * 5/6), 0, x, ( +h * 3/2) + this.corner); ctx.stroke(); (ctx.strokeStyle +) = (SpriteMorph.prototype.blockColor.control.lighter( +)).toString(); ctx.lineWidth = this.edge * 5/2; (ctx +).beginPath(); ctx.moveTo(0, (h * 3/2) + this.corner); +ctx.bezierCurveTo((x / 6), 0, (x * 5/6), 0, x, (h * 3/2 +) + this.corner); ctx.stroke(); ctx.arc(x - this.corner, +bottomCorner, radius, 0, Math.PI / 2, false); if (!((this +).isStop())) {ctx.lineTo(this.width() - this.corner, +bottom - inset); ctx.lineTo(this.corner * 3 + (this +).inset + this.dent, bottom - inset); ctx.lineTo( +indent + this.dent, bottom + this.corner - inset); +ctx.lineTo(indent, bottom + this.corner - inset); +ctx.lineTo(this.corner + this.inset, bottom - inset +);}; ctx.arc(this.corner, bottomCorner, radius, +Math.PI / 2, Math.PI, false);}; + +PrototypeHatBlockMorph.prototype.drawEdges = function (ctx) { + var shift = this.edge / 2, x = this.width(), + y = 0, indent = this.corner * 2 + this.inset, + top = this.top(), bump = -(1.5 * this.edge), + r = ((4 * (this.hatHeight ** 2)) + ((this + ).hatWidth ** 2)) / (8 * this.hatHeight), + cslots = this.clearSlots(), lgx = ( + this.corner + this.inset); ctx.lineWidth = this.edge; ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - ctx.strokeStyle = gradient; - ctx.beginPath(); - ctx.moveTo(shift, (this.hatHeight * 1.5) + this.corner); - ctx.lineTo(shift, this.height() - this.corner * 2 - shift); - ctx.stroke(); -}; - -PrototypeHatBlockMorph.prototype.drawTopLeftEdge = function (ctx, flag) { -if (asABool(flag)) { - var shift = this.edge * 0.5, - x = this.width(), - y, - gradient; - - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - gradient = ctx.createLinearGradient(x - this.edge, 0, x, 0); - gradient.addColorStop(0, this.color.toString()); - gradient.addColorStop(1, this.color.darker().toString()); - ctx.strokeStyle = gradient; - ctx.lineWidth = this.edge * 5; - - ctx.beginPath(); - ctx.moveTo(0, (this.hatHeight * 1.5) + this.corner); - ctx.bezierCurveTo(this.width() * (0.5 / 3), 0, this.width() * (2.5 / 3), 0, this.width(), (this.hatHeight * 1.5) + this.corner); - ctx.stroke(); - - gradient = ctx.createLinearGradient(x - this.edge, 0, x, 0); - gradient.addColorStop(0, SpriteMorph.prototype.blockColor.control.lighter().toString()); - gradient.addColorStop(1, this.color.toString()); - ctx.strokeStyle = gradient; - ctx.lineWidth = this.edge * 2.5; - - ctx.moveTo(0, (this.hatHeight * 1.5) + this.corner); - ctx.bezierCurveTo(this.width() * (0.5 / 3), 0, this.width() * (2.5 / 3), 0, this.width(), (this.hatHeight * 1.5) + this.corner); - ctx.stroke(); -};}; - -PrototypeHatBlockMorph.prototype.drawRightEdge = function (ctx) { - var shift = this.edge * 0.5, - x = this.width(), - y, - gradient; - - gradient = ctx.createLinearGradient(x - this.edge, 0, x, 0); - gradient.addColorStop(0, this.cachedClr); - gradient.addColorStop(1, this.cachedClrDark); - - ctx.lineWidth = this.edge; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - ctx.strokeStyle = gradient; - - ctx.beginPath(); - ctx.moveTo(x - shift, this.corner + (this.hatHeight * 1.5) + shift); - ctx.lineTo(x - shift, this.height() - this.corner * 2); - ctx.stroke(); -}; + ctx.lineCap = 'butt'; + + ctx.strokeStyle = this.cachedClrBright; ctx.beginPath(); + ctx.moveTo(shift, this.height() - this.corner * 2 - shift + ); ctx.lineTo(shift, 35 * shift); + ctx.bezierCurveTo((x / 6), bump, ((5 * x) / 6 + ), bump, x, 35 * shift); ctx.stroke(); + + ctx.strokeStyle = this.cachedClrDark; ctx.beginPath(); + ctx.moveTo(x - shift, (this.corner + this.hatHeight + ) + (this.edge * 3)); if (cslots.length > 0 + ) {cslots.forEach(slot => { + y = slot.top() - top; + ctx.lineTo(x - shift, + y); ctx.stroke(); + ctx.beginPath(); + ctx.moveTo(x - shift, y + slot.height( + ));});}; y = this.height() - this.corner; + ctx.arc(this.width() - this.corner, + this.height() - this.corner * 2, + this.corner - shift, 0, Math.PI / 2 + ); if (!(this.isStop())) {ctx.lineTo( + this.corner * 3 + this.inset + this.dent, + y - shift ); ctx.lineTo(indent + this.dent, + y + this.corner - shift); ctx.lineTo(indent + shift, + y + this.corner - shift); ctx.stroke(); ctx.beginPath( + ); ctx.moveTo(this.corner + this.inset - shift, y - shift +);}; ctx.lineTo(this.corner, y - shift); ctx.stroke();}; PrototypeHatBlockMorph.prototype.mouseClickLeft = function () {if (this.world().currentKey === 16) {return this.focus();}; this.parts()[1].mouseClickLeft();}; diff --git a/src/charts.js b/src/charts.js index 7ab9f00..0759572 100644 --- a/src/charts.js +++ b/src/charts.js @@ -54,14 +54,6 @@ */ -// Global settings ///////////////////////////////////////////////////// - -/*global modules, newCanvas, Point, Morph, WorldMorph, Color, BoxMorph, -StringMorph, ScrollFrameMorph, MorphicPreferences, SliderMorph, -ToggleMorph, HandleMorph*/ - -modules.charts = '2024-Jan-29'; - var GridMorph, LineMorph, ChartMorph; WorldMorph.prototype.customMorphs = function () { @@ -647,5 +639,5 @@ ChartMorph.prototype.renderGradient = function (context) { }; }; -ChartMorph.prototype.render = function anonymous ( -ctx) {this.renderGradient(ctx); this.fixLayout();}; \ No newline at end of file +ChartMorph.prototype.render = function (ctx) { +this.renderGradient(ctx); this.fixLayout();}; \ No newline at end of file diff --git a/src/compilers.js b/src/compilers.js index f50336b..0f8ba6a 100644 --- a/src/compilers.js +++ b/src/compilers.js @@ -1,4 +1,4 @@ -modules.compilers = '2023-June-01'; var JSCompiler; +var JSCompiler; // JSCompiler ///////////////////////////////////////////////////////////////// @@ -370,73 +370,13 @@ return ((contains(['number', 'Boolean'], (new Process).reportTypeOf(reportBasicT } else if (blocks.selector === 'reportJSFunction') {return '\(function anonymous \(' + blocks.inputs()[0].evaluate() + '\n\) \{\n' + blocks.inputs()[1].evaluate() + '\n\}\)'; } else if (blocks.selector === 'reportScript') {return '\(' + (new Function(blocks.inputs()[0].evaluate(), reportBasicToJS(blocks.inputs()[1].nestedBlock()))) + '\)'; } else if (blocks.selector === 'reify') {return '\(' + (new Function(blocks.inputs()[1].evaluate(), reportBasicToJS(blocks.inputs()[0].nestedBlock()))) + '\)'; +} else if (blocks.selector === 'reifyCommand') {return '\(' + (new Function(blocks.inputs()[1].evaluate(), reportBasicToJS(blocks.inputs()[0].nestedBlock()))) + '\)'; +} else if (blocks.selector === 'reifyReporter') {return '\(' + (new Function(blocks.inputs()[1].evaluate(), reportBasicToJS(blocks.inputs()[0].nestedBlock()))) + '\)'; +} else if (blocks.selector === 'reifyPredicate') {return '\(' + (new Function(blocks.inputs()[1].evaluate(), reportBasicToJS(blocks.inputs()[0].nestedBlock()))) + '\)'; } else if (blocks.selector === 'reportNewList') {return 'new List\(' + reportBasicToJS(blocks.inputs()[0]) + '\)'; } else if (blocks.selector === 'reportNumbers') {return '\(\(new Process\).reportNumbers\(' + reportBasicToJS(blocks.inputs()[0]) + ',' + reportBasicToJS(blocks.inputs()[1]) + '\)\)'; } else if (blocks.selector === 'reportConcatenatedLists') {return '\(new List\(\[\].concat\(' + reportBasicToJS(blocks.inputs()[0]) + '\)\)\)'; } else if (blocks.selector === 'evaluateCustomBlock') {return reportBasicToJS(blocks.definition.body.toBlock()) + '.apply\(this, \[' + blocks.inputs().map(value => reportBasicToJS(value)) + '\]\);'; } else if (blocks.selector === 'reportGetVar') {return blocks.blockSpec;} else {return '';};} else {return '';};}; function reportToJS (input) {if (input instanceof List) {return new List(input.asArray().map(miniInput => reportToJS(miniInput)));} -else if (input instanceof Context) {return reportBasicToJS(input);} else {return reportBasicToJS(new Context());};}; - -function JSBlocksCompiler (morphs) {var result = ''; -if (morphs instanceof CommandBlockMorph) { -if (morphs.selector === 'JSBlocksReturnStatement') { -result = result.concat('return '.concat(JSBlocksCompiler(morphs.children[1]), '\;')); -} else if (morphs.selector === 'JSBlocksSwitchStatement') { -result = result.concat('switch \('.concat((JSBlocksCompiler(morphs.children[0]) === '' ? 'null' : JSBlocksCompiler(morphs.children[0])), -'\) \{\n', JSBlocksCompiler(morphs.inputs()[1].nestedBlock()), '\}\;')); -} else if (morphs.selector === 'JSBlocksCaseStatement') { -result = result.concat('case \('.concat((JSBlocksCompiler(morphs.children[0]) === '' ? 'null' : JSBlocksCompiler(morphs.children[0])), -'\) :\n', JSBlocksCompiler(morphs.inputs()[1].nestedBlock()))); -} else if (morphs.selector === 'JSBlocksBreakStatement') { -result = result.concat('break'.concat((morphs.inputs()[0].inputs().length === 0 ? '' : (' ').concat(morphs.inputs()[0].inputs( -)[0].blockSpec)), '\;')); -} else if (morphs.selector === 'JSBlocksContinueStatement') {result = result.concat('continue'.concat( -(morphs.inputs()[0].inputs().length === 0 ? '' : (' ').concat(morphs.inputs()[0].inputs()[0].blockSpec)), '\;')); -} else if (morphs.selector === 'JSBlocksWithStatement') { -result = result.concat('with \('.concat((JSBlocksCompiler(morphs.children[0]) === '' ? 'null' : JSBlocksCompiler(morphs.children[0])), -'\) \{\n', JSBlocksCompiler(morphs.inputs()[1].nestedBlock()), '\}\;')); -} else { -result = result.concat((JSBlocksCompiler(morphs.children[0].nestedBlock()) === '' ? 'null' : JSBlocksCompiler( -morphs.children[0].nestedBlock())).concat('\;')); -}; if (morphs.nextBlock() instanceof CommandBlockMorph) {result = result.concat( -'\n', JSBlocksCompiler(morphs.nextBlock()));}; return result; -} else if (morphs instanceof ReporterBlockMorph) { -if (morphs.selector === 'JSBlocksTraditionalFunction') {return ''.concat(morphs.inputs()[0].evaluate(), ((morphs.inputs( -)[0].evaluate() === '') ? '' : ' '), morphs.inputs()[1].evaluate(), ' ', morphs.inputs()[2].contents().text, ((morphs.inputs( -)[2].contents().text === '') ? '' : ' '), '\(', morphs.inputs()[3].evaluate(), '\) \{\n', JSBlocksCompiler(morphs.inputs( -)[4].nestedBlock()), '\}'); -} else if (morphs.selector === 'JSBlocksArrowClosureFunction') {return '\('.concat(morphs.inputs( -)[0].evaluate(), '\) \=\> \{', JSBlocksCompiler(morphs.inputs()[1].nestedBlock()), '\}'); -} else if (morphs.selector === 'JSBlocksArrowResultFunction') { -return '\('.concat(morphs.inputs()[0].evaluate(), '\) \=\> ', '\(', (JSBlocksCompiler( -morphs.inputs()[1]) === '' ? 'null' : JSBlocksCompiler(morphs.inputs()[1])), '\)'); -} else if (morphs.selector === 'reportGetVar') {return morphs.blockSpec; -} else if (morphs.selector === 'reportBoolean') {return morphs.children[0].evaluate(); -} else if (morphs.selector === 'JSBlocksArray') {return ('\[').concat(JSBlocksCompiler(morphs.inputs()[0]), '\]'); -} else if (morphs.selector === 'JSBlocksCloser') {return ('\(').concat(JSBlocksCompiler(morphs.inputs()[0]), '\)'); -} else if (morphs.selector === 'JSBlocksString1') {return ('\'').concat(morphs.children[1].evaluate(), '\''); -} else if (morphs.selector === 'JSBlocksString2') {return ('\"').concat(morphs.children[1].evaluate(), '\"'); -} else if (morphs.selector === 'JSBlocksString3') {return ('\`').concat(morphs.children[1].evaluate(), '\`'); -} else if (morphs.selector === 'JSBlocksObjectProp1') {return (JSBlocksCompiler( -morphs.inputs()[0].nestedBlock())).concat('\[', JSBlocksCompiler(morphs.inputs()[1]), '\]'); -} else if (morphs.selector === 'JSBlocksObjectProp2') {return JSBlocksCompiler(morphs.inputs()[0]); -} else if (morphs.selector === 'JSBlocksCall') {return '\('.concat(JSBlocksCompiler(morphs.inputs()[0].nestedBlock()), -'\)\(', JSBlocksCompiler(morphs.inputs()[1]), '\)'); -} else if (morphs.selector === 'JSBlocksObjectDeclaration') { -return ('\{').concat(JSBlocksCompiler(morphs.inputs()[0]), '\}'); -} else if (morphs.selector === 'JSBlocksObjectProperty') { -return JSBlocksCompiler(morphs.inputs()[0]).concat(' \: ', JSBlocksCompiler(morphs.inputs()[1])); -} else if (morphs.selector === 'JSBlocksNewObject') { -return ('new ').concat(JSBlocksCompiler(morphs.children[1])); -} else if (morphs.selector === 'JSBlocksNewTarget') {return 'new.target'; -} else if (morphs.selector === 'JSBlocksNotOperator') { -return ('!').concat(JSBlocksCompiler(morphs.children[1])); -} else {return '';};} else if ( -morphs instanceof MultiArgMorph) {return (function anonymous (morphs) {var theChildren = morphs.inputs(), -i = 0, miniResult = ''; while (i < theChildren.length) {if (i === (theChildren.length - 1)) { -miniResult = miniResult.concat(JSBlocksCompiler(theChildren[i]));} else { -miniResult = miniResult.concat(JSBlocksCompiler(theChildren[i]), morphs.infix); -}; i++;}; return miniResult;})(morphs);} else if (morphs instanceof TextSlotMorph) { -return morphs.contents().text;} else if (morphs instanceof InputSlotMorph) { -return morphs.contents().text;} else {return '';};}; \ No newline at end of file +else if (input instanceof Context) {return reportBasicToJS(input);} else {return reportBasicToJS(new Context());};}; \ No newline at end of file diff --git a/src/console.js b/src/console.js index 9bd8b13..54067f7 100644 --- a/src/console.js +++ b/src/console.js @@ -1,45 +1,41 @@ -var localFonts = [], snavancedIsRunning = false; async function loadASourceFont (name, url) {var newFont = new FontFace(name, ( -'url\(').concat(window.location.toString().split('snap.html')[0], url, '\)')); try {/* :~) */ await newFont.load(); document.fonts.add( -newFont); localFonts.push([url, name, newFont]);} catch (error) {console.error(error); localFonts.push([url, name, newFont]);}; if (!( -localFonts.length < 11) && !snavancedIsRunning) {initSnavanced();};}; function initSnavanced () {function detectPreferredLanguage () { +var localFonts = [], snavancedIsRunning = false; async function loadAFont (name, url) {var newFont = new FontFace(name, ('url\(' +).concat(window.location.toString().split('snap.html')[0], url, '\)')); try {/* :~) */ await newFont.load(); document.fonts.add( +newFont); localFonts.push([url, name, newFont]);} catch (error) {console.error(error); localFonts.push([url, name, newFont]);}; if ( +!(localFonts.length < 12) && !snavancedIsRunning) {initSnavanced();};}; function initSnavanced () {function detectPreferredLanguage () { if ('language' in navigator) {var selectedLanguage = ((navigator.language).split('-'))[0]; return (contains(Object.keys(SnapTranslator.dict ), selectedLanguage) ? selectedLanguage : 'en');} else {return 'en';};}; if (isNil(localStorage['-snap-setting-language'])) {localStorage[ '-snap-setting-language'] = detectPreferredLanguage();}; snavancedIsRunning = true; if (asABool(sessionStorage['-snap-setting-isDesktopMode' ])) {/* world.add(new LoginUIMorph(world)); */ world.add(desk); if (isNil(BlockMorph.prototype.snapSound)) {BlockMorph.prototype.toggleSnapSound( );}; document.title = 'Snavanced! - Desktop Mode'; if (true || asABool(localStorage['-snap-notification-newFile'])) {localStorage[ '-snap-notification-newFile'] = false; (function () {var i = 0; deskItems.forEach(function (aDeskItem) {aDeskItem.destroy();});})(); -deskItems = []; ((function anonymous () {var anArray = [], i = 0, j = 1, storage = window.localStorage; while (i < storage.length) {if ( -storage.key(i).startsWith('-snap-file-')) {anArray.push([storage['-snap-file-project-' + j], j]); j++;}; i++;}; return anArray;}).apply(this -)).forEach(function (pair) {deskItems.push(new FileMorph(pair[0], pair[1]));}); (function () {var i = 0; deskItems.forEach(function (aDeskItem -) {desk.add(aDeskItem); aDeskItem.bounds.origin = new Point(15 + ((i % 19) * 75), 15 + (Math.floor(i / 19) * 75)); -aDeskItem.bounds.corner = new Point(aDeskItem.bounds.origin.x + 60, aDeskItem.bounds.origin.y + 60); i = i + 1;});})();}; - -function loop () {requestAnimationFrame(loop); world.doOneCycle(); world.rerender();}; - -} else {(new IDE_Morph).openIn(world); function loop () {requestAnimationFrame(loop); world.doOneCycle();};}; - -loop();}; - -IDE_Morph.prototype.doLog = function anonymous ( +deskItems = []; ((function anonymous () {var anArray = [], i = 0, j = 1, storage = window.localStorage; while (i < storage.length) { +if (storage.key(i).startsWith('-snap-file-')) {anArray.push([storage['-snap-file-project-' + j], j]); j++;}; i++;}; return anArray; +}).apply(this)).forEach(function (pair) {deskItems.push(new FileMorph(pair[0], pair[1]));}); (function () {var i = 0; (deskItems +).forEach(function (aDeskItem) {desk.add(aDeskItem); aDeskItem.bounds.origin = new Point(15 + ((i % 19) * 75), 15 + (Math.floor( +i / 19) * 75)); aDeskItem.bounds.corner = new Point(aDeskItem.bounds.origin.x + 60, aDeskItem.bounds.origin.y + 60); i++;});})( +);}; function loop () {requestAnimationFrame(loop); world.doOneCycle(); world.rerender();};} else {(new IDE_Morph).openIn(world +); function loop () {requestAnimationFrame(loop); world.doOneCycle();};}; loop();}; /* Load all the fonts and init Snavanced! */ + +IDE_Morph.prototype.doLog = function ( object) {this.console.push(['log', object]); this.newLogs = (this.newLogs + 1);}; -IDE_Morph.prototype.doWarn = function anonymous ( +IDE_Morph.prototype.doWarn = function ( object) {this.console.push(['warn', object]); this.newLogs = (this.newLogs + 1);}; -IDE_Morph.prototype.doError = function anonymous ( +IDE_Morph.prototype.doError = function ( object) {this.console.push(['error', object]); this.newLogs = (this.newLogs + 1);}; -IDE_Morph.prototype.doInform = function anonymous ( +IDE_Morph.prototype.doInform = function ( object) {this.console.push(['information', object]); this.newLogs = (this.newLogs + 1);}; -IDE_Morph.prototype.doDebug = function anonymous ( +IDE_Morph.prototype.doDebug = function ( object) {this.console.push(['debug', object]); this.newLogs = (this.newLogs + 1);}; -IDE_Morph.prototype.doClear = function anonymous ( +IDE_Morph.prototype.doClear = function ( ) {this.newLogs = 0; this.console = [];}; try {console._log = console.log; -console.log = function anonymous (object) { +console.log = function (object) { var center = (world.childThatIsA(IDE_Morph ) || world.childThatIsA(DesktopMorph)); if ((center instanceof IDE_Morph) || ( @@ -47,7 +43,7 @@ center instanceof DesktopMorph)) { center.doLog(object);}; this._log( object);}; /* Modifies the JS. */ console._warn = console.warn; -console.warn = function anonymous (object) { +console.warn = function (object) { var center = (world.childThatIsA(IDE_Morph ) || world.childThatIsA(DesktopMorph)); if ((center instanceof IDE_Morph) || ( @@ -55,7 +51,7 @@ center instanceof DesktopMorph)) { center.doWarn(object);}; this._warn( object);}; /* Modifies the JS. */ console._error = console.log; -console.error = function anonymous (object) { +console.error = function (object) { var center = (world.childThatIsA(IDE_Morph ) || world.childThatIsA(DesktopMorph)); if ((center instanceof IDE_Morph) || ( @@ -63,7 +59,7 @@ center instanceof DesktopMorph)) { center.doError(object);}; this._error( object);}; /* Modifies the JS. */ console._info = console.info; -console.info = function anonymous (object) { +console.info = function (object) { var center = (world.childThatIsA(IDE_Morph ) || world.childThatIsA(DesktopMorph)); if ((center instanceof IDE_Morph) || ( @@ -71,7 +67,7 @@ center instanceof DesktopMorph)) { center.doInform(object);}; this._info( object);}; /* Modifies the JS. */ console._debug = console.debug; -console.debug = function anonymous (object) { +console.debug = function (object) { var center = (world.childThatIsA(IDE_Morph ) || world.childThatIsA(DesktopMorph)); if ((center instanceof IDE_Morph) || ( @@ -79,7 +75,7 @@ center instanceof DesktopMorph)) { center.doDebug(object);}; this._debug( object);}; /* Modifies the JS. */ console._clear = console.clear; -console.clear = function anonymous () { +console.clear = function () { var center = (world.childThatIsA(IDE_Morph ) || world.childThatIsA(DesktopMorph)); if ((center instanceof IDE_Morph) || ( @@ -119,17 +115,6 @@ error) {console.error(error);}; */ -// Global settings ///////////////////////////////////////////////////// -// cloud.js should be able to exist indepent of Snap! -// (The module date is included for simplicity, but is not needed elsewhere.) - -/*global modules, hex_sha512*/ - -modules = modules || {}; -modules.cloud = '2021-February-04'; - -// Global stuff - var Cloud; // Cloud ///////////////////////////////////////////////////////////// diff --git a/src/desktop.js b/src/desktop.js index f42db8d..f8b7d3e 100644 --- a/src/desktop.js +++ b/src/desktop.js @@ -120,7 +120,7 @@ return j;}).apply(this)); delete localStorage['-snap-file-project-' + this.id]; this.destroy(); localStorage['-snap-notification-newFile'] = true;}); return menu;}; FileMorph.prototype.pickUp = function (wrrld) {this.userState = 'highlight'; this.rerender(); var world = wrrld || this.world(); this.setPosition(world.hand.position( -).subtract(this.extent().floorDivideBy(2))); world.hand.grab(this);}; +).subtract(this.extent().divideBy(2))); world.hand.grab(this);}; /* diff --git a/src/extensions.js b/src/extensions.js index 8e7c7c0..4eff5ff 100644 --- a/src/extensions.js +++ b/src/extensions.js @@ -6,7 +6,7 @@ written by Jens Mönig - Copyright (C) 2022 by Jens Mönig + Copyright (C) 2024 by Jens Mönig This file is part of Snap!. @@ -25,22 +25,9 @@ */ -// Global settings ///////////////////////////////////////////////////// - -/*global modules, List, StageMorph, Costume, SpeechSynthesisUtterance, Sound, -IDE_Morph, CamSnapshotDialogMorph, SoundRecorderDialogMorph, isSnapObject, nop, -Color, Process, contains*/ - -/*jshint esversion: 11*/ - -modules.extensions = '2022-December-19'; - -// Global stuff - -var SnapExtensions = {primitives: new Map(), -menus: new Map(), buttons: {palette: []}, +var SnapExtensions = {primitives: new Map, +menus: new Map, buttons: {palette: []}, scripts: [], urls: [// allow-list of trusted servers - 'libraries/', 'https://snap.berkeley.edu/', 'https://ecraft2learn.github.io/ai/', // Uni-Oxford, Ken Kahn 'https://microworld.edc.org' // EDC, E. Paul Goldenberg diff --git a/src/gui.js b/src/gui.js index 7d2afcc..9d5741f 100644 --- a/src/gui.js +++ b/src/gui.js @@ -66,22 +66,6 @@ */ -/*global modules, Morph, SpriteMorph, SyntaxElementMorph, Color, Cloud, Audio, -ListWatcherMorph, TextMorph, newCanvas, useBlurredShadows, Sound, Scene, Note, -StringMorph, Point, MenuMorph, morphicVersion, DialogBoxMorph, BlockEditorMorph, -ToggleButtonMorph, contains, ScrollFrameMorph, StageMorph, PushButtonMorph, sb, -InputFieldMorph, FrameMorph, Process, nop, SnapSerializer, ListMorph, detect, -AlignmentMorph, TabMorph, Costume, MorphicPreferences,BlockMorph, ToggleMorph, -InputSlotDialogMorph, ScriptsMorph, isNil, SymbolMorph, fontHeight, localize, -BlockExportDialogMorph, BlockImportDialogMorph, SnapTranslator, List, ArgMorph, -Uint8Array, HandleMorph, SVG_Costume, TableDialogMorph, CommentMorph, saveAs, -CommandBlockMorph, BooleanSlotMorph, RingReporterSlotMorph, ScriptFocusMorph, -BlockLabelPlaceHolderMorph, SpeechBubbleMorph, XML_Element, WatcherMorph, WHITE, -BlockRemovalDialogMorph,TableMorph, isSnapObject, isRetinaEnabled, SliderMorph, -disableRetinaSupport, enableRetinaSupport, isRetinaSupported, MediaRecorder, -Animation, BoxMorph, BlockDialogMorph, Project, ZERO, BLACK, -BlockVisibilityDialogMorph, ThreadManager*/ - // Declarations var IDE_Morph, ProjectDialogMorph, LibraryImportDialogMorph, SpriteIconMorph, @@ -106,7 +90,7 @@ BackpackItemMorph.uber = BoxMorph.prototype; function BackpackItemMorph () {this.init();}; -BackpackItemMorph.prototype.init = function anonymous () {BackpackItemMorph.uber.init.call(this); +BackpackItemMorph.prototype.init = function () {BackpackItemMorph.uber.init.call(this); this.setExtent(new Point(45, 45));}; BackpackItemMorph.prototype.fixLayout = function () {}; // IDE_Morph /////////////////////////////////////////////////////////// @@ -229,9 +213,9 @@ IDE_Morph.prototype.init = function (isAutoFill index * rate) / 360) % 2) < 1) ? (((0 - ((((index * rate) + 90) / 360) % 2)) + 1) * 4) : (Process.prototype.reportMonadic(['sin'], (((((index * rate) % 720) * 0.25)) - 90)) - 1))) * (volume / 100 ); /* The sawtooth type of Rob Hubbard is a good legend. :') */})), new MIDSoundData('Vocoder', 100, (function anonymous (note, volume, length, index, optional) {var rate = Math.pow(2, ((note - 59 ) / 12)); return ((optional > 0) ? Process.prototype.reportMonadic(['sin'], (index * rate * 2)) : 0) * (volume / ((((Math.round(index / ((optional * 57.6) / rate)) % 2) + 2) * 50)));})), - new MIDSoundData('False Voice', 50, (function anonymous (note, volume, length, index, optional) {var rate = Math.pow(2, ((note - 35) / 12)), value1 = Process.prototype.reportMonadic(['sin'], ( + new MIDSoundData('False Voice', 50, (function (note, volume, length, index, optional) {var rate = Math.pow(2, ((note - 35) / 12)), value1 = Process.prototype.reportMonadic(['sin'], ( index * rate)), sampleNumber = ((index * rate) % 720), value2 = (((sampleNumber > 90) && (sampleNumber < 450)) ? 1 : value1); return ((value1 * ((100 - optional) / 100)) + (value2 * ( - optional / 100))) * (volume / 100);})), new MIDSoundData('Circloid', 100, (function anonymous (note, volume, length, index, optional) {var rate = Math.pow(2, ((note - 59) / 12)); + optional / 100))) * (volume / 100);})), new MIDSoundData('Circloid', 100, (function (note, volume, length, index, optional) {var rate = Math.pow(2, ((note - 59) / 12)); return Process.prototype.reportMonadic(['circ'], index * rate * 2) * (volume / 100);})), new MIDSoundData('Ingenous String', 0, (function anonymous (note, volume, length, index, optional) { var rate = Math.pow(2, ((note - 59) / 12)); return (((((index * rate) % 180) < 22.5) ? Process.prototype.reportMonadic(['circ'], (index * rate * 8)) : ((((index * rate) % 180) < 157.5) ? -( Process.prototype.reportMonadic(['curve'], (((((index * rate) - 22.5) * 2) % 360) * (4 / 3))) / 2) : Process.prototype.reportMonadic(['curve'], (index * rate * 8)))) * ((Math.abs( @@ -330,7 +314,7 @@ IDE_Morph.prototype.setOldDesign = function () { IDE_Morph.prototype.rotationStyleColors = IDE_Morph.prototype.tabColors; IDE_Morph.prototype.noPaddingForEditor = true; IDE_Morph.prototype.appModeColor = BLACK; - IDE_Morph.prototype.padding = 2.5; + IDE_Morph.prototype.padding = 2; SpriteIconMorph.prototype.labelColor = IDE_Morph.prototype.buttonLabelColor; @@ -356,6 +340,11 @@ IDE_Morph.prototype.setOldDesign = function () { this.fpsViewer.fixLayoutAndPosition();}; this.scriptsSpecialColors = [this.categoryColor.lighter(2), this.categoryColor.lighter(2)]; IDE_Morph.prototype.scriptsPaneTexture = this.scriptsTexture(); + PushButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + TabMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleElementMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); }; IDE_Morph.prototype.setSimpleDesign = function () { @@ -416,6 +405,11 @@ IDE_Morph.prototype.setSimpleDesign = function () { this.fpsViewer.fixLayoutAndPosition();}; this.scriptsSpecialColors = [this.categoryColor.lighter(6), this.categoryColor]; IDE_Morph.prototype.scriptsPaneTexture = this.scriptsTexture(); + PushButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + TabMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleElementMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); }; IDE_Morph.prototype.setDefaultDesign = function () { @@ -432,9 +426,9 @@ IDE_Morph.prototype.setDefaultDesign = function () { IDE_Morph.prototype.frameColor = SpriteMorph.prototype.paletteColor; IDE_Morph.prototype.groupColor - = SpriteMorph.prototype.paletteColor.lighter(20); - IDE_Morph.prototype.categoryColor = SpriteMorph.prototype.paletteColor.lighter(5); + IDE_Morph.prototype.categoryColor + = IDE_Morph.prototype.groupColor; IDE_Morph.prototype.sliderColor = SpriteMorph.prototype.sliderColor; IDE_Morph.prototype.buttonLabelColor = WHITE; IDE_Morph.prototype.tabColors = [ @@ -443,9 +437,9 @@ IDE_Morph.prototype.setDefaultDesign = function () { IDE_Morph.prototype.categoryColor ]; IDE_Morph.prototype.buttonColors = [ + IDE_Morph.prototype.groupColor, IDE_Morph.prototype.groupColor.darker(50), - IDE_Morph.prototype.groupColor.darker(75), - IDE_Morph.prototype.groupColor.darker(75) + IDE_Morph.prototype.groupColor.darker(50) ]; IDE_Morph.prototype.rotationStyleColors = IDE_Morph.prototype.tabColors; IDE_Morph.prototype.noPaddingForEditor = false; @@ -474,12 +468,17 @@ IDE_Morph.prototype.setDefaultDesign = function () { if (this.fpsViewer instanceof IDE_FPSMorph) { this.fpsViewer.color = IDE_Morph.prototype.buttonLabelColor; this.fpsViewer.fixLayoutAndPosition();}; - this.scriptsSpecialColors = [this.categoryColor.lighter(2), this.categoryColor.lighter(2)]; + this.scriptsSpecialColors = [this.groupColor.lighter(2), this.groupColor.darker(2)]; IDE_Morph.prototype.scriptsPaneTexture = this.scriptsTexture(); + PushButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + TabMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleElementMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); }; IDE_Morph.prototype.setLightDesign = function () { - SpriteMorph.prototype.paletteColor = (new Color(249, 249, 249)).darker(5); + SpriteMorph.prototype.paletteColor = WHITE; SpriteMorph.prototype.paletteTextColor = new Color(70, 70, 70); StageMorph.prototype.paletteTextColor = SpriteMorph.prototype.paletteTextColor; @@ -487,18 +486,17 @@ IDE_Morph.prototype.setLightDesign = function () { SpriteMorph.prototype.sliderColor = SpriteMorph.prototype.paletteColor; IDE_Morph.prototype.buttonContrast = 30; - IDE_Morph.prototype.backgroundColor = WHITE; - IDE_Morph.prototype.frameColor = SpriteMorph.prototype.paletteColor; + IDE_Morph.prototype.backgroundColor = new Color(220, 220, 230); + IDE_Morph.prototype.frameColor = new Color(240, 240, 245); IDE_Morph.prototype.groupColor = WHITE; - IDE_Morph.prototype.categoryColor - = SpriteMorph.prototype.paletteColor.darker(5); + IDE_Morph.prototype.categoryColor = WHITE; IDE_Morph.prototype.sliderColor = SpriteMorph.prototype.sliderColor; - IDE_Morph.prototype.buttonLabelColor = new Color((255 / 3), (255 / 3), (255 / 3)); + IDE_Morph.prototype.buttonLabelColor = new Color(70, 70, 70); IDE_Morph.prototype.tabColors = [ - IDE_Morph.prototype.groupColor, - IDE_Morph.prototype.groupColor.darker(10), - IDE_Morph.prototype.groupColor.darker(20) + IDE_Morph.prototype.frameColor, + IDE_Morph.prototype.frameColor.lighter(50), + IDE_Morph.prototype.groupColor ]; IDE_Morph.prototype.buttonColors = IDE_Morph.prototype.tabColors; IDE_Morph.prototype.rotationStyleColors = IDE_Morph.prototype.tabColors; @@ -523,13 +521,18 @@ IDE_Morph.prototype.setLightDesign = function () { SceneIconMorph.prototype.labelColor = IDE_Morph.prototype.buttonLabelColor; - SyntaxElementMorph.prototype.contrast = 65; + SyntaxElementMorph.prototype.contrast = 25; ScriptsMorph.prototype.feedbackColor = WHITE; if (this.fpsViewer instanceof IDE_FPSMorph) { this.fpsViewer.color = IDE_Morph.prototype.buttonLabelColor; this.fpsViewer.fixLayoutAndPosition();}; - this.scriptsSpecialColors = [this.categoryColor.lighter(7), this.categoryColor.lighter(7)]; - IDE_Morph.prototype.scriptsPaneTexture = this.scriptsTexture(); + this.scriptsSpecialColors = [CLEAR, CLEAR]; + IDE_Morph.prototype.scriptsPaneTexture = null; + PushButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + TabMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleElementMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); }; IDE_Morph.prototype.setAnimatedDesign = function () { @@ -582,15 +585,20 @@ IDE_Morph.prototype.setAnimatedDesign = function () { if (this.fpsViewer instanceof IDE_FPSMorph) { this.fpsViewer.color = IDE_Morph.prototype.buttonLabelColor; this.fpsViewer.fixLayoutAndPosition();}; - this.scriptsSpecialColors = [this.categoryColor.lighter(7), this.categoryColor.lighter(7)]; - IDE_Morph.prototype.scriptsPaneTexture = this.scriptsTexture(); + this.scriptsSpecialColors = [CLEAR, CLEAR]; + IDE_Morph.prototype.scriptsPaneTexture = null; + PushButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleButtonMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + TabMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); + ToggleElementMorph.prototype.outlineColor = (IDE_Morph.prototype.frameColor).withAlpha(0.5); }; IDE_Morph.prototype.mathConstants = (() => [['π Pi', Math.PI], ['e Euler', Math.E], ['p Plastic', (Math.cbrt((9 + Math.sqrt(69)) / 18) + Math.cbrt((9 - Math.sqrt(69)) / 18))], ['φ Phi', ((1 + Math.sqrt(5)) / 2 )], ['ψ Psi', ((1 + Math.cbrt((29 + Math.sqrt(837)) / 2) + Math.cbrt((29 - Math.sqrt(837)) / 2)) / 3)], ['ε Epsilon', Number.EPSILON], ['i Imaginary', new ComplexNumber(0, 1)]]); /* | Okay, they are. :) | */ -IDE_Morph.prototype.scriptsTexture = function anonymous () { - var w = 100, h = w, pic = newCanvas(new Point(w, h)), +IDE_Morph.prototype.scriptsTexture = function () { + var w = 400, h = w, pic = newCanvas(new Point(w, h)), ctx = pic.getContext('2d'), i; for (i = 0; i < w; i += 4) { ctx.fillStyle = this.frameColor.toString(); @@ -928,49 +936,26 @@ IDE_Morph.prototype.openIn = function (world) {var hash, myself = this; this.bui // IDE_Morph construction -IDE_Morph.prototype.buildPanes = function () {this.createLogo(); this.createControlBar(); this.createCategories(); this.createPalette(); this.createStage(); this.createSpriteBar(); this.createSpriteEditor(); -this.createCorralBar(); this.createCorral();}; IDE_Morph.prototype.createLogo = function () {var myself = this; if (this.logo) {this.logo.destroy();}; this.logo = new Morph; this.logo.texture = snapLogoTexture; -this.logo.render = function (ctx) {var gradient = ctx.createLinearGradient(0, 0, this.width(), 0); gradient.addColorStop(0, IDE_Morph.prototype.frameColor.darker(25).toString()); gradient.addColorStop(0.5, -myself.frameColor.toString()); ctx.fillStyle = (MorphicPreferences.isFlat ? myself.frameColor.toString() : gradient); ctx.fillRect(0, 0, this.width(), this.height()); if (this.cachedTexture) { -this.renderCachedTexture(ctx);} else if (this.texture) {this.renderTexture(this.texture, ctx);}}; this.logo.renderCachedTexture = function (ctx) {ctx.drawImage(this.cachedTexture, 2, Math.round( -(this.height() - this.cachedTexture.height) / 2)); this.changed();}; this.logo.mouseClickLeft = function () {myself.snapMenu();}; this.logo.color = BLACK; this.logo.setExtent(new Point(200, 28)); -this.add(this.logo);}; IDE_Morph.prototype.createControlBar = function () { - var padding = 5, - button, - slider, - stopButton, - pauseButton, - startButton, - projectButton, - settingsButton, - stageSizeButton, - appModeButton, - steppingButton, - cloudButton, - gradient, x, - colors = this.buttonColors, - activeColor = new Color(153, 255, 213), - activeColors = [ - activeColor, - activeColor.lighter(40), - activeColor.lighter(40) - ], - myself = this; - - if (this.controlBar) { - this.controlBar.destroy(); - } - - this.controlBar = new Morph; - this.controlBar.color = this.frameColor; - this.controlBar.setHeight(this.logo.height()); - this.controlBar.mouseClickLeft = function () { - this.world().fillPage(); - }; - - this.add(this.controlBar); - - //smallStageButton +IDE_Morph.prototype.buildPanes = function () {this.createLogo(); this.createControlBar(); this.createCategories(); +this.createPalette(); this.createStage(); this.createSpriteBar(); this.createSpriteEditor(); this.createCorralBar( +); this.createCorral();}; IDE_Morph.prototype.createLogo = function () {var myself = this; if (this.logo) {(this +).logo.destroy();}; this.logo = new Morph; this.logo.texture = snapLogoTexture; this.logo.render = function (ctx) { +ctx.fillStyle = myself.frameColor.toString(); ctx.fillRect(0, 0, this.width(), this.height()); if (this.cachedTexture +) {this.renderCachedTexture(ctx);} else if (this.texture) {this.renderTexture(this.texture);};}; (this.logo +).renderCachedTexture = function (ctx) {ctx.imageSmoothingEnabled = false; ctx.drawImage(this.cachedTexture, +2, Math.round(this.height() - (this.cachedTexture.height)) / 2); this.changed();}; (this.logo.mouseClickLeft +) = function () {myself.snapMenu();}; this.logo.setExtent(new Point(200, 28)); this.add(this.logo);}; +IDE_Morph.prototype.createControlBar = function () {var padding = 5, button, slider, stopButton, +pauseButton, startButton, projectButton, settingsButton, stageSizeButton, appModeButton, +steppingButton, cloudButton, gradient, x, colors = this.buttonColors, activeColor = ( +new Color(153, 255, 213)), activeColors = [activeColor, activeColor.lighter(40), +activeColor.lighter(40)], myself = this; if (this.controlBar) {(this.controlBar +).destroy();}; this.controlBar = new Morph; this.controlBar.color = (this +).frameColor; this.controlBar.setHeight(this.logo.height()); (this +).controlBar.mouseClickLeft = (() => world.fillPage()); this.add( +this.controlBar); + + // smallStageButton button = new ToggleButtonMorph( null, //colors, this, // the IDE is the target @@ -991,9 +976,7 @@ this.add(this.logo);}; IDE_Morph.prototype.createControlBar = function () { button.padding = 0; button.labelShadowOffset = new Point(-1, -1); button.labelShadowColor = colors[1]; - button.labelColor = MorphicPreferences.isFlat ? - WHITE - : this.buttonLabelColor; + button.labelColor = WHITE; button.contrast = this.buttonContrast; // button.hint = 'stage size\nsmall & normal'; button.fixLayout(); @@ -1002,7 +985,7 @@ this.add(this.logo);}; IDE_Morph.prototype.createControlBar = function () { this.controlBar.add(stageSizeButton); this.controlBar.stageSizeButton = button; // for refreshing - //appModeButton + // appModeButton button = new ToggleButtonMorph( null, //colors, this, // the IDE is the target @@ -1032,17 +1015,15 @@ this.add(this.logo);}; IDE_Morph.prototype.createControlBar = function () { this.controlBar.add(appModeButton); this.controlBar.appModeButton = appModeButton; // for refreshing - //videoCaptureButton + // videoCaptureButton button = new ToggleButtonMorph( null, //colors, this, // the IDE is the target 'toggleScreenshotDialog', - [ - new SymbolMorph('video', 14), - new SymbolMorph('videoOutline', 14) - ], - () => ((world.children.filter(child => child instanceof DialogBoxMorph).filter(child => child.key === 'screenshotMaker').length) > 0) // query - ); + [new SymbolMorph('video', 14), + new SymbolMorph('videoOutline', 14)], () => ( + (world.children.filter(child => child instanceof DialogBoxMorph + ).filter(child => child.key === 'screenshotMaker').length) > 0)); button.hasNeutralBackground = true; button.corner = 12; @@ -1062,19 +1043,15 @@ this.add(this.logo);}; IDE_Morph.prototype.createControlBar = function () { this.controlBar.add(videoCaptureButton); this.controlBar.videoCaptureButton = videoCaptureButton; // for refreshing - //steppingButton + // steppingButton button = new ToggleButtonMorph( null, //colors, this, // the IDE is the target 'toggleSingleStepping', - [ - new SymbolMorph('footprints', 16), - new SymbolMorph('footprints', 16) - ], - () => Process.prototype.enableSingleStepping // query - ); - - button.corner = 12; + [new SymbolMorph('footprints', 16), + new SymbolMorph('footprints', 16)], + () => Process.prototype.enableSingleStepping + ); button.corner = 12; button.color = colors[0]; button.highlightColor = colors[1]; button.pressColor = activeColor; @@ -1091,7 +1068,7 @@ this.add(this.logo);}; IDE_Morph.prototype.createControlBar = function () { this.controlBar.add(steppingButton); this.controlBar.steppingButton = steppingButton; // for refreshing -// stopButton +// stopButton button = new TriggerMorph; button.cursorStyle = 'pointer'; stopButton = button; button.target = button; @@ -1134,13 +1111,14 @@ button.render = function (ctx) { button.refresh = button.rerender; button.setExtent(new Point(14, 14)); button.color = new Color(200, 0, 0); -button.highlightColor = new Color(255, 0, 0); -button.pressColor = new Color(127.5, 0, 0); -button.action = function () {this.parentThatIsA(IDE_Morph).stopAllScripts();}; -button.contrast = this.buttonContrast; +button.highlightColor = new Color(255, +0, 0); button.pressColor = new Color( +127.5, 0, 0); button.action = function ( +) {this.parentThatIsA(IDE_Morph).stopAllScripts( +);}; button.contrast = this.buttonContrast; button.fixLayout(); -// pauseButton +// pauseButton button = new TriggerMorph; button.cursorStyle = 'pointer'; pauseButton = button; button.target = button; @@ -1203,7 +1181,7 @@ button.action = function () {this.parentThatIsA(IDE_Morph).togglePauseResume();} button.contrast = this.buttonContrast; button.fixLayout(); -// startButton +// startButton button = new TriggerMorph; button.cursorStyle = 'pointer'; startButton = button; button.target = button; @@ -1273,12 +1251,10 @@ button.step = function () { var isRunning; if (!myself.stage) { return; - } - isRunning = !!myself.stage.threads.processes.length; + }; isRunning = !!myself.stage.threads.processes.length; if (isRunning === this.isActive) { return; - } - this.isActive = isRunning; + }; this.isActive = isRunning; if (isRunning) { this.color = activeColors[0]; this.highlightColor = activeColors[1]; @@ -1287,26 +1263,21 @@ button.step = function () { this.color = new Color(0, 200, 0); this.highlightColor = new Color(0, 255, 0); this.pressColor = new Color(0, 127.5, 0); - } - this.rerender(); -}; + }; this.rerender();}; button.action = function () {this.parentThatIsA(IDE_Morph).pressStart();}; button.contrast = this.buttonContrast; button.fixLayout(); - // steppingSlider + // steppingSlider slider = new SliderMorph( - 61, - 1, - Process.prototype.flashTime * 100 + 1, - 6, + 61, 1, (((Process + ).prototype.flashTime + ) * 100) + 1, 6, 'horizontal' - ); - slider.action = (num) => { + ); slider.action = (num) => { Process.prototype.flashTime = (num - 1) / 100; this.controlBar.refreshResumeSymbol(); - }; - slider.color = activeColor; + }; slider.color = activeColor; slider.alpha = MorphicPreferences.isFlat ? (1 / 4) : (1 / 8); slider.setExtent(new Point(50, 14)); this.controlBar.add(slider); @@ -1334,7 +1305,7 @@ button.fixLayout(); this.controlBar.add(projectButton); this.controlBar.projectButton = projectButton; - // settingsButton + // settingsButton button = new PushButtonMorph( this, 'settingsMenu', @@ -1356,10 +1327,10 @@ button.fixLayout(); this.controlBar.add(settingsButton); this.controlBar.settingsButton = settingsButton; - // cloudButton + // userButton button = new PushButtonMorph( this, - function anonymous () {/* var dialog = new DialogBoxMorph; dialog.popUp(world); */ + function () {/* var dialog = new DialogBoxMorph; dialog.popUp(world); */ var menu, pos = this.controlBar.cloudButton.bottomLeft(), shiftClicked = (world.currentKey === 16); menu = new MenuMorph(this); menu.addItem('Change your username...', function () {world.childThatIsA(IDE_Morph).prompt(localize('Where is your new username?'), function (output) {if (output === '') {myself.removeSetting('user');} else {world.childThatIsA(IDE_Morph).saveSetting('user', output);};}, null, 'Changing Name');}); menu.popup(world, pos);}, @@ -1377,7 +1348,7 @@ button.fixLayout(); button.labelShadowColor = colors[1]; button.labelColor = this.buttonLabelColor; button.contrast = this.buttonContrast; - button.hint = 'This is your user-interface, ' + this.getUser() + '.'; + button.hint = 'This is your user interface, ' + this.getUser() + '.'; button.fixLayout(); cloudButton = button; this.controlBar.add(cloudButton); @@ -1391,22 +1362,15 @@ button.fixLayout(); button.setRight(x + (button.width() * 1.25)); x -= padding; } - ); - - x = Math.min( + ); x = Math.min( startButton.left() - (3 * padding + 2 * stageSizeButton.width()), myself.right() - myself.stage.dimensions.x * (myself.isSmallStage ? myself.stageRatio : 1) ); [stageSizeButton, appModeButton, videoCaptureButton].forEach(button => { - x += padding; - button.setCenter(myself.controlBar.center()); - button.setLeft(x); - x += button.width(); - } - ); - - slider.setCenter(myself.controlBar.center()); + x += padding; button.setCenter(myself.controlBar.center()); + button.setLeft(x); x += button.width();} + ); slider.setCenter(myself.controlBar.center()); slider.setRight(stageSizeButton.left() - padding); steppingButton.setCenter(myself.controlBar.center()); @@ -1421,9 +1385,7 @@ button.fixLayout(); projectButton.setRight(cloudButton.left() - padding); this.refreshSlider(); this.updateLabel(); - }; - - this.controlBar.refreshSlider = function () { + }; this.controlBar.refreshSlider = function () { if (Process.prototype.enableSingleStepping && !myself.isAppMode) { slider.fixLayout(); slider.rerender(); @@ -1449,23 +1411,17 @@ button.fixLayout(); false, MorphicPreferences.isFlat ? null : new Point(2, 1), myself.frameColor.darker(myself.buttonContrast) - ); - txt.color = myself.buttonLabelColor; + ); txt.color = myself.buttonLabelColor; this.label = new FrameMorph; this.label.acceptsDrops = false; this.label.alpha = 0; txt.setPosition(this.label.position()); this.label.add(txt); this.label.setExtent( - new Point( - steppingButton.left() - settingsButton.right() - padding * 2, - txt.height() - ) - ); this.label.setCenter(this.center()); - this.label.setLeft(this.settingsButton.right() + padding); - this.add(this.label); - }; -}; + new Point(myself.logo.right(), txt.height( + ))); this.label.setCenter(this.center()); + this.label.setLeft((settingsButton.right( + )) + 5); this.add(this.label);};}; IDE_Morph.prototype.initializeBackpack = function () {var ide = this; if (ide.backpack) { @@ -1510,17 +1466,11 @@ backpack.reactToDropOf = (droppedMorph, hand) => { ide.initializeBackpack(); }; -backpack.fixLayout = function() { - var frame = this.parent.spriteEditor; - this.setLeft(frame.left()); - this.setWidth(frame.width()); - this.setBottom(frame.bottom()); - this.setHeight((SyntaxElementMorph.prototype.scale || 1) * 80); - this.rerender(); - this.toggleButton.fixLayout(); - this.backButton.fixLayout(); - this.nextButton.fixLayout(); -} +backpack.fixLayout = function() {var frame = this.parent.spriteEditor; +this.setLeft(frame.left()); this.setWidth(frame.width()); this.setBottom( +frame.bottom()); this.setHeight(Math.round(((SyntaxElementMorph.prototype +).scale || 1) * 80)); this.rerender(); this.toggleButton.fixLayout(); +this.backButton.fixLayout(); this.nextButton.fixLayout();}; backpack.page = 0; backpack.pages = window.blockArrays; @@ -1581,11 +1531,9 @@ button.fixLayout = function () { this.setTop(backpack.top()); } else { this.setBottom(backpack.bottom()); - }; - this.label.setCenter(this.center().translateBy(new Point(0, -1))); + }; this.label.setCenter(this.center().translateBy(new Point(0, -1))); this.setWidth(ide.spriteEditor.width()); if (ide.isAppMode) {this.isVisible = !ide.isAppMode;}; - }; button = new TriggerMorph; @@ -1953,7 +1901,8 @@ IDE_Morph.prototype.createCategories = function () { this.categories.refreshEmpty = function () { var dict = myself.currentSprite.emptyCategories(); this.buttons.forEach(cat => { - if (dict[cat.category]) { + if (dict[cat.category] || ( + cat.category === 'other')) { cat.enable(); } else { cat.disable(); @@ -1978,8 +1927,7 @@ IDE_Morph.prototype.createCategories = function () { var labelWidth = 75, colors = [ myself.frameColor, - myself.frameColor.darker((asANum( - !MorphicPreferences.isFlat) * 10) * 5), + myself.frameColor.darker((1 + (MorphicPreferences.isFlat * 9)) * 5), SpriteMorph.prototype.blockColor[category] ], button; @@ -2001,22 +1949,17 @@ IDE_Morph.prototype.createCategories = function () { button.labelShadowOffset = new Point(-1, -1); button.labelShadowColor = colors[1]; button.labelColor = myself.buttonLabelColor; - if (MorphicPreferences.isFlat) { - button.labelPressColor = WHITE; - } - button.fixLayout(); - button.refresh(); - myself.categories.add(button); + button.labelPressColor = WHITE; + button.fixLayout(); button.refresh( + ); myself.categories.add(button); myself.categories.buttons.push(button); return button; - } - - function addCustomCategoryButton(category, color) { + }; function addCustomCategoryButton(category, color) { var labelWidth = 75, colors = [ myself.frameColor, - myself.frameColor.darker(MorphicPreferences.isFlat ? 5 : 50), - color + myself.frameColor.darker((1 + (MorphicPreferences.isFlat * 9)) * 5), + SpriteMorph.prototype.blockColor[category] ], button; button = new ToggleButtonMorph( @@ -2037,10 +1980,9 @@ IDE_Morph.prototype.createCategories = function () { button.labelShadowOffset = new Point(-1, -1); button.labelShadowColor = colors[1]; button.labelColor = myself.buttonLabelColor; - if (MorphicPreferences.isFlat) { - button.labelPressColor = WHITE; - }; button.fixLayout(); button.refresh(); - myself.categories.add(button); + button.labelPressColor = WHITE; + button.fixLayout(); button.refresh( + ); myself.categories.add(button); myself.categories.buttons.push(button); return button; }; function fixCategoriesLayout() { @@ -2048,11 +1990,8 @@ IDE_Morph.prototype.createCategories = function () { buttonHeight = myself.categories.children[0].height(), border = 3, rows = Math.ceil((myself.categories.children.length) / 2), - xPadding = (200 // myself.logo.width() - - border - - buttonWidth * 2) / 3, - yPadding = 2, - l = myself.categories.left(), + xPadding = (200 - border - buttonWidth * 2) / 3, + yPadding = 2, l = myself.categories.left(), t = myself.categories.top(), i = 0, row, col; @@ -2193,28 +2132,20 @@ IDE_Morph.prototype.createStageHandle = function () { IDE_Morph.prototype.createSpriteBar = function () { // assumes that the categories pane has already been created - var rotationStyleButtons = [], - thumbSize = new Point(45, 45), - nameField, - padlock, - thumbnail, - tabCorner = 15, - tabColors = this.tabColors, + var rotationStyleButtons = [], thumbSize = new Point(45, 45 + ), nameField, padlock, thumbnail, tabCorner = 15, + tabColors = this.tabColors, tab, myself = this, tabBar = new AlignmentMorph('row', -tabCorner * 2), - tab, symbols = [ new SymbolMorph('square', 3.75), new SymbolMorph('turnAround', 10), new SymbolMorph('arrowLeftRightThin', 10), - ], - labels = ['don\'t rotate', 'can rotate', 'only face left/right'], - myself = this; + ], labels = ['don\'t rotate', 'can rotate', + 'only face left/right']; if (this.spriteBar) { this.spriteBar.destroy(); - } - - this.spriteBar = new Morph; + }; this.spriteBar = new Morph; this.spriteBar.color = this.frameColor; this.add(this.spriteBar); @@ -2288,77 +2219,68 @@ IDE_Morph.prototype.createSpriteBar = function () { }; }; - nameField = new InputFieldMorph(this.currentSprite.name); - nameField.setWidth(100); // fixed dimensions - nameField.contrast = 90; - nameField.setPosition(thumbnail.topRight().add(new Point(10, 3))); - this.spriteBar.add(nameField); - this.spriteBar.nameField = nameField; - nameField.fixLayout(); + nameField = new InputFieldMorph((this.currentSprite + ).name); nameField.setWidth(100); (nameField.contrast + ) = 90; nameField.setPosition(thumbnail.topRight( + ).add(new Point(10, 3))); this.spriteBar.add( + nameField); this.spriteBar.nameField = ( + nameField); nameField.fixLayout(); nameField.accept = function () { - var newName = nameField.getValue(); - myself.currentSprite.setName( - myself.newSpriteName(newName, myself.currentSprite) - ); - nameField.setContents(myself.currentSprite.name); + var newName = nameField.getValue( + ); myself.currentSprite.setName( + myself.newSpriteName(newName, + myself.currentSprite)); + nameField.setContents(( + myself.currentSprite).name); myself.recordUnsavedChanges(); - }; - this.spriteBar.reactToEdit = nameField.accept; + }; ((this.spriteBar).reactToEdit + ) = nameField.accept; // padlock padlock = new ToggleMorph( - 'checkbox', - null, - () => { - this.currentSprite.isDraggable = !this.currentSprite.isDraggable; - this.recordUnsavedChanges(); - }, - localize('draggable'), - () => this.currentSprite.isDraggable - ); - padlock.label.isBold = false; - padlock.label.setColor(this.buttonLabelColor); - padlock.color = tabColors[2]; - padlock.highlightColor = tabColors[0]; - padlock.pressColor = tabColors[1]; - - padlock.tick.shadowOffset = MorphicPreferences.isFlat ? - ZERO : new Point(-1, -1); + 'checkbox', null, () => {( + this.currentSprite).setDraggableTo( + !((this.currentSprite).isDraggable + )); this.recordUnsavedChanges();}, + localize('draggable'), (function ( + ) {return ((myself.currentSprite + ).isDraggable);})); (padlock.label + ).isBold = false; (padlock.label + ).setColor(this.buttonLabelColor + ); padlock.color = tabColors[2]; + padlock.highlightColor = tabColors[ + 0]; padlock.pressColor = tabColors[1]; + + padlock.tick.shadowOffset = (( + MorphicPreferences).isFlat ? ( + ZERO) : new Point(-1, -1)); padlock.tick.shadowColor = BLACK; padlock.tick.color = this.buttonLabelColor; padlock.tick.isBold = false; padlock.tick.fixLayout(); padlock.setPosition(nameField.bottomLeft().add(2)); - padlock.fixLayout(); - this.spriteBar.add(padlock); + padlock.fixLayout(); this.spriteBar.add(padlock); if (this.currentSprite instanceof StageMorph) { - padlock.hide(); - } + padlock.hide();}; // tab bar - tabBar.tabTo = function (tabString) { - var active; - if (myself.currentTab === tabString) {return; } - myself.world().hand.destroyTemporaries(); + tabBar.tabTo = function ( + tabString) {var active; + if (myself.currentTab === tabString) {return; + }; myself.world().hand.destroyTemporaries(); myself.currentTab = tabString; this.children.forEach(each => { - each.refresh(); - if (each.state) {active = each;}; - }); - active.refresh(); // needed when programmatically tabbing - myself.createSpriteEditor(); - myself.fixLayout('tabEditor'); - }; - - tab = new TabMorph( - tabColors, - null, // target + each.refresh(); if ( + each.state) {active = ( + each);};}); active.refresh( + ); myself.createSpriteEditor( + ); myself.fixLayout('tabEditor');}; + tab = new TabMorph(tabColors, null, () => tabBar.tabTo('scripts'), - localize('Scripts'), // label - () => this.currentTab === 'scripts' // query - ); - tab.padding = 3; + localize('Scripts'), () => ( + this.currentTab === 'scripts' + )); tab.padding = 3; tab.corner = tabCorner; tab.edge = 1; tab.labelShadowOffset = new Point(-1, -1); @@ -3389,13 +3311,11 @@ IDE_Morph.prototype.startFastTracking = function () {this.stage.isFastTracked = IDE_Morph.prototype.stopFastTracking = function () {this.stage.isFastTracked = false;}; IDE_Morph.prototype.runScripts = function () {if (this.stage.threads.pauseCustomHatBlocks) {this.stage.threads.pauseCustomHatBlocks = false; this.controlBar.stopButton.refresh();}; this.stage.fireGreenFlagEvent( -);}; IDE_Morph.prototype.togglePauseResume = function () {if (this.stage.threads.isPaused()) {world.children.filter(function (child) {if (child instanceof DialogBoxMorph) {return child.key === 'debug';} else { -return false;}}).forEach(function (child) {child.destroy();}); this.stage.timerProcedure.resumeNow(); this.stage.threads.resumeAll(this.stage);} else {this.stage.threads.pauseAll(this.stage); if ( -this.stage.threads.processes.length > 0) {this.stage.timerProcedure.pauseNow();} else {if (this.stage.timerProcedure.state === 'paused') {this.stage.timerProcedure.resumeNow();} else { -this.stage.timerProcedure.pauseNow();};};}; this.controlBar.pauseButton.refresh();}; IDE_Morph.prototype.isPaused = function () {if (!this.stage) {return false;}; return this.stage.threads.isPaused();}; -IDE_Morph.prototype.stopAllScripts = function () {var ide = this; if (this.world().currentKey === 16) {this.scenes.map(scn => scn.stop(true));} else {this.scene.stop();}; var dialog = world.children.filter( -child => child instanceof DialogBoxMorph).filter(child => child.key === 'screenshotMaker'); if (dialog.length > 0) {dialog = dialog[0]; if ((dialog.button2.labelString.color.g > 0) && ( -dialog.button1.labelString.name === 'circleSolid')) {dialog.button1.action(); dialog.button1.fixLayout();};};}; +);}; IDE_Morph.prototype.togglePauseResume = function () {if (this.stage.threads.isPaused()) {world.children.filter(function (child) {if (child instanceof DialogBoxMorph) {return child.key === 'debug'; +} else {return false;};}).forEach(function (child) {child.destroy();}); this.stage.timerProcedure.resumeNow(); this.stage.threads.resumeAll(this.stage);} else {this.stage.threads.pauseAll((this +).stage); if ((this.stage).threads.processes.length > 0) {this.stage.timerProcedure.pauseNow();} else {if (this.stage.timerProcedure.state === 'paused') {this.stage.timerProcedure.resumeNow( +);} else {(this.stage.timerProcedure).pauseNow();};};}; this.controlBar.pauseButton.refresh();}; IDE_Morph.prototype.isPaused = function () {if (!this.stage) {return false;}; return (this.stage +).threads.isPaused();}; IDE_Morph.prototype.stopAllScripts = function () {var ide = this; if (this.world().currentKey === 16) {this.scenes.map(scn => scn.stop(true));} else {this.scene.stop();};}; IDE_Morph.prototype.selectSprite = function (sprite, noEmptyRefresh) { if (this.currentSprite && this.currentSprite.scripts.focus) { @@ -3572,7 +3492,7 @@ var username = this.cloud.username; this.scene.captureGlobalSettings(); } else {callback()}; }; -IDE_Morph.prototype.clearBackup = function () {this.confirm('Do you wanna to delete the backup?\n\(All unsaved data will be erased.\)', 'Hmm...', +IDE_Morph.prototype.clearBackup = function () {this.confirm('Do you want to delete the backup?\n\(All unsaved data will be erased.\)', 'Hmm...', function () {delete localStorage['-snap-bakflag-']; delete localStorage['-snap-bakuser-']; delete localStorage['-snap-backup-'];});}; IDE_Morph.prototype.availableBackup = function (anyway) {var username = this.cloud.username, bak, ix; @@ -4240,7 +4160,7 @@ IDE_Morph.prototype.settingsMenu = function () { addPreference( 'Backuping Projects', () => {if (asABool(this.getSetting('backup'))) {this.saveSetting('backup', false);} else {this.saveSetting('backup', true);};}, asABool(this.getSetting('backup')), - 'uncheck to not create backups\nof your projects\n\(don\'t unckeck this if you don\'t wanna to stay\nsad about of your losted projects.\)', 'check to create backups\nof your projects', true + 'uncheck to not create backups\nof your projects\n\(don\'t unckeck this if you don\'t want to stay\nsad about of your losted projects.\)', 'check to create backups\nof your projects', true ); addPreference( 'Animations', @@ -4496,9 +4416,9 @@ if (storage.key(i).startsWith('-snap-file-')) {anArray.push([storage.getItem(sto }); menu.addItem('Save As...', 'saveProjectsBrowser');}; menu.addItem('Reload', function () {location.reload();}); menu.addItem('Quit', function () {window.close();}); if (backup) {menu.addItem('Open Backup', 'restore', backup, new Color(100, 0, 0)); menu.addItem('Delete Backup', 'clearBackup', backup, new Color(100, 0, 0));}; menu.addLine(); menu.addItem('Open Snapinator', () => {window.open( (window.location.toString().split('snap.html')[0]).concat('src/snapinator/index.html'), 'Snapinator', "width=1025, height=775");}); menu.addItem('Open Tetris', function () {window.open( -window.location.toString().split('index.html')[0] + 'src/tetris/index.html', 'JsTetris - javascript tetris game', "width=302, height=312");}); menu.addItem('Open Colors', function () { -window.open(window.location.toString().split('index.html')[0] + 'src/colors.html', 'Colors v1.0', "width=572, height=447");}); menu.addItem('Open Alonzweeper', function () {window.open( -window.location.toString().split('index.html')[0] + 'src/alonzweeper/index.html', 'Alonzweeper', "width=1440, height=990");}); menu.addLine(); menu.addItem('Import...', 'importLocalFile', +window.location.toString().split('snap.html')[0] + 'src/tetris/index.html', 'JsTetris - javascript tetris game', "width=302, height=312");}); menu.addItem('Open Colors', function () { +window.open(window.location.toString().split('snap.html')[0] + 'src/colors.html', 'Colors v1.0', "width=572, height=447");}); menu.addItem('Open Alonzweeper', function () {window.open( +window.location.toString().split('snap.html')[0] + 'src/alonzweeper/index.html', 'Alonzweeper', "width=1440, height=990");}); menu.addLine(); menu.addItem('Import...', 'importLocalFile', 'file menu import hint'); menu.addItem('Export project...', () => {var pn = this.getProjectName(); if (pn) {this.exportProject(pn);} else {this.prompt('Export Project As...', name => this.exportProject(name), null, 'exportProject');};}, 'save project data as XML\nto your downloads folder'); menu.addItem( @@ -4824,8 +4744,7 @@ IDE_Morph.prototype.undeleteSprites = function (pos) { if (!this.scene.trash.length) { this.showMessage('NO ITEM IN TRASH'); return; - } - this.scene.trash.forEach(sprite => + }; this.scene.trash.forEach(sprite => menu.addItem( [ sprite.thumbnail(new Point(24, 24), null, true), @@ -4833,8 +4752,7 @@ IDE_Morph.prototype.undeleteSprites = function (pos) { ], sprite ) - ); - menu.popup(this.world(), pos); + ); menu.popup(this.world(), pos); }; IDE_Morph.prototype.undelete = function (aSprite, pos) { @@ -4852,7 +4770,7 @@ IDE_Morph.prototype.undelete = function (aSprite, pos) { aSprite.name = this.newSpriteName(aSprite.name); this.stage.add(aSprite); aSprite.setXPosition(rnd.call(this, -50, 50)); - aSprite.setYPosition(rnd.call(this, -50, 59)); + aSprite.setYPosition(rnd.call(this, -50, 50)); aSprite.fixLayout(); aSprite.rerender(); this.sprites.add(aSprite); @@ -4866,10 +4784,10 @@ IDE_Morph.prototype.undelete = function (aSprite, pos) { // IDE_Morph menu actions IDE_Morph.prototype.certificate = function () {pic = new Image; pic.onload = function () {certificate = newCanvas(new Point(pic.width, pic.height), true); -ctx = certificate.getContext('2d'); ctx.drawImage(pic, 0, 0); new DialogBoxMorph().inform('Cerificate of Appreciation', null, world, certificate);}; -pic.src = 'src/certificate.svg';}; /* The certificate is here to see the persons that I'm inspired to make my mod. Thanks! :-) */ +ctx = certificate.getContext('2d'); ctx.drawImage(pic, 0, 0); new DialogBoxMorph().inform('Cerificate of Appreciation', null, world, certificate); +}; pic.src = 'src/certificate.svg';}; /* The certificate is here to see the persons that I'm inspired to make my mod. Thanks! :-) */ -IDE_Morph.prototype.aboutSnap = function () {var dlg, aboutTxt, noticeTxt, creditsTxt, versions = '', translations, module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn, world = this.world(); +IDE_Morph.prototype.aboutSnap = function () {var dlg, aboutTxt, noticeTxt, creditsTxt, versions = '', translations, module, btn1, btn2, btn3, licenseBtn, translatorsBtn, world = this.world(); aboutTxt = 'Snavanced! ' + SnavancedVersion + ' - Programming Mode (' + LastUpdated + ') \nBuild Your Own Blocks - a reimplementation of Scratch.\n' + 'Alessandrito123 \(Alessandro Moisés\)\n' + 'aless01pime@gmail.com\n' @@ -4934,17 +4852,6 @@ IDE_Morph.prototype.aboutSnap = function () {var dlg, aboutTxt, noticeTxt, credi + '\nAchal Dave: Web Audio' + '\nJoe Otto: Morphic Testing and Debugging'; - for (module in modules) { - if (Object.prototype.hasOwnProperty.call(modules, module)) { - versions += ('\n' + module + ' (' + - modules[module] + ')'); - } - } - if (versions !== '') { - versions = localize('current module versions:') + ' \n\n' + - 'morphic (' + morphicVersion + ')' + - versions; - } translations = localize('Translations') + '\n' + SnapTranslator.credits(); dlg = new DialogBoxMorph; @@ -4961,8 +4868,7 @@ IDE_Morph.prototype.aboutSnap = function () {var dlg, aboutTxt, noticeTxt, credi null, MorphicPreferences.isFlat ? null : new Point(1, 1), WHITE - ), - scroller, + ), scroller, maxHeight = world.height() - dlg.titleFontSize * 10; if (tm.height() > maxHeight) { scroller = new ScrollFrameMorph(); @@ -4973,12 +4879,10 @@ IDE_Morph.prototype.aboutSnap = function () {var dlg, aboutTxt, noticeTxt, credi scroller.addContents(tm); scroller.color = new Color(0, 0, 0, 0); return scroller; - } - return tm; - } - - dlg.inform('About Snavanced!', aboutTxt, world, this.logo.cachedTexture); - btn1 = dlg.buttons.children[0]; btn1.hint = (new Context).getBYOB(); + }; return tm; + }; dlg.inform('About Snavanced!', aboutTxt, world, + this.logo.cachedTexture); btn1 = dlg.buttons.children[ + 0]; btn1.hint = (new Context).getBYOB(); translatorsBtn = dlg.addButton( () => { dlg.addBody(txt(translations)); @@ -4986,30 +4890,26 @@ IDE_Morph.prototype.aboutSnap = function () {var dlg, aboutTxt, noticeTxt, credi btn1.show(); btn2.show(); btn3.hide(); - btn4.hide(); licenseBtn.hide(); translatorsBtn.hide(); dlg.fixLayout(); dlg.setCenter(world.center()); }, 'Translators...' - ); - btn2 = dlg.addButton( + ); btn2 = dlg.addButton( () => { dlg.addBody(txt(aboutTxt)); dlg.body.fixLayout(); btn1.show(); btn2.hide(); btn3.show(); - btn4.show(); licenseBtn.show(); translatorsBtn.hide(); dlg.fixLayout(); dlg.setCenter(world.center()); }, 'Back...' - ); - btn2.hide(); + ); btn2.hide(); licenseBtn = dlg.addButton( () => { dlg.addBody(txt(noticeTxt)); @@ -5017,30 +4917,13 @@ IDE_Morph.prototype.aboutSnap = function () {var dlg, aboutTxt, noticeTxt, credi btn1.show(); btn2.show(); btn3.hide(); - btn4.hide(); licenseBtn.hide(); translatorsBtn.hide(); dlg.fixLayout(); dlg.setCenter(world.center()); }, 'License...' - ); - btn3 = dlg.addButton( - () => { - dlg.addBody(txt(versions)); - dlg.body.fixLayout(); - btn1.show(); - btn2.show(); - btn3.hide(); - btn4.hide(); - licenseBtn.hide(); - translatorsBtn.hide(); - dlg.fixLayout(); - dlg.setCenter(world.center()); - }, - 'Modules...' - ); - btn4 = dlg.addButton( + ); btn3 = dlg.addButton( () => { dlg.addBody(txt(creditsTxt)); dlg.body.fixLayout(); @@ -5048,14 +4931,12 @@ IDE_Morph.prototype.aboutSnap = function () {var dlg, aboutTxt, noticeTxt, credi btn2.show(); translatorsBtn.show(); btn3.hide(); - btn4.hide(); licenseBtn.hide(); dlg.fixLayout(); dlg.setCenter(world.center()); }, 'Credits...' - ); - translatorsBtn.hide(); + ); translatorsBtn.hide(); dlg.fixLayout(); }; @@ -5405,13 +5286,13 @@ IDE_Morph.prototype.exportProjectSummary = function (useDropShadows) { function addNode(tag, node, contents) { if (!node) {node = body; } return new XML_Element(tag, contents, node); - } + }; function add(contents, tag, node) { if (!tag) {tag = 'p'; } if (!node) {node = body; } return new XML_Element(tag, contents, node); - } + }; function addImage(canvas, node, inline) { if (!node) {node = body; } @@ -5419,7 +5300,7 @@ IDE_Morph.prototype.exportProjectSummary = function (useDropShadows) { pic = addNode('img', para || node); pic.attributes.src = canvas.toDataURL(); return pic; - } + }; function addVariables(varFrame) { var names = varFrame.names().sort(), @@ -5703,9 +5584,7 @@ IDE_Morph.prototype.rawOpenProjectString = function (str) { this.openProject( this.serializer.load(str, this) ); - } - this.stopFastTracking(); -}; + }; this.stopFastTracking();}; IDE_Morph.prototype.openBlocksString = function (str, name, silently) { var msg; @@ -5715,8 +5594,7 @@ IDE_Morph.prototype.openBlocksString = function (str, name, silently) { this.rawOpenBlocksString(str, name, silently); msg.destroy(); } - ]); -}; + ]);}; IDE_Morph.prototype.rawOpenBlocksString = function (str, name, silently) { // name is optional (string), so is silently (bool) @@ -5728,11 +5606,10 @@ IDE_Morph.prototype.rawOpenBlocksString = function (str, name, silently) { blocks = this.serializer.loadBlocks(str, this.stage); } catch (err) { this.showMessage('Load failed: ' + err); - } + }; } else { blocks = this.serializer.loadBlocks(str, this.stage); - } - if (silently) { + }; if (silently) { blocks.global.forEach(def => { def.receiver = this.stage; this.stage.globalBlocks.push(def); @@ -5755,8 +5632,7 @@ IDE_Morph.prototype.rawOpenBlocksString = function (str, name, silently) { this.stage, name ).popUp(); - } - this.createCategories(); + }; this.createCategories(); this.categories.refreshEmpty(); this.createPaletteHandle(); this.categories.fixLayout(); @@ -5785,21 +5661,14 @@ IDE_Morph.prototype.rawOpenSpritesString = function (str) { } } else { this.serializer.loadSprites(str, this); - } -}; + };}; -IDE_Morph.prototype.openMediaString = function (str) { - if (Process.prototype.isCatchingErrors) { - try { - this.serializer.loadMedia(str); - } catch (err) { - this.showMessage('Load failed: ' + err); - } - } else { - this.serializer.loadMedia(str); - } - this.showMessage('Imported Media Module.', 2); -}; +IDE_Morph.prototype.openMediaString = function (str +) {if (Process.prototype.isCatchingErrors) {try { +this.serializer.loadMedia(str);} catch (err) { +this.showMessage('Load failed: ' + err);};} else { +this.serializer.loadMedia(str);}; this.showMessage( +'Imported Media Module.', 2);}; IDE_Morph.prototype.openScriptString = function (str) { var msg; @@ -5823,9 +5692,8 @@ IDE_Morph.prototype.rawOpenScriptString = function (str) { this.showMessage('Load failed: ' + err); }; } else { - script = this.deserializeScriptString(str); - }; - script.fixBlockColor(null, true); + script = this.deserializeScriptString( + str);}; script.fixBlockColor(null, true); this.spriteBar.tabBar.tabTo('scripts'); scripts.add(script); script.fixBlockColor(null, true); // force zebra coloring @@ -5840,8 +5708,7 @@ IDE_Morph.prototype.rawOpenScriptString = function (str) { this.showMessage( 'Imported Script.', 2 - ); -}; + );}; IDE_Morph.prototype.deserializeScriptString = function (str) { var xml = this.serializer.parse(str, this.currentSprite), @@ -5881,8 +5748,7 @@ IDE_Morph.prototype.openDataString = function (str, name, type) { this.rawOpenDataString(str, name, type); msg.destroy(); } - ]); -}; + ]);}; IDE_Morph.prototype.rawOpenDataString = function (str, name, type) { var data, vName, dlg, @@ -5897,9 +5763,8 @@ IDE_Morph.prototype.rawOpenDataString = function (str, name, type) { while (contains(existing, newName)) { count += 1; newName = stem + '(' + count + ')'; - } - return newName; - } + }; return newName; + }; switch (type) { case 'csv': @@ -6174,7 +6039,7 @@ IDE_Morph.prototype.toggleBlurredShadows = function () { this.removeSetting('solidshadow'); } else { this.saveSetting('solidshadow', false); - } + }; }; IDE_Morph.prototype.toggleLongFormInputDialog = function () { @@ -6184,7 +6049,7 @@ IDE_Morph.prototype.toggleLongFormInputDialog = function () { this.saveSetting('longform', true); } else { this.removeSetting('longform'); - } + }; }; IDE_Morph.prototype.togglePlainPrototypeLabels = function () { @@ -6194,7 +6059,7 @@ IDE_Morph.prototype.togglePlainPrototypeLabels = function () { this.saveSetting('plainprototype', true); } else { this.removeSetting('plainprototype'); - } + }; }; IDE_Morph.prototype.togglePreferEmptySlotDrops = function () { @@ -6266,8 +6131,7 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) { if (this.isAppMode) { this.wasSingleStepping = Process.prototype.enableSingleStepping; if (this.wasSingleStepping) { - this.toggleSingleStepping(); - }; + this.toggleSingleStepping();}; this.setColor(SpriteMorph.prototype.paletteColor); this.controlBar.setColor(SpriteMorph.prototype.paletteColor); this.controlBar.appModeButton.refresh(); @@ -6285,24 +6149,20 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) { document.documentElement.requestFullscreen();};} else { if (this.wasSingleStepping && !Process.prototype.enableSingleStepping) { this.toggleSingleStepping(); - } - this.setColor(this.backgroundColor); + }; this.setColor(this.backgroundColor); this.controlBar.setColor(this.frameColor); elements.forEach(e => e.show() - ); - this.stage.setScale(1); + ); this.stage.setScale(1); world.children.forEach(morph => { if (morph instanceof DialogBoxMorph) { morph.show(); }; - }); - world.allChildren().filter(c => + }); world.allChildren().filter(c => c instanceof ScrollFrameMorph ).forEach(s => s.adjustScrollBars() - ); - if (this.currentSprite === this.stage) { + ); if (this.currentSprite === this.stage) { this.spriteBar.children.forEach(child => { if (child instanceof PushButtonMorph) { child.hide(); @@ -6326,9 +6186,7 @@ IDE_Morph.prototype.toggleStageSize = function (isSmall, forcedRatio) { function toggle() { myself.isSmallStage = isNil(isSmall) ? !myself.isSmallStage : isSmall; - } - - function zoomTo(targetRatio) { + }; function zoomTo(targetRatio) { myself.isSmallStage = true; world.animations.push(new Animation( ratio => { @@ -6351,40 +6209,38 @@ IDE_Morph.prototype.toggleStageSize = function (isSmall, forcedRatio) { this.stage.dimensions.x; if (!this.isSmallStage || (smallRatio === this.stageRatio)) { toggle(); - } + }; } else if (altClicked) { smallRatio = this.width() / 2 / this.stage.dimensions.x; if (!this.isSmallStage || (smallRatio === this.stageRatio)) { toggle(); - } + }; } else { toggle(); - } - if (this.isSmallStage) { + }; if (this.isSmallStage) { zoomTo(smallRatio); } else { zoomTo(1); - } + }; }; -IDE_Morph.prototype.toggleScreenshotDialog = function anonymous () {if ((world.children.filter(child => child instanceof DialogBoxMorph).filter(child => child.key === 'screenshotMaker').length) > 0) { +IDE_Morph.prototype.toggleScreenshotDialog = function () {if ((world.children.filter(child => child instanceof DialogBoxMorph).filter(child => child.key === 'screenshotMaker').length) > 0) { world.children.filter(child => child instanceof DialogBoxMorph).filter(child => child.key === 'screenshotMaker')[0].destroy();} else {var dialog = new DialogBoxMorph; dialog.key = 'screenshotMaker'; dialog.labelString = 'Video Capture'; dialog.createLabel(); dialog.spriteEditor = new StageMorph; dialog.spriteEditor.alpha = 0; var video = new SpriteMorph; video.screenshots = []; video.isRecording = false; video.isDraggable = false; dialog.add(dialog.spriteEditor); dialog.spriteEditor.add(video); dialog.spriteEditor.setPosition(new Point(0, 28)); video.step = function anonymous () { var screenshot = world.childThatIsA(StageMorph).fullImage(); this.wearCostume(new Costume(screenshot)); if (this.isRecording) {this.screenshots.push(screenshot.toDataURL().slice(22));}; this.setTop( dialog.spriteEditor.top()); this.setLeft(dialog.left());}; var button = dialog.addButton((function anonymous () {if (button.labelString.name === 'pointRight') {video.startTime = Date.now(); video.isRecording = true; button.labelString = new SymbolMorph('circleSolid', 10, new Color(200, 0, 0));} else {video.isRecording = false; video.endTime = Date.now(); var zip = new JSZip; -world.childThatIsA(IDE_Morph).showMessage('Creating \"video.zip\"...\nStay tuned!'); world.nextSteps([(function anonymous () {this.rerender();})]); var screenshotsFile = zip.folder("screenshots"), i = 0; while ( +world.childThatIsA(IDE_Morph).showMessage('Creating \"video.zip\"...\nStay tuned!'); world.nextSteps([(function () {this.rerender();})]); var screenshotsFile = zip.folder("screenshots"), i = 0; while ( i < video.screenshots.length) {screenshotsFile.file(i + '.png', video.screenshots[i], {base64: true}); i++;}; zip.file("duration.txt", ('The video had the duration of ' + (video.endTime - video.startTime -) + ' milliseconds')); zip.generateAsync({type:"blob"}).then(function(content) {/* see FileSaver.js */ video.screenshots = []; saveAs(content, "video.zip");}); button.labelString = new SymbolMorph('pointRight', -10, new Color(0, 200, 0));}; button.createLabel();}), new SymbolMorph('pointRight', 10, new Color(0, 200, 0))); button.createLabel = function anonymous () {if (!isNil(this.label)) {this.label.destroy();}; if ( -this.labelString instanceof Morph) {this.label = this.labelString.fullCopy();}; this.add(this.label);}; button.updateLabelColors = function () {if (this.label) {this.label.fixLayout(true);};}; button.createLabel( -); button.fixLayout(); var greenFlag = dialog.addButton((function anonymous () {if (greenFlag.labelString.color.g > 0) {greenFlag.labelString.color.g = 0;} else {greenFlag.labelString.color.g = 200;};}), -new SymbolMorph('flag', 10, new Color(0, 0, 0))); greenFlag.createLabel = function anonymous () {if (!isNil(this.label)) {this.label.destroy();}; if (this.labelString instanceof Morph) { -this.label = this.labelString.fullCopy();}; this.add(this.label);}; greenFlag.updateLabelColors = function () {if (this.label) {this.label.fixLayout(true);};}; greenFlag.createLabel( -); greenFlag.fixLayout(); dialog.setExtent(new Point(480, 360)); dialog.spriteEditor.userMenu = nop; video.userMenu = nop; dialog.button1 = button; dialog.button2 = greenFlag; -dialog.fixLayout(); dialog.popUp(world);};}; /* Now you can record a video with this. Like Turbowarp, there is a recording dialog for the stage too!!! Try it!!! :-) */ +) + ' milliseconds')); zip.generateAsync({type:"blob"}).then(function(content) {video.screenshots = []; saveAs(content, "video.zip");}); button.labelString = new SymbolMorph('pointRight', 10, new Color( +0, 200, 0));}; button.createLabel();}), new SymbolMorph('pointRight', 10, new Color(0, 200, 0))); button.createLabel = function () {if (!isNil(this.label)) {this.label.destroy();}; if ((this.labelString +) instanceof Morph) {this.label = this.labelString.fullCopy();}; this.add(this.label);}; button.updateLabelColors = function () {if (this.label) {this.label.fixLayout(true);};}; button.createLabel(); +button.fixLayout(); var greenFlag = dialog.addButton((function () {if (greenFlag.labelString.color.g > 0) {greenFlag.labelString.color.g = 0;} else {greenFlag.labelString.color.g = 200;};}), new SymbolMorph( +'flag', 10, new Color(0, 0, 0))); greenFlag.createLabel = function anonymous () {if (!isNil(this.label)) {this.label.destroy();}; if (this.labelString instanceof Morph) {this.label = this.labelString.fullCopy(); +}; this.add(this.label);}; greenFlag.updateLabelColors = function () {if (this.label) {this.label.fixLayout(true);};}; greenFlag.createLabel(); greenFlag.fixLayout(); dialog.setExtent(new Point(480, 360)); +dialog.spriteEditor.userMenu = nop; video.userMenu = nop; dialog.button1 = button; dialog.button2 = greenFlag; dialog.fixLayout(); dialog.popUp(world);};}; IDE_Morph.prototype.toggleUnifiedPalette = function () {this.setUnifiedPalette(!this.scene.unifiedPalette); this.recordUnsavedChanges();}; @@ -6407,32 +6263,26 @@ IDE_Morph.prototype.openProjectsBrowser = function () {this.importLocalFile();}; IDE_Morph.prototype.saveProjectsBrowser = function () {this.prompt('Export Project As...', name => this.exportProject(name), null, 'exportProject');}; -IDE_Morph.prototype.value_depthMenu = function anonymous () { +IDE_Morph.prototype.value_depthMenu = function () { var menu = new MenuMorph(this, localize('Value-depth colors')), world = this.world(), pos = this.controlBar.settingsButton.bottomLeft(), qualities = [255, 128, 64, 32, 16, 8, 4, 2, 1], tick = new SymbolMorph( 'tick', - MorphicPreferences.menuFontSize * 0.75 - ), - empty = tick.fullCopy(); + MorphicPreferences.menuFontSize * 3/4 + ), empty = tick.fullCopy(); empty.render = nop; qualities.forEach((quality, i) => { menu.addItem( [ - +localStorage['-snap-setting-colorQuality'] === [ - 255, 128, 64, 32, 16, 8, 4, 2, 1][i] ? tick : empty, - quality.toString() + (+(localStorage['-snap-setting-colorQuality']) === ( + qualities[i]) ? tick : empty, quality.toString()) ], () => {localStorage['-snap-setting-colorQuality' - ] = [255, 128, 64, 32, 16, 8, 4, 2, 1 - ][i]; location.reload();} - ); - }); - menu.popup(world, pos); -}; + ] = qualities[i]; location.reload();});} + ); menu.popup(world, pos);}; // IDE_Morph microphone settings @@ -6445,12 +6295,10 @@ IDE_Morph.prototype.microphoneMenu = function anonymous () { tick = new SymbolMorph( 'tick', MorphicPreferences.menuFontSize * 0.75 - ), - on = new SymbolMorph( + ), on = new SymbolMorph( 'checkedBox', MorphicPreferences.menuFontSize * 0.75 - ), - empty = tick.fullCopy(); + ), empty = tick.fullCopy(); empty.render = nop; if (microphone.isReady) { @@ -6460,10 +6308,8 @@ IDE_Morph.prototype.microphoneMenu = function anonymous () { localize('Microphone') ], () => microphone.stop() - ); - menu.addLine(); - } - resolutions.forEach((res, i) => { + ); menu.addLine(); + }; resolutions.forEach((res, i) => { menu.addItem( [ microphone.resolution === i + 1 ? tick : empty, @@ -6471,9 +6317,7 @@ IDE_Morph.prototype.microphoneMenu = function anonymous () { ], () => microphone.setResolution(i + 1) ); - }); - menu.popup(world, pos); -}; + }); menu.popup(world, pos);}; IDE_Morph.prototype.themesMenu = function () {var menu = new MenuMorph(this), pos = this.controlBar.settingsButton.bottomLeft(), themes = ['old', 'simple', 'default', 'light', 'animated'], tick = new SymbolMorph( 'tick', MorphicPreferences.menuFontSize * 0.75), on = new SymbolMorph('checkedBox', MorphicPreferences.menuFontSize * 0.75), empty = tick.fullCopy(); empty.render = nop; themes.forEach((theme, i) => {menu.addItem( @@ -6506,12 +6350,10 @@ IDE_Morph.prototype.languageMenu = function () { } ) ); menu.popup(world, pos); -}; - -IDE_Morph.prototype.setLanguage = function (lang, callback, noSave) {var translation = document.getElementById('language'), src; SnapTranslator.unload(); if (translation) {document.head.removeChild(translation);}; -if (!(lang in SnapTranslator.dict)) {if (lang.includes('_') && lang.split('_')[0] in SnapTranslator.dict) {lang = lang.split('_')[0];} else {lang = 'en';};}; if (lang === 'en') {return this.reflectLanguage('en', -callback, noSave);}; src = this.resourceURL('src', 'locale', 'lang-' + lang + '.js'); translation = document.createElement('script'); translation.id = 'language'; translation.onload = () => this.reflectLanguage( -lang, callback, noSave); document.head.appendChild(translation); translation.src = src;}; +}; IDE_Morph.prototype.setLanguage = function (lang, callback, noSave) {var translation = document.getElementById('language'), src; SnapTranslator.unload(); if (translation) {(document +).head.removeChild(translation);}; if (!(lang in SnapTranslator.dict)) {if (lang.includes('_') && lang.split('_')[0] in SnapTranslator.dict) {lang = lang.split('_')[0];} else {lang = 'en'; +};}; if (lang === 'en') {return this.reflectLanguage('en', callback, noSave);}; src = this.resourceURL('src', 'locale', 'lang-' + lang + '.js'); translation = document.createElement( +'script'); translation.id = 'language'; translation.onload = () => this.reflectLanguage(lang, callback, noSave); document.head.appendChild(translation); translation.src = src;}; IDE_Morph.prototype.reflectLanguage = function (lang, callback, noSave) { var projectData, @@ -6526,14 +6368,13 @@ IDE_Morph.prototype.reflectLanguage = function (lang, callback, noSave) { ); } catch (err) { this.showMessage('Serialization failed: ' + err); - } + }; } else { projectData = this.serializer.serialize( new Project(this.scenes, this.scene) ); - } - } - SpriteMorph.prototype.initBlocks(); + }; + }; SpriteMorph.prototype.initBlocks(); this.spriteBar.tabBar.tabTo('scripts'); this.createCategories(); this.categories.refreshEmpty(); @@ -6544,89 +6385,55 @@ IDE_Morph.prototype.reflectLanguage = function (lang, callback, noSave) { location.hash = urlBar; } else { this.openProjectString(projectData); - } - if (!noSave) { + }; if (!noSave) { this.saveSetting('language', lang); - } - if (callback) {callback.call(this); } + }; if (callback) {callback.call(this);}; }; // IDE_Morph blocks scaling -IDE_Morph.prototype.userSetBlocksScale = function () { - var scrpt, - blck, - shield, - sample, - action, - dlg; - - scrpt = new CommandBlockMorph; - scrpt.color = SpriteMorph.prototype.blockColor.control; - scrpt.setSpec(localize('ZOOM TEST STRING 2')); - blck = new CommandBlockMorph; - blck.color = SpriteMorph.prototype.blockColor.variables; - blck.setSpec(localize('ZOOM TEST STRING 3')); - scrpt.nextBlock(blck); - blck = new CommandBlockMorph; - blck.color = SpriteMorph.prototype.blockColor.lists; - blck.setSpec(localize('ZOOM TEST STRING 4')); - scrpt.bottomBlock().nextBlock(blck); - blck = SpriteMorph.prototype.blockForSelector('zoomLambdaTest'); - blck.inputs()[0].nestedBlock(scrpt); - - sample = new FrameMorph; sample.acceptsDrops = false; - sample.color = IDE_Morph.prototype.categoryColor; - if (SyntaxElementMorph.prototype.alpha > 0.8) { - sample.cachedTexture = this.scriptsPaneTexture; - }; sample.setExtent(new Point(250, 125)); - blck.setPosition(sample.position().add(20)); - sample.add(blck); shield = new Morph; - shield.alpha = 0; shield.setExtent( - sample.extent()); shield.setPosition( - sample.position()); sample.add(shield); - - action = (num) => { - var backup = blck.children[blck.children.length - 1].nestedBlock( - ).fullCopy(); blck.setScale(num); blck.setSpec(blck.blockSpec); - blck.children[blck.children.length - 1].nestedBlock(backup); - blck.inputs()[0].setScale(num); blck.inputs()[0].fixLayout(); - backup.setScale(num); backup.setSpec(backup.blockSpec); - backup.fixLayout(); backup.blockSequence().forEach( - block => {block.setScale(num); block.setSpec( - block.blockSpec); block.fixLayout();}); - blck.inputs()[0].fixLayout(); blck.fullChanged(); - }; - - dlg = new DialogBoxMorph( - null, - num => this.setBlocksScale(num) - ).withKey('zoomBlocks'); - if (MorphicPreferences.isTouchDevice) { - dlg.isDraggable = false; - } - dlg.prompt( - 'ZOOM MENU STRING', - SyntaxElementMorph.prototype.scale.toString(), - this.world(), - sample, - { - 'ZOOM 1 SIZE' : 1, - 'ZOOM 1.2 SIZE' : 1.2, - 'ZOOM 1.4 SIZE' : 1.4, - 'ZOOM 1.5 SIZE' : 1.5, - 'ZOOM 2 SIZE' : 2, - 'ZOOM 4 SIZE' : 4, - 'ZOOM 8 SIZE' : 8, - 'ZOOM 10 SIZE' : 10 - }, - false, - true, - 1, - 10, - action - ); -}; +IDE_Morph.prototype.userSetBlocksScale = function ( +) {var scrpt, blck, shield, sample, action, dlg; +scrpt = new CommandBlockMorph; scrpt.color = ( +SpriteMorph.prototype.blockColor.control); (scrpt +).setSpec(localize('ZOOM TEST STRING 2')); (blck +) = new CommandBlockMorph; blck.color = (SpriteMorph +).prototype.blockColor.variables; blck.setSpec(localize( +'ZOOM TEST STRING 3')); scrpt.nextBlock(blck); blck = ( +new CommandBlockMorph); blck.color = (SpriteMorph.prototype +).blockColor.lists; blck.setSpec(localize('ZOOM TEST STRING 4' +)); scrpt.bottomBlock().nextBlock(blck); blck = (SpriteMorph +).prototype.blockForSelector('zoomLambdaTest'); blck.inputs( +)[0].nestedBlock(scrpt); sample = new FrameMorph; (sample +).acceptsDrops = false; sample.color = (IDE_Morph.prototype +).categoryColor; if ((SyntaxElementMorph.prototype.alpha +) > 0.8) {sample.cachedTexture = this.scriptsPaneTexture; +}; sample.setExtent(new Point(250, 125)); blck.setPosition( +sample.position().add(20)); sample.add(blck); shield = ( +new Morph); shield.alpha = 0; shield.setExtent(sample.extent( +)); shield.setPosition(sample.position()); sample.add(shield +); action = (num => {var backup = blck.children[(blck.children +).length - 1].nestedBlock().fullCopy(); blck.setScale(num); +blck.setSpec(blck.blockSpec); blck.children[(blck.children +).length - 1].nestedBlock(backup); blck.inputs()[0].setScale( +num); blck.inputs()[0].fixLayout(); backup.setScale(num); +backup.setSpec(backup.blockSpec); backup.fixLayout(); +backup.blockSequence().forEach((block => {block.setScale( +num); block.setSpec(block.blockSpec); block.fixLayout();})); +blck.inputs()[0].fixLayout(); blck.fullChanged();}); dlg = ( +new DialogBoxMorph(null, num => this.setBlocksScale(num +))).withKey('zoomBlocks'); if ((MorphicPreferences +).isTouchDevice) {dlg.isDraggable = false;}; (dlg +).prompt('ZOOM MENU STRING', (SyntaxElementMorph +).prototype.scale.toString(), world, sample, { +'ZOOM 0.5 SIZE' : 0.5, 'ZOOM 0.75 SIZE' : 0.75, +'ZOOM 0.9 SIZE' : 0.9, 'ZOOM 1 SIZE' : 1, +'ZOOM 1.11 SIZE' : 1.11, 'ZOOM 1.295 SIZE' : 1.295, +'ZOOM 1.365 SIZE' : 1.365, 'ZOOM 1.445 SIZE' : 1.445, +'ZOOM 1.5 SIZE' : 1.5, 'ZOOM 2 SIZE' : 2, +'ZOOM 4 SIZE' : 4, 'ZOOM 8 SIZE' : 8, +'ZOOM 10 SIZE' : 10}, false, +true, 0.5, 10, action);}; IDE_Morph.prototype.setBlocksScale = function (num) { var projectData; @@ -6657,45 +6464,16 @@ var projectData; // IDE_Morph blocks fading -IDE_Morph.prototype.userFadeBlocks = function () { - var dlg, - initial = 100 - (SyntaxElementMorph.prototype.alpha * 100); - - dlg = new DialogBoxMorph( - null, - num => this.setBlockTransparency(num, true) - ).withKey('fadeBlocks'); - if (MorphicPreferences.isTouchDevice) { - dlg.isDraggable = false; - } - - dlg.cancel = () => { - this.setBlockTransparency(initial); - dlg.destroy(); - }; - - dlg.prompt( - 'FADING MENU STRING', - initial.toString(), - this.world(), - null, // pic - { - 'block-solid (0)' : 0, - 'medium (50)' : 50, - 'light (70)' : 70, - 'shimmering (80)' : 80, - 'elegant (90)' : 90, - 'subtle (95)' : 95, - 'text-only (100)' : 100 - }, - false, // read only? - true, // numeric - 0, // slider min - 100, // slider max - num => this.setBlockTransparency(num), // slider action - 0 // decimals - ); -}; +IDE_Morph.prototype.userFadeBlocks = function () {var dlg, +initial = (1 - SyntaxElementMorph.prototype.alpha) * 100; dlg = ( +new DialogBoxMorph(null, num => this.setBlockTransparency(num, true +))).withKey('fadeBlocks'); if (MorphicPreferences.isTouchDevice) {(dlg +).isDraggable = false;}; dlg.cancel = () => {this.setBlockTransparency( +initial); dlg.destroy();}; dlg.prompt('FADING MENU STRING', (initial +).toString(), world, null, {'block-solid (0)' : 0, 'medium (50)' : 50, +'light (70)' : 70, 'shimmering (80)' : 80, 'elegant (90)' : 90, +'subtle (95)' : 95, 'text-only (100)' : 100}, false, true, +0, 100, num => this.setBlockTransparency(num), 0);}; IDE_Morph.prototype.setBlockTransparency = function (num, save) { SyntaxElementMorph.prototype.setAlphaScaled(100 - num); @@ -6705,28 +6483,16 @@ IDE_Morph.prototype.setBlockTransparency = function (num, save) { this.removeSetting('fade'); } else { this.saveSetting('fade', num); - } - } -}; + }; + };}; // IDE_Morph stage size manipulation IDE_Morph.prototype.userSetStageSize = function () { - new DialogBoxMorph( - this, - this.setStageExtent, - this - ).promptVector( - "Stage size", - this.stage.dimensions, - new Point(480, 360), - 'Stage width', - 'Stage height', - this.world(), - null, // pic - null // msg - ); -}; +(new DialogBoxMorph(this, this.setStageExtent, this) +).promptVector("Stage size", this.stage.dimensions, +new Point(480, 360), 'Stage width', 'Stage height', +world, null, null);}; IDE_Morph.prototype.setStageExtent = function (aPoint) { var myself = this, @@ -6744,13 +6510,12 @@ IDE_Morph.prototype.setStageExtent = function (aPoint) { } else { myself.stage.dimensions = myself.stage.dimensions.add(delta); - } - myself.stage.setExtent(myself.stage.dimensions); + }; myself.stage.setExtent(myself.stage.dimensions); myself.stage.clearPenTrails(); myself.fixLayout(); this.setExtent(world.extent()); }; - } + }; this.stageRatio = 1; this.isSmallStage = false; @@ -7409,24 +7174,24 @@ IDE_Morph.prototype.getUser = function () {var thisUser = this.getSetting('user' IDE_Morph.prototype.isNonWebStandardBrowser = function anonymous () {var ua = navigator.userAgent; return ua.indexOf("MSIE ") > -1 || ua.indexOf("Trident/") > -1;}; -IDE_Morph.prototype.getRandomTip = function anonymous () {var numberOfTip = (0 - Math.round(0 - Math.random() * 30)); var aRandomTip = ''; if (this.isNonWebStandardBrowser( -)) {aRandomTip = 'If do you wanna to run Snavanced!\nto the best graphics and speed,\nrun this with Google Chrome, Firefox,\nor another browser which it\'s a web-standards. 🤨'; +IDE_Morph.prototype.getRandomTip = function () {var numberOfTip = (0 - Math.round(0 - Math.random() * 30)); var aRandomTip = ''; if (this.isNonWebStandardBrowser( +)) {aRandomTip = 'If do you want to run Snavanced!\nto the best graphics and speed,\nrun this with Google Chrome, Firefox,\nor another browser which it\'s a web-standards. 🤨'; } else if (numberOfTip === 0) {aRandomTip = 'Snap! is a broadly\ninviting programming language\nfor kids and adults that\'s also a platform\nfor serious study of computer science. 🙂'; } else if (numberOfTip === 1) {aRandomTip = '\"Anything you can do from the GUI,\nyou should be able to do from\nthe programming language\nand viceversa.\"\nMike Eisenberg, d. 3/12/2019 Rest In Peace. 😭'; } else if (numberOfTip === 2) {aRandomTip = 'BYOB is Build Your Own Blocks.\nA mod for Scratch 1.4. Too old! 🙂'; } else if (numberOfTip === 3) {aRandomTip = 'Brian Harvey is the co-developer\nof Snap! \(BYOB\), he is a lecturer and\nis the official creator of the UCB LOGO. 🙂'; -} else if (numberOfTip === 4) {aRandomTip = 'TypeScript has syntax-types for JavaScript. 🙂\nIf you wanna to try it, go to:\ntypescriptlang.org/play'; +} else if (numberOfTip === 4) {aRandomTip = 'TypeScript has syntax-types for JavaScript. 🙂\nIf you want to try it, go to:\ntypescriptlang.org/play'; } else if (numberOfTip === 5) {aRandomTip = 'Snap! (BYOB) have the famous \"λ calculus\".\nIn other context, all of the things are first class. 🙂'; } else if (numberOfTip === 6) {aRandomTip = 'Did you know what, Snavanced!\nadded more features than Snap!, just look!'; } else if (numberOfTip === 7) {aRandomTip = '\u0049\u0020\u0064\u006F\u006E\u0027\u0074\u0020\u006B\u006E\u006F\u0077\u0020\u0077\u0068\u0061\u0074\u0020\u0069\u0074\u0027\u0073\u0020\u0073\u0075\u0070\u0070\u006F\u0073\u0065\u0064\u0020\u0074\u006F\u0020\u006D\u0065\u0061\u006E\u000A\u0074\u0068\u0061\u0074\u0020\u0049\u0027\u006D\u0020\u0073\u006F\u0020\u0073\u0061\u0064\u002C\u0020\u0061\u0020\u0066\u0061\u0069\u0072\u0079\u0020\u0074\u0061\u006C\u0065\u0020\u0066\u0072\u006F\u006D\u0020\u0061\u006E\u0063\u0069\u0065\u006E\u0074\u0020\u0074\u0069\u006D\u0065\u0073\u002C\u000A\u0049\u0020\u0063\u0061\u006E\u0027\u0074\u0020\u0067\u0065\u0074\u0020\u0074\u0068\u0061\u0074\u0020\u006F\u0075\u0074\u0020\u006F\u0066\u0020\u006D\u0079\u0020\u006D\u0069\u006E\u0064\u002E\u000A\u0054\u0068\u0065\u0020\u0061\u0069\u0072\u0020\u0069\u0073\u0020\u0063\u006F\u006F\u006C\u0020\u0061\u006E\u0064\u0020\u0069\u0074\u0020\u0069\u0073\u0020\u0067\u0065\u0074\u0074\u0069\u006E\u0067\u0020\u0064\u0061\u0072\u006B\u002C\u0020\u0061\u006E\u0064\u0020\u0074\u0068\u0065\u0020\u0052\u0068\u0069\u006E\u0065\u0020\u0066\u006C\u006F\u0077\u0073\u0020\u0063\u0061\u006C\u006D\u006C\u0079\u003B\u000A\u0074\u0068\u0065\u0020\u0070\u0065\u0061\u006B\u0020\u006F\u0066\u0020\u0074\u0068\u0065\u0020\u006D\u006F\u0075\u006E\u0074\u0061\u0069\u006E\u0020\u0073\u0070\u0061\u0072\u006B\u006C\u0065\u0073\u0020\u0069\u006E\u0020\u0074\u0068\u0065\u0020\u0065\u0076\u0065\u006E\u0069\u006E\u0067\u0020\u0073\u0075\u006E\u0073\u0068\u0069\u006E\u0065\u002E\u000A\u0054\u0068\u0065\u0020\u006D\u006F\u0073\u0074\u0020\u0062\u0065\u0061\u0075\u0074\u0069\u0066\u0075\u006C\u0020\u006D\u0061\u0069\u0064\u0065\u006E\u0020\u0073\u0069\u0074\u0073\u0020\u0077\u006F\u006E\u0064\u0065\u0072\u0066\u0075\u006C\u006C\u0079\u0020\u0075\u0070\u0020\u0074\u0068\u0065\u0072\u0065\u002C\u000A\u0068\u0065\u0072\u0020\u0067\u006F\u006C\u0064\u0065\u006E\u0020\u006A\u0065\u0077\u0065\u006C\u0072\u0079\u0020\u0066\u006C\u0061\u0073\u0068\u0065\u0073\u002C\u0020\u0073\u0068\u0065\u0020\u0063\u006F\u006D\u0062\u0073\u0020\u0068\u0065\u0072\u0020\u0067\u006F\u006C\u0064\u0065\u006E\u0020\u0068\u0061\u0069\u0072\u002C\u000A\u0073\u0068\u0065\u0020\u0063\u006F\u006D\u0062\u0073\u0020\u0069\u0074\u0020\u0077\u0069\u0074\u0068\u0020\u0061\u0020\u0067\u006F\u006C\u0064\u0065\u006E\u0020\u0063\u006F\u006D\u0062\u002C\u0020\u0061\u006E\u0064\u0020\u0073\u0069\u006E\u0067\u0073\u0020\u0061\u0020\u0073\u006F\u006E\u0067\u0020\u0077\u0068\u0069\u006C\u0065\u0020\u0064\u006F\u0069\u006E\u0067\u0020\u0069\u0074\u003B\u000A\u0069\u0074\u0020\u0068\u0061\u0073\u0020\u0061\u0020\u0077\u006F\u006E\u0064\u0072\u006F\u0075\u0073\u002C\u0020\u0070\u006F\u0077\u0065\u0072\u0066\u0075\u006C\u0020\u006D\u0065\u006C\u006F\u0064\u0079\u002E\u000A\u0054\u0068\u0065\u0020\u0073\u0061\u0069\u006C\u006F\u0072\u0020\u0069\u006E\u0020\u0074\u0068\u0065\u0020\u006C\u0069\u0074\u0074\u006C\u0065\u0020\u0073\u0068\u0069\u0070\u0020\u0069\u0073\u0020\u0073\u0065\u0069\u007A\u0065\u0064\u0020\u0077\u0069\u0074\u0068\u0020\u0077\u0069\u006C\u0064\u0020\u0070\u0061\u0069\u006E\u003B\u000A\u0068\u0065\u0020\u0064\u006F\u0065\u0073\u006E\u0027\u0074\u0020\u006C\u006F\u006F\u006B\u0020\u0061\u0074\u0020\u0074\u0068\u0065\u0020\u0063\u006C\u0069\u0066\u0066\u0073\u002C\u0020\u0068\u0065\u0020\u006A\u0075\u0073\u0074\u0020\u006C\u006F\u006F\u006B\u0073\u0020\u0075\u0070\u0020\u0069\u006E\u0074\u006F\u0020\u0074\u0068\u0065\u0020\u0073\u006B\u0079\u002E\u000A\u0049\u0020\u0074\u0068\u0069\u006E\u006B\u0020\u0069\u006E\u0020\u0074\u0068\u0065\u0020\u0065\u006E\u0064\u0020\u0074\u0068\u0065\u0020\u0077\u0061\u0076\u0065\u0073\u0020\u0077\u0069\u006C\u006C\u0020\u0073\u0077\u0061\u006C\u006C\u006F\u0077\u0020\u0075\u0070\u0020\u0074\u0068\u0065\u0020\u0073\u006B\u0069\u0070\u0070\u0065\u0072\u0020\u0061\u006E\u0064\u0020\u0062\u0061\u0072\u0067\u0065\u002C\u000A\u0061\u006E\u0064\u0020\u0074\u0068\u0061\u0074\u0020\u0068\u0061\u0073\u0020\u0062\u0065\u0065\u006E\u0020\u0064\u006F\u006E\u0065\u0020\u0077\u0069\u0074\u0068\u0020\u0068\u0065\u0072\u0020\u0073\u0069\u006E\u0067\u0069\u006E\u0067\u002C\u0020\u0074\u0068\u0065\u0020\u004C\u006F\u0072\u0065\u006C\u0065\u0069\u002E';} -else if (numberOfTip === 8) {aRandomTip = 'There\'s a mod of Snap! called NetsBlox. 🙂\nIf do you wanna to try it, go to:\nhttps://editor.netsblox.org';} +else if (numberOfTip === 8) {aRandomTip = 'There\'s a mod of Snap! called NetsBlox. 🙂\nIf do you want to try it, go to:\nhttps://editor.netsblox.org';} else if (numberOfTip === 9) {aRandomTip = 'Did you know what, Snavanced!\nit\'s called that because the GameBoy Advance,\nis the next generation of GameBoy. 🙂';} else if (numberOfTip === 10) {aRandomTip = 'Did you know what, Snavanced!\nis a probably succesor of the self Snap!. 🙂';} else if (numberOfTip === 11) {aRandomTip = 'Did you know what, Snavanced!\nis based too much of BYOB. 🙂';} else if (numberOfTip === 12) {aRandomTip = 'Did you know what, Snavanced!\nis a bit slow. It\'s not intentional. 😕';} else if (numberOfTip === 13) {aRandomTip = 'Did you know what, Snavanced!\nhas the new and the old \n\"λ blocks\" in the same mod. 😄';} else if (numberOfTip === 14) {if (isNil(this.getSetting('user'))) { -aRandomTip = 'If you don\'t wanna to have a username yet,\n you simply leave your username\nin blank, and you will be a \"Guest\". 🙂'; +aRandomTip = 'If you don\'t want to have a username yet,\n you simply leave your username\nin blank, and you will be a \"Guest\". 🙂'; } else {aRandomTip = 'Did you know what, your username\nis only to you, to have your identity. 🙂';}; } else if (numberOfTip === 15) {aRandomTip = 'The Snap!\'s mascot, Alonzo,\nhave a \"λ type\" of haircut. 🙂';} else if (numberOfTip === 16) {aRandomTip = 'Brian Harvey loves the Animaniacs,\nprincipally, Wakko. 😄';} @@ -7589,7 +7354,7 @@ ProjectDialogMorph.prototype.buildContents = function () { if (this.cachedTexture) { this.renderCachedTexture(ctx); } else if (this.texture) { - this.renderTexture(this.texture, ctx); + this.renderTexture(this.texture); } }; this.preview.renderCachedTexture = function (ctx) { @@ -8638,7 +8403,7 @@ ProjectRecoveryDialogMorph.prototype.buildContents = function () { if (this.cachedTexture) { this.renderCachedTexture(ctx); } else if (this.texture) { - this.renderTexture(this.texture, ctx); + this.renderTexture(this.texture); } }; this.preview.renderCachedTexture = function (ctx) { @@ -9204,7 +8969,7 @@ LibraryImportDialogMorph.prototype.showMessage = function (msgText) { // SpriteIconMorph inherits from ToggleButtonMorph (Widgets) -SpriteIconMorph.prototype = new ToggleButtonMorph(); +SpriteIconMorph.prototype = new ToggleButtonMorph; SpriteIconMorph.prototype.constructor = SpriteIconMorph; SpriteIconMorph.uber = ToggleButtonMorph.prototype; @@ -9220,38 +8985,29 @@ SpriteIconMorph.prototype.fontSize = 9; function SpriteIconMorph(aSprite) { this.init(aSprite); -} - -SpriteIconMorph.prototype.init = function (aSprite) { +}; SpriteIconMorph.prototype.init = function (aSprite) { var colors, action, query, hover; colors = [ IDE_Morph.prototype.categoryColor, IDE_Morph.prototype.frameColor, IDE_Morph.prototype.frameColor - ]; - - action = () => { + ]; action = () => { // make my sprite the current one var ide = this.parentThatIsA(IDE_Morph); if (ide) { ide.selectSprite(this.object); - } - }; - - query = () => { + }; + }; query = () => { // answer true if my sprite is the current one var ide = this.parentThatIsA(IDE_Morph); if (ide) { - return ide.currentSprite === this.object; - } - return false; - }; - - hover = () => { - if (!aSprite.exemplar) {return null; } + return (ide.currentSprite === this.object); + }; return false; + }; hover = () => { + if (!aSprite.exemplar) {return null;}; return (localize('parent') + ':\n' + aSprite.exemplar.name); }; @@ -9284,9 +9040,7 @@ SpriteIconMorph.prototype.init = function (aSprite) { SpriteIconMorph.prototype.createThumbnail = function () { if (this.thumbnail) { this.thumbnail.destroy(); - } - - this.thumbnail = new Morph(); + }; this.thumbnail = new Morph; this.thumbnail.isCachingImage = true; this.thumbnail.bounds.setExtent(this.thumbSize); if (this.object instanceof SpriteMorph) { // support nested sprites @@ -9310,8 +9064,7 @@ SpriteIconMorph.prototype.createLabel = function () { if (this.label) { this.label.destroy(); - } - txt = new StringMorph( + }; txt = new StringMorph( this.object.name, this.fontSize, this.fontStyle, @@ -9323,7 +9076,7 @@ SpriteIconMorph.prototype.createLabel = function () { this.labelColor ); - this.label = new FrameMorph(); + this.label = new FrameMorph; this.label.acceptsDrops = false; this.label.alpha = 0; this.label.setExtent(txt.extent()); @@ -9692,7 +9445,7 @@ SpriteIconMorph.prototype.flash = function () { // CostumeIconMorph inherits from ToggleButtonMorph (Widgets) // ... and copies methods from SpriteIconMorph -CostumeIconMorph.prototype = new ToggleButtonMorph(); +CostumeIconMorph.prototype = new ToggleButtonMorph; CostumeIconMorph.prototype.constructor = CostumeIconMorph; CostumeIconMorph.uber = ToggleButtonMorph.prototype; @@ -9940,7 +9693,7 @@ CostumeIconMorph.prototype.prepareToBeGrabbed = function () { // TurtleIconMorph inherits from ToggleButtonMorph (Widgets) // ... and copies methods from SpriteIconMorph -TurtleIconMorph.prototype = new ToggleButtonMorph(); +TurtleIconMorph.prototype = new ToggleButtonMorph; TurtleIconMorph.prototype.constructor = TurtleIconMorph; TurtleIconMorph.uber = ToggleButtonMorph.prototype; @@ -10118,7 +9871,7 @@ TurtleIconMorph.prototype.userMenu = function () { // WardrobeMorph inherits from ScrollFrameMorph -WardrobeMorph.prototype = new ScrollFrameMorph(); +WardrobeMorph.prototype = new ScrollFrameMorph; WardrobeMorph.prototype.constructor = WardrobeMorph; WardrobeMorph.uber = ScrollFrameMorph.prototype; @@ -10142,7 +9895,6 @@ WardrobeMorph.prototype.init = function (aSprite, sliderColor) { WardrobeMorph.uber.init.call(this, null, null, sliderColor); // configure inherited properties - // this.fps = 2; // commented out to make scrollbars more responsive this.updateList(); }; @@ -10368,7 +10120,7 @@ WardrobeMorph.prototype.reactToDropOf = function (icon) { // SoundIconMorph inherits from ToggleButtonMorph (Widgets) // ... and copies methods from SpriteIconMorph -SoundIconMorph.prototype = new ToggleButtonMorph(); +SoundIconMorph.prototype = new ToggleButtonMorph; SoundIconMorph.prototype.constructor = SoundIconMorph; SoundIconMorph.uber = ToggleButtonMorph.prototype; @@ -10590,7 +10342,7 @@ SoundIconMorph.prototype.prepareToBeGrabbed = function () { // JukeboxMorph instance creation -JukeboxMorph.prototype = new ScrollFrameMorph(); +JukeboxMorph.prototype = new ScrollFrameMorph; JukeboxMorph.prototype.constructor = JukeboxMorph; JukeboxMorph.uber = ScrollFrameMorph.prototype; @@ -10609,7 +10361,6 @@ JukeboxMorph.prototype.init = function (aSprite, sliderColor) { // configure inherited properties this.acceptsDrops = false; - // this.fps = 2; // commented out to make scrollbars more responsive this.updateList(); }; @@ -10728,13 +10479,6 @@ JukeboxMorph.prototype.reactToDropOf = function (icon) { // MIDIMorph //////////////////////////////////////////////////// -/* - I am a selectable element in a SceneAlbum, keeping - a self-updating thumbnail of the scene I'm respresenting, and a - self-updating label of the scene's name (in case it is changed - elsewhere) -*/ - // MIDIMorph inherits from Morph MIDIMorph.prototype = new FrameMorph; @@ -10759,15 +10503,12 @@ var aMID = new MIDSoundData('Unnamed', 0, ((note, volume, length, index, optional) => 0), true); this.parentThatIsA(IDE_Morph).mids.push(aMID); this.add(new MIDIIconMorph(aMID)); this.fixLayout();}; this.add(new SliderMorph(0, myMIDs.length)); this.children[2].setPosition(new Point( -99, 0)); this.children[2].mouseDownLeft = function anonymous (pos) { - var world; - +99, 0)); this.children[2].mouseDownLeft = function (pos) { if (!this.button.bounds.containsPoint(pos)) { this.offset = new Point(); // return null; } else { this.offset = pos.subtract(this.button.bounds.origin); - } - world = this.root(); + }; this.step = () => { var mousePos, newX, newY; @@ -10816,7 +10557,7 @@ if (myMIDs.length > 0) {this.visualizer.selectedMID = myMIDs[0];}; this.add(new MIDIIconMorph(myMIDs[i])); i++;};}).apply(this, [myMIDs]); this.fixLayout();}; -MIDIMorph.prototype.fixLayout = function anonymous () { +MIDIMorph.prototype.fixLayout = function () { var myChildren = this.children, myMIDs = (isNil(this.parentThatIsA( IDE_Morph)) ? [] : this.parentThatIsA(IDE_Morph).mids); myChildren.filter(child => child instanceof MIDIIconMorph @@ -10830,13 +10571,6 @@ morph => morph instanceof MIDIIconMorph).indexOf(child) + 1)) - child.bounds.hei // MIDIVisualizerMorph //////////////////////////////////////////////////// -/* - I am a selectable element in a SceneAlbum, keeping - a self-updating thumbnail of the scene I'm respresenting, and a - self-updating label of the scene's name (in case it is changed - elsewhere) -*/ - // MIDIVisualizerMorph inherits from Morph MIDIVisualizerMorph.prototype = new Morph; @@ -10924,13 +10658,6 @@ MIDIIconMorph.prototype.fixLayout = function () { // SoundVisualizerMorph //////////////////////////////////////////////////// -/* - I am a selectable element in a SceneAlbum, keeping - a self-updating thumbnail of the scene I'm respresenting, and a - self-updating label of the scene's name (in case it is changed - elsewhere) -*/ - // SoundVisualizerMorph inherits from Morph SoundVisualizerMorph.prototype = new Morph; @@ -11337,8 +11064,7 @@ StageHandleMorph.prototype.init = function (target) { this.target = target || null; this.userState = 'normal'; // or 'highlight' HandleMorph.uber.init.call(this); - this.color = MorphicPreferences.isFlat ? - IDE_Morph.prototype.backgroundColor : new Color(190, 190, 190); + this.color = IDE_Morph.prototype.categoryColor.lighter(); this.isDraggable = false; this.setExtent(new Point(12, 50)); @@ -11351,13 +11077,12 @@ StageHandleMorph.prototype.render = function (ctx) { if (this.userState === 'highlight') { this.renderOn( ctx, - MorphicPreferences.isFlat ? - new Color(245, 245, 255) : new Color(100, 100, 255), + (this.color).darker(), this.color ); } else { // assume 'normal' this.renderOn(ctx, this.color); - } + }; }; StageHandleMorph.prototype.renderOn = function ( @@ -11367,10 +11092,7 @@ StageHandleMorph.prototype.renderOn = function ( ) { var l = this.height() / 8, w = this.width() / 6, - r = w / 2, - x, - y, - i; + r = w / 2, x, y, i; ctx.lineWidth = w; ctx.lineCap = 'round'; @@ -11384,11 +11106,9 @@ StageHandleMorph.prototype.renderOn = function ( ctx.moveTo(x, y - (l - r)); ctx.lineTo(x, y + (l - r)); ctx.stroke(); - } - x += (w * 2); + }; x += (w * 2); l *= 2; - } - if (shadowColor) { + }; if (shadowColor) { ctx.strokeStyle = shadowColor.toString(); x = this.width() / 12 + w; l = this.height() / 8; @@ -11398,69 +11118,47 @@ StageHandleMorph.prototype.renderOn = function ( ctx.moveTo(x, y - (l - r)); ctx.lineTo(x, y + (l - r)); ctx.stroke(); - } - x += (w * 2); + }; x += (w * 2); l *= 2; - } - } + }; + }; }; // StageHandleMorph layout: -StageHandleMorph.prototype.fixLayout = function () { - if (!this.target) {return; } - var ide = this.target.parentThatIsA(IDE_Morph); - this.setTop(this.target.top() + 10); - this.setRight(this.target.left()); - if (ide) {ide.add(this); } // come to front -}; +StageHandleMorph.prototype.fixLayout = function () {if ( +this.target instanceof Morph) {var ide = (this.target +).parentThatIsA(IDE_Morph); this.setTop((this.target +).top() + 10); this.setRight(this.target.left()); +if (ide instanceof Morph) {ide.add(this);};};}; // StageHandleMorph stepping: StageHandleMorph.prototype.step = null; -StageHandleMorph.prototype.mouseDownLeft = function (pos) { - var world = this.world(), - offset = this.right() - pos.x, - ide = this.target.parentThatIsA(IDE_Morph); - - if (!this.target) { - return null; - } - ide.isSmallStage = true; - ide.controlBar.stageSizeButton.refresh(); - - this.step = function () { - var newPos, newWidth; - if (world.hand.mouseButton) { - newPos = world.hand.bounds.origin.x + offset; - newWidth = this.target.right() - newPos; - ide.stageRatio = newWidth / this.target.dimensions.x; - ide.setExtent(world.extent()); - - } else { - this.step = null; - ide.isSmallStage = (ide.stageRatio !== 1); - ide.controlBar.stageSizeButton.refresh(); - } - }; -}; +StageHandleMorph.prototype.mouseDownLeft = function ( +pos) {if (!isNil(this.target)) {var world = this.world( +), offset = this.right() - pos.x, ide = (this.target +).parentThatIsA(IDE_Morph); ide.isSmallStage = true; +ide.controlBar.stageSizeButton.refresh(); (this.step +) = function () {var newPos, newWidth; if ((world.hand +).mouseButton) {newPos = ((world.hand.bounds.origin.x +) + offset); newWidth = this.target.right() - newPos; +ide.stageRatio = newWidth / this.target.dimensions.x; +ide.setExtent(world.extent());} else {this.step = null; +ide.isSmallStage = (ide.stageRatio !== 1); (ide.controlBar +).stageSizeButton.refresh();};};} else {return null;};}; // StageHandleMorph events: -StageHandleMorph.prototype.mouseEnter = function () { - this.userState = 'highlight'; - this.rerender(); -}; +StageHandleMorph.prototype.mouseEnter = function ( +) {this.userState = 'highlight'; this.rerender();}; -StageHandleMorph.prototype.mouseLeave = function () { - this.userState = 'normal'; - this.rerender(); -}; +StageHandleMorph.prototype.mouseLeave = function ( +) {this.userState = 'normal'; this.rerender();}; -StageHandleMorph.prototype.mouseDoubleClick = function () { - this.target.parentThatIsA(IDE_Morph).toggleStageSize(this.isSmallStage); -}; +StageHandleMorph.prototype.mouseDoubleClick = function () {(this +).target.parentThatIsA(IDE_Morph).toggleStageSize(this.isSmallStage);}; // PaletteHandleMorph //////////////////////////////////////////////////////// @@ -11481,7 +11179,7 @@ PaletteHandleMorph.prototype.init = function (target) { this.target = target || null; this.userState = 'normal'; HandleMorph.uber.init.call(this); - this.color = new Color(190, 190, 190); + this.color = IDE_Morph.prototype.categoryColor.lighter(); this.isDraggable = false; this.setExtent(new Point(12, 50)); @@ -11712,8 +11410,7 @@ CamSnapshotDialogMorph.prototype.close = function () { if (this.videoElement && this.videoElement.stream) { this.videoElement.stream.getTracks()[0].stop(); this.videoElement.remove(); - } - CamSnapshotDialogMorph.uber.destroy.call(this); + }; CamSnapshotDialogMorph.uber.destroy.call(this); }; // SoundRecorderDialogMorph //////////////////////////////////////////////////// @@ -11725,48 +11422,30 @@ CamSnapshotDialogMorph.prototype.close = function () { // SoundRecorderDialogMorph inherits from DialogBoxMorph: -SoundRecorderDialogMorph.prototype = new DialogBoxMorph; -SoundRecorderDialogMorph.prototype.constructor = SoundRecorderDialogMorph; -SoundRecorderDialogMorph.uber = DialogBoxMorph.prototype; - -// SoundRecorderDialogMorph instance creation - -function SoundRecorderDialogMorph (onAccept) {this.init(onAccept);}; - -SoundRecorderDialogMorph.prototype.init = function (onAccept) {var myself = this; this.padding = 10; this.accept = onAccept; this.mediaRecorder = null; this.audioElement = document.createElement('audio' -); this.audioElement.hidden = true; this.audioElement.onended = function (event) {myself.stop();}; document.body.appendChild(this.audioElement); this.recordButton = null; this.stopButton = null; -this.playButton = null; this.progressBar = new BoxMorph(); SoundRecorderDialogMorph.uber.init.call(this); this.labelString = 'Sound Recorder'; this.createLabel(); this.buildContents();}; - -SoundRecorderDialogMorph.prototype.buildContents = function () {var audioChunks = []; this.recordButton = new PushButtonMorph(this, 'record', new SymbolMorph('circleSolid', 10)); this.stopButton = new -PushButtonMorph(this, 'stop', new SymbolMorph('rectangleSolid', 10)); this.playButton = new PushButtonMorph(this, 'play', new SymbolMorph('pointRight', 10)); this.buildProgressBar(); this.addBody(new -AlignmentMorph('row', this.padding)); this.body.add(this.recordButton); this.body.add(this.stopButton); this.body.add(this.playButton); this.body.add(this.progressBar); this.body.fixLayout(); if -(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {navigator.mediaDevices.getUserMedia({audio: {channelCount: 1}}).then(stream => {this.mediaRecorder = new MediaRecorder(stream); -this.mediaRecorder.ondataavailable = (event) => {audioChunks.push(event.data);}; this.mediaRecorder.onstop = (event) => {var buffer = new Blob(audioChunks), reader = new window.FileReader(); -reader.readAsDataURL(buffer); reader.onloadend = () => {var base64 = reader.result; base64 = 'data:audio/ogg;base64,' + base64.split(',')[1]; this.audioElement.src = base64; -this.audioElement.load(); audioChunks = [];};};});}; this.addButton('ok', 'Save'); this.addButton('cancel', 'Cancel'); this.fixLayout(); this.rerender();}; - -SoundRecorderDialogMorph.prototype.buildProgressBar = function () {var line = new Morph(), myself = this; this.progressBar.setExtent(new Point(150, 20)); this.progressBar.setColor(new Color(200, 200, 200)); -this.progressBar.setBorderWidth(1); this.progressBar.setBorderColor(new Color(150, 150, 150)); line.setExtent(new Point(130, 2)); line.setColor(new Color(50, 50, 50)); line.setCenter(this.progressBar.center()); -this.progressBar.add(line); this.progressBar.indicator = new Morph(); this.progressBar.indicator.setExtent(new Point(5, 15)); this.progressBar.indicator.setColor(new Color(50, 200, 50)); -this.progressBar.indicator.setCenter(line.leftCenter()); this.progressBar.add(this.progressBar.indicator); -this.progressBar.setPercentage = function (percentage) {this.indicator.setLeft(line.left() + (line.width() / 100 * percentage) - this.indicator.width() / 2);}; -this.progressBar.step = function () {if (myself.audioElement.duration) {this.setPercentage(myself.audioElement.currentTime / myself.audioElement.duration * 100);} else {this.setPercentage(0);}};}; - -SoundRecorderDialogMorph.prototype.record = function anonymous () {if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {this.stop(); -return;}; this.mediaRecorder.start(); this.recordButton.label.setColor(new Color(255, 0, 0)); this.playButton.label.setColor(new Color(0, 0, 0));}; - -SoundRecorderDialogMorph.prototype.stop = function () {if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {this.mediaRecorder.stop( -);}; this.audioElement.pause(); this.audioElement.currentTime = 0; this.recordButton.label.setColor(BLACK); this.playButton.label.setColor(BLACK);}; - -SoundRecorderDialogMorph.prototype.play = function () {this.stop(); this.audioElement.oncanplaythrough = function ( -) {this.play(); this.oncanplaythrough = nop;}; this.playButton.label.setColor(new Color(0, 255, 0));}; - -SoundRecorderDialogMorph.prototype.ok = function () {var myself = this; this.stop(); this.audioElement.oncanplaythrough = function anonymous () {if (this.duration && (this.duration !== Infinity -)) {myself.accept(this); this.oncanplaythrough = nop; myself.destroy();} else {myself.buttons.children.forEach(button => button.disable()); this.play();};};}; - -SoundRecorderDialogMorph.prototype.destroy = function anonymous () {this.stop(); this.audioElement.remove( -); if (this.mediaRecorder && this.mediaRecorder.stream) {this.mediaRecorder.stream.getTracks()[0].stop( -);}; SoundRecorderDialogMorph.uber.destroy.call(this);}; /* The recorder is now updated too... :-) */ +function SoundRecorderDialogMorph (onAccept) {this.init(onAccept);}; SoundRecorderDialogMorph.prototype = new DialogBoxMorph; SoundRecorderDialogMorph.prototype.constructor = SoundRecorderDialogMorph; +SoundRecorderDialogMorph.uber = DialogBoxMorph.prototype; SoundRecorderDialogMorph.prototype.init = function (onAccept) {var myself = this; this.padding = 10; this.accept = onAccept; this.mediaRecorder = ( +null); this.audioElement = document.createElement('audio'); this.audioElement.hidden = true; this.audioElement.onended = function (event) {myself.stop();}; document.body.appendChild(this.audioElement); (this +).recordButton = null; this.stopButton = null; this.playButton = null; this.progressBar = new BoxMorph; SoundRecorderDialogMorph.uber.init.call(this); this.labelString = 'Sound Recorder'; this.createLabel(); +this.buildContents();}; SoundRecorderDialogMorph.prototype.buildContents = function () {var audioChunks = []; this.recordButton = new PushButtonMorph(this, 'record', new SymbolMorph('circleSolid', 10)); (this +).stopButton = new PushButtonMorph(this, 'stop', new SymbolMorph('rectangleSolid', 10)); this.playButton = new PushButtonMorph(this, 'play', new SymbolMorph('pointRight', 10)); this.buildProgressBar(); (this +).addBody(new AlignmentMorph('row', this.padding)); this.body.add(this.recordButton); this.body.add(this.stopButton); this.body.add(this.playButton); this.body.add(this.progressBar); this.body.fixLayout(); +if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {navigator.mediaDevices.getUserMedia({audio: {channelCount: 1}}).then(stream => {this.mediaRecorder = new MediaRecorder(stream); (this +).mediaRecorder.ondataavailable = (event) => {audioChunks.push(event.data);}; this.mediaRecorder.onstop = (event) => {var buffer = new Blob(audioChunks), reader = new window.FileReader(); (reader +).readAsDataURL(buffer); reader.onloadend = () => {var base64 = reader.result; base64 = 'data:audio/ogg;base64,' + base64.split(',')[1]; this.audioElement.src = base64; this.audioElement.load(); +audioChunks = [];};};});}; this.addButton('ok', 'Save'); this.addButton('cancel', 'Cancel'); this.fixLayout(); this.rerender();}; SoundRecorderDialogMorph.prototype.buildProgressBar = function ( +) {var line = new Morph(), myself = this; this.progressBar.setExtent(new Point(150, 20)); this.progressBar.setColor(new Color(200, 200, 200)); this.progressBar.setBorderWidth(1); (this.progressBar +).setBorderColor(new Color(150, 150, 150)); line.setExtent(new Point(130, 2)); line.setColor(new Color(50, 50, 50)); line.setCenter(this.progressBar.center()); this.progressBar.add(line); (this +).progressBar.indicator = new Morph; this.progressBar.indicator.setExtent(new Point(5, 15)); this.progressBar.indicator.setColor(new Color(50, 200, 50)); (this.progressBar).indicator.setCenter( +line.leftCenter()); this.progressBar.add(this.progressBar.indicator); this.progressBar.setPercentage = function (percentage) {this.indicator.setLeft(line.left() + (line.width() / (100 * percentage +)) - this.indicator.width() / 2);}; this.progressBar.step = function () {if (myself.audioElement.duration) {this.setPercentage(myself.audioElement.currentTime / ((myself.audioElement).duration * 100 +));} else {this.setPercentage(0);}};}; SoundRecorderDialogMorph.prototype.record = function () {if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {this.stop(); return;}; (this +).mediaRecorder.start(); this.recordButton.label.setColor(new Color(255, 0, 0)); this.playButton.label.setColor(new Color(0, 0, 0));}; SoundRecorderDialogMorph.prototype.stop = (function ( +) {if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {this.mediaRecorder.stop();}; this.audioElement.pause(); this.audioElement.currentTime = 0; (this.recordButton.label +).setColor(BLACK); this.playButton.label.setColor(BLACK);}); SoundRecorderDialogMorph.prototype.play = function () {this.stop(); this.audioElement.oncanplaythrough = function () {(this +).play(); this.oncanplaythrough = nop;}; this.playButton.label.setColor(new Color(0, 255, 0));}; SoundRecorderDialogMorph.prototype.ok = function () {var myself = this; this.stop(); (this +).audioElement.oncanplaythrough = function () {if (this.duration && (this.duration !== Infinity)) {myself.accept(this); this.oncanplaythrough = nop; myself.destroy();} else {(myself +).buttons.children.forEach(button => button.disable()); this.play();};};}; SoundRecorderDialogMorph.prototype.destroy = function () {this.stop(); this.audioElement.remove(); +if (this.mediaRecorder && this.mediaRecorder.stream) {this.mediaRecorder.stream.getTracks()[0].stop();}; SoundRecorderDialogMorph.uber.destroy.call(this);}; // IDE_FPSMorph ////////////////////////////////////////////////////////// @@ -11774,8 +11453,7 @@ SoundRecorderDialogMorph.prototype.destroy = function anonymous () {this.stop(); // IDE_FPSMorph inherits from FPSMorph: -IDE_FPSMorph = function IDE_FPSMorph () {this.init();}; IDE_FPSMorph.prototype = new FPSMorph; IDE_FPSMorph.prototype.constructor = IDE_FPSMorph; IDE_FPSMorph.uber = FPSMorph.prototype; -IDE_FPSMorph.prototype.step = function anonymous () {this.frameCounter++; if (!(Date.now() < (this.startTime + 1000))) {this.text = (('FPS\: ').concat(this.frameCounter)); -this.fixLayoutAndPosition(); this.frameCounter = 0; this.startTime = Date.now();};}; IDE_FPSMorph.prototype.fixLayoutAndPosition = function anonymous ( -) {try {this.fixLayout(); if (this.parent instanceof IDE_Morph) {this.setRight(this.parent.right()); this.setBottom(this.parent.bottom( -)); this.parent.add(this);}; if (!this.isVisible) {this.isVisible = true;}; this.rerender();} catch (error) {};}; \ No newline at end of file +function IDE_FPSMorph () {this.init();}; IDE_FPSMorph.prototype = new FPSMorph; IDE_FPSMorph.prototype.constructor = IDE_FPSMorph; IDE_FPSMorph.uber = FPSMorph.prototype; (IDE_FPSMorph +).prototype.step = function () {this.text = (('FPS\: ').concat(Math.round(((performance.now() - this.startTime) > 0) ? (1000 / (performance.now() - this.startTime)) : 0).toString())); +this.fixLayoutAndPosition(); this.startTime = performance.now();}; IDE_FPSMorph.prototype.fixLayoutAndPosition = function () {try {this.fixLayout(); if (this.parent instanceof IDE_Morph +) {this.setRight((this.parent).right()); this.setBottom(this.parent.bottom()); this.parent.add(this);}; this.isVisible = true; this.rerender();} catch (error) {};}; \ No newline at end of file diff --git a/src/lists.js b/src/lists.js index 202b5b4..5c417c6 100644 --- a/src/lists.js +++ b/src/lists.js @@ -7,7 +7,7 @@ written by Jens Mönig and Brian Harvey jens@moenig.org, bh@cs.berkeley.edu - Copyright (C) 2023 by Jens Mönig and Brian Harvey + Copyright (C) 2024 by Jens Mönig and Brian Harvey This file is part of Snap!. @@ -54,21 +54,7 @@ */ -/*global modules, BoxMorph, HandleMorph, PushButtonMorph, SyntaxElementMorph, -Color, Point, WatcherMorph, StringMorph, SpriteMorph, ScrollFrameMorph, isNil, -CellMorph, ArrowMorph, MenuMorph, snapEquals, localize, isString, IDE_Morph, -MorphicPreferences, TableDialogMorph, SpriteBubbleMorph, SpeechBubbleMorph, -TableFrameMorph, TableMorph, Variable, isSnapObject, Costume, contains, detect, -ZERO, WHITE*/ - -/*jshint esversion: 6*/ - -// Global settings ///////////////////////////////////////////////////// - -modules.lists = '2023-July-24'; - -var List; -var ListWatcherMorph; +var List, ListWatcherMorph; // List //////////////////////////////////////////////////////////////// @@ -144,11 +130,12 @@ List.prototype.enableTables = true; // List printing -List.prototype.toString = function anonymous () {return 'a List [' + this.length() + ' elements]';}; +List.prototype.toString = function () {return 'a List [' + this.length() + ' elements]';}; // List updating: -List.prototype.changed = function anonymous () {this.lastChanged = Date.now();}; +List.prototype.changed = function ( +) {this.lastChanged = Date.now();}; // Linked List ops: @@ -156,8 +143,7 @@ List.prototype.cons = function (car, cdr) { var answer = new List(); if (!(cdr instanceof List || isNil(cdr))) { throw new Error("cdr isn't a list: " + cdr); - } - answer.first = isNil(car) ? null : car; + }; answer.first = isNil(car) ? null : car; answer.rest = cdr || null; answer.isLinked = true; return answer; @@ -167,16 +153,12 @@ List.prototype.cdr = function () { var result, i; if (this.isLinked) { return this.rest || new List(); - } - if (this.contents.length < 2) { - return new List(); - } - - result = new List(); + }; if (this.contents.length < 2) { + return new List; + }; result = new List; for (i = this.contents.length; i > 1; i -= 1) { result = this.cons(this.at(i), result); - } - return result; + }; return result; }; // List array setters: @@ -204,8 +186,8 @@ List.prototype.put = function (element, index) { this.becomeArray(); if (idx < 1 || idx > this.contents.length) { return; - } - this.contents[idx - 1] = data; + }; this.contents[ + idx - 1] = data; this.changed(); }; @@ -226,9 +208,12 @@ List.prototype.clear = function () { // List utilities -List.prototype.map = function (callback) {return new List(this.itemsArray().map(callback));}; +List.prototype.map = function (callback +) {return new List(this.itemsArray( +).map(callback));}; -List.prototype.deepMap = function (callback) {return this.map(item => ((item instanceof List) ? item.deepMap(callback) : callback(item)));}; +List.prototype.deepMap = function (callback) {return this.map(item => ( +(item instanceof List) ? item.deepMap(callback) : callback(item)));}; // List getters (all hybrid): @@ -239,10 +224,9 @@ List.prototype.length = function () { while (pair && pair.isLinked) { result += 1; pair = pair.rest; - } - return result + (pair ? pair.contents.length : 0); - } - return this.contents.length; + }; return result + ( + pair ? pair.contents.length : 0); + }; return this.contents.length; }; List.prototype.at = function (index) { @@ -262,15 +246,17 @@ List.prototype.at = function (index) { return isNil(value) ? '' : value; }; -List.prototype.contains = function anonymous (element) { -return (this.indexOf(element) > 0);}; /* Now is fast. */ +List.prototype.contains = function (element +) {return (this.indexOf(element) > 0);}; -List.prototype.onlyHas = function anonymous (element) {var result = [], i = 0; if (this.isEmpty()) { -return false;}; while (i < this.length()) {result.push((this.at(i + 1) instanceof List) ? snapEquals( -this.at(i + 1), element) : Process.prototype.reportIsIdentical(this.at(i + 1), element)); i++;}; i = 0; -while (i < result.length) {if (!(result[i])) {return false;}; i++;}; return true;}; /* Exclusive true. */ +List.prototype.onlyHas = function (element) {var result = [], i = 0; +if (this.isEmpty()) {return false;}; while (i < this.length()) { +result.push((this.at(i + 1) instanceof List) ? snapEquals( +this.at(i + 1), element) : Process.prototype.reportIsIdentical( +this.at(i + 1), element)); i++;}; i = 0; while (i < result.length +) {if (!(result[i])) {return false;}; i++;}; return true;}; -List.prototype.isEmpty = function anonymous () { +List.prototype.isEmpty = function () { if (this.isLinked) {return isNil(this.first );}; return !(this.contents.length);}; @@ -283,7 +269,6 @@ pair.first instanceof Context Process.prototype.reportIsIdentical( pair.first, element)) {return idx;}; pair = pair.rest; idx += 1;}; -/* in case I'm arrayed */ len = pair.contents.length; for (i = 0; i < len; i += 1) { if (((pair.contents[i] instanceof Context diff --git a/src/locale.js b/src/locale.js index fd8ea95..4b32dc3 100644 --- a/src/locale.js +++ b/src/locale.js @@ -250,10 +250,15 @@ SnapTranslator.dict.en = { 'toki pona' : 'toki pona', 'IDIOM MENU STRING' : 'Idiom', 'ZOOM MENU STRING' : 'Zoom blocks', +'ZOOM 0.5 SIZE' : 'pocket (0.5x)', +'ZOOM 0.75 SIZE' : 'little (0.75x)', +'ZOOM 0.9 SIZE' : 'legacy (0.9x)', 'ZOOM 1 SIZE' : 'normal (1x)', -'ZOOM 1.2 SIZE' : 'demo (1.2x)', -'ZOOM 1.4 SIZE' : 'presentation (1.4x)', -'ZOOM 1.5 SIZE' : 'master (1.5x)', +'ZOOM 1.11 SIZE' : 'demo (1.11x)', +'ZOOM 1.295 SIZE' : 'presentation (1.295x)', +'ZOOM 1.365 SIZE' : 'master (1.365x)', +'ZOOM 1.445 SIZE' : 'moderator (1.445x)', +'ZOOM 1.5 SIZE' : 'studio (1.5x)', 'ZOOM 2 SIZE' : 'big (2x)', 'ZOOM 4 SIZE' : 'huge (4x)', 'ZOOM 8 SIZE' : 'giant (8x)', @@ -270,9 +275,9 @@ SnapTranslator.dict.en = { 'SELECTOR forward INPUTS %n %optDir' : 'move %n steps %optDir', 'SELECTOR bounceOffEdge' : 'if on edge, bounce', -'SELECTOR turn INPUTS %n degrees' : 'turn $turnRight-1.5 %n degrees', -'SELECTOR turnLeft INPUTS %n degrees' : 'turn $turnLeft-1.5 %n degrees', -'SELECTOR setHeading INPUTS %dir' : 'point in direction %dir', +'SELECTOR turn INPUTS %n degrees' : 'turn right \( $turnRight-1 \) %n º', +'SELECTOR turnLeft INPUTS %n degrees' : 'turn left \( $turnLeft-1 \) %n º', +'SELECTOR setHeading INPUTS %dir' : 'point in direction %dir º', 'SELECTOR doFaceTowards INPUTS %dst' : 'point towards %dst', 'SELECTOR gotoDeviatedXY INPUTS %n %n %optDir' : 'go to x\: %n y\: %n %optDir', 'SELECTOR doGotoObject INPUTS %dst' : 'go to %dst', diff --git a/src/locale/lang-es.js b/src/locale/lang-es.js index 3b941b9..2e1437a 100644 --- a/src/locale/lang-es.js +++ b/src/locale/lang-es.js @@ -32,7 +32,7 @@ SnapTranslator.dict.es = { 'Input names:' : 'Nombres de entrada:', 'Remove viewer from stage' : 'Remove viewer from...', -'View on stage' : 'View on...' +'View on stage' : 'View on...', diff --git a/src/locale/lang-tok.js b/src/locale/lang-tok.js index f4b1e1f..30c8685 100644 --- a/src/locale/lang-tok.js +++ b/src/locale/lang-tok.js @@ -22,5 +22,4 @@ SnapTranslator.dict.tok = { - }; \ No newline at end of file diff --git a/src/maps.js b/src/maps.js index 4781b52..7f79a08 100644 --- a/src/maps.js +++ b/src/maps.js @@ -32,15 +32,8 @@ credits: -------- https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames -*/ - -/*global modules, Point, newCanvas, radians, StringMorph, normalizeCanvas*/ - -// Global stuff //////////////////////////////////////////////////////// -modules.maps = '2021-June-15'; - -// WorldMap ///////////////////////////////////////////////////////////// +*/ function WorldMap(host) { this.tileServers = { @@ -255,8 +248,8 @@ WorldMap.prototype.render = function () { this.position.y % 1 ).multiplyBy(size), tileOrigin = cntr.subtract(off), - tileDistance = tileOrigin.floorDivideBy(size).add(1), - tileGrid = this.extent.floorDivideBy(size).add(2), + tileDistance = tileOrigin.divideBy(size).add(1), + tileGrid = this.extent.divideBy(size).add(2), originTile = tile.subtract(tileDistance), mapOrigin = tileOrigin.subtract( tileDistance.multiplyBy(size) @@ -362,4 +355,4 @@ WorldMap.prototype.addCredits = function () { this.canvas.width - crd.width, this.canvas.height - crd.height ); -}; +}; \ No newline at end of file diff --git a/src/math.js b/src/math.js index 3683e12..ba77405 100644 --- a/src/math.js +++ b/src/math.js @@ -1,26 +1,1357 @@ -NaturalMath = {}; NaturalMath.getNumberFromString = function (string) {return (isNil(string) ? '0' : (isNil(string.toString) ? '0' : string.toString( -)));}; NaturalMath.basicAddOne = function (string) {var starters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], succesors = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']; -string = NaturalMath.getNumberFromString(string); var last = succesors[string[string.length - 1]], fromStart = string.slice(0, string.length - 1); return ((fromStart.length > 0) ? (( -last === '0') ? NaturalMath.basicAddOne(fromStart) : fromStart) : ((string[0] === '9') && (last === '0') ? '1' : '')) + last;}; NaturalMath.basicDeleteOne = function (string) { -var starters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], succesors = ['9', '0', '1', '2', '3', '4', '5', '6', '7', '8']; string = NaturalMath.getNumberFromString(string); -var last = succesors[string[string.length - 1]], fromStart = string.slice(0, string.length - 1); return ((fromStart.length > 0) ? ((last === '9') ? NaturalMath.basicDeleteOne(fromStart -) : fromStart) : ((string[0] === '9') && (last === '0') ? '1' : '')) + last;}; NaturalMath.fixZeroesOnNumber = function (string) {var i = 0, checker = []; -string = NaturalMath.getNumberFromString(string); if (string === '0') {return string;} else {while ((i < string.length) && (string[i] === '0')) {checker.push(string[i]); i++;}; -var j = checker.length, arrangement = ''; i = 0; while (i < string.length) {if (!(i < j)) {arrangement = (arrangement + string[i]);}; i++;}; return arrangement;};}; -NaturalMath.addOne = function (string) {return NaturalMath.fixZeroesOnNumber(NaturalMath.basicAddOne(string));}; NaturalMath.deleteOne = function (string) { -string = NaturalMath.getNumberFromString(string); return ((string === '0') ? string : NaturalMath.fixZeroesOnNumber(NaturalMath.basicDeleteOne(string)));}; -NaturalMath.basicOnePlusTwo = function (string1, string2) {while (!(string2 === '0')) {string1 = NaturalMath.addOne(string1); string2 = NaturalMath.deleteOne(string2);}; -return string1;}; NaturalMath.basicOneMinusTwo = function (string1, string2) {while (!(string2 === '0')) {string1 = NaturalMath.deleteOne(string1); string2 = NaturalMath.deleteOne( -string2);}; return string1;}; NaturalMath.basicOneTimesTwo = function (string1, string2) {var string3 = NaturalMath.getNumberFromString(string1); -string1 = NaturalMath.getNumberFromString(string1); string2 = NaturalMath.getNumberFromString(string2); if ((string1 === '0') || (string2 === '0')) {return '0';} else {while (!( -string2 === '0')) {string1 = NaturalMath.basicOnePlusTwo(string1, ((string2 === '1') ? '0' : string3)); string2 = NaturalMath.deleteOne(string2);}; return string1;};}; -NaturalMath.basicOnePowerTwo = function (string1, string2) {var string3 = NaturalMath.getNumberFromString(string1); string1 = NaturalMath.getNumberFromString(string1); -string2 = NaturalMath.getNumberFromString(string2); if (string1 === '0') {return '0';} else if (string2 === '0') {return '1';} else {while (!(string2 === '0')) { -string1 = NaturalMath.basicOneTimesTwo(string1, ((string2 === '1') ? '1' : string3)); string2 = NaturalMath.deleteOne(string2);}; return string1;};}; function IntegerNumber ( -naturalNumber, isNegative) {this.naturalNumber = NaturalMath.fixZeroesOnNumber(NaturalMath.getNumberFromString(naturalNumber || '0')); this.isNegative = asABool( -isNegative);}; IntegerNumber.prototype = new IntegerNumber; IntegerNumber.prototype.constructor = IntegerNumber; IntegerNumber.uber = IntegerNumber.prototype; -IntegerNumber.prototype.fullCopy = function () {return new IntegerNumber(this.naturalNumber, this.isNegative);}; -/* IntegerNumber.prototype.addWith = function ( -integer) {if (!isNil(integer)) {var changedInteger = this.fullCopy(); if (integer.isNegative) {changedInteger.naturalNumber -} else {changedInteger.naturalNumber = changedInteger. -}; this.addWith(changedInteger);};}; */ /* In development... */ \ No newline at end of file +/* "math.js" is an advanced arbitrary-precision math library for any JavaScript project, made with harder work. Written by Alessandro Moisés, email: aless01pime@gmail.com. Copyleft (Ɔ) 2024 +by Alessandro Moisés. The following list shows the order in which all constructors are defined. Use this list to locate code on this document: BigNumMemoizer; [BigDec, {BigMgn, BigCmp}]. */ + +const BigNumMemoizer = function() { + this.init(); +}; +BigNumMemoizer.prototype.saveOnTheStorage = function(selectedInput, selectedOutput) { + if (!(isNil(this.localStorage))) { + if ((this.localStorage).getItem('bigNumMemoizerInputs') == '') { + this.localStorage.setItem('bigNumMemoizerInputs', selectedInput); + } else { + this.localStorage.setItem('bigNumMemoizerInputs', (this.localStorage.getItem('bigNumMemoizerInputs')).concat('\|', selectedInput)); + } + ;if (this.localStorage.getItem('bigNumMemoizerOutputs') == '') { + this.localStorage.setItem('bigNumMemoizerOutputs', selectedOutput); + } else { + this.localStorage.setItem('bigNumMemoizerOutputs', (this.localStorage.getItem('bigNumMemoizerOutputs')).concat('\|', selectedOutput)); + } + ; + } + ; +} +; +BigNumMemoizer.prototype.memoize = function(selectedFunction, selectedFirstInput, selectedSecondInput) { + var selectedString = selectedFunction.concat(',', selectedFirstInput.toString(), ',', isNil(selectedSecondInput) ? 'monadic' : (selectedSecondInput.toString()), ',', BigDec.prototype.maximumDecimals.toString()) + , selectedSearch = this.memoizedInputs.indexOf(selectedString); + var result; + if (selectedSearch == -1) { + try { + result = ((selectedFirstInput[selectedFunction])(selectedSecondInput)).toString(); + } catch (exception) { + result = 'error'; + console.error(exception); + } + ;this.memoizedInputs.push(selectedString); + this.memoizedOutputs.push(result); + if (false) { + this.saveOnTheStorage(selectedString, result); + } + ; + } else { + result = this.memoizedOutputs[selectedSearch]; + } + ;var selectedConstructor = (selectedFirstInput).constructor.name + , receivedOutput = new Function('text',('return \(new ').concat(selectedConstructor, '\(text\)\)\;')); + if (result == 'error') { + throw Error('Unsupported calculation.'); + } else { + return receivedOutput(result); + } + ; +} +; +BigNumMemoizer.prototype.clearTheCache = function() { + if (!(isNil(this.localStorage))) { + this.localStorage.setItem('bigNumMemoizerInputs', ''); + (this.localStorage).setItem('bigNumMemoizerOutputs', ''); + } + ;this.memoizedInputs = []; + this.memoizedOutputs = []; +} +; +BigNumMemoizer.prototype.init = function() { + this.memoizedInputs = []; + this.memoizedOutputs = []; + this.localStorage = null; + try { + this.localStorage = window.localStorage; + } catch (error) {} + ;if (!isNil(this.localStorage)) { + if (isNil(this.localStorage.getItem('bigNumMemoizerInputs'))) { + (this).localStorage.setItem('bigNumMemoizerInputs', ''); + } + ;if (isNil(this.localStorage.getItem('bigNumMemoizerOutputs'))) { + this.localStorage.setItem('bigNumMemoizerOutputs', ''); + } + ;(this.memoizedInputs) = (this.localStorage.getItem('bigNumMemoizerInputs')).split('\|'); + this.memoizedOutputs = (this.localStorage.getItem('bigNumMemoizerOutputs')).split('\|'); + } + ; +} +; +(BigNumMemoizer.prototype.constructor) = BigNumMemoizer; +Array.prototype.flatten = function() { + var result = []; + this.deepMap(item=>result.push(item)); + return result; +} +; +Array.prototype.shallowCopy = function() { + var result = []; + (this).forEach(item=>result.push(item)); + return result; +} +; +Array.prototype.deepMap = function(callback) { + return this.map(item=>((item instanceof Array) ? item.deepMap(callback) : callback(item))); +} +; +Array.prototype.completeCopy = function() { + return (this.deepMap(item=>((item instanceof Array) ? item.fullCopy() : (isNil(item) ? item : ((item.fullCopy instanceof Function) ? item.fullCopy() : (item)))))); +} +; +Array.prototype.fullCopy = function() { + return this.deepMap(item=>((item instanceof Array) ? item.fullCopy() : item)); +} +; +Array.prototype.uniques = function() { + return this.filter((item,index,list)=>(list.indexOf(item) == index)); +} +; +const isNil = (thing=>((thing === null) || (thing === undefined))) + , getHiddenVariable = function(selectedVar) { + if (isNil(selectedVar)) { + return (undefined); + } else if ((selectedVar.toString)instanceof Function) { + selectedVar = selectedVar.toString(); + } else { + return undefined; + } + ;return (new Function(('try \{return ').concat(selectedVar, '\;\} catch \(error\) \{return undefined\;\}\;')))(); +} + , isADigit = (digit=>(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '.']).includes(digit)) + , getNZeroes = function(zeroes) { + zeroes = Math.trunc(Math.max(zeroes, 0)); + if (zeroes == 0) { + return ''; + } else { + return ((10n ** BigInt(zeroes.toString())).toString()).slice(1, zeroes + 1); + } + ; +} + , BigDec = function(text) { + if (new.target instanceof Function) { + this.init(text); + } else { + return new BigDec(text); + } + ; +} + , isSecureForNumbers = function(text) { + return (['-Infinity', 'Infinity'].includes(text) || (text.split('')).every(isADigit)); +} + , LocalBigNumMemoizer = new BigNumMemoizer + , containsNumbers = function(text) { + return (text.split('')).some(isADigit); +}; +BigDec.prototype.constructor = BigDec; +(BigDec).prototype.init = function(text) { + this.bignum = this; + this.imaginaryPart = null; + if (isNil(text)) { + text = ''; + } else if (text.toString instanceof Function) { + text = text.toString(); + text = (isSecureForNumbers(text) ? text : ''); + } else { + text = ''; + } + ;if (['-Infinity', 'Infinity'].includes(text)) { + this.naturalContainer = BigInt('1'); + this.isNegative = (text[0] == '-'); + (this).isInfinite = true; + this.dotPosition = 0; + } else { + this.isInfinite = false; + var splittedNumeral = text.split('.'); + this.isNegative = ((splittedNumeral[0])[0] == '-'); + this.dotPosition = 0; + if (this.isNegative) { + splittedNumeral[0] = (splittedNumeral[0]).slice(1, (splittedNumeral[0]).length); + } + ;if (splittedNumeral.length > 1) { + if (((splittedNumeral[1]).length) > this.maximumDecimals) { + splittedNumeral[1] = (splittedNumeral[1]).slice(0, this.maximumDecimals); + } + ;while (true) { + if ((splittedNumeral[1])[splittedNumeral[1].length - 1] == '0') { + splittedNumeral[1] = ((splittedNumeral[1]).slice(0, ((splittedNumeral[1]).length - 1))); + } else { + break; + } + ; + } + ; + } else { + splittedNumeral.push(''); + } + ;this.dotPosition = (splittedNumeral[1]).length; + this.naturalContainer = BigInt((splittedNumeral[0]).concat(splittedNumeral[1])); + if (this.naturalContainer.toString() == '0') { + this.isNegative = false; + } + ;this.magnitudes = []; + } + ;return this; +} +; +BigDec.prototype.maximumDecimals = 16; +(BigDec.prototype).toString = function() { + if (this.isInfinite) { + return (this.isNegative ? '-' : '').concat('Infinity'); + } + ;var numeral = this.naturalContainer.toString(); + if (this.dotPosition > 0) { + return ((this).isNegative ? '-' : '').concat((!(this.dotPosition < ((this.naturalContainer).toString()).length) ? '0' : ''), numeral.slice(0, Math.max((numeral.length - this.dotPosition), 0)), '.', getNZeroes(this.dotPosition - (this.naturalContainer.toString()).length), numeral.slice(Math.max((numeral.length - this.dotPosition), 0), numeral.length)); + } else { + return ((this.isNegative ? '-' : '').concat(numeral)); + } + ; +} +; +BigDec.prototype.toSignedInteger = function() { + var copy = this.fullCopy(); + copy.dotPosition = 0; + return copy.toString(); +} +; +BigDec.prototype.fullCopy = function() { + if (this.isInfinite) { + return BigDec(this); + } else { + var splittedNumeral = (this.toString()).split('.'); + if (splittedNumeral.length > 1) { + if ((splittedNumeral[1]).length > this.maximumDecimals) { + splittedNumeral[1] = (splittedNumeral[1]).slice(0, this.maximumDecimals); + } + ; + } else { + splittedNumeral.push('0'); + } + ;return BigDec((splittedNumeral[0]).concat('.', splittedNumeral[1])); + } + ; +} +; +(BigDec.prototype.subtractWith) = function(anotherBigNum) { + return this.addWith(anotherBigNum.negativeCopy()); +} +; +BigDec.prototype.negativeCopy = function() { + var copy = this.fullCopy(); + copy.isNegative = !(copy.isNegative); + return copy; +} +; +BigDec.prototype.getImaginaryPart = function() { + var imag = this.imaginaryPart; + return (isNil(imag) ? theZero : imag); +} +; +BigDec.prototype.addWith = function(anotherBigNum) { + if (this.isInfinite || anotherBigNum.isInfinite) { + if (this.isInfinite && anotherBigNum.isInfinite) { + if (this.isNegative == anotherBigNum.isNegative) { + return this.fullCopy(); + } else { + return theZero; + } + ; + } else { + if (this.isInfinite) { + return this.fullCopy(); + } else { + return anotherBigNum.fullCopy(); + } + ; + } + ; + } else { + var firstNum = this.toSignedInteger(), firstDot = this.dotPosition, secondNum = (anotherBigNum).toSignedInteger(), secondDot = anotherBigNum.dotPosition, result; + if (firstDot > secondDot) { + secondNum = secondNum.concat(getNZeroes(firstDot - secondDot)); + result = BigDec(BigInt(firstNum) + BigInt(secondNum)); + result.dotPosition = firstDot; + return result.fullCopy(); + } else if (secondDot > firstDot) { + firstNum = firstNum.concat(getNZeroes(secondDot - firstDot)); + result = BigDec(BigInt(firstNum) + (BigInt(secondNum))); + result.dotPosition = secondDot; + return result.fullCopy(); + } else { + result = BigDec(BigInt(firstNum) + BigInt(secondNum)); + result.dotPosition = firstDot; + return result.fullCopy(); + } + ; + } + ; +} +; +BigDec.prototype.isPureInteger = function() { + return (this.getDecimals()).isEqualTo(theZero); +} +; +BigDec.prototype.isGreaterThan = function(anotherBigNum) { + return (anotherBigNum.subtractWith(this)).isNegative; +} +; +BigDec.prototype.isLessThan = function(anotherBigNum) { + return (this.subtractWith(anotherBigNum)).isNegative; +} +; +BigDec.prototype.truncate = function() { + return (BigDec((((this.fullCopy()).toString()).split('.'))[0])); +} +; +BigDec.prototype.floor = function() { + return ((this.isNegative && !(this.isPureInteger())) ? (this.truncate()).addWith(theDarkUnit) : this.truncate()); +} +; +(BigDec).prototype.isEqualTo = function(anotherBigNum) { + return (((anotherBigNum.subtractWith(this)).absoluteValue()).toString() == '0'); +} +; +BigDec.prototype.ceiling = function() { + return ((!(this.isNegative) && !(this.isPureInteger())) ? theOne.addWith(this.truncate()) : (this.truncate())); +} +; +BigDec.prototype.getSignum = function() { + return this.divideWith(this.absoluteValue()); +} +; +(BigDec.prototype).getDecimals = function() { + return this.subtractWith(this.truncate()); +} +; +BigDec.prototype.absoluteValue = function() { + return (this.isNegative ? this.negativeCopy() : this.fullCopy()); +} +; +(BigDec).prototype.simpleFactorial = function() { + var factor = this.basicRound(); + if (factor.isGreaterThan(theOne)) { + return (factor.multiplicateWith(factor.addWith(theDarkUnit))).multiplicateWith(LocalBigNumMemoizer.memoize('simpleFactorial', factor.subtractWith(theFartNum))); + } else { + return theOne; + } + ; +} +; +BigDec.prototype.basicModulateWith = function(anotherBigNum) { + if (this.isInfinite) { + return theZero; + } else if (anotherBigNum.isInfinite) { + var copy = this.fullCopy(); + if (anotherBigNum.isNegative) { + copy.isNegative = !(copy.isNegative); + } + ;return copy; + } else { + var firstNum = ((this).absoluteValue()).toSignedInteger(), firstDot = this.dotPosition, secondNum = (anotherBigNum.absoluteValue()).toSignedInteger(), secondDot = anotherBigNum.dotPosition, result; + if (this.isEqualTo(anotherBigNum)) { + return theZero; + } else if (anotherBigNum.isEqualTo(theZero)) { + return infinitySignedAs(this.isNegative); + } + ;if (firstDot > secondDot) { + secondNum = secondNum.concat(getNZeroes((firstDot) - secondDot)); + result = BigDec(BigInt(firstNum) % BigInt(secondNum)); + result.dotPosition = firstDot; + result.isNegative = this.isNegative; + return result.fullCopy(); + } else if (secondDot > firstDot) { + firstNum = firstNum.concat(getNZeroes(secondDot - firstDot)); + result = BigDec(BigInt(firstNum) % BigInt(secondNum)); + result.dotPosition = secondDot; + result.isNegative = this.isNegative; + return (result).fullCopy(); + } else { + result = BigDec(BigInt(firstNum) % BigInt(secondNum)); + result.dotPosition = firstDot; + result.isNegative = this.isNegative; + return result.fullCopy(); + } + ; + } + ; +} +; +(BigDec.prototype).betterModulateWith = function(anotherBigNum) { + if (this.isInfinite) { + return theZero; + } else if (anotherBigNum.isInfinite) { + var copy = this.fullCopy(); + if (anotherBigNum.isNegative) { + (copy.isNegative) = !(copy.isNegative); + } + ;return copy; + } else if (anotherBigNum.isEqualTo(theZero)) { + return infinitySignedAs(this.isNegative); + } else { + return ((this.basicModulateWith(anotherBigNum)).addWith(anotherBigNum)).basicModulateWith(anotherBigNum); + } + ; +} +; +BigDec.prototype.basicRound = function() { + return (!(((this.absoluteValue()).getDecimals()).isLessThan(theHalf)) ? this.ceiling() : this.floor()); +} +; +(BigDec).prototype.betterRound = function() { + var rounded = (this.absoluteValue()).basicRound(); + rounded.isNegative = this.isNegative; + return rounded; +} +; +BigDec.prototype.multiplicateWith = function(anotherBigNum) { + if (theOne.isEqualTo(anotherBigNum)) { + return (this.fullCopy()); + } else if (anotherBigNum.isEqualTo(theZero)) { + return theZero; + } else if (this.isInfinite || anotherBigNum.isInfinite) { + return (infinitySignedAs(!(this.isNegative == anotherBigNum.isNegative))); + } else { + var secondNum = anotherBigNum.toSignedInteger() + , firstNum = this.toSignedInteger() + , firstDot = this.dotPosition + , secondDot = anotherBigNum.dotPosition + , result = BigDec(BigInt(firstNum) * BigInt(secondNum)); + result.dotPosition = firstDot + secondDot; + return result.fixDecimals(); + } + ; +} +; +BigDec.prototype.min = (function(anotherBigNum) { + if (isNil(anotherBigNum)) { + anotherBigNum = theZero; + } + ;return [anotherBigNum, this][+(this.isLessThan(anotherBigNum))]; +} +); +BigDec.prototype.max = function(anotherBigNum) { + if (isNil(anotherBigNum)) { + anotherBigNum = theZero; + } + ;return [anotherBigNum, this][+(this.isGreaterThan(anotherBigNum))]; +} +; +BigDec.prototype.divideWith = function(divisor) { + if ((this.isInfinite) || divisor.isInfinite) { + if (this.isInfinite && divisor.isInfinite) { + return getUnitWithSign((this.isNegative + divisor.isNegative) == 1); + } else { + if (this.isInfinite) { + return infinitySignedAs(((this.isNegative + divisor.isNegative) == 1)); + } + ;if (divisor.isInfinite) { + return theZero; + } + ; + } + ; + } else { + var dividend = this.naturalContainer, divisorDotPosition = divisor.dotPosition, isNegative = ((this.isNegative + divisor.isNegative) == 1), quotient; + divisor = divisor.naturalContainer; + if (dividend == '0') { + quotient = theZero; + } else if ((dividend == divisor) && (this.dotPosition == (divisorDotPosition))) { + quotient = getUnitWithSign(isNegative); + } else if (divisor == '0') { + return infinitySignedAs(this.isNegative); + } else { + var multiplier = ('1').concat(getNZeroes(((this).maximumDecimals + divisorDotPosition) - this.dotPosition)); + quotient = (dividend * BigInt(multiplier)) / divisor; + quotient = BigDec(quotient); + quotient.dotPosition = this.maximumDecimals; + quotient = quotient.fixDecimals(); + quotient.isNegative = isNegative; + } + ;return quotient; + } + ; +} +; +BigDec.prototype.exponential = function() { + return (this.isEqualTo(theZero) ? theOne : ((this).isInfinite ? (this.isNegative ? theZero : positiveInfinity) : (LocalBigNumMemoizer.memoize('exponentialHelper', this)).fixDecimals())); +} +; +BigDec.prototype.exponentialHelper = function() { + if (this.isLessThan(theZero)) { + return ((this.negativeCopy()).exponentialHelper()).getReciprocal(); + } else if (this.isEqualTo(theZero)) { + return theOne; + } else if (this.isGreaterThan(theOne)) { + return (eulerNatural.raiseWith(this.truncate())).multiplicateWith((this.getDecimals()).exponentialHelper()); + } else { + return (repeatedSummatory((n=>(this.raiseWith(n)).divideWith((n).simpleFactorial())), theZero, theSevenTeen)).fixDecimals(); + } + ; +} +; +BigDec.prototype.raisingHelper = function(power) { + try { + var result = BigDec(this.naturalContainer ** (power.truncate()).naturalContainer); + result.dotPosition = (this.dotPosition * (+((power.truncate()).toString()))); + if (this.isNegative) { + result.isNegative = theOne.isEqualTo((power.truncate()).betterModulateWith(theFartNum)); + } + ;result = result.fullCopy(); + return result; + } catch (error) { + return repeatedProduct((()=>this), theZero, power.addWith(theDarkUnit)); + } + ; +} +; +BigDec.prototype.naturalLogarithm = function() { + return this.logarithmWith(eulerNatural); +} +; +BigDec.prototype.powerWith = function(exponent) { + if (exponent.isNegative) { + return (this.powerWith(exponent.negativeCopy())).getReciprocal(); + } else if (exponent.isEqualTo(theOne)) { + return this.fullCopy(); + } else if (exponent.isEqualTo(theZero)) { + return ((this).divideWith(this)); + } else if (this.isInfinite || exponent.isInfinite) { + if (exponent.isInfinite) { + if (this.isInfinite) { + return positiveInfinity; + } else if ((this.absoluteValue()).isGreaterThan(theZero)) { + return positiveInfinity; + } else if ((this.absoluteValue()).isEqualTo(theOne)) { + return theOne; + } else { + return theZero; + } + ; + } else if (exponent.isGreaterThan(theZero)) { + return positiveInfinity; + } + ; + } else if (this.isEqualTo(theZero)) { + return theZero; + } else if (this.isEqualTo(eulerNatural)) { + return exponent.exponential(); + } else if ((this).isEqualTo(theTen)) { + result = (BigDec(('1').concat(getNZeroes((+(exponent)).toString())))); + exponent = exponent.getDecimals(); + if (exponent.isGreaterThan(theZero)) { + result = (result.multiplicateWith(this.radicateWith(exponent.getReciprocal()))); + } + ;return result; + } else { + var result = this.raiseWith(exponent); + exponent = exponent.getDecimals(); + if (exponent.isGreaterThan(theZero)) { + result = result.multiplicateWith(this.radicateWith(exponent.getReciprocal())); + } + ;return result.fixDecimals(); + } + ; +} +; +(BigDec.prototype.getReciprocal) = function() { + return theOne.divideWith(this); +} +; +BigDec.prototype.raiseWith = function(power) { + return LocalBigNumMemoizer.memoize('raisingHelper', this, power); +} +; +(BigDec.prototype).decimalLogarithm = function() { + var i = BigDec(((((this.truncate()).naturalContainer)).toString()).length - 1) + , characteristic = (this.absoluteValue()).divideWith(theTen.raiseWith(i)); + while (true) { + if (characteristic.isLessThan(theTen)) { + break; + } + ;i = i.addWith(theOne); + characteristic = characteristic.divideWith(theTen); + } + ;if (characteristic.isGreaterThan(theOne)) { + var k, j = 0, mantissa = '.'; + while (j < this.maximumDecimals) { + characteristic = characteristic.raiseWith(theTen); + k = 0; + while (true) { + if (characteristic.isLessThan(theTen)) { + break; + } + ;characteristic = characteristic.divideWith(theTen); + k++; + } + ;mantissa = mantissa.concat(k.toString()); + j++; + } + ;return (i.addWith(BigDec(mantissa))).fixDecimals(); + } else { + return i; + } + ; +} +; +BigDec.prototype.squarePower = function() { + return this.multiplicateWith(this); +} +; +BigDec.prototype.logarithmHelper = function(base) { + if (this.isEqualTo(base)) { + return theOne; + } else if (base.isEqualTo(theOne) || !(base.isGreaterThan(theZero))) { + return negativeInfinity; + } else if (base.isLessThan(theOne)) { + return ((this.logarithmHelper(base.getReciprocal())).fixDecimals()).negativeCopy(); + } else if ((this.truncate()).isEqualTo(theZero)) { + return (((this.getReciprocal()).logarithmWith(base)).fixDecimals()).negativeCopy(); + } else { + return ((this.decimalLogarithm()).divideWith(base.decimalLogarithm())).fixDecimals(); + } + ; +} +; +BigDec.prototype.logarithmWith = function(base) { + if (base.isNegative) { + return negativeInfinity; + } else if (base.isInfinite) { + return ((this.isInfinite && !(this.isNegative)) ? theOne : theZero); + } else if (this.isNegative) { + return negativeInfinity; + } else { + return LocalBigNumMemoizer.memoize('logarithmHelper', this, base); + } + ; +} +; +BigDec.prototype.logistic = function() { + return (this.isLessThan(theZero) ? theOne.subtractWith((this.negativeCopy()).logistic()) : (theOne.addWith((this.negativeCopy()).exponential())).getReciprocal()); +} +; +BigDec.prototype.logit = function() { + return (this.divideWith(theOne.subtractWith(this))).naturalLogarithm(); +} +; +BigDec.prototype.fixDecimals = function() { + var copy = (this.fullCopy()); + var decimals = (copy.toString()).split('.'); + if (decimals.length > 1) { + decimals = decimals[1]; + if (decimals.length === this.maximumDecimals) { + var result = this.fullCopy(); + result.maximumDecimals -= 3; + result = result.fullCopy(); + decimals = (result.toString()).split('.'); + if (decimals.length > 1) { + decimals = decimals[1]; + if ((decimals.split('')).every(digit=>(digit === '9'))) { + copy = (result.truncate()).addWith(result.isNegative ? theDarkUnit : theOne); + } else if (decimals.length === 0) { + copy = result; + } + ; + } + ; + } + ; + } + ;return copy; +} +; +const theOne = BigDec(1) + , octaveOfTurn = BigDec(45) + , tripleOfHalfTurn = BigDec(270) + , theZero = BigDec() + , negativeInfinity = BigDec(-Infinity) + , halfTurn = BigDec(180) + , theFartNum = BigDec(2) + , theSevenTeen = BigDec(17) + , entireTurn = BigDec(360) + , oldBase = BigDec(60) + , positiveInfinity = BigDec(Infinity) + , theTen = BigDec(10) + , theHalf = BigDec(0.5) + , theDarkUnit = BigDec(-1) + , twoSquaredTimesThree = BigDec(12) + , theSerpentNum = BigDec(3) + , getUnitWithSign = function(isNegative) { + return BigDec((isNegative ? '-' : '').concat('1')); +} + , infinitySignedAs = function(isNegative) { + return BigDec(((isNegative) ? '-' : '').concat('Infinity')); +} + , threePlusTwo = BigDec(5) + , twoCubed = BigDec(8) + , quarterOfTurn = BigDec(90) + , getRandomDigit = (()=>((Math.round(Math.random() * 10)).toString())[0]) + , summatoryIntegral = function(func, upperBound, lowerBound, intervals) { + return ((upperBound.subtractWith(lowerBound)).divideWith(intervals)).multiplicateWith((((func(upperBound)).addWith(func(lowerBound))).divideWith(theFartNum)).addWith(repeatedSummatory((k=>func(lowerBound.addWith((k.multiplicateWith(upperBound.subtractWith(lowerBound))).divideWith(intervals)))), theOne, intervals.addWith(theDarkUnit)))) +} + , repeatedProduct = function(func, offset, steps) { + var result = theOne + , offset = offset.betterRound() + , steps = (steps.betterRound()).subtractWith(offset); + while (!(steps.isLessThan(theZero))) { + result = result.multiplicateWith(func(offset)); + steps = steps.addWith(theDarkUnit); + offset = offset.addWith(theOne); + } + ;return result; +} + , getDerativeOf = (function(func, value, distance) { + return ((func(value.addWith(distance))).subtractWith(func(value))).divideWith(distance); +} +) + , repeatedSummatory = function(func, offset, steps) { + var result = (theZero) + , offset = offset.betterRound() + , steps = (steps.betterRound()).subtractWith(offset); + while (!(steps.isLessThan(theZero))) { + result = result.addWith(func(offset)); + steps = steps.addWith(theDarkUnit); + offset = offset.addWith(theOne); + } + ;return result; +} + , twoSquared = BigDec(4) + , eulerNatural = theOne.exponential(); +BigDec.prototype.cosine = function() { + var modular = (this).betterModulateWith(entireTurn); + if (modular.isGreaterThan(tripleOfHalfTurn)) { + return (entireTurn.subtractWith(modular)).cosine(); + } else if (modular.isGreaterThan(halfTurn)) { + return ((modular.subtractWith(halfTurn)).cosine()).negativeCopy(); + } else if (modular.isGreaterThan(quarterOfTurn)) { + return ((halfTurn.subtractWith(modular)).cosine()).negativeCopy(); + } else { + return LocalBigNumMemoizer.memoize('cosineHelper', modular); + } + ; +} +; +BigDec.prototype.cosineHelper = function() { + if (this.isEqualTo(quarterOfTurn)) { + return theZero; + } else if ((oldBase).isEqualTo(this)) { + return theHalf; + } else if (this.isEqualTo(theZero)) { + return theOne; + } else { + return (repeatedSummatory((k=>((theDarkUnit.powerWith(k)).multiplicateWith((this.radians()).powerWith(theFartNum.multiplicateWith(k)))).divideWith((k.multiplicateWith(theFartNum)).simpleFactorial())), theZero, twoCubed)).fixDecimals(); + } + ; +} +; +BigDec.prototype.sine = function() { + return (this.isInfinite ? theZero : ((this.addWith(quarterOfTurn)).cosine()).negativeCopy()); +} +; +BigDec.prototype.tangent = function() { + return (this.sine()).divideWith(this.cosine()); +} +; +BigDec.prototype.cotangent = function() { + return (this.isInfinite ? positiveInfinity : (quarterOfTurn.subtractWith(this)).tangent()); +} +; +BigDec.prototype.isInTheRangeOf = function(startPoint, endPoint) { + return (this.isGreaterThan(startPoint) && this.isLessThan(endPoint)); +} +; +BigDec.prototype.cosecant = function() { + return (this.sine()).getReciprocal(); +} +; +(BigDec).prototype.getMagnitudeNames = (()=>[]); +BigDec.prototype.secant = function() { + return (this.cosine()).getReciprocal(); +} +; +BigDec.prototype.sinc = function() { + return (this.isEqualTo(theZero) ? theOne.radians() : (this.sine()).divideWith(this)); +} +; +BigDec.prototype.radians = function() { + return (this.multiplicateWith(piIncalculable)).divideWith(halfTurn); +} +; +(BigDec).prototype.squareRoot = function(isFaster) { + return (isFaster ? ((this.naturalLogarithm()).divideWith(theFartNum)).exponential() : this.radicateWith(theFartNum)); +} +; +(BigDec.prototype).getCoreMetallicMean = function() { + return ((twoSquared.addWith(this.squarePower())).squareRoot(true)).divideWith(theFartNum); +} +; +BigDec.prototype.getIntervalMetallicMean = function() { + return (this.addWith((twoSquared.addWith(this.squarePower())).squareRoot(true))).divideWith(theFartNum); +} +; +BigDec.prototype.productIntegral = function() { + return (summatoryIntegral((y=>func(y.naturalLogarithm())), upperBound, lowerBound, intervals)).exponential(); +} +; +BigDec.prototype.radicateWith = function(anotherBigNum) { + var index = anotherBigNum.absoluteValue(); + if (index.isInfinite) { + return theZero; + } else if (this.isInfinite) { + return positiveInfinity; + } else if ((index.getDecimals()).isGreaterThan(theZero)) { + return LocalBigNumMemoizer.memoize('radicationHelper', this, anotherBigNum); + } else { + if ((index.basicModulateWith(theFartNum)).isGreaterThan(theZero)) { + return (LocalBigNumMemoizer.memoize('radicationHelper', this.absoluteValue(), anotherBigNum)).multiplicateWith(this.getSignum()); + } else { + return LocalBigNumMemoizer.memoize('radicationHelper', this, anotherBigNum); + } + ; + } + ; +} +; +BigDec.prototype.degrees = function() { + return (this.multiplicateWith(halfTurn)).divideWith(piIncalculable); +} +; +BigDec.prototype.doubleFactorial = function() { + var factor = this.basicRound(); + if (factor.isGreaterThan(theFartNum)) { + return (factor.multiplicateWith(factor.subtractWith(theFartNum))).multiplicateWith(LocalBigNumMemoizer.memoize('doubleFactorial', factor.subtractWith(twoSquared))); + } else { + return (factor.max(theOne)); + } + ; +} +; +BigDec.prototype.radicationHelper = function(index) { + if (index.isLessThan(theZero)) { + return (this.radicateWith(index.negativeCopy())).getReciprocal(); + } else if (this.isEqualTo(theZero)) { + return theZero; + } else if (index.isEqualTo(theZero)) { + return positiveInfinity; + } else if (this.isEqualTo(theZero)) { + return theZero; + } else if (index.isLessThan(theOne)) { + return this.powerWith(index.getReciprocal()); + } else if (index.isEqualTo(theOne)) { + return this.fullCopy(); + } else { + var i = theZero + , result = theZero; + if ((index.getDecimals()).isGreaterThan(i)) { + return ((this.naturalLogarithm()).divideWith(index)).exponential(); + } else { + while (result.isLessThan(this)) { + i = i.addWith(theOne); + result = i.powerWith(index); + } + ;if (result.isGreaterThan(this)) { + if ((this.getDecimals()).isGreaterThan(theZero)) { + return ((this.naturalLogarithm()).divideWith(index)).exponential(); + } else { + var limit = ((Math.trunc(this.maximumDecimals / 4)) * (+(index.toString())) * ((this.truncate()).toString()).length) + , j = 0; + result = this.subtractWith((i.addWith(theDarkUnit)).powerWith(index)); + while (j < limit) { + result = (result.subtractWith(((result.powerWith(index)).subtractWith(this)).divideWith(index.multiplicateWith(result.powerWith(index.addWith(theDarkUnit)))))); + j++; + } + ;return result; + } + ; + } else { + return i; + } + ; + } + ; + } + ; +} +; +(BigDec).prototype.customFibonacci = function(base) { + var metallicPower = (base.getIntervalMetallicMean()).powerWith(this) + , result = (metallicPower.subtractWith(((halfTurn.multiplicateWith(this)).cosine()).divideWith(metallicPower))).divideWith(base.getCoreMetallicMean()); + if (this.isPureInteger()) { + result = result.betterRound(); + } + ;return result; +} +; +(BigDec.prototype.customLucas) = function(base) { + var metallicPower = (base.getIntervalMetallicMean()).powerWith(this) + , result = metallicPower.addWith(((halfTurn.multiplicateWith(this)).cosine()).divideWith(metallicPower)); + if (this.isPureInteger()) { + result = result.betterRound(); + } + ;return result; +} +; +BigDec.prototype.standardLucas = function() { + return this.customLucas(theOne); +} +; +(BigDec.prototype.standardFibonacci) = function() { + return this.customFibonacci(theOne); +} +; +BigDec.prototype.textRepresentation = function() { + return (this.isInfinite ? (this.isNegative ? '-' : '').concat('∞') : this.toString()); +} +; +BigDec.prototype.hypotenuse = function(anotherBigNum) { + return ((this.squarePower()).addWith(anotherBigNum.squarePower())).squareRoot(); +} +; +BigDec.prototype.getMagnitudeNamed = (()=>['', '0']); +BigDec.prototype.containsMagnitudeNamed = (()=>false); +BigDec.prototype.permutateWith = function(anotherBigNum) { + return (this.simpleFactorial()).divideWith((this.subtractWith(anotherBigNum)).simpleFactorial()); +} +; +BigDec.prototype.getRandomNumberFromSignedUnits = function() { + return this.multiplicateWith(theDarkUnit.dealWith(theOne)); +} +; +BigDec.prototype.combineWith = function(anotherBigNum) { + return (this.permutateWith(anotherBigNum)).divideWith(anotherBigNum.simpleFactorial()); +} +; +BigDec.prototype.arcTangent = function() { + return (this.isLessThan(theZero) ? (halfTurn).subtractWith((this.negativeCopy()).arcTangent()) : (this.isGreaterThan(theOne) ? quarterOfTurn.subtractWith((this.getReciprocal()).arcTangent()) : (((this.arcTangentRadians()).divideWith(arcPi)).multiplicateWith(octaveOfTurn)))); +} +; +BigDec.prototype.arcTangent2 = function(anotherBigNum) { + if (anotherBigNum.isLessThan(theZero) && this.isGreaterThan(theZero)) { + return halfTurn.subtractWith(this.arcTangent2(anotherBigNum.negativeCopy())); + } else if (anotherBigNum.isLessThan(theZero) && this.isEqualTo(theZero)) { + return halfTurn; + } else if ((anotherBigNum.isLessThan(theZero)) && this.isLessThan(theZero)) { + return (halfTurn.addWith((this.negativeCopy()).arcTangent2(anotherBigNum.negativeCopy()))); + } else if ((anotherBigNum).isEqualTo(theZero) && this.isLessThan(theZero)) { + return tripleOfHalfTurn; + } else if (anotherBigNum.isGreaterThan(theZero) && this.isLessThan(theZero)) { + return (entireTurn.subtractWith((this.negativeCopy()).arcTangent2(anotherBigNum))); + } else if (anotherBigNum.isGreaterThan(theZero) && this.isEqualTo(theZero)) { + return theZero; + } else { + return quarterOfTurn.subtractWith((anotherBigNum.divideWith(this)).arcTangent()); + } + ; +} +; +BigDec.prototype.arcCosine = function() { + return (this.isGreaterThan(theDarkUnit) ? (this.isGreaterThan(theOne) ? negativeInfinity : (((theOne.subtractWith(this.squarePower())).squareRoot()).divideWith(this)).arcTangent()) : (this.isLessThan(theDarkUnit) ? positiveInfinity : halfTurn)); +} +; +BigDec.prototype.arcSine = (function() { + var result = quarterOfTurn.subtractWith(this.arcCosine()); + return (result.isInfinite ? result : result.betterModulateWith(entireTurn)); +} +); +BigDec.prototype.arcSecant = (function() { + return (this.getReciprocal()).arcCosine(); +} +); +BigDec.prototype.arcCosecant = function() { + return (this.getReciprocal()).arcSine(); +} +; +BigDec.prototype.arcCotangent = (function() { + return (quarterOfTurn.subtractWith(this.arcTangent())); +} +); +const arithmeticMean = function() { + var list = Array.from(arguments); + return ((list.length > 1) ? (list.reduce((a,b)=>a.addWith(b))).divideWith(BigDec(list.length)) : ((list.length > 0) ? list[0] : theZero)); +} + , medianMean = function() { + var list = (Array.from(arguments)).sort((a,b)=>(a.isLessThan(b))); + return (list.length > 1 ? ((list.length % 2) > 0) ? list[Math.ceil(list.length / 2)] : arithmeticMean(list[list.length / 2], list[(list.length / 2) + 1]) : (list.length > 0 ? list[0] : theZero)); +} + , geometricMean = function() { + var list = Array.from(arguments); + return ((list.length > 1) ? (list.reduce((a,b)=>a.multiplicateWith(b))).radicateWith(BigDec(list.length)) : ((list.length > 0) ? list[0] : theOne)); +} + , harmonicMean = function() { + var basic = Array.from(arguments) + , list = (basic.fullCopy()).map(n=>(n.getReciprocal())); + return ((list.length > 1) ? (BigDec(list.length)).divideWith(list.reduce((a,b)=>a.addWith(b))) : ((list.length > 0) ? basic[0] : positiveInfinity)); +}; +BigDec.prototype.dealWith = function(anotherBigNum) { + var max = this.max(anotherBigNum) + , min = this.min(anotherBigNum) + , result = max.subtractWith(min) + , digitPlacers = ((result.truncate()).toString()).length + 15; + if (result.isEqualTo(theZero)) { + return min; + } else { + var randomness = '' + , i = 0; + while (i < digitPlacers) { + randomness = randomness.concat(getRandomDigit()); + i++; + } + ;result = result.multiplicateWith(BigDec(randomness)); + result.dotPosition += digitPlacers; + return (result.fullCopy()).addWith(min); + } + ; +} +; +(BigDec.prototype.agm) = function(anotherBigNum) { + var firstA = this, firstB = anotherBigNum, secondA, secondB, i = 0, limit = (((((((arithmeticMean(firstA, firstB)).betterRound()).absoluteValue()).toString()).length) * this.maximumDecimals) * 2); + while (i < limit) { + secondA = arithmeticMean(firstA, firstB); + secondB = geometricMean(firstA, firstB); + firstA = secondA; + firstB = secondB; + i++; + } + ;return arithmeticMean(firstA, firstB); +} +; +BigDec.prototype.ghm = function(anotherBigNum) { + var firstA = this, firstB = anotherBigNum, secondA, secondB, i = 0, limit = (((((((harmonicMean(firstA, firstB)).betterRound()).absoluteValue()).toString()).length) * this.maximumDecimals) * 2); + while (i < limit) { + secondA = harmonicMean(firstA, firstB); + secondB = geometricMean(firstA, firstB); + firstA = secondA; + firstB = secondB; + i++; + } + ;return harmonicMean(firstA, firstB); +} +; +BigDec.prototype.cubeRoot = function(isFaster) { + return (isFaster ? ((this.naturalLogarithm()).divideWith(theSerpentNum)).exponential() : this.radicateWith(theSerpentNum)); +} +; +BigDec.prototype.hiperbolicSine = function() { + return ((this.exponential()).subtractWith((this.negativeCopy()).exponential())).divideWith(theFartNum); +} +; +BigDec.prototype.hiperbolicTangent = function() { + return ((this.exponential()).subtractWith((this.negativeCopy()).exponential())).divideWith((this.exponential()).addWith((this.negativeCopy()).exponential())); +} +; +BigDec.prototype.hiperbolicCosine = function() { + return ((this.exponential()).addWith((this.negativeCopy()).exponential())).divideWith(theFartNum); +} +; +(BigDec).prototype.hiperbolicCotangent = function() { + return (this.hiperbolicTangent()).getReciprocal(); +} +; +BigDec.prototype.hiperbolicSecant = function() { + return (this.hiperbolicCosine()).getReciprocal(); +} +; +BigDec.prototype.hiperbolicCosecant = function() { + return (this.hiperbolicSine()).getReciprocal(); +} +; +BigDec.prototype.hiperbolicArcSine = function() { + return this.addWith((theOne.addWith((this).squarePower())).squareRoot(true)); +} +; +BigDec.prototype.hiperbolicArcTangent = function() { + return (((theOne.addWith(this)).divideWith(theOne.subtractWith(this))).naturalLogarithm()).divideWith(theFartNum); +} +; +BigDec.prototype.hiperbolicArcCosine = function() { + return this.addWith((theDarkUnit.addWith(this.squarePower())).squareRoot(true)); +} +; +BigDec.prototype.hiperbolicArcCosecant = (function() { + return (this.getReciprocal()).hiperbolicArcSine(); +} +); +BigDec.prototype.hiperbolicArcSecant = function() { + return (this.getReciprocal()).hiperbolicArcCosine(); +} +; +(BigDec.prototype).hiperbolicArcCotangent = function() { + return (this.getReciprocal()).hiperbolicArcTangent(); +} +; +BigDec.prototype.arcTangentRadians = function() { + return (this.multiplicateWith(repeatedSummatory((n=>repeatedProduct((k=>(theFartNum.multiplicateWith(k.multiplicateWith(this.squarePower()))).divideWith((theOne.addWith(theFartNum.multiplicateWith(k))).multiplicateWith(theOne.addWith(this.squarePower())))), theOne, n)), theZero, BigDec(61)))).divideWith(theOne.addWith(this.squarePower())); +} +; +const goldenRatio = theOne.getIntervalMetallicMean() + , silverRatio = (theFartNum).getIntervalMetallicMean() + , piIncalculable = BigDec('3.1415926535897932') + , plasticRatio = ((((BigDec(9)).addWith((BigDec(69)).squareRoot(true))).divideWith(BigDec(18))).cubeRoot(true)).addWith((((BigDec(9)).subtractWith((BigDec(69)).squareRoot(true))).divideWith(BigDec(18))).cubeRoot(true)) + , dottieNumber = BigDec('.9998477415310881') + , mascheroniEulerConstant = BigDec('.5772156649015329') + , strangeLemniscate = BigDec('2.6220575542921198') + , arcPi = theOne.arcTangentRadians(); +BigDec.prototype.gamma = function() {} +; + +(Object.keys(BigDec.prototype)).forEach(key=>console.log(('BigDec.prototype.').concat(key))); + +BigDec.prototype.tetrateWith = function(anotherBigNum) { + var out = theOne.addWith((anotherBigNum.absoluteValue()).getDecimals()); + if (!(anotherBigNum.isLessThan(theOne))) { + while (!(anotherBigNum.isLessThan(theOne))) { + out = this.powerWith(out); + anotherBigNum = anotherBigNum.addWith(theDarkUnit); + } + ; + } else { + while (anotherBigNum.isLessThan(theZero)) { + out = this.logarithmWith(out); + anotherBigNum = anotherBigNum.addWith(theOne); + } + ; + } + ;return out; +} +; + +var BigCmp = function(real, imag) { + if (new.target instanceof Function) { + this.init(real, imag); + } else { + return new BigCmp(real,imag); + } + ; +}; +BigCmp.prototype = BigDec(); +BigCmp.prototype.constructor = BigCmp; +BigCmp.prototype.init = function(real, imag) { + this.bignum = real; + this.imaginaryPart = imag; + this.naturalContainer = (this.bignum).naturalContainer; + this.isNegative = (this.bignum).isNegative; +} +; + +/* getImaginaryPart() */ + +BigCmp.prototype.textRepresentation = function() { + var imag = this.imaginaryPart + , bigText = (this.bignum).textRepresentation(); + if (imag.isEqualTo(theZero)) { + return bigText; + } else { + if ((this.bignum).isEqualTo(theZero)) { + return (imag.textRepresentation()).concat('i'); + } else { + return bigText.concat(((imag.isNegative) ? '−' : '+').concat((imag.absoluteValue()).textRepresentation(), 'i')); + } + ; + } + ; +} +; + +BigCmp.prototype.fullCopy = function() { + return BigCmp((this.bignum).fullCopy(), (this.imaginaryPart).fullCopy()); +} +; +BigCmp.prototype.negativeCopy = function() { + return (BigCmp(theZero, theZero)).subtractWith(this); +} +; +BigCmp.prototype.addWith = function(anotherBigCmp) { + return BigCmp((this.bignum).addWith(anotherBigCmp.bignum), (this.getImaginaryPart()).addWith(anotherBigCmp.getImaginaryPart())); +} +; +BigCmp.prototype.subtractWith = function(anotherBigCmp) { + return BigCmp((this.bignum).subtractWith(anotherBigCmp.bignum), (this.getImaginaryPart()).subtractWith((anotherBigCmp).getImaginaryPart())); +} +; +BigCmp.prototype.multiplicateWith = function(anotherBigCmp) { + var realResult = (this.bignum).multiplicateWith(anotherBigCmp.bignum) + , imaginaryResult = ((this.bignum).multiplicateWith((anotherBigCmp).getImaginaryPart())).addWith((this.getImaginaryPart()).multiplicateWith(anotherBigCmp.bignum)); + if (((this.getImaginaryPart()).isGreaterThan(theZero) && (anotherBigCmp.getImaginaryPart()).isLessThan(theZero)) || ((this.getImaginaryPart()).isLessThan(theZero) && (anotherBigCmp.getImaginaryPart()).isGreaterThan(theZero))) { + realResult = (realResult.addWith((this.getImaginaryPart()).multiplicateWith((anotherBigCmp.getImaginaryPart()).negativeCopy()))); + } else if (((this.getImaginaryPart()).getSignum()).isEqualTo((anotherBigCmp.getImaginaryPart()).getSignum()) && (!((this.getImaginaryPart()).isEqualTo(theZero)) && !((anotherBigCmp.getImaginaryPart()).isEqualTo(theZero)))) { + realResult = realResult.subtractWith((this.getImaginaryPart()).multiplicateWith(anotherBigCmp.getImaginaryPart())); + } + ;return BigCmp(realResult, imaginaryResult); +} +; +BigCmp.prototype.getConjugate = (function() { + return BigCmp(this.bignum, (this.getImaginaryPart()).negativeCopy()); +} +); +BigCmp.prototype.divideWith = function(anotherBigCmp) { + if ((this.getImaginaryPart()).isEqualTo(theZero) && (anotherBigCmp.getImaginaryPart()).isEqualTo(theZero)) { + return BigCmp((this.bignum).divideWith(anotherBigCmp.bignum), theZero); + } else { + var numerator = this.multiplicateWith((anotherBigCmp).getConjugate()) + , denominator = (BigCmp((anotherBigCmp.bignum).multiplicateWith(anotherBigCmp.bignum), theZero)).addWith(BigCmp((anotherBigCmp.imaginaryPart).multiplicateWith(anotherBigCmp.imaginaryPart), theZero)); + return BigCmp((numerator.bignum).divideWith(denominator), (numerator.imaginaryPart).divideWith(denominator)); + } + ; +} +; +BigCmp.prototype.getReciprocal = function() { + return (BigCmp(theOne, theZero)).divideWith(this); +} +; +BigCmp.prototype.exponential = function() { + return BigCmp(((this.bignum).exponential()).multiplicateWith(((this.imaginaryPart).degrees()).cosine()), ((this.bignum).exponential()).multiplicateWith(((this.imaginaryPart).degrees()).sine())); +} +; +BigCmp.prototype.absoluteValue = function() { + return BigCmp((((this.bignum).squarePower()).addWith((this.imaginaryPart).squarePower())).squareRoot(), theZero); +} +; +BigCmp.prototype.getArgument = function(inRadians) { + var result = (this.bignum).arcTangent2(this.imaginaryPart); + return BigCmp((inRadians ? result.degrees() : result), theZero); +} +; + +var isANonMagnitude = ((magnitude)=>{ + var exceptions = ['ºC', 'ºF', 'K', 'º', 'rad']; + return (exceptions.indexOf(magnitude) > -1); +} +) + , BigMgn = function(bignum, magnitudes) { + this.init(bignum, magnitudes); +}; +BigMgn.prototype = BigDec(); +BigMgn.prototype.textRepresentation = function() { + var text = (this.bignum).textRepresentation(), i = 0, splittedMagnitude; + while (i < (this.magnitudes).length) { + splittedMagnitude = (this.magnitudes[i]).split('\|'); + text = text.concat(splittedMagnitude[0], (isANonMagnitude(splittedMagnitude[0]) ? '' : (+(splittedMagnitude[1])).toSuperScript())); + i++; + } + ;return text; +} +; +BigMgn.prototype.constructor = BigMgn; +BigMgn.prototype.init = (function(bignum, magnitudes) { + this.bignum = (isNil(bignum) ? theZero : bignum); + this.naturalContainer = (this.bignum).naturalContainer; + this.isNegative = (this.bignum).isNegative; + this.dotPosition = this.bignum.dotPosition; + this.magnitudes = (isNil(magnitudes) ? [] : magnitudes); +} +); +Number.prototype.toSuperScript = function() { + var inputs = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-'], outputs = ['⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹', '⁻'], copy = ((Math.round(Math.abs(this))) * Math.sign(this)).toString(), result = '', i = 0, selectedIndex; + while (i < copy.length) { + selectedIndex = inputs.indexOf(copy[i]); + result = result.concat((selectedIndex > -1) ? (outputs[selectedIndex]) : ''); + i++; + } + ;return result; +} +; +BigMgn.prototype.addWith = function(anotherBigMgn) { + return new BigMgn((this.bignum).addWith(anotherBigMgn.bignum),this.magnitudes); +} +; +BigMgn.prototype.getMagnitudeNames = function() { + var i = 0 + , names = []; + while (i < (this.magnitudes).length) { + names.push(((this.magnitudes[i]).split('\|'))[0]); + i++; + } + ;return names; +} +; +BigMgn.prototype.checkEmptyMagnitudes = function() { + var i = 0 + , magnitudes = []; + while (i < this.magnitudes.length) { + if (!(((this.magnitudes[i]).split('\|'))[1] == '0')) { + magnitudes.push(this.magnitudes[i]); + } + ;i++; + } + ;this.magnitudes = magnitudes; +} +; +BigMgn.prototype.containsMagnitudeNamed = function(magnitude) { + return ((this.getMagnitudeNames()).indexOf(magnitude) > -1); +} +; +BigMgn.prototype.subtractWith = function(anotherBigMgn) { + return new BigMgn((this.bignum).subtractWith(anotherBigMgn.bignum),this.magnitudes); +} +; +BigMgn.prototype.getMagnitudeNamed = function(magnitude) { + return (this.containsMagnitudeNamed(magnitude)) ? (this.magnitudes[(this.getMagnitudeNames()).indexOf(magnitude)]).split('\|') : ['', '0']; +} +; +BigMgn.prototype.negativeCopy = function() { + return new BigMgn((this.bignum).negativeCopy(),this.magnitudes); +} +; +BigMgn.prototype.fullCopy = function() { + return new BigMgn((this.bignum).fullCopy(),(this.magnitudes).fullCopy()); +} +; +BigMgn.prototype.multiplicateWith = function(anotherBigMgn) { + var bignum = (this.bignum).multiplicateWith(anotherBigMgn.bignum), magnitudeNames = (this.getMagnitudeNames()).concat((anotherBigMgn).getMagnitudeNames()), firstItem, secondItem, i = 0, result = []; + magnitudeNames = magnitudeNames.uniques(); + while (i < (magnitudeNames.length)) { + firstItem = this.getMagnitudeNamed(magnitudeNames[i]); + secondItem = anotherBigMgn.getMagnitudeNamed(magnitudeNames[i]); + result.push((magnitudeNames[i]).concat('\|', ((+(firstItem[1])) + (+(secondItem[1]))).toString())); + i++; + } + ;bignum = new BigMgn(bignum,result); + bignum.checkEmptyMagnitudes(); + return bignum; +} +; +BigMgn.prototype.getReciprocal = function() { + return (new BigMgn(theOne)).divideWith(this); +} +; +BigMgn.prototype.divideWith = function(anotherBigMgn) { + var bignum = (this.bignum).divideWith(anotherBigMgn.bignum), magnitudeNames = (this.getMagnitudeNames()).concat(anotherBigMgn.getMagnitudeNames()), firstItem, secondItem, i = 0, result = []; + magnitudeNames = magnitudeNames.uniques(); + while (i < magnitudeNames.length) { + firstItem = (this.getMagnitudeNamed(magnitudeNames[i])); + secondItem = (anotherBigMgn.getMagnitudeNamed(magnitudeNames[i])); + result.push((magnitudeNames[i]).concat('\|', ((+(firstItem[1])) - (+(secondItem[1]))).toString())); + i++; + } + ;bignum = new BigMgn(bignum,result); + bignum.checkEmptyMagnitudes(); + return bignum; +} +; +BigMgn.prototype.powerWith = function(anotherBigMgn) { + var bignum = (this.bignum).powerWith(anotherBigMgn.bignum), magnitudeNames = this.getMagnitudeNames(), selectedItem, i = 0, result = []; + magnitudeNames = (magnitudeNames.uniques()); + while (i < (magnitudeNames.length)) { + firstItem = this.getMagnitudeNamed(magnitudeNames[i]); + result.push((magnitudeNames[i]).concat('\|', ((+(firstItem[1])) * (+((anotherBigMgn.bignum).toString()))).toString())); + i++; + } + ;bignum = new BigMgn(bignum,result); + bignum.checkEmptyMagnitudes(); + return bignum; +} +; +BigMgn.prototype.radicateWith = function(anotherBigMgn) { + var bignum = (this.bignum).radicateWith(anotherBigMgn.bignum), magnitudeNames = this.getMagnitudeNames(), selectedItem, i = 0, result = []; + magnitudeNames = magnitudeNames.uniques(); + while (i < (magnitudeNames.length)) { + firstItem = this.getMagnitudeNamed(magnitudeNames[i]); + result.push((magnitudeNames[i]).concat('\|', ((+(firstItem[1])) / (+((anotherBigMgn.bignum).toString()))).toString())); + i++; + } + ;bignum = (new BigMgn(bignum,result)); + bignum.checkEmptyMagnitudes(); + return bignum; +} +; \ No newline at end of file diff --git a/src/midi.js b/src/midi.js index f0a3b1f..2a1a19a 100644 --- a/src/midi.js +++ b/src/midi.js @@ -9,9 +9,9 @@ Copyleft (Ɔ) 2024 by Alessandro Moisés - This file is part of Snap!. + This file is part of Snavanced! - Snap! is free software: you can redistribute it and/or modify + Snavanced! is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. @@ -48,9 +48,18 @@ // Declarations -var MIDSoundSystem = {basicHertzValue : 256, -basicLogarithmicValue : 59.760344731969152}, -MIDSoundData, MIDVoiceData; +var MIDSoundSystem = {basicHertzValue : BigDec(256), +basicLogarithmicValue : BigDec('59.760344731969152'), +basicSampleRateValue : BigDec(20)}; /* Starters. */ + +MIDSoundSystem.createWhiteNoise = function (volume, duration) {if (isNil(volume)) {volume = theOne; +} else {volume = (theOne.min(volume.max())).squareRoot(true);}; if (isNil(duration)) {duration = ( +MIDSoundSystem.basicSampleRateValue).multiplicateWith(new BigDec('1000'));} else {duration = ( +duration.max()).basicRound();}; duration = +(duration.toString()); var i = 0, result = [new List, +new List]; while (i < duration) {result[0].add(volume.getRandomNumberFromSignedUnits()); +result[1].add(volume.getRandomNumberFromSignedUnits()); i++;}; return new List(result);}; + +var MIDSoundData, MIDVoiceData; // MIDSoundSystem ////////////////////////////////////////////// @@ -60,17 +69,16 @@ MIDSoundData, MIDVoiceData; function MIDSoundData (name, optional, callback, isEditable) {this.init(name, optional, callback, isEditable);}; -MIDSoundData.prototype.init = function anonymous (name, optional, callback, isEditable -) {this.name = name; if ((typeof callback) === 'function') {this.callback = callback; -} else {this.callback = (() => 0);}; this.makeInitialData(720, optional); -this.isEditable = asABool(isEditable); this.defaultOptional = optional;}; -MIDSoundData.prototype.makeInitialData = function anonymous (length, -optional) {this.initialData = []; var i = 0; while (i < length) { -this.initialData.push(Process.prototype.fixSimpleNumber( -this.callback(47, 100, length, (i + 1), optional))); -i = Process.prototype.reportBasicSum(i, 1);};}; - -Process.prototype.makeMIDSound = function anonymous (note, volume, length, instrument, optional, isNormal) { +MIDSoundData.prototype.init = function (name, optional, callback, isEditable +) {this.name = name; if ((typeof callback) === 'function') {this.callback = ( +callback);} else {this.callback = (() => 0);}; this.makeInitialData(720, +optional); this.isEditable = asABool(isEditable); this.defaultOptional = ( +optional);}; MIDSoundData.prototype.makeInitialData = function (length, +optional) {this.initialData = []; var i = 0; while (i < length) {(this +).initialData.push(Process.prototype.fixSimpleNumber(this.callback(47, +100, length, (i + 1), optional))); i++;};}; + +Process.prototype.makeMIDSound = function (note, volume, length, instrument, optional, isNormal) { var finalData = [], i = 0, selectedMID = ((this.reportTypeOf(instrument) === 'number') ? world.childThatIsA( IDE_Morph).mids[instrument - 1] : world.childThatIsA(IDE_Morph).mids.filter(mid => (mid.name === instrument) )[0]); if (selectedMID instanceof MIDSoundData) {var callback = selectedMID.callback;} else {var callback = (( @@ -83,7 +91,7 @@ selectedMID.initialData))); i = Process.prototype.reportBasicSum(i, 1);}; return /* Makes a list with all of the generated data from a MID to show to the end-user's screen, use any type of MID to create songs with any type of voices like FNF', use them and I'm going to be more happy thanks to you. :-) */ -Process.prototype.makeNoiseSound = function anonymous (intensity, length, volume) { +Process.prototype.makeNoiseSound = function (intensity, length, volume) { var aList = new List, i = 0; intensity = Math.max(0, Math.min(100, intensity)); while (i < length) {if (intensity > 0) {aList.add(((Process.prototype.reportRound( Math.random(), new List([Math.round(Math.max(1, Math.min(100, intensity)) - 1)]) @@ -102,7 +110,7 @@ MIDVoiceData.uber = MIDSoundData.prototype; function MIDVoiceData (name, data, callback, optional) {this.init(name, data, callback, optional);}; -MIDVoiceData.prototype.init = function anonymous (name, data, callback, optional) { +MIDVoiceData.prototype.init = function (name, data, callback, optional) { this.name = name; if ((typeof callback) === 'function') {this.callback = callback; } else {this.callback = (() => 0);}; if (data instanceof Array) { this.initialData = data;} else {this.initialData = [];}; diff --git a/src/morphic.js b/src/morphic.js index 0e769f7..92ab2ce 100644 --- a/src/morphic.js +++ b/src/morphic.js @@ -8,9 +8,7 @@ written by Jens Mönig jens@moenig.org - Copyright (C) 2010-2023 by Jens Mönig - - This documentation last changed: February 29, 2024 + Copyright (C) 2010-2024 by Jens Mönig This file is part of Snap!. @@ -232,10 +230,10 @@ a "Gold Standard" for self sustaining systems which morphic.js cannot and does not aspire to meet. - This Morphic implementation for JavaScript is not a direct port of - Squeak's Morphic, but still many individual functions have been + This Morphic implementation for JavaScript is not a direct port + of Squeak's Morphic, but still many individual functions have been ported almost literally from Squeak, sometimes even including their - comments, e.g. the morph duplication mechanism fullCopy(). Squeak + comments, e.g. the object duplication mechanism fullCopy(). Squeak has been a treasure trove, and if morphic.js looks, feels and smells a lot like Squeak, I'll take it as a compliment. @@ -272,31 +270,18 @@ - Jens Mönig -*/ - -// Global settings ///////////////////////////////////////////////////// - -/*global window, HTMLCanvasElement, FileReader, Audio, FileList, Map*/ +*/ // Global Functions //////////////////////////////////////////////// -/*jshint esversion: 6*/ - -var morphicVersion = '2024-February-29'; var useBlurredShadows = true; - -// Global Functions //////////////////////////////////////////////////// - -function asAnArray (input) {return ((input instanceof Array) ? input : [input]);}; function asANum (input) {return (contains(['number', 'string', 'boolean'], (typeof input)) ? (isNaN(+input) ? 0 : +input) : ( -isNil(input) ? 0 : input.isComplex ? new ComplexNumber(+input, +(input.i)) : (input.isAlphanumerical ? +input : 0)));}; function asABool (input) {if (isNil(input)) {return false;} else {return ((asANum(input -) > 0) ? true : (input === 'true'));};}; function nop () {return null;}; function localize (string) {return string;}; function isNil (thing) {return contains([undefined, null], thing);}; function contains ( -list, element) {return ((list instanceof Array) ? (list.indexOf(element) > -1) : false);}; Array.prototype.deepMap = function anonymous (callback) {return this.map(item => ((item instanceof Array) ? item.deepMap( -callback) : callback(item)));}; Array.prototype.fullCopy = function anonymous () {return this.deepMap(item => ((item instanceof Array) ? item.fullCopy() : item));}; function detect (list, predicate) {var i, -size = list.length; for (i = 0; i < size; i += 1) {if (predicate.call(null, list[i])) {return list[i];};}; return null;}; function sizeOf (object) {var size = 0, key; for (key in object) {if ( -Object.prototype.hasOwnProperty.call(object, key)) {size += 1;};}; return size;}; function isString (target) {return (((typeof target) === 'string') || (target instanceof String));}; -function isObject (target) {return (target !== null) && (typeof target === 'object' || target instanceof Object);}; function radians (degrees) {return degrees * (Math.PI / 180);}; function degrees (radians -) {return radians * (180 / Math.PI);}; function fontHeight (height) {var minHeight = Math.max(height, MorphicPreferences.minimumFontHeight); return minHeight * 1.2;}; function isWordChar (aCharacter) { -return aCharacter.match(/[A-zÀ-ÿ0-9]/);}; function isURLChar (aCharacter) {return aCharacter.match(/[A-z0-9./:?&_+%-]/);}; function isURL(text) {return /^https?:\/\//.test(text);}; if (isNil(localStorage[ -'-snap-setting-isShowingBlanks'])) {localStorage['-snap-setting-isShowingBlanks'] = true;}; const BLACK = new Color; const CLEAR = new Color(0, 0, 0, 0); const WHITE = new Color(255, 255, 255); -const ZERO = new Point; Object.freeze(ZERO); Object.freeze(BLACK); Object.freeze(WHITE); function extraContains (list, element) {if (element instanceof Array) {var result = element.deepMap(item => contains( -list, item)), i = 0; while (i < result.length) {if (result[i]) {return true;}; i++;}; return false;} else {return contains(list, element);};}; /* Better Morphic functions and better improvements. :~) */ +var getText = (text, data) => (((typeof text) === 'function') ? text.call(data) : text), asAnArray = ((input) => ((input instanceof Array) ? input : [input])), asANum = ((input) => {return (contains(['number', +'string', 'boolean'], (typeof input)) ? (isNaN(+input) ? 0 : +input) : (isNil(input) ? 0 : input.isComplex ? new ComplexNumber(+input, +(input.i)) : (input.isAlphanumerical ? +input : 0)));}); function asABool ( +input) {if (isNil(input)) {return false;} else {return ((asANum(input) > 0) ? true : (input === 'true'));};}; function nop () {return null;}; function localize (string) {return string;}; function contains (list, +element) {return ((list instanceof Array) ? (list.indexOf(element) > -1) : false);}; function detect (list, predicate) {var i, size = list.length; for (i = 0; i < size; i += 1) {if (predicate.call(null, list[i +])) {return list[i];};}; return null;}; function sizeOf (object) {var size = 0, key; for (key in object) {if (Object.prototype.hasOwnProperty.call(object, key)) {size += 1;};}; return size;}; var isString = ( +target => (((typeof target) === 'string') || (target instanceof String))), isObject = (target => ((target !== null) && (typeof target === 'object' || target instanceof Object))), radians = (degrees => ((degrees +) * (Math.PI / 180))), degrees = (radians => (radians * (180 / Math.PI))), fontHeight = ((height) => (Math.max(height, MorphicPreferences.minimumFontHeight) * 1.2)), isWordChar = (aCharacter => (aCharacter.match( +/[A-zÀ-ÿ0-9]/))), isURLChar = (aCharacter => aCharacter.match(/[A-z0-9./:?&_+%-]/)), isURL = (text => (/^https?:\/\//.test(text))); if (isNil(localStorage['-snap-setting-isShowingBlanks'])) {localStorage[ +'-snap-setting-isShowingBlanks'] = true;}; function extraContains (list, element) {if (element instanceof Array) {var result = element.deepMap(item => contains(list, item)), i = 0; while (i < ( +result.length)) {if (result[i]) {return true;}; i++;}; return false;} else {return contains(list, element);};}; /* Morphic has now better and newer improvements to try within the world. */ var standardSettings = { minimumFontHeight: getMinimumFontHeight(), @@ -316,7 +301,7 @@ var standardSettings = { isFlat: false, grabThreshold: 0, showHoles: false -}; var touchScreenSettings = { +}, touchScreenSettings = { minimumFontHeight: getMinimumFontHeight(), globalFontFamily: 'morphicGlobalFont', menuFontName: 'sans-serif', @@ -334,7 +319,8 @@ var standardSettings = { isFlat: false, grabThreshold: 0, showHoles: false -}; var MorphicPreferences = standardSettings; +}, useBlurredShadows = true, +MorphicPreferences = standardSettings; function newCanvas(extentPoint, nonRetina, recycleMe) { // answer a new empty instance of Canvas, don't display anywhere @@ -352,21 +338,18 @@ function newCanvas(extentPoint, nonRetina, recycleMe) { (recycleMe.isRetinaEnabled || false) !== nonRetina && ext.x === recycleMe.width && ext.y === recycleMe.height ) { - canvas = recycleMe; - canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height); - return canvas; + canvas = recycleMe; canvas.getContext("2d").clearRect(0, 0, + canvas.width, canvas.height); } else { - canvas = document.createElement('canvas'); - canvas.width = ext.x; + canvas = document.createElement( + 'canvas'); canvas.width = ext.x; canvas.height = ext.y; canvas.getContext("2d", { willReadFrequently: true }); - } - if (nonRetina && canvas.isRetinaEnabled) { + }; if (nonRetina && canvas.isRetinaEnabled) { canvas.isRetinaEnabled = false; - } - return canvas; + }; return canvas; } function copyCanvas(aCanvas) { @@ -376,11 +359,9 @@ function copyCanvas(aCanvas) { c = newCanvas( new Point(aCanvas.width, aCanvas.height), !aCanvas.isRetinaEnabled - ); - c.getContext("2d").drawImage(aCanvas, 0, 0); + ); c.getContext("2d").drawImage(aCanvas, 0, 0); return c; - } - return aCanvas; + }; return aCanvas; } function getMinimumFontHeight() { @@ -598,19 +579,17 @@ function enableRetinaSupport() { }; // [Jens]: only install retina utilities if the display supports them - if (backingStorePixelRatio === originalDevicePixelRatio) {return; } + if (backingStorePixelRatio === originalDevicePixelRatio) {return;}; // [Jens]: check whether properties can be overridden, needed for Safari if (Object.keys(uber).some(any => { var prop = uber[any]; return prop.hasOwnProperty('configurable') && (!prop.configurable); - })) {return; } + })) {return;}; function getPixelRatio(imageSource) { return imageSource.isRetinaEnabled ? (originalDevicePixelRatio || 1) / backingStorePixelRatio : 1; - } - - canvasProto._isRetinaEnabled = true; + }; canvasProto._isRetinaEnabled = true; // [Jens]: remember the original non-retina properties, // so they can be restored again canvasProto._bak = uber; @@ -716,8 +695,7 @@ function enableRetinaSupport() { default: throw Error('Called drawImage() with ' + arguments.length + ' arguments'); - } - uber.drawImage.call( + }; uber.drawImage.call( this, image, sx * pixelRatio, sy * pixelRatio, sWidth * pixelRatio, sHeight * pixelRatio, @@ -892,7 +870,7 @@ function Animation(setter, getter, delta, duration, easing, onComplete) { this.destination = null; this.isActive = false; this.start(); -} +}; Animation.prototype.easings = { // dictionary of a few pre-defined easing functions used to transition @@ -946,7 +924,7 @@ Animation.prototype.step = function () { this.destination - (this.delta * this.easing((this.endTime - now) / this.duration)) ); - } + }; }; // Colors ////////////////////////////////////////////////////////////// @@ -956,29 +934,37 @@ Animation.prototype.step = function () { function Color (r, g, b, a) {this.r = Math.max(Math.min(r, 255), 0) || 0; this.g = Math.max(Math.min(g, 255), 0) || 0; this.b = Math.max(Math.min( b, 255), 0) || 0; this.a = !isNil(a) ? Math.max(Math.min(a, 1), 0) : 1; -this.quality = (isNil(localStorage['-snap-setting-colorQuality']) ? -1 : (255 / +(localStorage['-snap-setting-colorQuality'])));}; +this.quality = (isNil(localStorage['-snap-setting-colorQuality']) ? ( +1) : (255 / +(localStorage['-snap-setting-colorQuality'])));}; +const BLACK = Object.freeze(new Color); const CLEAR = ( +Object.freeze(new Color(0, 0, 0, 0))); const WHITE = ( +Object.freeze(new Color(255, 255, 255))); -// Color string representation: e.g. 'rgba(255,165,0,1)' +// Color string representation: e.g. rgba(255,165,0,1) -Color.prototype.toString = function anonymous () {return ('rgba\(').concat((Math.round(this.r / this.quality) * this.quality), ',', +Color.prototype.toString = function () {return ('rgba\(').concat((Math.round(this.r / this.quality) * this.quality), ',', (Math.round(this.g / this.quality) * this.quality), ',', (Math.round(this.b / this.quality) * this.quality), ',', this.a, '\)');}; -Color.prototype.toRGBstring = function anonymous () {return ('rgb\(').concat((Math.round(this.r / this.quality) * this.quality), ',', +Color.prototype.toRGBstring = function () {return ('rgb\(').concat((Math.round(this.r / this.quality) * this.quality), ',', (Math.round(this.g / this.quality) * this.quality), ',', (Math.round(this.b / this.quality) * this.quality), '\)');}; -Color.fromString = function (aString) {var components = aString.split(/[\(),]/).slice(1,5); return new Color(components[0], components[1], components[2], components[3]);}; +Color.fromString = function (aString) {var components = aString.split(/[\(),]/).slice( +1, 5); return new Color(components[0], components[1], components[2], components[3]);}; + +Color.prototype.withAlpha = function (num) { +var copy = this.copy(); copy.a = num; return copy;}; // Color copying: -Color.prototype.copy = function anonymous () {return new Color(this.r, this.g, this.b, this.a);}; +Color.prototype.copy = function () {return ( +new Color(this.r, this.g, this.b, this.a));}; // Color comparison: -Color.prototype.eq = function anonymous (aColor, observeAlpha) { -return (aColor instanceof Color) && (this.r === aColor.r && -this.g === aColor.g && this.b === aColor.b && ( -observeAlpha ? this.a === aColor.a : true));}; +Color.prototype.eq = function (aColor, observeAlpha) { +return (aColor instanceof Color) && ((this.r === aColor.r +) && (this.g === aColor.g) && (this.b === aColor.b) && ( +observeAlpha ? (this.a === aColor.a) : true));}; Color.prototype.equalTo = Color.prototype.eq; Color.prototype.isCloseTo = function (aColor, observeAlpha, tolerance) { @@ -990,9 +976,7 @@ Color.prototype.isCloseTo = function (aColor, observeAlpha, tolerance) { function dist(a, b) { var diff = a - b; return diff < 0 ? 255 + diff : diff; - } - - return aColor && + }; return aColor && dist(this.r, aColor.r) < thres && dist(this.g, aColor.g) < thres && dist(this.b, aColor.b) < thres && @@ -1027,10 +1011,8 @@ Color.prototype.hsv = function () { case bb: h = (rr - gg) / d + 4; break; - } - h /= 6; - } - return [h, s, v]; + }; h /= 6; + }; return [h, s, v]; }; Color.prototype.set_hsv = function (h, s, v) { @@ -1072,7 +1054,7 @@ Color.prototype.set_hsv = function (h, s, v) { this.g = p; this.b = q; break; - } + }; this.r *= 255; this.g *= 255; @@ -1087,11 +1069,11 @@ Color.prototype.hsl = function () { var rr = this.r / 255, gg = this.g / 255, bb = this.b / 255, - max = Math.max(rr, gg, bb), min = Math.min(rr, gg, bb), - h, - s, - l = (max + min) / 2, - d; + max = Math.max(rr, + gg, bb), min = ( + Math.min(rr, gg, + bb)), h, s, l = ( + max + min) / 2, d; if (max === min) { // achromatic h = 0; s = 0; @@ -1108,10 +1090,8 @@ Color.prototype.hsl = function () { case bb: h = (rr - gg) / d + 4; break; - } - h /= 6; - } - return [h, s, l]; + }; h /= 6; + }; return [h, s, l]; }; Color.prototype.set_hsl = function (h, s, l) { @@ -1121,23 +1101,16 @@ Color.prototype.set_hsl = function (h, s, l) { function hue2rgb(p, q, t) { if (t < 0) { t += 1; - } - if (t > 1) { + }; if (t > 1) { t -= 1; - } - if (t < 1/6) { + }; if (t < 1/6) { return p + (q - p) * 6 * t; - } - if (t < 1/2) { + }; if (t < 1/2) { return q; - } - if (t < 2/3) { + }; if (t < 2/3) { return p + (q - p) * (2/3 - t) * 6; - } - return p; - } - - if (s == 0) { // achromatic + }; return p; + }; if (s == 0) { // achromatic this.r = l; this.g = l; this.b = l; @@ -1147,7 +1120,7 @@ Color.prototype.set_hsl = function (h, s, l) { this.r = hue2rgb(p, q, h + 1/3); this.g = hue2rgb(p, q, h); this.b = hue2rgb(p, q, h - 1/3); - } + }; this.r *= 255; this.g *= 255; @@ -1158,37 +1131,39 @@ Color.prototype.set_hsl = function (h, s, l) { Color.prototype.mixed = function (proportion, otherColor) { // answer a copy of this color mixed with another color, ignore alpha - var frac1 = Math.min(Math.max(proportion, 0), 1), + var frac1 = Math.min(Math.max( + proportion, 0), 1), frac2 = 1 - frac1; return new Color( this.r * frac1 + otherColor.r * frac2, this.g * frac1 + otherColor.g * frac2, - this.b * frac1 + otherColor.b * frac2 + this.b * frac1 + otherColor.b * frac2, + this.a * frac1 + otherColor.a * frac2 ); }; Color.prototype.darker = function (percent) { // return an rgb-interpolated darker copy of me, ignore alpha - var fract = 0.8333; + var fract = 5/6; if (percent) { - fract = (100 - percent) / 100; - } - return this.mixed(fract, BLACK); + fract = 1 - (percent / 100); + }; return this.mixed(fract, + new Color(0, 0, 0, this.a)); }; Color.prototype.lighter = function (percent) { // return an rgb-interpolated lighter copy of me, ignore alpha - var fract = 0.8333; + var fract = 5/6; if (percent) { - fract = (100 - percent) / 100; - } - return this.mixed(fract, WHITE); + fract = 1 - (percent / 100); + }; return this.mixed(fract, + new Color(255, 255, 255, this.a)); }; Color.prototype.dansDarker = function () { // return an hsv-interpolated darker copy of me, ignore alpha var hsv = this.hsv(), - result = new Color(), + result = new Color, vv = Math.max(hsv[2] - 0.16, 0); result.set_hsv(hsv[0], hsv[1], vv); return result; @@ -1198,7 +1173,8 @@ Color.prototype.inverted = function () { return new Color( 255 - this.r, 255 - this.g, - 255 - this.b + 255 - this.b, + this.a ); }; @@ -1215,15 +1191,14 @@ Color.prototype.solid = function () { // Point instance creation: function Point (x, y -) {this.x = asANum(x -); this.y = asANum(y -);}; /* Restored. */ +) {this.x = asANum(x); +this.y = asANum(y);}; // Point string representation: e.g. '12@68' Point.prototype.toString = function () { - return Math.round(this.x.toString()) + - '@' + Math.round(this.y.toString()); + return Math.round((this.x).toString()) + + '@' + Math.round((this.y).toString()); }; // Point copying: @@ -1288,15 +1263,14 @@ Point.prototype.mirror = function () { }; Point.prototype.floor = function () { - return new Point( - Math.max(Math.floor(this.x), 0), - Math.max(Math.floor(this.y), 0) - ); -}; +return new Point(Math.max(Math.floor( +this.x), 0), Math.max(Math.floor( +this.y), 0));}; Point.prototype.ceil = function () { - return new Point(Math.ceil(this.x), Math.ceil(this.y)); -}; +return new Point(Math.max(Math.ceil( +this.x), 0), Math.max(Math.ceil( +this.y), 0));}; // Point arithmetic: @@ -1314,20 +1288,24 @@ Point.prototype.subtract = function (other) { Point.prototype.multiplyBy = function (other) { if (other instanceof Point) { - return new Point(this.x * other.x, this.y * other.y); - }; return new Point(this.x * other, this.y * other); + return new Point(this.x * other.x, + this.y * other.y); + }; return new Point(this.x * other, + this.y * other); }; Point.prototype.divideBy = function (other) { if (other instanceof Point) { - return new Point(this.x / other.x, this.y / other.y); - }; return new Point(this.x / other, this.y / other); + return new Point(this.x / other.x, + this.y / other.y); + }; return new Point(this.x / other, + this.y / other); }; Point.prototype.floorDivideBy = function (other) { if (other instanceof Point) { return new Point(Math.floor(this.x / other.x), - Math.floor(this.y / other.y)); + Math.floor(this.y / other.y)); }; return new Point(Math.floor(this.x / other), Math.floor(this.y / other)); }; @@ -1335,9 +1313,7 @@ Point.prototype.floorDivideBy = function (other) { // Point polar coordinates: Point.prototype.r = function () { - var t = (this.multiplyBy(this)); - return Math.sqrt(t.x + t.y); -}; +return Math.hypot(this.x, this.y);}; Point.prototype.degrees = function () { /* @@ -1523,22 +1499,18 @@ Rectangle.prototype.setTo = function (left, top, right, bottom) { // Rectangle mutating Rectangle.prototype.setExtent = function(aPoint) { - this.setWidth(aPoint.x); - this.setHeight(aPoint.y); -}; +this.setWidth(aPoint.x); this.setHeight(aPoint.y);}; Rectangle.prototype.setWidth = function (width) { - this.corner.x = this.origin.x + width; -}; +this.corner.x = this.origin.x + width;}; Rectangle.prototype.setHeight = function (height) { - this.corner.y = this.origin.y + height; -}; +this.corner.y = this.origin.y + height;}; // Rectangle accessing - getting: -Rectangle.prototype.area = function anonymous () {return (Math.abs( -this.width()) * Math.abs(this.height()));}; /* -Better now. :-)- */ +Rectangle.prototype.area = function () {return Math.abs( +this.width() * this.height());}; /* -Better now:= :~) */ Rectangle.prototype.bottom = function () { return this.corner.y; @@ -1699,17 +1671,13 @@ Rectangle.prototype.amountToTranslateWithin = function (aRect) { if (this.right() > aRect.right()) { dx = aRect.right() - this.right(); - } - if (this.bottom() > aRect.bottom()) { + }; if (this.bottom() > aRect.bottom()) { dy = aRect.bottom() - this.bottom(); - } - if ((this.left() + dx) < aRect.left()) { + }; if ((this.left() + dx) < aRect.left()) { dx = aRect.left() - this.left(); - } - if ((this.top() + dy) < aRect.top()) { + }; if ((this.top() + dy) < aRect.top()) { dy = aRect.top() - this.top(); - } - return new Point(dx, dy); + }; return new Point(dx, dy); }; Rectangle.prototype.regionsAround = function (aRect) { @@ -1718,8 +1686,7 @@ Rectangle.prototype.regionsAround = function (aRect) { var regions = []; if (!this.intersects(aRect)) { return regions; - } - // left + }; // left if (aRect.left() > this.left()) { regions.push( new Rectangle( @@ -1729,8 +1696,7 @@ Rectangle.prototype.regionsAround = function (aRect) { this.bottom() ) ); - } - // above: + }; // above: if (aRect.top() > this.top()) { regions.push( new Rectangle( @@ -1740,8 +1706,7 @@ Rectangle.prototype.regionsAround = function (aRect) { aRect.top() ) ); - } - // right: + }; // right: if (aRect.right() < this.right()) { regions.push( new Rectangle( @@ -1751,8 +1716,7 @@ Rectangle.prototype.regionsAround = function (aRect) { this.bottom() ) ); - } - // below: + }; // below: if (aRect.bottom() < this.bottom()) { regions.push( new Rectangle( @@ -1762,8 +1726,7 @@ Rectangle.prototype.regionsAround = function (aRect) { this.bottom() ) ); - } - return regions; + }; return regions; }; // Rectangle testing: @@ -1811,13 +1774,16 @@ Rectangle.prototype.translateBy = function (delta) { // Rectangle converting: -Rectangle.prototype.asArray = function () { - return [this.left(), this.top(), this.right(), this.bottom()]; -}; +Rectangle.prototype.asArray = function ( +) {return [this.left(), this.top(), +this.right(), this.bottom()];}; -Rectangle.prototype.asArray_xywh = function () { - return [this.left(), this.top(), this.width(), this.height()]; -}; +Rectangle.prototype.asArray_xywh = function ( +) {return [this.left(), this.top(), +this.width(), this.height()];}; + +const ZERO = new Point; +Object.freeze(ZERO); // Nodes /////////////////////////////////////////////////////////////// @@ -1825,21 +1791,22 @@ Rectangle.prototype.asArray_xywh = function () { function Node(parent, childrenArray) {this.init(parent, childrenArray);}; -Node.prototype.init = function (parent, children) { -this.parent = (parent instanceof Node) ? parent : null; -this.children = (children instanceof Array) ? children : [];}; +Node.prototype.init = function (parent, children) {this.parent = (parent instanceof Node +) ? parent : null; this.children = (children instanceof Array) ? children : [];}; // Node string representation: e.g. 'a Node[3]' Node.prototype.toString = function () { - return 'a Node' + '[' + this.children.length.toString() + ']'; -}; +return 'a Node' + '[' + (this.children +).length.toString() + ']';}; // Node accessing: -Node.prototype.addChild = function (aNode) {this.children.push(aNode); aNode.parent = this;}; +Node.prototype.addChild = function (aNode) { +this.children.push(aNode); aNode.parent = this;}; -Node.prototype.addChildFirst = function (aNode) {this.children.unshift(aNode); aNode.parent = this;}; +Node.prototype.addChildFirst = function (aNode) { +this.children.unshift(aNode); aNode.parent = this;}; Node.prototype.removeChild = function (aNode) { var idx = this.children.indexOf(aNode); if ( @@ -1858,18 +1825,17 @@ return myself;} else if ((condition instanceof Array return myself;} else {return myself.parent.parentThatChecks( condition);};}; -Node.prototype.depth = function () { -if (this.parent instanceof Node) { -return this.parent.depth() + 1; -} else {return 0;};}; +Node.prototype.depth = function ( +) {if (this.parent instanceof Node +) {return ((this.parent.depth() +) + 1);} else {return 0;};}; Node.prototype.allChildren = function () { // includes myself var result = [this]; this.children.forEach(child => { result = result.concat(child.allChildren()); - }); - return result; + }); return result; }; Node.prototype.forAllChildren = function (aFunction) { @@ -1895,7 +1861,7 @@ Node.prototype.allLeafs = function () { if (element.children.length === 0) { result.push(element); }; - }); return result; + }); return result; }; Node.prototype.allParents = function () { @@ -1949,22 +1915,13 @@ Node.prototype.childThatIsA = function () { // Morph: referenced constructors -var Morph, -FPSMorph, -HandMorph, -WorldMorph, -FlashMorph, -ShadowMorph, -FrameMorph, -MenuMorph, -HandleMorph, -StringFieldMorph, -ColorPickerMorph, -SliderMorph, -ScrollFrameMorph, -InspectorMorph, -StringMorph, -TextMorph; +var Morph, HandMorph, WorldMorph, +FlashMorph, ShadowMorph, FrameMorph, +MenuMorph, HandleMorph, FPSMorph, +StringFieldMorph, ColorPickerMorph, +SliderMorph, ScrollFrameMorph, +InspectorMorph, StringMorph, +TextMorph; /* Morphs */ // Morph inherits from Node: @@ -2021,9 +1978,9 @@ Morph.prototype.toString = function () { // Morph deleting: -Morph.prototype.destroy = function anonymous ( -) {if (!isNil(this.parent)) {this.fullChanged( -); this.parent.removeChild(this);};}; /* :o */ +Morph.prototype.destroy = function () {if ( +!isNil(this.parent)) {this.fullChanged(); +this.parent.removeChild(this);};}; // Morph stepping: @@ -2148,9 +2105,8 @@ Morph.prototype.fullBounds = function () { this.children.forEach(child => { if (child.isVisible) { result = result.merge(child.fullBounds()); - } - }); - return result; + }; + }); return result; }; Morph.prototype.fullBoundsNoShadow = function () { @@ -2160,9 +2116,8 @@ Morph.prototype.fullBoundsNoShadow = function () { this.children.forEach(child => { if (!(child instanceof ShadowMorph) && (child.isVisible)) { result = result.merge(child.fullBounds()); - } - }); - return result; + }; + }); return result; }; Morph.prototype.visibleBounds = function () { @@ -2183,14 +2138,14 @@ Morph.prototype.moveBy = function (delta) { this.changed(); for (i; i > 0; i -= 1) { children[i - 1].moveBy(delta); - } + }; }; Morph.prototype.setPosition = function (aPoint) { var delta = aPoint.subtract(this.topLeft()); if (!(delta.eq(ZERO))) { this.moveBy(delta); - } + }; }; Morph.prototype.setLeft = function (x) { @@ -2251,19 +2206,16 @@ Morph.prototype.keepWithin = function (aMorph) { rightOff = this.fullBounds().right() - aMorph.right(); if (rightOff > 0) { this.moveBy(new Point(-rightOff, 0)); - } - leftOff = this.fullBounds().left() - aMorph.left(); + }; leftOff = this.fullBounds().left() - aMorph.left(); if (leftOff < 0) { this.moveBy(new Point(-leftOff, 0)); - } - bottomOff = this.fullBounds().bottom() - aMorph.bottom(); + }; bottomOff = this.fullBounds().bottom() - aMorph.bottom(); if (bottomOff > 0) { this.moveBy(new Point(0, -bottomOff)); - } - topOff = this.fullBounds().top() - aMorph.top(); + }; topOff = this.fullBounds().top() - aMorph.top(); if (topOff < 0) { this.moveBy(new Point(0, -topOff)); - } + }; }; Morph.prototype.scrollIntoView = function () { @@ -2276,26 +2228,22 @@ Morph.prototype.scrollIntoView = function () { ); if (rightOff > 0) { sf.contents.moveBy(new Point(-rightOff, 0)); - } - leftOff = this.fullBounds().left() - sf.left(); + }; leftOff = this.fullBounds().left() - sf.left(); if (leftOff < 0) { sf.contents.moveBy(new Point(-leftOff, 0)); - } - topOff = this.fullBounds().top() - sf.top(); + }; topOff = this.fullBounds().top() - sf.top(); if (topOff < 0) { sf.contents.moveBy(new Point(0, -topOff)); - } - bottomOff = this.fullBounds().bottom() - sf.bottom(); + }; bottomOff = this.fullBounds().bottom() - sf.bottom(); if (bottomOff > 0) { sf.contents.moveBy(new Point(0, -bottomOff)); - } - sf.adjustScrollBars(); + }; sf.adjustScrollBars(); }; // Morph accessing - dimensional changes requiring a complete redraw Morph.prototype.setExtent = function (aPoint) { - if (aPoint.eq(this.extent())) {return; } + if (aPoint.eq(this.extent())) {return;}; this.changed(); this.bounds.setWidth(aPoint.x); this.bounds.setHeight(aPoint.y); @@ -2316,63 +2264,36 @@ Morph.prototype.setColor = function (aColor) { if (!this.color.eq(aColor)) { this.color = aColor; this.rerender(); - } - } + }; + }; }; // Morph rendering: -Morph.prototype.getImage = function () { - var img; - if (this.cachedImage && !this.shouldRerender) { - return this.cachedImage; - } - img = newCanvas(this.extent(), false, this.cachedImage); - if (this.isCachingImage) { - this.cachedImage = img; - } - this.render(img.getContext('2d')); - this.shouldRerender = false; - return img; -}; - +Morph.prototype.getImage = function () {var img; +if (this.cachedImage && !this.shouldRerender) { +return this.cachedImage;}; img = newCanvas((this +).extent(), false, this.cachedImage); (img +).imageSmoothingEnabled = false; if ((this +).isCachingImage) {this.cachedImage = img;}; +var ctx = img.getContext('2d'); (this +).render(img.getContext('2d')); (this +).shouldRerender = false; return img;}; Morph.prototype.render = function (aContext) { - aContext.fillStyle = this.getRenderColor().toString(); - aContext.fillRect(0, 0, this.width(), this.height()); - if (this.cachedTexture) { - this.renderCachedTexture(aContext); - } else if (this.texture) { - this.renderTexture(this.texture, aContext); - } -}; +aContext.fillStyle = this.getRenderColor().toString( +); aContext.fillRect(0, 0, this.width(), this.height( +)); if (this.cachedTexture) {this.renderCachedTexture( +aContext);} else if (this.texture) {this.renderTexture( +this.texture);};}; (Morph.prototype.getRenderColor +) = function () {return this.color;}; (Morph +).prototype.fixLayout = nop; -Morph.prototype.getRenderColor = function () { - // can be overriden by my heirs or instances - return this.color; -}; - -Morph.prototype.fixLayout = function () { - // implemented by my heirs - // determine my extent and arrange my submorphs, if any - // default is to do nothing - // NOTE: If you need to set the extent, in order to avoid - // infinite recursion instead of calling setExtent() (which will - // in turn call fixLayout() again) directly modify the bounds - // property, e.g. like this: this.bounds.setExtent() - return; -}; - -Morph.prototype.fixHolesLayout = function () { - // implemented by my heirs - // arrange my untouchable areas, if any - // default is to do nothing - return; -}; +Morph.prototype.fixHolesLayout = nop; // Morph displaying: -Morph.prototype.renderTexture = function (url, ctx) { - this.cachedTexture = new Image; +Morph.prototype.renderTexture = function ( + url) {this.cachedTexture = new Image; this.cachedTexture.onload = () => this.changed(); this.cachedTexture.src = this.texture = url; }; @@ -2380,89 +2301,78 @@ Morph.prototype.renderTexture = function (url, ctx) { Morph.prototype.renderCachedTexture = function (ctx) { var bg = this.cachedTexture, x, y, cols = Math.floor( this.width() / bg.width), lines = Math.floor( - this.height() / bg.height); ctx.save(); - ctx.globalAlpha = this.alpha; ctx.beginPath(); - ctx.rect(0, 0, this.width(), this.height()); + this.height() / bg.height); ctx.imageSmoothingEnabled = false; + ctx.save(); ctx.globalAlpha = this.alpha; ctx.beginPath( + ); ctx.rect(0, 0, this.width(), this.height()); ctx.clip(); for (y = 0; y <= lines; y += 1) { for (x = 0; x <= cols; x += 1) { - ctx.drawImage(bg, (x * bg.width), (y * bg.height)); - }; - }; ctx.restore(); -}; - -Morph.prototype.drawOn = function (ctx, rect) { - var clipped = rect.intersect(this.bounds), - pos = this.position(), - pic, src, w, h, sl, st; - - if (!clipped.extent().gt(ZERO)) {return;}; - ctx.save(); - ctx.globalAlpha = this.alpha; - if (this.isCachingImage) { - pic = this.getImage(); - src = clipped.translateBy(pos.neg()); - sl = src.left(); - st = src.top(); - w = Math.min(src.width(), pic.width - sl); - h = Math.min(src.height(), pic.height - st); - if (w < 1 || h < 1) {return; } - ctx.drawImage( - pic, - sl, - st, - w, - h, - clipped.left(), - clipped.top(), - w, - h - ); - } else { // render directly on target canvas - ctx.beginPath(); - ctx.rect(clipped.left(), clipped.top(), clipped.width(), clipped.height()); - ctx.clip(); - ctx.translate(pos.x, pos.y); - this.render(ctx); - if (MorphicPreferences.showHoles) { // debug hole rendering + ctx.drawImage(bg, Math.round(x * bg.width + ), Math.round(y * bg.height));}; + }; ctx.restore(); +}; + +Morph.prototype.drawOn = function (ctx, + rect) {var clipped = rect.intersect( + this.bounds), pos = this.position(), pic, src, + w, h, sl, st; if (!(clipped.extent().gt(ZERO)) + ) {return;}; ctx.save(); ctx.globalAlpha = ( + this).alpha; if (this.isCachingImage) { + pic = this.getImage(); src = (clipped + ).translateBy(pos.neg()); sl = src.left( + ); st = src.top(); w = Math.min(src.width( + ), pic.width - sl); h = Math.min(src.height( + ), pic.height - st); if (w < 1 || h < 1) { + return;}; ctx.drawImage(pic, sl, st, w, + h, clipped.left(), clipped.top(), w, h); + } else {// render directly on target canvas + ctx.beginPath(); ctx.rect(clipped.left(), + clipped.top(), clipped.width(), (clipped + ).height()); ctx.clip(); ctx.translate( + pos.x, pos.y); this.render(ctx); if ( + MorphicPreferences.showHoles) { ctx.translate(-pos.x, -pos.y); ctx.globalAlpha = 0.25; ctx.fillStyle = 'white'; this.holes.forEach(hole => { - var sect = hole.translateBy(pos).intersect(clipped); - ctx.fillRect( - sect.left(), - sect.top(), - sect.width(), - sect.height() + var sect = hole.translateBy( + pos).intersect(clipped + ); ctx.fillRect( + sect.left(), sect.top(), + sect.width(), sect.height() ); }); - } - } - ctx.restore(); + }; + }; ctx.restore(); }; -Morph.prototype.fullDrawOn = function (aContext, aRect) {if (this.isVisible) {this.drawOn( -aContext, aRect); this.children.forEach(child => child.fullDrawOn(aContext, aRect));};}; +Morph.prototype.fullDrawOn = function (aContext, aRect) {if ( +this.isVisible) {this.drawOn(aContext, aRect); (this.children +).forEach(child => child.fullDrawOn(aContext, aRect));};}; -Morph.prototype.show = function anonymous () {if (!this.isVisible) {this.isVisible = true; this.changed();};}; -Morph.prototype.hide = function anonymous () {if (this.isVisible) {this.isVisible = false; this.changed();};}; +Morph.prototype.show = function () {if (!this.isVisible +) {this.isVisible = true; this.changed();};}; (Morph +).prototype.hide = function () {if (this.isVisible +) {this.isVisible = false; this.changed();};}; -Morph.prototype.toggleVisibility = function anonymous () {if (this.isVisible) {this.hide();} else {this.show();};}; +Morph.prototype.toggleVisibility = function () {if ( +this.isVisible) {this.hide();} else {this.show();};}; // Morph full image: -Morph.prototype.fullImage = function anonymous () {var fb = this.fullBounds(), img = newCanvas(fb.extent()), -ctx = img.getContext('2d'); ctx.translate(-fb.origin.x, -fb.origin.y); this.fullDrawOn(ctx, fb); return img;}; +Morph.prototype.fullImage = function () { +var fb = this.fullBounds(), img = newCanvas( +fb.extent()), ctx = img.getContext('2d'); (ctx +).translate(-fb.origin.x, -fb.origin.y); (this +).fullDrawOn(ctx, fb); return img;}; // Morph screenshot: -Morph.prototype.screenshot = function anonymous () {var aWorld = (world || this.world()); if (aWorld.currentKey === 16) {var canvas = this.fullImage( -); IDE_Morph.prototype.saveFileAs(canvas.toDataURL(), 'image/png', 'screenshot'); /* You can switch to any screenshot mode with the shift key of your -keyboard. :) */} else {this.nextSteps([(function anonymous () {this.rerender();}), (function anonymous () {var canvas = newCanvas(this.bounds.extent( -)); var ctx = canvas.getContext('2d'); var width = this.bounds.width(); var height = this.bounds.height(); var i = 0; while (i < (width * height)) { -ctx.fillStyle = aWorld.getGlobalPixelColor(new Point(((i % width) + this.bounds.origin.x), (Math.floor(i / width) + this.bounds.origin.y)) -).toString(); ctx.fillRect((i % width), Math.floor(i / width), 1, 1); i++;}; IDE_Morph.prototype.saveFileAs(canvas.toDataURL(), 'image/png', -'screenshot');})]);};}; /* The screenshot function is very useful, use it if do you want to take pictures of morphs in dev mode. :) */ +Morph.prototype.screenshot = function () {var aWorld = (world || this.world()); if (aWorld.currentKey === 16) {var canvas = this.fullImage( +); IDE_Morph.prototype.saveFileAs(canvas.toDataURL(), 'image/png', 'screenshot');} else {this.nextSteps([(function () {this.rerender();}), ( +function () {var canvas = newCanvas(this.bounds.extent()); var ctx = canvas.getContext('2d'); var width = this.bounds.width(); var height = ( +this.bounds.height()); var i = 0; while (i < (width * height)) {ctx.fillStyle = aWorld.getGlobalPixelColor(new Point(((i % width) + (this.bounds +).origin.x), (Math.floor(i / width) + this.bounds.origin.y))).toString(); ctx.fillRect((i % width), Math.floor(i / width), 1, +1); i++;}; IDE_Morph.prototype.saveFileAs(canvas.toDataURL(), 'image/png', 'screenshot');})]);};}; // Morph shadow: @@ -2477,8 +2387,7 @@ Morph.prototype.shadowImage = function (off, color) { } else { // optimization when all submorphs are contained inside fb = this.extent(); img = this.getImage(); - } - outline = newCanvas(fb); + }; outline = newCanvas(fb); ctx = outline.getContext('2d'); ctx.drawImage(img, 0, 0); ctx.globalCompositeOperation = 'destination-out'; @@ -2486,8 +2395,7 @@ Morph.prototype.shadowImage = function (off, color) { img, -offset.x, -offset.y - ); - sha = newCanvas(fb); + ); sha = newCanvas(fb); ctx = sha.getContext('2d'); ctx.drawImage(outline, 0, 0); ctx.globalCompositeOperation = 'source-atop'; @@ -2498,7 +2406,8 @@ Morph.prototype.shadowImage = function (off, color) { Morph.prototype.shadowImageBlurred = function (off, color) { var fb, img, sha, ctx, - offset = off || new Point(7, 7), + offset = (off || ( + new Point(7, 7))), blur = this.shadowBlur, clr = color || BLACK; if (this.fullShadowSource) { @@ -2507,8 +2416,7 @@ Morph.prototype.shadowImageBlurred = function (off, color) { } else { // optimization when all submorphs are contained inside fb = this.extent().add(blur * 2); img = this.getImage(); - } - sha = newCanvas(fb); + }; sha = newCanvas(fb); ctx = sha.getContext('2d'); ctx.shadowOffsetX = offset.x; ctx.shadowOffsetY = offset.y; @@ -2518,8 +2426,7 @@ Morph.prototype.shadowImageBlurred = function (off, color) { img, blur - offset.x, blur - offset.y - ); - ctx.shadowOffsetX = 0; + ); ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.shadowBlur = 0; ctx.globalCompositeOperation = 'destination-out'; @@ -2527,8 +2434,7 @@ Morph.prototype.shadowImageBlurred = function (off, color) { img, blur - offset.x, blur - offset.y - ); - return sha; + ); return sha; }; Morph.prototype.shadow = function (off, a, color) { @@ -2545,15 +2451,13 @@ Morph.prototype.shadow = function (off, a, color) { shadow.cachedImage = this.shadowImage(offset, color); shadow.alpha = alpha; shadow.setPosition(fb.origin.add(offset)); - } - shadow.shouldRerender = false; + }; shadow.shouldRerender = false; return shadow; }; Morph.prototype.addShadow = function (off, a, color) { - var shadow, - offset = off || new Point(7, 7), - alpha = a || ((a === 0) ? 0 : 0.2); + var shadow, offset = off || new Point(7, + 7), alpha = a || ((a === 0) ? 0 : 0.2); shadow = this.shadow(offset, alpha, color); this.addBack(shadow); this.fullChanged(); @@ -2564,11 +2468,9 @@ Morph.prototype.getShadow = function () { var shadows; shadows = this.children.slice(0).reverse().filter( child => child instanceof ShadowMorph - ); - if (shadows.length !== 0) { + ); if (shadows.length !== 0) { return shadows[0]; - } - return null; + }; return null; }; Morph.prototype.removeShadow = function () { @@ -2576,7 +2478,7 @@ Morph.prototype.removeShadow = function () { if (shadow !== null) { this.fullChanged(); this.removeChild(shadow); - } + }; }; // Morph pen trails: @@ -2592,19 +2494,17 @@ Morph.prototype.penTrails = function () { // Morph updating: -Morph.prototype.rerender = function () { - this.shouldRerender = true; - this.changed(); -}; +Morph.prototype.rerender = function ( +) {this.shouldRerender = true; +this.changed();}; Morph.prototype.changed = function () { var w = this.root(); if (w instanceof WorldMorph) { w.broken.push(this.visibleBounds().spread()); - } - if (this.parent) { + }; if (this.parent) { this.parent.childChanged(this); - } + }; }; Morph.prototype.fullChanged = function () { @@ -2613,7 +2513,7 @@ Morph.prototype.fullChanged = function () { w.broken.push( this.fullBounds().spread() ); - } + }; }; Morph.prototype.childChanged = function () { @@ -2622,7 +2522,7 @@ Morph.prototype.childChanged = function () { // override this method for Morphs that need to adjust accordingly if (this.parent) { this.parent.childChanged(this); - } + }; }; // Morph accessing - structure: @@ -2631,27 +2531,23 @@ Morph.prototype.world = function () { var root = this.root(); if (root instanceof WorldMorph) { return root; - } - if (root instanceof HandMorph) { + }; if (root instanceof HandMorph) { return root.world; - } - return world; + }; return world; }; Morph.prototype.add = function (aMorph) { var owner = aMorph.parent; if (owner !== null) { owner.removeChild(aMorph); - } - this.addChild(aMorph); + }; this.addChild(aMorph); }; Morph.prototype.addBack = function (aMorph) { var owner = aMorph.parent; if (owner !== null) { owner.removeChild(aMorph); - } - this.addChildFirst(aMorph); + }; this.addChildFirst(aMorph); }; Morph.prototype.topMorphAt = function (point) { @@ -2660,38 +2556,25 @@ Morph.prototype.topMorphAt = function (point) { for (i = this.children.length - 1; i >= 0; i -= 1) { result = this.children[i].topMorphAt(point); if (result) {return result; } - } - if (this.bounds.containsPoint(point)) { + }; if (this.bounds.containsPoint(point)) { if (this.holes.some( any => any.translateBy(this.position()).containsPoint(point)) ) { return null; - } - if (this.isFreeForm) { + }; if (this.isFreeForm) { if (!this.isTransparentAt(point)) { - return this; - } - } else { - return this; - } - } - return null; -}; + return this;}; + } else {return this;}; +}; return null;}; Morph.prototype.topMorphSuchThat = function (predicate) { - var next; - if (predicate.call(null, this)) { + var next; if (predicate.call(null, this)) { next = detect( this.children.slice(0).reverse(), predicate - ); - if (next) { + ); if (next) { return next.topMorphSuchThat(predicate); - } - return this; - } - return null; -}; +}; return this;}; return null;}; Morph.prototype.overlappedMorphs = function () { //exclude the World @@ -2709,35 +2592,31 @@ Morph.prototype.overlappedMorphs = function () { !contains(allParents, m) && !contains(allChildren, m) && m.fullBounds().intersects(fb); - }); -}; +});}; // Morph pixel access: -Morph.prototype.getPixelColor = function anonymous (aPoint) {try { -var point = aPoint.subtract(this.bounds.origin), -context = this.getImage().getContext('2d'), data; -data = context.getImageData(point.x, point.y, 1, 1).data; -return new Color(data[0], data[1], data[2], (data[3] / 255)); -} catch {return new Color(0, 0, 0, 1);};}; +Morph.prototype.getPixelColor = function (aPoint) { +try {var point = aPoint.subtract(this.bounds.origin), +context = this.getImage().getContext('2d'), data = ( +context.getImageData(point.x, point.y, 1, 1).data +); return new Color(data[0], data[1], data[2], +(data[3] / 255));} catch {return BLACK;};}; Morph.prototype.isTransparentAt = function (aPoint) { var point, context, data; if (this.bounds.containsPoint(aPoint)) { if (this.texture) { return false; - } - point = aPoint.subtract(this.bounds.origin); - context = this.getImage().getContext('2d'); + }; point = aPoint.subtract(this.bounds.origin + ); context = this.getImage().getContext('2d'); data = context.getImageData( Math.floor(point.x), Math.floor(point.y), 1, 1 - ); - return data.data[3] === 0; - } - return false; + ); return data.data[3] === 0; + }; return false; }; // Morph duplicating: @@ -2844,7 +2723,7 @@ Morph.prototype.pickUp = function (wrrld) { var world = wrrld || this.world(); this.setPosition( world.hand.position().subtract( - this.extent().floorDivideBy(2) + this.extent().divideBy(2) ) ); world.hand.grab(this); @@ -3656,15 +3535,24 @@ HandleMorph.prototype.init = function ( if (this.type === 'movePivot') { size *= 2; }; this.setExtent(new Point(size, - size)); this.fixLayout(); - this.cursorStyle = 'nwse-resize'; + size)); this.fixLayout(); if ( + this.type === 'moveHorizontal' + ) {this.cursorStyle = 'ew-resize'; + } else if ((['moveCenter', 'movePivot']).includes(this.type)) { + this.cursorStyle = 'move'; + } else {this.cursorStyle = ( + 'nwse-resize');}; }; // HandleMorph drawing: HandleMorph.prototype.fixLayout = function () { if (this.target) { - if (this.type === 'moveCenter') { + if (this.type === 'moveHorizontal') { + this.setCenter(this.target.center()); + this.setRight(this.target.right() + this.inset.x); + this.cursorStyle = 'ew-resize'; + } else if (this.type === 'moveCenter') { this.setCenter(this.target.center()); this.cursorStyle = 'move'; } else if (this.type === 'movePivot') { @@ -3673,8 +3561,7 @@ HandleMorph.prototype.fixLayout = function () { } else { this.setPosition( this.target.bottomRight().subtract( - this.extent().add(this.inset) - ) + this.extent().add(this.inset)) ); this.cursorStyle = 'nwse-resize'; }; this.target.add(this); this.target.changed(); @@ -3682,12 +3569,20 @@ HandleMorph.prototype.fixLayout = function () { }; HandleMorph.prototype.render = function (ctx) { - if (this.type === 'movePivot') { + if (this.type === 'moveHorizontal') { + if (this.isHighlighted) { + this.renderSeparatorOn(ctx, + MorphicPreferences.isFlat ? + new Color(245, 245, 255) : new Color(100, 100, 255), + this.color);} else { + this.renderSeparatorOn(ctx, this.color); + }; + } else if (this.type === 'movePivot') { if (this.isHighlighted) { this.renderCrosshairsOn(ctx, 0.5); } else { this.renderCrosshairsOn(ctx, 0.6); - } + }; } else { if (this.isHighlighted) { this.renderHandleOn( @@ -3701,8 +3596,44 @@ HandleMorph.prototype.render = function (ctx) { this.color, new Color(100, 100, 100) ); - } - } + }; + }; +}; + +HandleMorph.prototype.renderSeparatorOn = function ( + ctx, + color, + shadowColor +) { + var l = this.height() / 2, + w = this.width() / 6, + r = w / 2, x, y, i; + + ctx.lineWidth = w; + ctx.lineCap = 'round'; + y = this.height() / 2; + + ctx.strokeStyle = color.toString(); + x = this.width() / 12; + for (i = 0; i < 3; i += 1) { + if (i > 0) { + ctx.beginPath(); + ctx.moveTo(x, y - (l - r)); + ctx.lineTo(x, y + (l - r)); + ctx.stroke(); + }; x += (w * 2); + }; if (shadowColor) { + ctx.strokeStyle = shadowColor.toString(); + x = this.width() / 12 + w; + for (i = 0; i < 3; i += 1) { + if (i > 0) { + ctx.beginPath(); + ctx.moveTo(x, y - (l - r)); + ctx.lineTo(x, y + (l - r)); + ctx.stroke(); + }; x += (w * 2); + }; + }; }; HandleMorph.prototype.renderCrosshairsOn = function (ctx, fract) { @@ -3829,17 +3760,24 @@ HandleMorph.prototype.mouseDownLeft = function (pos) { if (!this.target) { return null; } - if (this.type.indexOf('move') === 0) { + if ((['moveCenter', 'movePivot', + 'move']).includes(this.type)) { offset = pos.subtract(this.center()); } else { offset = pos.subtract(this.bounds.origin); - } + }; this.step = () => { var newPos, newExt; if (world.hand.mouseButton) { newPos = world.hand.bounds.origin.copy().subtract(offset); - if (this.type === 'resize') { + if (this.type === 'moveHorizontal') { + newExt = ((newPos.add(this.extent( + ))).subtract(this.inset)).subtract( + this.target.bounds.origin); + newExt = newExt.max(this.minExtent + ); this.target.setExtent(newExt); + } else if (this.type === 'resize') { newExt = newPos.add( this.extent().add(this.inset) ).subtract(this.target.bounds.origin); @@ -3864,12 +3802,12 @@ HandleMorph.prototype.mouseDownLeft = function (pos) { } } else { this.step = null; - } + }; }; if (!this.target.step) { this.target.step = nop; - } + }; }; // HandleMorph dragging and dropping: @@ -3918,7 +3856,7 @@ var PenMorph; // PenMorph inherits from Morph: -PenMorph.prototype = new Morph(); +PenMorph.prototype = new Morph; PenMorph.prototype.constructor = PenMorph; PenMorph.uber = Morph.prototype; @@ -3926,149 +3864,82 @@ PenMorph.uber = Morph.prototype; function PenMorph() {this.init();}; -PenMorph.prototype.init = function () {var size = MorphicPreferences.handleSize * 4; this.isWarped = false; this.heading = 0; this.isDown = true; this.size = 1; this.penBounds = null; -if (this instanceof SpriteMorph) {this.penPoint = 'middle';} else {this.penPoint = 'tip';}; HandleMorph.uber.init.call(this); this.setExtent(new Point(size, size));}; +PenMorph.prototype.init = function () {if (this instanceof SpriteMorph) {this.penPoint = 'middle';} else {this.penPoint = 'tip';}; var size = MorphicPreferences.handleSize * 4; this.isWarped = false; (this +).heading = 0; this.isDown = true; this.size = 1; this.penBounds = null;PenMorph.uber.init.call(this); this.setExtent(new Point(size, size)); this.cursorStyle = 'grab'; this.cursorGrabStyle = 'grabbing';}; // PenMorph updating - optimized for warping, i.e atomic recursion -PenMorph.prototype.changed = function () { - if (this.isWarped) {return; } - PenMorph.uber.changed.call(this); - -}; +PenMorph.prototype.changed = function () {if (!((this +).isWarped)) {PenMorph.uber.changed.call(this);};}; // PenMorph display: PenMorph.prototype.render = function (ctx, facing) { -if (this.scale > 0) { - var start, dest, left, right, len, - direction = (facing || this.heading); - - len = (this.width() / 2); - start = this.center().subtract(this.bounds.origin); - - if (this.penPoint === 'middle') { - dest = start.distanceAngle(len * 0.75, direction); - left = start.distanceAngle(len * (1 / 3), direction + 230); - right = start.distanceAngle(len * (1 / 3), direction - 230); - } else { - dest = start.distanceAngle(len * 0.75, direction - 180); - left = start.distanceAngle(len, direction + 195); - right = start.distanceAngle(len, direction - 195); - }; - - // cache penBounds - this.penBounds = new Rectangle( - Math.min(start.x, dest.x, left.x, right.x), - Math.min(start.y, dest.y, left.y, right.y), - Math.max(start.x, dest.x, left.x, right.x), - Math.max(start.y, dest.y, left.y, right.y) - ); - var realSize = ((this.normalExtent instanceof Point) ? ((aPoint) => (aPoint.x + aPoint.y) / 2)(this.extent().divideBy(this.normalExtent)) : 1) / this.scale; - - // draw arrow shape - ctx.fillStyle = this.color.toString(); - ctx.beginPath(); - - ctx.moveTo(start.x, start.y); - ctx.lineTo(left.x, left.y); - ctx.lineTo(dest.x, dest.y); - ctx.lineTo(right.x, right.y); - - ctx.closePath(); - ctx.strokeStyle = 'white'; - ctx.lineWidth = (2.5 * realSize); - ctx.stroke(); - ctx.strokeStyle = 'black'; - ctx.lineWidth = realSize; - ctx.stroke(); - ctx.fill(); -};}; - -// PenMorph access: - -PenMorph.prototype.setHeading = function (degrees) { - this.heading = ((+degrees % 360) + 360) % 360; - this.fixLayout(); - this.rerender(); -}; - -PenMorph.prototype.numericalSetters = function () { - // for context menu demo purposes - return [ - 'setLeft', - 'setTop', - 'setWidth', - 'setHeight', - 'setAlphaScaled', - 'setHeading' - ]; -}; +if (!(this instanceof SpriteMorph)) {this.scale = 1; +}; if (this.scale > 0) {var start, dest, left, right, +len, direction = (facing || this.heading); len = ( +this.width() / 2); start = (this.center()).subtract( +this.bounds.origin); if (this.penPoint === 'middle' +) {dest = start.distanceAngle(len * 3/4, direction); +left = start.distanceAngle(len / 3, direction + 230); +right = start.distanceAngle(len / 3, direction + 130 +);} else {dest = start.distanceAngle(len * 3/4, +direction - 180); left = start.distanceAngle(len, +direction + 195); right = start.distanceAngle(len, +direction + 165);}; if (isNil(this.normalExtent)) { +this.normalExtent = this.extent();}; (this.penBounds +) = new Rectangle(Math.min(start.x, dest.x, left.x, +right.x), Math.min(start.y, dest.y, left.y, right.y), +Math.max(start.x, dest.x, left.x, right.x), Math.max( +start.y, dest.y, left.y, right.y)); var realSize = (( +this.normalExtent instanceof Point) ? ((aPoint) => ( +aPoint.x + aPoint.y) / 2)(this.extent().divideBy((this +).normalExtent)) : 1) / this.scale; ctx.fillStyle = ( +this.color).toString(); ctx.beginPath(); ctx.moveTo( +start.x, start.y); ctx.lineTo(left.x, left.y); (ctx +).lineTo(dest.x, dest.y); ctx.lineTo(right.x, right.y +); ctx.closePath(); ctx.strokeStyle = 'white'; (ctx +).lineWidth = (5 * realSize) / 2; ctx.stroke(); (ctx +).strokeStyle = 'black'; ctx.lineWidth = realSize; +ctx.stroke(); ctx.fill();};}; (PenMorph.prototype +).setHeading = function (degrees) {this.heading = ( +(+degrees % 360) + 360) % 360; this.fixLayout(); (this +).rerender();}; (PenMorph.prototype.numericalSetters +) = function () {return ['setLeft', 'setTop', 'setWidth', +'setHeight', 'setAlphaScaled', 'setHeading'];}; // PenMorph menu: -PenMorph.prototype.developersMenu = function () { - var menu = PenMorph.uber.developersMenu.call(this); - menu.addLine(); - menu.addItem( - 'set rotation', - "setRotation", - 'interactively turn this morph\nusing a dial widget' - ); - return menu; -}; - -PenMorph.prototype.setRotation = function () { - var menu, dial, - name = this.name || this.constructor.name; - if (name.length > 10) { - name = name.slice(0, 9) + '...'; - } - menu = new MenuMorph(this, name); - dial = new DialMorph(this.heading); - dial.rootForGrab = () => dial; - dial.target = this; - dial.action = 'setHeading'; - menu.items.push(dial); - menu.addLine(); - menu.addItem('(90) right', () => this.setHeading(90)); - menu.addItem('(270) left', () => this.setHeading(270)); - menu.addItem('(0) up', () => this.setHeading(0)); - menu.addItem('(180) down', () => this.setHeading(180)); - menu.isDraggable = true; - menu.popUpAtHand(this.world()); -}; +PenMorph.prototype.developersMenu = function () {var menu = (PenMorph.uber).developersMenu.call( +this); menu.addLine(); menu.addItem('set rotation', "setRotation", ('interactively turn this morph' +).concat('\nusing a dial widget')); return menu;}; PenMorph.prototype.setRotation = function () { +var menu, dial, name = (this.name || this.constructor.name); if (name.length > 10) {name = (name +).slice(0, 9) + '...';}; menu = new MenuMorph(this, name); dial = new DialMorph(this.heading); +dial.rootForGrab = (() => dial); dial.target = this; dial.action = 'setHeading'; (menu.items +).push(dial); menu.addLine(); menu.addItem('(90) right', () => this.setHeading(90)); (menu +).addItem('(270) left', () => this.setHeading(270)); menu.addItem('(0) up', () => (this +).setHeading(0)); menu.addItem('(180) down', () => this.setHeading(180)); (menu +).isDraggable = true; menu.popUpAtHand(this.world());}; // PenMorph drawing: PenMorph.prototype.drawLine = function (start, dest) { - var context = this.parent.penTrails().getContext('2d'), - from = start.subtract(this.parent.bounds.origin), - to = dest.subtract(this.parent.bounds.origin); - if (this.isDown) { - context.lineWidth = this.size; - context.strokeStyle = this.color.toString(); - context.lineCap = 'round'; - context.lineJoin = 'round'; - context.beginPath(); - context.moveTo(from.x, from.y); - context.lineTo(to.x, to.y); - context.stroke(); - if (this.isWarped === false) { - this.world().broken.push( - start.rectangle(dest).expandBy( - Math.max(this.size / 2, 1) - ).intersect(this.parent.visibleBounds()).spread() - ); - } - } -}; +var context = this.parent.penTrails().getContext('2d'), +from = start.subtract(this.parent.bounds.origin), to = ( +dest.subtract(this.parent.bounds.origin)); if (this.isDown +) {context.lineWidth = this.size; context.strokeStyle = ( +this.color).toString(); context.lineCap = 'round'; +context.lineJoin = 'round'; context.beginPath(); +context.moveTo(from.x, from.y); context.lineTo( +to.x, to.y); context.stroke(); if (!(this.isWarped +)) {this.world().broken.push(start.rectangle(dest +).expandBy(Math.max(this.size / 2, 1)).intersect( +this.parent.visibleBounds()).spread());};};}; // PenMorph turtle ops: -PenMorph.prototype.turn = function (degrees) { - this.setHeading(this.heading + parseFloat(degrees)); -}; +PenMorph.prototype.turn = function (degrees) {(this +).setHeading(this.heading + parseFloat(degrees));}; PenMorph.prototype.forward = function (steps) { var start = this.center(), @@ -4081,15 +3952,18 @@ PenMorph.prototype.forward = function (steps) { Math.abs(dist), (this.heading - 180) ); - } - this.setPosition(dest); - this.drawLine(start, this.center()); -}; + }; this.setPosition(dest); +this.drawLine(start, this.center());}; PenMorph.prototype.up = function () {this.isDown = false;}; PenMorph.prototype.down = function () {this.isDown = true;}; PenMorph.prototype.clear = function () {this.parent.rerender();}; +PenMorph.prototype.setDraggableTo = function (bool) { +bool = asABool(bool); if (bool) {this.cursorStyle = 'grab'; +this.cursorGrabStyle = 'grabbing';} else {this.cursorStyle = ( +null); this.cursorGrabStyle = null;}; this.isDraggable = bool;}; + // PenMorph optimization for atomic recursion: PenMorph.prototype.startWarp = function () {this.isWarped = true;}; @@ -4925,7 +4799,7 @@ function SpeechBubbleMorph( padding, isThought, noShadow, - isShouted + isShouting ) { this.init( contents, @@ -4936,7 +4810,7 @@ function SpeechBubbleMorph( padding, isThought, noShadow, - isShouted + isShouting ); } @@ -4949,7 +4823,7 @@ SpeechBubbleMorph.prototype.init = function ( padding, isThought, // bool or anything but "true" to draw no hook at all noShadow, // explicit TRUE to suppress - isShouted // bool or anything but "true" to draw jags on the bubble + isShouting // bool or anything but "true" to draw jags on the bubble ) { this.isPointingRight = true; // orientation of text this.contents = contents || ''; @@ -5077,18 +4951,27 @@ SpeechBubbleMorph.prototype.outlinePath = function (ctx, radius, inset) { function circle(x, y, r) { ctx.moveTo(x + r, y); ctx.arc(x, y, r, radians(0), radians(360)); - }; if (asABool(this.isShouted)) { + }; if (asABool(this.isShouting)) { ctx.moveTo(inset, inset); ctx.lineTo(w - inset, inset); - h = this.height() - y - inset; - jags = Math.round(h / 10); + h = this.height() - inset; + jags = (Math.round(h / 10) / ((this.normalExtent instanceof Point + ) ? ((aPoint) => (aPoint.x + aPoint.y) / 2)(this.extent( + ).divideBy(this.normalExtent)) : 1)); delta = h / jags; - for (i = 0; i < (jags - 1); i += 1) { + for (i = 0; i < (jags - 2); i += 1) { y += delta / 2; ctx.lineTo(w - ((5 + inset) * (Math.random() + 1)), y); y += delta / 2; ctx.lineTo(w - (inset * (Math.random() + 1)), y); - };} else { + }; y += delta / 2; + ctx.lineTo(w - ((5 + inset + ) * (Math.random() + 1)), + h - inset - radius); + ctx.lineTo(w - (inset * ( + Math.random() + 1)), + h - inset - radius); + } else { // top left: ctx.arc( offset, @@ -5136,16 +5019,18 @@ SpeechBubbleMorph.prototype.outlinePath = function (ctx, radius, inset) { ); }; }; // bottom left: - if (this.isShouted) { + if (this.isShouting) { ctx.lineTo(offset, h - inset - radius); ctx.lineTo(0, h - inset - radius); y = h - inset - radius; - for (i = 0; i < (jags - 1); i += 1) { + for (i = 0; i < (jags - 2); i += 1) { y -= delta / 2; ctx.lineTo(((5 + inset) * (Math.random() + 1)), y); y -= delta / 2; ctx.lineTo((inset * (Math.random() + 1)), y); - };} else { + }; ctx.lineTo(((5 + inset) * (Math.random() + 1) + ), 0); ctx.lineTo((inset * (Math.random() + 1)), + 0);} else { ctx.arc( offset, h - offset - radius, @@ -5682,12 +5567,9 @@ SliderButtonMorph.prototype.init = function (orientation) { this.highlightColor = new Color(90, 90, 140); this.pressColor = new Color(80, 80, 160); this.userState = 'normal'; // 'highlight', 'pressed' - this.is3D = false; - this.hasMiddleDip = true; + this.is3D = false; this.hasMiddleDip = true; SliderButtonMorph.uber.init.call(this, orientation); - - this.cursorStyle = 'pointer'; -}; + this.cursorStyle = 'pointer';}; SliderButtonMorph.prototype.autoOrientation = nop; @@ -5831,37 +5713,24 @@ SliderButtonMorph.prototype.renderEdges = function (ctx) { ); ctx.closePath(); ctx.fill(); - } - } -}; +};};}; //SliderButtonMorph events: -SliderButtonMorph.prototype.mouseEnter = function () { - this.userState = 'highlight'; - this.rerender(); -}; +SliderButtonMorph.prototype.mouseEnter = function ( +) {this.userState = 'highlight'; this.rerender();}; -SliderButtonMorph.prototype.mouseLeave = function () { - this.userState = 'normal'; - this.rerender(); -}; +SliderButtonMorph.prototype.mouseLeave = function ( +) {this.userState = 'normal'; this.rerender();}; -SliderButtonMorph.prototype.mouseDownLeft = function (pos) { - this.userState = 'pressed'; - this.rerender(); - this.escalateEvent('mouseDownLeft', pos); -}; +SliderButtonMorph.prototype.mouseDownLeft = function ( +pos) {this.userState = 'pressed'; this.rerender(); +this.escalateEvent('mouseDownLeft', pos);}; -SliderButtonMorph.prototype.mouseClickLeft = function () { - this.userState = 'highlight'; - this.rerender(); -}; +SliderButtonMorph.prototype.mouseClickLeft = function ( +) {this.userState = 'highlight'; this.rerender();}; -SliderButtonMorph.prototype.mouseMove = function () { - // prevent my parent from getting picked up - nop(); -}; +SliderButtonMorph.prototype.mouseMove = nop; // SliderMorph /////////////////////////////////////////////////// @@ -5923,13 +5792,10 @@ SliderMorph.prototype.ratio = function () { }; SliderMorph.prototype.unitSize = function () { - if (this.orientation === 'vertical') { - return (this.height() - this.button.height()) / - this.rangeSize(); - } - return (this.width() - this.button.width()) / - this.rangeSize(); -}; +if (this.orientation === 'vertical') {return ( +this.height() - this.button.height()) / ((this +).rangeSize());}; return (this.width() - (this +).button.width()) / this.rangeSize();}; SliderMorph.prototype.fixLayout = function () { var bw, bh, posX, posY; @@ -5947,34 +5813,23 @@ SliderMorph.prototype.fixLayout = function () { ), 0 ); - } else { - bh = this.height() - 2; - bw = Math.max(bh, Math.round(this.width() * this.ratio())); - this.button.setExtent(new Point(bw, bh)); - posY = 1; - posX = Math.max( - Math.min( - Math.round((this.value - this.start) * this.unitSize()), - this.width() - this.button.width() - ), - 0 - ); - } - this.button.setPosition( - new Point(posX, posY).add(this.bounds.origin) - ); -}; + } else {bh = this.height() - 2; bw = Math.max( + bh, Math.round(this.width() * this.ratio()) + ); this.button.setExtent(new Point(bw, bh) + ); posY = 1; posX = Math.max( + Math.min(Math.round((this.value - this.start + ) * this.unitSize()), this.width() - ((this + ).button.width())), 0); + }; this.button.setPosition( + new Point(posX, posY).add( + this.bounds.origin));}; SliderMorph.prototype.updateValue = function () { - var relPos; - if (this.orientation === 'vertical') { - relPos = this.button.top() - this.top(); - } else { - relPos = this.button.left() - this.left(); - } - this.value = Math.round(relPos / this.unitSize() + this.start); - this.updateTarget(); -}; +var relPos; if (this.orientation === 'vertical') { +relPos = this.button.top() - this.top();} else { +relPos = this.button.left() - this.left();}; (this +).value = Math.round(relPos / this.unitSize( +) + this.start); this.updateTarget();}; SliderMorph.prototype.updateTarget = function () { if (this.action) { @@ -5982,9 +5837,7 @@ SliderMorph.prototype.updateTarget = function () { this.action.call(this.target, this.value); } else { // assume it's a String this.target[this.action](this.value); - } - } -}; + };};}; // SliderMorph menu: @@ -5994,8 +5847,7 @@ SliderMorph.prototype.developersMenu = function () { "show value...", 'showValue', 'display a dialog box\nshowing the selected number' - ); - menu.addItem( + ); menu.addItem( "floor...", () => { this.prompt( @@ -6010,8 +5862,7 @@ SliderMorph.prototype.developersMenu = function () { ); }, 'set the minimum value\nwhich can be selected' - ); - menu.addItem( + ); menu.addItem( "ceiling...", () => { this.prompt( @@ -6026,8 +5877,7 @@ SliderMorph.prototype.developersMenu = function () { ); }, 'set the maximum value\nwhich can be selected' - ); - menu.addItem( + ); menu.addItem( "button size...", () => { this.prompt( @@ -6042,15 +5892,13 @@ SliderMorph.prototype.developersMenu = function () { ); }, 'set the range\ncovered by\nthe slider button' - ); - menu.addLine(); + ); menu.addLine(); menu.addItem( 'set target', "setTarget", 'select another morph\nwhose numerical property\nwill be ' + 'controlled by this one' - ); - return menu; + ); return menu; }; SliderMorph.prototype.showValue = function () { @@ -6067,20 +5915,16 @@ SliderMorph.prototype.setStart = function (num, noUpdate) { var newStart; if (typeof num === 'number') { this.start = Math.min( - num, - this.stop - this.size - ); + num, this.stop - this.size); } else { newStart = parseFloat(num); if (!isNaN(newStart)) { this.start = Math.min( - newStart, - this.stop - this.size - ); - } - } - this.value = Math.max(this.value, this.start); - if (!noUpdate) {this.updateTarget(); } + newStart, this.stop - ( + this.size)); + }; + }; this.value = Math.max(this.value, this.start); + if (!noUpdate) {this.updateTarget();}; this.fixLayout(); this.rerender(); }; @@ -6089,41 +5933,31 @@ SliderMorph.prototype.setStop = function (num, noUpdate) { // for context menu demo purposes var newStop; if (typeof num === 'number') { - this.stop = Math.max(num, this.start + this.size); + this.stop = Math.max( + num, this.start + this.size); } else { newStop = parseFloat(num); if (!isNaN(newStop)) { - this.stop = Math.max(newStop, this.start + this.size); - } - } - this.value = Math.min(this.value, this.stop); - if (!noUpdate) {this.updateTarget(); } + this.stop = Math.max( + newStop, this.start + ( + this.size)); + }; + }; this.value = Math.min(this.value, this.stop); + if (!noUpdate) {this.updateTarget();}; this.fixLayout(); this.rerender(); }; -SliderMorph.prototype.setSize = function (num, noUpdate) { - // for context menu demo purposes - var newSize; - if (typeof num === 'number') { - this.size = Math.min( - Math.max(num, 1), - this.stop - this.start - ); - } else { - newSize = parseFloat(num); - if (!isNaN(newSize)) { - this.size = Math.min( - Math.max(newSize, 1), - this.stop - this.start - ); - } - } - this.value = Math.min(this.value, this.stop - this.size); - if (!noUpdate) {this.updateTarget(); } - this.fixLayout(); - this.rerender(); -}; +SliderMorph.prototype.setSize = function (num, +noUpdate) {var newSize; if ((typeof num) === ( +'number')) {this.size = Math.min(Math.max(num, +1), this.stop - this.start);} else {(newSize +) = parseFloat(num); if (!isNaN(newSize)) { +this.size = Math.min(Math.max(newSize, 1), +this.stop - this.start);};}; this.value = ( +Math.min(this.value, this.stop - this.size) +); if (!noUpdate) {this.updateTarget();}; +this.fixLayout(); this.rerender();}; SliderMorph.prototype.setTarget = function () { var choices = this.overlappedMorphs(), @@ -6135,51 +5969,36 @@ SliderMorph.prototype.setTarget = function () { this.target = each; this.setTargetSetter(); }); - }); - if (choices.length === 1) { + }); if (choices.length === 1) { this.target = choices[0]; this.setTargetSetter(); } else if (choices.length > 0) { menu.popUpAtHand(this.world()); - } -}; + };}; SliderMorph.prototype.setTargetSetter = function () { - var choices = this.target.numericalSetters(), - menu = new MenuMorph(this, 'choose target property:'); - - choices.forEach(each => { - menu.addItem(each, () => this.action = each); - }); - if (choices.length === 1) { - this.action = choices[0]; - } else if (choices.length > 0) { - menu.popUpAtHand(this.world()); - } -}; +var choices = this.target.numericalSetters(), menu = ( +new MenuMorph(this, 'choose target property:')); +choices.forEach(each => {menu.addItem(each, +() => this.action = each);}); if ((choices +).length === 1) {this.action = choices[ +0];} else if (choices.length > 0) { +menu.popUpAtHand(this.world());};}; SliderMorph.prototype.numericalSetters = function () { - // for context menu demo purposes - var list = SliderMorph.uber.numericalSetters.call(this); - list.push('setStart', 'setStop', 'setSize'); - return list; -}; +var list = SliderMorph.uber.numericalSetters.call(this); +list.push('setStart', 'setStop', 'setSize'); return list;}; // SliderMorph stepping: SliderMorph.prototype.step = null; SliderMorph.prototype.mouseDownLeft = function (pos) { - var world; - if (!this.button.bounds.containsPoint(pos)) { - this.offset = new Point(); // return null; + this.offset = new Point; } else { this.offset = pos.subtract(this.button.bounds.origin); - } - world = this.root(); - - this.step = () => { + }; this.step = () => { var mousePos, newX, newY; if (world.hand.mouseButton) { mousePos = world.hand.bounds.origin; @@ -6189,8 +6008,7 @@ SliderMorph.prototype.mouseDownLeft = function (pos) { Math.min( mousePos.y - this.offset.y, this.bottom() - this.button.height() - ), - this.top() + ), this.top() ); } else { newY = this.button.bounds.origin.y; @@ -6198,17 +6016,13 @@ SliderMorph.prototype.mouseDownLeft = function (pos) { Math.min( mousePos.x - this.offset.x, this.right() - this.button.width() - ), - this.left() + ), this.left() ); - } - this.button.setPosition(new Point(newX, newY)); - this.updateValue(); + }; this.button.setPosition(new Point( + newX, newY)); this.updateValue(); } else { this.step = null; - } - }; -}; + };};}; // MouseSensorMorph //////////////////////////////////////////////////// @@ -6224,41 +6038,25 @@ MouseSensorMorph.uber = BoxMorph.prototype; // MouseSensorMorph instance creation: -function MouseSensorMorph(edge, border, borderColor) { - this.init(edge, border, borderColor); -} - -MouseSensorMorph.prototype.init = function (edge, border, borderColor) { - MouseSensorMorph.uber.init.call(this); - this.edge = edge || 4; - this.border = border || 2; - this.color = WHITE; - this.borderColor = borderColor || BLACK; - this.isTouched = false; - this.upStep = 0.05; - this.downStep = 0.02; -}; - -MouseSensorMorph.prototype.touch = function () { - if (!this.isTouched) { - this.isTouched = true; - this.alpha = 0.6; - - this.step = () => { - if (this.isTouched) { - if (this.alpha < 1) { - this.alpha += this.upStep; - } - } else if (this.alpha > this.downStep) { - this.alpha -= this.downStep; - } else { - this.alpha = 0; - this.step = null; - } - this.changed(); - }; - } -}; +function MouseSensorMorph(edge, border, borderColor +) {this.init(edge, border, borderColor);}; + +MouseSensorMorph.prototype.init = function ( +edge, border, borderColor) {(MouseSensorMorph +).uber.init.call(this); this.edge = edge || 4; +this.border = border || 2; this.color = WHITE; +this.borderColor = borderColor || BLACK; (this +).isTouched = false; this.upStep = 1/20; +this.downStep = 1/50;}; + +MouseSensorMorph.prototype.touch = function ( +) {if (!this.isTouched) {this.isTouched = true; +this.alpha = 3/5; this.step = () => {if ((this +).isTouched) {if (this.alpha < 1) {(this.alpha +) += this.upStep;};} else if ((this.alpha) > ( +this.downStep)) {this.alpha -= this.downStep; +} else {this.alpha = 0; this.step = null; +}; this.changed();};};}; MouseSensorMorph.prototype.unTouch = function () {this.isTouched = false;}; @@ -6285,9 +6083,9 @@ InspectorMorph.uber = BoxMorph.prototype; // InspectorMorph instance creation: -function InspectorMorph(target) { - this.init(target); -} +function InspectorMorph( +target) {this.init( +target);}; InspectorMorph.prototype.init = function (target) { // additional properties: @@ -6301,71 +6099,35 @@ InspectorMorph.prototype.init = function (target) { InspectorMorph.uber.init.call(this); // override inherited properties: - this.isDraggable = true; - this.border = 1; - this.edge = MorphicPreferences.isFlat ? 1 : 5; - this.color = new Color(60, 60, 60); + this.isDraggable = true; this.border = 1; + this.edge = 5 - ((MorphicPreferences.isFlat + ) * 4); this.color = new Color(60, 60, 60); this.borderColor = new Color(95, 95, 95); - this.fps = 25; - - // panes: - this.label = null; - this.list = null; - this.detail = null; - this.work = null; - this.buttonInspect = null; - this.buttonClose = null; - this.buttonSubset = null; - this.buttonEdit = null; - this.resizer = null; - - if (this.target) { - this.buildPanes(); - } - - this.setExtent( - new Point( + this.fps = 25; this.label = null; (this + ).list = null; this.detail = null; (this + ).work = null; this.buttonInspect = null; + this.buttonEdit = null; this.resizer = null; + this.buttonSubset = null; (this.buttonClose + ) = null; if (this.target) {this.buildPanes( + );}; this.setExtent(new Point( MorphicPreferences.handleSize * 20, - MorphicPreferences.handleSize * 20 * 2 / 3 - ) - ); -}; - -InspectorMorph.prototype.setTarget = function (target) { - this.target = target; - this.currentProperty = null; - this.buildPanes(); -}; + (MorphicPreferences.handleSize * 40) / 3) +);}; InspectorMorph.prototype.setTarget = function (target) {(this +).target = target; this.currentProperty = null; this.buildPanes();}; InspectorMorph.prototype.updateCurrentSelection = function () { - var val, txt, cnts, - sel = this.list.selected, - currentTxt = this.detail.contents.children[0], - root = this.root(); - - if (root && - (root.keyboardFocus instanceof CursorMorph) && - (root.keyboardFocus.target === currentTxt)) { - this.hasUserEditedDetails = true; - return; - } - if (isNil(sel) || this.hasUserEditedDetails) {return; } - val = this.target[sel]; - this.currentProperty = val; - if (isNil(val)) { - txt = 'NULL'; - } else if (isString(val)) { - txt = val; - } else { - txt = val.toString(); - } - if (currentTxt.text === txt) {return; } - cnts = new TextMorph(txt); - cnts.isEditable = true; - cnts.enableSelecting(); - cnts.setReceiver(this.target); - this.detail.setContents(cnts); -}; +var val, txt, cnts, sel = this.list.selected, currentTxt = ( +this.detail.contents.children)[0], root = this.root(); if ( +root && (root.keyboardFocus instanceof CursorMorph) && ( +root.keyboardFocus.target === currentTxt)) {(this +).hasUserEditedDetails = true; return;}; if (isNil( +sel) || this.hasUserEditedDetails) {return;}; val = ( +this.target[sel]); this.currentProperty = val; if (isNil( +val)) {txt = 'null';} else if (isString(val)) {txt = val; +} else {txt = val.toString();}; if (currentTxt.text === txt +) {return;}; cnts = new TextMorph(txt); cnts.isEditable = ( +true); cnts.enableSelecting(); cnts.setReceiver(this.target +); this.detail.setContents(cnts);}; InspectorMorph.prototype.buildPanes = function () { var attribs = [], property, ctrl, ev, doubleClickAction; @@ -6374,9 +6136,8 @@ InspectorMorph.prototype.buildPanes = function () { this.children.forEach(m => { if (m !== this.work) { // keep work pane around m.destroy(); - } - }); - this.children = []; + }; + }); this.children = []; // label this.label = new TextMorph(this.target.toString()); @@ -6389,9 +6150,8 @@ InspectorMorph.prototype.buildPanes = function () { for (property in this.target) { if (property) { // dummy condition, to be refined attribs.push(property); - } - } - if (this.showing === 'attributes') { + }; + }; if (this.showing === 'attributes') { attribs = attribs.filter( prop => typeof this.target[prop] !== 'function' ); @@ -6399,22 +6159,17 @@ InspectorMorph.prototype.buildPanes = function () { attribs = attribs.filter( prop => typeof this.target[prop] === 'function' ); - } // otherwise show all properties - + }; // otherwise show all properties doubleClickAction = () => { var world, inspector; - if (!isObject(this.currentProperty)) {return; } - world = this.world(); - inspector = new InspectorMorph( + if (!isObject(this.currentProperty)) { + return;}; inspector = new InspectorMorph( this.currentProperty - ); - inspector.setPosition(world.hand.position()); - inspector.keepWithin(world); - world.add(inspector); + ); inspector.setPosition((world.hand + ).position()); inspector.keepWithin( + world); world.add(inspector); inspector.changed(); - }; - - this.list = new ListMorph( + }; this.list = new ListMorph( this.target instanceof Array ? attribs : attribs.sort(), null, // label getter this.markOwnProperties ? @@ -6431,20 +6186,16 @@ InspectorMorph.prototype.buildPanes = function () { ] : null, doubleClickAction - ); - - this.list.action = () => { + ); this.list.action = () => { this.hasUserEditedDetails = false; this.updateCurrentSelection(); - }; - - this.list.hBar.alpha = 0.6; - this.list.vBar.alpha = 0.6; + }; this.list.hBar.alpha = 3/5; + this.list.vBar.alpha = 3/5; this.list.contents.step = null; this.add(this.list); // details pane - this.detail = new ScrollFrameMorph(); + this.detail = new ScrollFrameMorph; this.detail.acceptsDrops = false; this.detail.contents.acceptsDrops = false; this.detail.isTextLineWrapping = true; @@ -6461,7 +6212,7 @@ InspectorMorph.prototype.buildPanes = function () { // work ('evaluation') pane // don't refresh the work pane if it already exists if (this.work === null) { - this.work = new ScrollFrameMorph(); + this.work = new ScrollFrameMorph; this.work.acceptsDrops = false; this.work.contents.acceptsDrops = false; this.work.isTextLineWrapping = true; @@ -6473,54 +6224,41 @@ InspectorMorph.prototype.buildPanes = function () { ev.enableSelecting(); ev.setReceiver(this.target); this.work.setContents(ev); - } - this.add(this.work); + }; this.add(this.work); - // properties button - this.buttonSubset = new TriggerMorph(); + // properties button + this.buttonSubset = new TriggerMorph; this.buttonSubset.labelString = 'show...'; this.buttonSubset.createLabel(); - this.buttonSubset.action = () => { - var menu; - menu = new MenuMorph(); + this.buttonSubset.action = (() => { + var menu = new MenuMorph; menu.addItem( - 'attributes', - () => { + 'attributes', () => { this.showing = 'attributes'; this.buildPanes(); } - ); - menu.addItem( - 'methods', - () => { + ); menu.addItem( + 'methods', () => { this.showing = 'methods'; this.buildPanes(); } - ); - menu.addItem( - 'all', - () => { + ); menu.addItem( + 'all', () => { this.showing = 'all'; this.buildPanes(); } - ); - menu.addLine(); + ); menu.addLine(); menu.addItem( (this.markOwnProperties ? 'un-mark own' : 'mark own'), - () => { - this.markOwnProperties = !this.markOwnProperties; + () => {this.markOwnProperties = !( + this.markOwnProperties); this.buildPanes(); - }, - 'highlight\n\'own\' properties' - ); - menu.popUpAtHand(this.world()); - }; - - this.add(this.buttonSubset); - - // inspect button - this.buttonInspect = new TriggerMorph(); + }, 'highlight\n\'own\' properties' + ); menu.popUpAtHand(this.world()); + }); this.add(this.buttonSubset); + // inspect button + this.buttonInspect = new TriggerMorph; this.buttonInspect.labelString = 'inspect...'; this.buttonInspect.createLabel(); this.buttonInspect.action = () => { @@ -6543,20 +6281,18 @@ InspectorMorph.prototype.buildPanes = function () { menu.addItem( 'here...', () => this.setTarget(this.currentProperty) - ); - menu.popUpAtHand(this.world()); + ); menu.popUpAtHand(this.world()); } else { this.inform( (this.currentProperty === null ? 'null' : typeof this.currentProperty) + '\nis not inspectable' ); - } - }; - this.add(this.buttonInspect); + }; + }; this.add(this.buttonInspect); // edit button - this.buttonEdit = new TriggerMorph(); + this.buttonEdit = new TriggerMorph; this.buttonEdit.labelString = 'edit...'; this.buttonEdit.createLabel(); this.buttonEdit.action = () => { @@ -6567,11 +6303,10 @@ InspectorMorph.prototype.buildPanes = function () { menu.addItem("rename...", 'renameProperty'); menu.addItem("remove...", 'removeProperty'); menu.popUpAtHand(this.world()); - }; - this.add(this.buttonEdit); + }; this.add(this.buttonEdit); // close button - this.buttonClose = new TriggerMorph(); + this.buttonClose = new TriggerMorph; this.buttonClose.labelString = 'close'; this.buttonClose.createLabel(); this.buttonClose.action = () => this.destroy(); @@ -6579,16 +6314,8 @@ InspectorMorph.prototype.buildPanes = function () { // resizer this.resizer = new HandleMorph( - this, - 150, - 100, - this.edge, - this.edge - ); - - // update layout - this.fixLayout(); -}; + this, 150, 100, this.edge, (this + ).edge); this.fixLayout();}; InspectorMorph.prototype.fixLayout = function () { var x, y, r, b, w, h; @@ -6658,10 +6385,7 @@ InspectorMorph.prototype.fixLayout = function () { w = r - x; this.buttonClose.setPosition(new Point(x, y)); this.buttonClose.setExtent(new Point(w, h)); - - // resizer - this.resizer.fixLayout(); -}; + /* resizer */ this.resizer.fixLayout();}; // InspectorMorph editing ops: @@ -6674,8 +6398,7 @@ InspectorMorph.prototype.save = function () { this.target.changed(); } catch (err) { this.inform(err); - } -}; + };}; InspectorMorph.prototype.addProperty = function () { this.prompt( @@ -6685,12 +6408,10 @@ InspectorMorph.prototype.addProperty = function () { this.target[prop] = null; this.buildPanes(); this.target.changed(); - } - }, - this, + }; + }, this, 'property' - ); -}; + );}; InspectorMorph.prototype.renameProperty = function () { var propertyName = this.list.selected; @@ -6702,14 +6423,9 @@ InspectorMorph.prototype.renameProperty = function () { this.target[prop] = this.currentProperty; } catch (err) { this.inform(err); - } - this.buildPanes(); + }; this.buildPanes(); this.target.changed(); - }, - this, - propertyName - ); -}; + }, this, propertyName);}; InspectorMorph.prototype.removeProperty = function () { var prop = this.list.selected; @@ -6876,19 +6592,15 @@ MenuMorph.prototype.createLabel = function () { var text; if (this.label !== null) { this.label.destroy(); - } - text = new TextMorph( + }; text = new TextMorph( localize(this.title), this.fontSize || MorphicPreferences.menuFontSize, MorphicPreferences.menuFontName, - true, - false, - 'center' - ); - text.alignment = 'center'; - text.color = WHITE; - text.backgroundColor = this.borderColor; - text.fixLayout(); + true, false, 'center' + ); text.alignment = 'center'; + text.color = WHITE; (text + ).backgroundColor = (this + ).borderColor; text.fixLayout(); this.label = new BoxMorph(3, 0); this.label.color = this.borderColor; this.label.borderColor = this.borderColor; @@ -6913,8 +6625,7 @@ MenuMorph.prototype.createItems = function () { this.borderColor = new Color(60, 60, 60); this.setExtent(new Point(0, 0)); - y = 2; - x = this.left() + 4; + y = 2; x = this.left() + 4; if (!this.isListContents) { if (this.title) { this.createLabel(); @@ -6923,9 +6634,8 @@ MenuMorph.prototype.createItems = function () { y = this.label.bottom(); } else { y = this.top() + 4; - } - } - y += 1; + }; + }; y += 1; this.items.forEach(tuple => { isLine = false; if (tuple instanceof StringFieldMorph || @@ -6956,82 +6666,58 @@ MenuMorph.prototype.createItems = function () { ); }; if (isLine) { y += 1; - }; item.setPosition(new Point(x, y)); - this.add(item); + }; item.setPosition(new Point( + x, y)); this.add(item); y = y + item.height(); - if (isLine) { - y += 1; - }; - }); - - fb = this.fullBounds(); + if (isLine) {y += 1;}; + }); fb = this.fullBounds(); this.setExtent(fb.extent().add(4)); - this.adjustWidths(); -}; - -MenuMorph.prototype.maxWidth = function () { - var w = 0; - - if (this.parent instanceof FrameMorph) { - if (this.parent.scrollFrame instanceof ScrollFrameMorph) { - w = this.parent.scrollFrame.width(); - } - } - this.children.forEach(item => { - if (item instanceof MenuItemMorph) { - w = Math.max( - w, - item.label.width() + 8 + - (item.shortcut ? item.shortcut.width() + 4 : 0) - ); - } else if ((item instanceof StringFieldMorph) || - (item instanceof ColorPickerMorph) || - (item instanceof SliderMorph) || - (item instanceof DialMorph)) { - w = Math.max(w, item.width()); - } - }); - if (this.label) { - w = Math.max(w, this.label.width()); - } - return w; -}; + this.adjustWidths();}; + +MenuMorph.prototype.maxWidth = function () {var w = 0; +if (this.parent instanceof FrameMorph) {if ((this.parent +).scrollFrame instanceof ScrollFrameMorph) {w = ((this +).parent).scrollFrame.width();};}; (this.children +).forEach(item => {if (item instanceof MenuItemMorph +) {w = Math.max(w, item.label.width() + 8 + ((item +).shortcut ? item.shortcut.width() + 4 : 0)); +} else if ((item instanceof StringFieldMorph +) || (item instanceof ColorPickerMorph) || ( +item instanceof SliderMorph) || ((item +) instanceof DialMorph)) {w = Math.max(w, +item.width());};}); if (this.label) {w = ( +Math.max(w, this.label.width()));}; return w;}; MenuMorph.prototype.adjustWidths = function () { var w = this.maxWidth(); this.children.forEach(item => { if (!(item instanceof DialMorph)) { item.setWidth(w); - } - item.fixLayout(); + }; item.fixLayout(); if (item === this.label) { item.text.setPosition( item.center().subtract( item.text.extent().divideBy(2) ) ); - } - }); -}; + }; + });}; MenuMorph.prototype.unselectAllItems = function () { this.children.forEach(item => { if (item instanceof MenuItemMorph) { if (item.userState !== 'normal') { item.userState = 'normal'; - item.rerender(); - } + item.rerender();}; } else if (item instanceof ScrollFrameMorph) { - item.contents.children.forEach(morph => { - if (morph instanceof MenuItemMorph && - morph.userState !== 'normal') { - morph.userState = 'normal'; + item.contents.children.forEach(morph => { + if ((morph instanceof MenuItemMorph + ) && (morph.userState !== 'normal') + ) {morph.userState = 'normal'; morph.rerender(); } }); - } - }); -}; + };});}; // MenuMorph popping up @@ -7051,15 +6737,11 @@ MenuMorph.prototype.popup = function (world, pos) { this.addShadow(new Point(2, 2), 80); scroller.setHeight(world.bottom() - scroller.top() - 6); scroller.adjustScrollBars(); // ? - } - - if (world.activeMenu) { + }; if (world.activeMenu) { world.activeMenu.destroy(); - } - if (this.items.length < 1 && !this.title) { // don't show empty menus + }; if (this.items.length < 1 && !this.title) { // don't show empty menus return; - } - world.add(this); + }; world.add(this); world.activeMenu = this; this.world = world; // optionally enable keyboard support this.fullChanged(); @@ -7090,10 +6772,8 @@ MenuMorph.prototype.popUpCenteredAtHand = function (world) { this.popup( wrrld, wrrld.hand.position().subtract( - this.extent().floorDivideBy(2) - ) - ); -}; + this.extent().divideBy(2) + ));}; MenuMorph.prototype.popUpCenteredInWorld = function (world) { var wrrld = world || this.world; @@ -7102,7 +6782,7 @@ MenuMorph.prototype.popUpCenteredInWorld = function (world) { this.popup( wrrld, wrrld.center().subtract( - this.extent().floorDivideBy(2) + this.extent().divideBy(2) ) ); }; @@ -7114,7 +6794,7 @@ MenuMorph.prototype.closeRootMenu = function () { this.parent.closeRootMenu(); } else { this.destroy(); - } + }; }; MenuMorph.prototype.closeSubmenu = function () { @@ -7123,7 +6803,7 @@ MenuMorph.prototype.closeSubmenu = function () { this.submenu = null; this.unselectAllItems(); this.world.activeMenu = this; - } + }; }; // MenuMorph keyboard accessibility @@ -7144,9 +6824,8 @@ MenuMorph.prototype.processKeyDown = function (event) { this.selection.mouseClickLeft(); if (this.submenu) { this.submenu.getFocus(); - } - } - return; + }; + }; return; case 27: // 'esc' return this.destroy(); case 37: // 'left arrow' @@ -7159,7 +6838,7 @@ MenuMorph.prototype.processKeyDown = function (event) { return this.selectDown(); default: nop(); - } + }; }; MenuMorph.prototype.processKeyUp = function (event) { @@ -8476,10 +8155,8 @@ TextMorph.prototype.enableSelecting = StringMorph.prototype.enableSelecting; TextMorph.prototype.disableSelecting = StringMorph.prototype.disableSelecting; -TextMorph.prototype.selectAllAndEdit = function () { - this.edit(); - this.selectAll(); -}; +TextMorph.prototype.selectAllAndEdit = function ( +) {this.edit(); this.selectAll();}; // TextMorph menus: @@ -8500,52 +8177,36 @@ TextMorph.prototype.developersMenu = function () { 100, true ); - }, - 'set this Text\'s\nfont point size' - ); - if (this.alignment !== 'left') { + }, 'set this Text\'s\nfont point size' + ); if (this.alignment !== 'left') { menu.addItem("align left", 'setAlignmentToLeft'); - } - if (this.alignment !== 'right') { + }; if (this.alignment !== 'right') { menu.addItem("align right", 'setAlignmentToRight'); - } - if (this.alignment !== 'center') { + }; if (this.alignment !== 'center') { menu.addItem("align center", 'setAlignmentToCenter'); - } - menu.addLine(); + }; menu.addLine(); if (this.fontStyle !== 'serif') { menu.addItem("serif", 'setSerif'); - } - if (this.fontStyle !== 'sans-serif') { + }; if (this.fontStyle !== 'sans-serif') { menu.addItem("sans-serif", 'setSansSerif'); - } - if (this.isBold) { + }; if (this.isBold) { menu.addItem("normal weight", 'toggleWeight'); } else { menu.addItem("bold", 'toggleWeight'); - } - if (this.isItalic) { + }; if (this.isItalic) { menu.addItem("normal style", 'toggleItalic'); } else { menu.addItem("italic", 'toggleItalic'); - } - return menu; -}; + }; return menu;}; -TextMorph.prototype.setAlignmentToLeft = function () { - this.alignment = 'left'; - this.rerender(); -}; +TextMorph.prototype.setAlignmentToLeft = function ( +) {this.alignment = 'left'; this.rerender();}; -TextMorph.prototype.setAlignmentToRight = function () { - this.alignment = 'right'; - this.rerender(); -}; +TextMorph.prototype.setAlignmentToRight = function ( +) {this.alignment = 'right'; this.rerender();}; -TextMorph.prototype.setAlignmentToCenter = function () { - this.alignment = 'center'; - this.rerender(); -}; +TextMorph.prototype.setAlignmentToCenter = function ( +) {this.alignment = 'center'; this.rerender();}; TextMorph.prototype.toggleIsDraggable = StringMorph.prototype.toggleIsDraggable; @@ -8572,51 +8233,35 @@ TextMorph.prototype.evaluationMenu = function () { "do it", 'doIt', 'evaluate the\nselected expression' - ); - menu.addItem( + ); menu.addItem( "show it", 'showIt', 'evaluate the\nselected expression\nand show the result' - ); - menu.addItem( + ); menu.addItem( "inspect it", 'inspectIt', 'evaluate the\nselected expression\nand inspect the result' - ); - menu.addLine(); - menu.addItem("select all", 'selectAllAndEdit'); - return menu; -}; + ); menu.addLine(); menu.addItem("select all", + 'selectAllAndEdit'); return menu;}; -TextMorph.prototype.setReceiver = function (obj) { - this.receiver = obj; - this.customContextMenu = this.evaluationMenu(); -}; +TextMorph.prototype.setReceiver = function (obj) {(this.receiver +) = obj; this.customContextMenu = this.evaluationMenu();}; -TextMorph.prototype.doIt = function () { - this.receiver.evaluateString(this.selection()); - this.edit(); -}; +TextMorph.prototype.doIt = function () {(this.receiver +).evaluateString(this.selection()); this.edit();}; TextMorph.prototype.showIt = function () { - var result = this.receiver.evaluateString(this.selection()); - if (result !== null) { - this.inform(result); - } -}; +var result = this.receiver.evaluateString( +this.selection()); if (!isNil(result +)) {this.inform(result);};}; TextMorph.prototype.inspectIt = function () { - var result = this.receiver.evaluateString(this.selection()), - world = this.world(), - inspector; - if (isObject(result)) { - inspector = new InspectorMorph(result); - inspector.setPosition(world.hand.position()); - inspector.keepWithin(world); - world.add(inspector); - inspector.changed(); - } -}; +var result = this.receiver.evaluateString((this +).selection()), inspector; if (isObject(result +)) {inspector = new InspectorMorph(result); +inspector.setPosition(world.hand.position() +); inspector.keepWithin(world); world.add( +inspector); inspector.changed();};}; // TriggerMorph //////////////////////////////////////////////////////// @@ -8624,7 +8269,7 @@ TextMorph.prototype.inspectIt = function () { // TriggerMorph inherits from Morph: -TriggerMorph.prototype = new Morph(); +TriggerMorph.prototype = new Morph; TriggerMorph.prototype.constructor = TriggerMorph; TriggerMorph.uber = Morph.prototype; @@ -8656,7 +8301,7 @@ function TriggerMorph( labelItalic, doubleClickAction ); -} +}; TriggerMorph.prototype.init = function ( target, @@ -8705,16 +8350,13 @@ TriggerMorph.prototype.render = function (ctx) { this.color = this.highlightColor; } else if (this.userState === 'pressed') { this.color = this.pressColor; - } - TriggerMorph.uber.render.call(this, ctx); - this.color = colorBak; -}; + }; TriggerMorph.uber.render.call(this, ctx + ); this.color = colorBak;}; TriggerMorph.prototype.createLabel = function () { if (this.label !== null) { this.label.destroy(); - } - this.label = new StringMorph( + }; this.label = new StringMorph( this.labelString, this.fontSize, this.fontStyle, @@ -8724,10 +8366,8 @@ TriggerMorph.prototype.createLabel = function () { null, // shadow offset null, // shadow color this.labelColor - ); - this.fixLayout(); - this.add(this.label); -}; + ); this.fixLayout(); + this.add(this.label);}; TriggerMorph.prototype.fixLayout = function () { this.label.setPosition( @@ -8762,21 +8402,18 @@ TriggerMorph.prototype.trigger = function () { */ if (this.schedule) { this.schedule.isActive = false; - } - if (typeof this.target === 'function') { + }; if (typeof this.target === 'function') { if (typeof this.action === 'function') { this.target.call(this.environment, this.action.call(), this); } else { this.target.call(this.environment, this.action, this); - } + }; } else { if (typeof this.action === 'function') { this.action.call(this.target); } else { // assume it's a String this.target[this.action](); - } - } -}; + };};}; TriggerMorph.prototype.triggerDoubleClick = function () { // same as trigger() but use doubleClickAction instead of action property @@ -8784,8 +8421,7 @@ TriggerMorph.prototype.triggerDoubleClick = function () { if (!this.doubleClickAction) {return; } if (this.schedule) { this.schedule.isActive = false; - } - if (typeof this.target === 'function') { + }; if (typeof this.target === 'function') { if (typeof this.doubleClickAction === 'function') { this.target.call( this.environment, @@ -8794,15 +8430,13 @@ TriggerMorph.prototype.triggerDoubleClick = function () { ); } else { this.target.call(this.environment, this.doubleClickAction, this); - } + }; } else { if (typeof this.doubleClickAction === 'function') { this.doubleClickAction.call(this.target); } else { // assume it's a String this.target[this.doubleClickAction](); - } - } -}; + };};}; // TriggerMorph events: @@ -8812,62 +8446,39 @@ TriggerMorph.prototype.mouseEnter = function () { this.rerender(); if (contents) { this.bubbleHelp(contents); - } -}; + };}; TriggerMorph.prototype.mouseLeave = function () { this.userState = 'normal'; this.rerender(); if (this.schedule) { this.schedule.isActive = false; - } - if (this.hint) { + }; if (this.hint) { this.world().hand.destroyTemporaries(); - } -}; + };}; -TriggerMorph.prototype.mouseDownLeft = function () { - this.userState = 'pressed'; - this.rerender(); -}; +TriggerMorph.prototype.mouseDownLeft = function ( +) {this.userState = 'pressed'; this.rerender();}; -TriggerMorph.prototype.mouseClickLeft = function () { - this.userState = 'highlight'; - this.rerender(); - this.trigger(); -}; +TriggerMorph.prototype.mouseClickLeft = function () {(this +).userState = 'highlight'; this.rerender(); this.trigger();}; -TriggerMorph.prototype.mouseDoubleClick = function () { - this.triggerDoubleClick(); -}; +TriggerMorph.prototype.mouseDoubleClick = ( +function () {this.triggerDoubleClick();}); -TriggerMorph.prototype.rootForGrab = function () { - return this.isDraggable ? TriggerMorph.uber.rootForGrab.call(this) : null; -}; +TriggerMorph.prototype.rootForGrab = function () {return ((this +).isDraggable ? TriggerMorph.uber.rootForGrab.call(this) : null);}; // TriggerMorph bubble help: -TriggerMorph.prototype.bubbleHelp = function (contents) { - var world = this.world(); - this.schedule = new Animation( - nop, - nop, - 0, - 500, - nop, - () => this.popUpbubbleHelp(contents) - ); - world.animations.push(this.schedule); -}; +TriggerMorph.prototype.bubbleHelp = function (contents +) {var myself = this; myself.schedule = new Animation( +nop, nop, 0, 500, nop, (() => myself.popUpbubbleHelp( +contents))); world.animations.push(this.schedule);}; TriggerMorph.prototype.popUpbubbleHelp = function (contents) { - new SpeechBubbleMorph( - localize(contents), - null, - null, - 1 - ).popUp(this.world(), this.rightCenter().add(new Point(-8, 0))); -}; +new SpeechBubbleMorph(localize(contents), null, null, 1).popUp( +this.world(), this.rightCenter().add(new Point(-8, 0)));}; // MenuItemMorph /////////////////////////////////////////////////////// @@ -8896,8 +8507,7 @@ function MenuItemMorph( italic, doubleClickAction, // optional when used as list morph item shortcut // optional string, Morph, Canvas or tuple: [icon, string] -) { - // additional properties: +) {// additional properties: this.shortcutString = shortcut || null; this.shortcut = null; @@ -8914,29 +8524,24 @@ function MenuItemMorph( bold, italic, doubleClickAction - ); this.cursorStyle = 'pointer'; -} +); this.cursorStyle = 'pointer';}; MenuItemMorph.prototype.createLabel = function () { var w, h; if (this.label) { this.label.destroy(); - } - this.label = this.createLabelPart(this.labelString); + }; this.label = this.createLabelPart(this.labelString); this.add(this.label); w = this.label.width(); h = this.label.height(); if (this.shortcut) { this.shortcut.destroy(); - } - if (this.shortcutString) { + }; if (this.shortcutString) { this.shortcut = this.createLabelPart(this.shortcutString); w += this.shortcut.width() + 4; h = Math.max(h, this.shortcut.height()); this.add(this.shortcut); - } - this.setExtent(new Point(w + 8, h)); -}; + }; this.setExtent(new Point(w + 8, h));}; MenuItemMorph.prototype.fixLayout = function () { var cntr = this.center(); @@ -8945,15 +8550,13 @@ MenuItemMorph.prototype.fixLayout = function () { if (this.shortcut) { this.shortcut.setCenter(cntr); this.shortcut.setRight(this.right() - 4); - } -}; + };}; MenuItemMorph.prototype.createLabelPart = function (source) { var part, icon, lbl; if (isString(source)) { return this.createLabelString(source); - } - if (source instanceof Array) { + }; if (source instanceof Array) { // assume its pattern is: [icon, string] part = new Morph(); part.alpha = 0; // transparent @@ -8966,8 +8569,7 @@ MenuItemMorph.prototype.createLabelPart = function (source) { part.bounds = (icon.bounds.merge(lbl.bounds)); part.rerender(); return part; - } - // assume it's either a Morph or a Canvas + }; // assume it's either a Morph or a Canvas return this.createIcon(source); }; @@ -8977,9 +8579,8 @@ MenuItemMorph.prototype.createIcon = function (source) { if (source instanceof Morph) { return source.fullCopy(); - } - // assume a Canvas - icon = new Morph(); + }; // assume a Canvas + icon = new Morph; icon.isCachingImage = true; icon.cachedImage = source; // should we copy the canvas? icon.bounds.setWidth(source.width); @@ -8994,8 +8595,8 @@ MenuItemMorph.prototype.createLabelString = function (string) { this.fontStyle, this.labelBold, this.labelItalic - ); - lbl.setColor(this.labelColor); + ); lbl.setColor( + this.labelColor); return lbl; }; @@ -9005,19 +8606,16 @@ MenuItemMorph.prototype.mouseEnter = function () { var menu = this.parentThatIsA(MenuMorph); if (this.isShowingSubmenu()) { return; - } - if (menu) { + }; if (menu) { menu.closeSubmenu(); - } - if (!this.isListItem()) { + }; if (!this.isListItem()) { this.userState = 'highlight'; this.rerender(); - } - if (this.action instanceof MenuMorph) { + }; if (this.action instanceof MenuMorph) { this.delaySubmenu(); } else if (this.hint) { this.bubbleHelp(this.hint); - } + }; }; MenuItemMorph.prototype.mouseLeave = function () { @@ -9026,31 +8624,22 @@ MenuItemMorph.prototype.mouseLeave = function () { this.userState = 'highlight'; } else { this.userState = 'normal'; - } - this.rerender(); - } - if (this.schedule) { + }; this.rerender(); + }; if (this.schedule) { this.schedule.isActive = false; - } - if (this.hint) { + }; if (this.hint) { this.world().hand.destroyTemporaries(); - } + }; }; -MenuItemMorph.prototype.mouseDownLeft = function (pos) { - if (this.isListItem()) { - this.parentThatIsA(MenuMorph).unselectAllItems(); - this.escalateEvent('mouseDownLeft', pos); - } - this.userState = 'pressed'; - this.rerender(); -}; +MenuItemMorph.prototype.mouseDownLeft = function ( +pos) {if (this.isListItem()) {this.parentThatIsA( +MenuMorph).unselectAllItems(); this.escalateEvent( +'mouseDownLeft', pos);}; this.userState = 'pressed'; +this.rerender();}; -MenuItemMorph.prototype.mouseMove = function () { - if (this.isListItem()) { - this.escalateEvent('mouseMove'); - } -}; +MenuItemMorph.prototype.mouseMove = function () {if ( +this.isListItem()) {this.escalateEvent('mouseMove');};}; MenuItemMorph.prototype.mouseClickLeft = function () { if (this.action instanceof MenuMorph) { @@ -9059,76 +8648,49 @@ MenuItemMorph.prototype.mouseClickLeft = function () { if (!this.isListItem()) { this.parentThatIsA(MenuMorph).closeRootMenu(); this.world().activeMenu = null; - } - this.trigger(); - } -}; + }; this.trigger();};}; MenuItemMorph.prototype.isListItem = function () { var menu = this.parentThatIsA(MenuMorph); if (menu) { return menu.isListContents; - } - return false; -}; + }; return false;}; MenuItemMorph.prototype.isSelectedListItem = function () { if (this.isListItem()) { return this.userState === 'pressed'; - } - return false; -}; + }; return false;}; MenuItemMorph.prototype.isShowingSubmenu = function () { var menu = this.parentThatIsA(MenuMorph); if (menu && (this.action instanceof MenuMorph)) { return menu.submenu === this.action; - } - return false; -}; + }; return false;}; // MenuItemMorph submenus: MenuItemMorph.prototype.delaySubmenu = function () { - var world = this.world(); - this.schedule = new Animation( - nop, - nop, - 0, - 500, - nop, - () => this.popUpSubmenu() - ); - world.animations.push(this.schedule); -}; +var myself = this; myself.schedule = new Animation( +nop, nop, 0, 500, nop, (() => myself.popUpSubmenu( +))); world.animations.push(this.schedule);}; MenuItemMorph.prototype.popUpSubmenu = function () { - var menu = this.parentThatIsA(MenuMorph), - world = this.world(), - scroller; - - if (!(this.action instanceof MenuMorph)) {return; } - this.action.createItems(); - this.action.setPosition(this.topRight().subtract(new Point(0, 5))); - this.action.addShadow(new Point(2, 2), 80); - this.action.keepWithin(this.world()); - if (this.action.items.length < 1 && !this.action.title) {return; } - - if (this.action.bottom() > world.bottom()) { - // scroll menu items if the menu is taller than the world - this.action.removeShadow(); - scroller = this.action.scroll(); - this.action.bounds.corner.y = world.bottom() - 2; - this.action.addShadow(new Point(2, 2), 80); - scroller.setHeight(world.bottom() - scroller.top() - 6); - scroller.adjustScrollBars(); // ? - } - - menu.add(this.action); - menu.submenu = this.action; - menu.submenu.world = menu.world; // keyboard control - this.action.fullChanged(); -}; +if (this.action instanceof MenuMorph) {var menu = ( +this).parentThatIsA(MenuMorph), world = this.world( +), scroller; this.action.createItems(); (this.action +).setPosition(this.topRight().subtract(new Point(0, +5))); this.action.addShadow(new Point(2, 2), 80); +this.action.keepWithin(this.world()); if ((((this +).action.items.length) < 1) && !(this.action.title +)) {return;}; if (this.action.bottom() > ((world +).bottom())) {this.action.removeShadow(); (scroller +) = this.action.scroll(); (this.action.bounds.corner +).y = world.bottom() - 2; this.action.addShadow( +new Point(2, 2), 80); scroller.setHeight((world +).bottom() - scroller.top() - 6); (scroller +).adjustScrollBars();}; menu.add(this.action); +menu.submenu = this.action; (menu.submenu.world +) = menu.world; this.action.fullChanged();};}; // FrameMorph ////////////////////////////////////////////////////////// @@ -9142,7 +8704,7 @@ FrameMorph.uber = Morph.prototype; function FrameMorph(aScrollFrame) { this.init(aScrollFrame); -} +}; FrameMorph.prototype.init = function (aScrollFrame) { this.scrollFrame = aScrollFrame || null; @@ -9152,130 +8714,88 @@ FrameMorph.prototype.init = function (aScrollFrame) { this.acceptsDrops = true; if (this.scrollFrame) { - this.isDraggable = false; - this.alpha = 0; - } -}; + this.isDraggable = false; + this.alpha = 0;};}; FrameMorph.prototype.fullBounds = function () { - var shadow = this.getShadow(); - if (shadow !== null) { - return this.bounds.merge(shadow.bounds); - } - return this.bounds; -}; +var shadow = this.getShadow(); if (isNil(shadow +)) {return this.bounds;} else {return (((this +).bounds).merge(shadow.bounds));};}; -FrameMorph.prototype.fullImage = function () { - // use only for shadows - return this.getImage(); -}; +FrameMorph.prototype.fullImage = FrameMorph.prototype.getImage; FrameMorph.prototype.fullDrawOn = function (ctx, aRect) { var shadow, clipped; - if (!this.isVisible) {return; } + if (!this.isVisible) {return;}; clipped = this.bounds.intersect(aRect); - if (!clipped.extent().gt(ZERO)) {return; } + if (!clipped.extent().gt(ZERO)) {return;}; this.drawOn(ctx, clipped); this.children.forEach(child => { if (child instanceof ShadowMorph) { shadow = child; } else { child.fullDrawOn(ctx, clipped); - } - }); - if (shadow) { + }; + }); if (shadow) { shadow.drawOn(ctx, aRect); - } -}; +};}; // FrameMorph navigation: -FrameMorph.prototype.topMorphAt = function (point) { - var i, result; - if (!(this.isVisible && this.bounds.containsPoint(point))) { - return null; - } - for (i = this.children.length - 1; i >= 0; i -= 1) { - result = this.children[i].topMorphAt(point); - if (result) {return result; } - } - if (this.isFreeForm) { - return this.isTransparentAt(point) ? null : this; - } - return this; -}; +FrameMorph.prototype.topMorphAt = function ( +point) {var i, result; if (!((this.isVisible +) && this.bounds.containsPoint(point))) { +return null;}; for (i = ((this.children +).length - 1); i >= 0; i -= 1) {(result +) = this.children[i].topMorphAt(point +); if (result) {return result;};}; +if (this.isFreeForm) {return ((this +).isTransparentAt(point) ? (null +) : this);}; return this;}; // FrameMorph scrolling support: FrameMorph.prototype.submorphBounds = function () { - var result = null; - - if (this.children.length > 0) { - result = this.children[0].bounds; - this.children.forEach(child => { - result = result.merge(child.fullBounds()); - }); - } - return result; -}; +var result = null; if ((this.children).length > 0 +) {result = this.children[0].bounds; (this.children +).forEach(child => {result = result.merge((child +).fullBounds());});}; return result;}; FrameMorph.prototype.keepInScrollFrame = function () { - if (this.scrollFrame === null) { - return null; - } + if (isNil(this.scrollFrame)) {return null;} else { if (this.left() > this.scrollFrame.left()) { this.moveBy( new Point(this.scrollFrame.left() - this.left(), 0) ); - } - if (this.right() < this.scrollFrame.right()) { + }; if (this.right() < this.scrollFrame.right()) { this.moveBy( new Point(this.scrollFrame.right() - this.right(), 0) ); - } - if (this.top() > this.scrollFrame.top()) { + }; if (this.top() > this.scrollFrame.top()) { this.moveBy( new Point(0, this.scrollFrame.top() - this.top()) ); - } - if (this.bottom() < this.scrollFrame.bottom()) { + }; if (this.bottom() < this.scrollFrame.bottom()) { this.moveBy( - 0, - new Point(this.scrollFrame.bottom() - this.bottom(), 0) + new Point(0, this.scrollFrame.bottom() - this.bottom()) ); - } + };}; }; FrameMorph.prototype.adjustBounds = function () { - var subBounds, - newBounds; - - if (this.scrollFrame === null) {return; } - subBounds = this.submorphBounds(); - if (subBounds && (!this.scrollFrame.isTextLineWrapping)) { - newBounds = subBounds - .expandBy(this.scrollFrame.padding) - .growBy(this.scrollFrame.growth) - .merge(this.scrollFrame.bounds); - } else { - newBounds = this.scrollFrame.bounds.copy(); - } - if (!this.bounds.eq(newBounds)) { - this.bounds = newBounds; - this.keepInScrollFrame(); - } - if (this.scrollFrame.isTextLineWrapping) { - this.children.forEach(morph => { - if (morph instanceof TextMorph) { - morph.setWidth(this.width()); - this.setHeight( - Math.max(morph.height(), this.scrollFrame.height()) - ); - } - }); - } - this.scrollFrame.adjustScrollBars(); -}; +var subBounds, newBounds; if (!isNil(this.scrollFrame +)) {subBounds = this.submorphBounds(); if (subBounds && ( +!((this.scrollFrame).isTextLineWrapping))) {newBounds = ( +subBounds).expandBy((this.scrollFrame).padding).growBy( +(this.scrollFrame).growth).merge(this.scrollFrame.bounds +);} else {newBounds = this.scrollFrame.bounds.copy();}; +if (!this.bounds.eq(newBounds)) {this.bounds = newBounds; +this.keepInScrollFrame();}; if ((this.scrollFrame +).isTextLineWrapping) {this.children.forEach((morph +) => {if (morph instanceof TextMorph) {morph.setWidth( +this.width()); this.setHeight(Math.max(morph.height(), +this.scrollFrame.height()));};});}; (this.scrollFrame +).adjustScrollBars();};}; // FrameMorph dragging & dropping of contents: @@ -9308,7 +8828,7 @@ FrameMorph.prototype.keepAllSubmorphsWithin = function () { // ScrollFrameMorph //////////////////////////////////////////////////// -ScrollFrameMorph.prototype = new FrameMorph(); +ScrollFrameMorph.prototype = new FrameMorph; ScrollFrameMorph.prototype.constructor = ScrollFrameMorph; ScrollFrameMorph.uber = FrameMorph.prototype; @@ -9318,7 +8838,7 @@ function ScrollFrameMorph(scroller, size, sliderColor) { ScrollFrameMorph.prototype.init = function (scroller, size, sliderColor) { ScrollFrameMorph.uber.init.call(this); - this.scrollBarSize = size || MorphicPreferences.scrollBarSize; + this.scrollBarSize = Math.round(size) || MorphicPreferences.scrollBarSize; this.autoScrollTrigger = null; this.enableAutoScrolling = true; // change to suppress this.isScrollingByDragging = true; // change to suppress @@ -9335,8 +8855,7 @@ ScrollFrameMorph.prototype.init = function (scroller, size, sliderColor) { null, // size 'horizontal', sliderColor - ); - this.hBar.setHeight(this.scrollBarSize); + ); this.hBar.setHeight(this.scrollBarSize); this.hBar.action = (num) => { this.contents.setPosition( new Point( @@ -9344,8 +8863,7 @@ ScrollFrameMorph.prototype.init = function (scroller, size, sliderColor) { this.contents.position().y ) ); - }; - this.hBar.isDraggable = false; + }; this.hBar.isDraggable = false; this.add(this.hBar); this.vBar = new SliderMorph( null, // start @@ -9354,8 +8872,7 @@ ScrollFrameMorph.prototype.init = function (scroller, size, sliderColor) { null, // size 'vertical', sliderColor - ); - this.vBar.setWidth(this.scrollBarSize); + ); this.vBar.setWidth(this.scrollBarSize); this.vBar.action = (num) => { this.contents.setPosition( new Point( @@ -9363,81 +8880,56 @@ ScrollFrameMorph.prototype.init = function (scroller, size, sliderColor) { this.top() - num ) ); - }; - this.vBar.isDraggable = false; - this.add(this.vBar); - this.toolBar = null; // optional slot -}; + }; this.vBar.isDraggable = false; + this.add(this.vBar); (this + ).toolBar = null;}; -ScrollFrameMorph.prototype.adjustScrollBars = function () { - var hWidth = this.width() - this.scrollBarSize, - vHeight = this.height() - this.scrollBarSize; +ScrollFrameMorph.prototype.adjustScrollBars = function ( +) {var hWidth = this.width() - this.scrollBarSize, +vHeight = this.height() - this.scrollBarSize; this.changed(); if (this.contents.width() > this.width()) { this.hBar.show(); if (this.hBar.width() !== hWidth) { this.hBar.setWidth(hWidth); - } - - this.hBar.setPosition( + }; this.hBar.setPosition( new Point( this.left(), - this.bottom() - this.hBar.height() - ) - ); - this.hBar.start = 0; - this.hBar.stop = this.contents.width() - - this.width() + - this.scrollBarSize; - this.hBar.size = - this.width() / this.contents.width() * this.hBar.stop; + this.bottom() - this.hBar.height()) + ); this.hBar.start = 0; + this.hBar.stop = Math.round(this.contents.width( + ) - this.width()) + this.scrollBarSize; + this.hBar.size = Math.round( + this.width() / this.contents.width() * this.hBar.stop); this.hBar.value = this.left() - this.contents.left(); this.hBar.fixLayout(); } else { this.hBar.hide(); - } - - if (this.contents.height() > this.height()) { + }; if (this.contents.height() > this.height()) { this.vBar.show(); if (this.vBar.height() !== vHeight) { this.vBar.setHeight(vHeight); - } - - this.vBar.setPosition( + }; this.vBar.setPosition( new Point( this.right() - this.vBar.width(), - this.top() - ) - ); - this.vBar.start = 0; - this.vBar.stop = this.contents.height() - - this.height() + - this.scrollBarSize; - this.vBar.size = - this.height() / this.contents.height() * this.vBar.stop; + this.top()) + ); this.vBar.start = 0; + this.vBar.stop = Math.round(this.contents.height( + ) - this.height()) + this.scrollBarSize; + this.vBar.size = Math.round( + this.height() / this.contents.height() * this.vBar.stop); this.vBar.value = this.top() - this.contents.top(); this.vBar.fixLayout(); - } else { - this.vBar.hide(); - } - this.adjustToolBar(); -}; + } else {this.vBar.hide(); + }; this.adjustToolBar();}; ScrollFrameMorph.prototype.adjustToolBar = function () { - var padding = 3; - if (this.toolBar) { - this.toolBar.setTop(this.top() + padding); - this.toolBar.setRight( - (this.vBar.isVisible ? this.vBar.left() : this.right()) - padding - ); - } -}; - -ScrollFrameMorph.prototype.addContents = function (aMorph) { - this.contents.add(aMorph); - this.contents.adjustBounds(); -}; +var padding = 3; if (this.toolBar) {this.toolBar.setTop( +this.top() + padding); this.toolBar.setRight(((this.vBar +).isVisible ? this.vBar.left() : this.right()) - padding +);};}; ScrollFrameMorph.prototype.addContents = function ( +aMorph) {this.contents.add(aMorph); this.contents.adjustBounds();}; ScrollFrameMorph.prototype.setContents = function (aMorph) { this.contents.children.forEach(m => m.destroy()); @@ -9474,7 +8966,7 @@ ScrollFrameMorph.prototype.scrollX = function (steps) { if (newX > l) { newX = l; }; - if (newX !== cl) { + if (!(newX == cl)) { this.contents.setLeft(newX); }; }; @@ -9497,7 +8989,7 @@ ScrollFrameMorph.prototype.scrollY = function (steps) { if (newY > t) { newY = t; }; - if (newY !== ct) { + if (!(newY == ct)) { this.contents.setTop(newY); }; }; @@ -10223,7 +9715,7 @@ HandMorph.prototype.drop = function () { morphToDrop.removeShadow(); } this.children = []; - this.setExtent(new Point()); + this.setExtent(new Point); if (morphToDrop.justDropped) { morphToDrop.justDropped(this); } @@ -10799,13 +10291,11 @@ HandMorph.prototype.processDrop = function (event) { } img = new Image(); img.onload = () => { - canvas = newCanvas(new Point(img.width, img.height), true); - canvas.getContext('2d').drawImage(img, 0, 0); - target.droppedImage(canvas); - }; - src = parseImgURL(txt); - if (src) {img.src = src; } - } + canvas = newCanvas(new Point(img.width, img.height), + true); canvas.getContext('2d').drawImage(img, 0, 0); + target.droppedImage(canvas);}; src = parseImgURL( + txt); if (src) {img.src = src;}; + }; }; // HandMorph tools @@ -10822,7 +10312,7 @@ HandMorph.prototype.destroyTemporaries = function () { && morph.bounds.containsPoint(this.position()))) { morph.destroy(); this.temporaries.splice(this.temporaries.indexOf(morph), 1); - } + }; }); }; @@ -10836,21 +10326,18 @@ FPSMorph = function FPSMorph () {this.init( );}; FPSMorph.prototype = new StringMorph; FPSMorph.prototype.constructor = FPSMorph; FPSMorph.uber = StringMorph.prototype; -FPSMorph.prototype.init = function anonymous () { -FPSMorph.uber.init.call(this); this.frameCounter = 0; -this.isVisible = false; this.fontSize = 22; -this.startTime = Date.now();}; -FPSMorph.prototype.step = function anonymous ( -) {this.frameCounter++; if (!(Date.now() < ( -this.startTime + 1000))) {this.text = ('FPS\: ' -.concat(this.frameCounter)); this.fixLayout( -); if (this.parent instanceof Morph -) {this.setLeft(this.parent.left()); -this.setBottom(this.parent.bottom( -)); this.parent.add(this);}; if ( -!this.isVisible) {this.isVisible = true; -}; this.frameCounter = 0; -this.startTime = Date.now();};}; +FPSMorph.prototype.init = function ( +) {FPSMorph.uber.init.call(this); (this +).startTime = performance.now(); (this +).isVisible = false; this.fontSize = 22; +}; FPSMorph.prototype.step = function () { +this.text = (('FPS\: ').concat(Math.round( +((performance.now() - this.startTime) > 0) ? ( +1000 / (performance.now() - this.startTime)) : 0 +).toString())); this.fixLayout(); if ((this.parent +) instanceof Morph) {this.setLeft(this.parent.left() +); this.setBottom(this.parent.bottom()); (this.parent +).add(this); this.isVisible = true; this.startTime = performance.now();};}; // WorldMorph ////////////////////////////////////////////////////////// @@ -10872,53 +10359,38 @@ function WorldMorph(aCanvas, fillPage) {this.init(aCanvas, fillPage);}; // WorldMorph initialization: -WorldMorph.prototype.init = function anonymous (aCanvas, fillPage) { - WorldMorph.uber.init.call(this); - var wrrld = this; - this.color = new Color(205, 205, 205); - this.alpha = 1; - this.bounds = new Rectangle(0, 0, aCanvas.width, aCanvas.height); - this.isVisible = true; - this.isDraggable = false; - this.currentKey = null; // currently pressed key code - this.worldCanvas = aCanvas; - this.worldCanvas.getContext("2d", { - willReadFrequently: true}); - - // additional properties: - this.stamp = Date.now(); // reference in multi-world setups - while (this.stamp === Date.now()) {nop();}; - this.stamp = Date.now(); - - this.useFillPage = fillPage; - if (isNil(this.useFillPage)) { - this.useFillPage = true;}; - this.isDevMode = false; - this.broken = []; - this.animations = []; - this.hand = new HandMorph(this); - this.keyboardHandler = null; - this.keyboardFocus = null; - this.cursor = null; - this.lastEditedText = null; - this.activeMenu = null; - this.activeHandle = null; - - this.initKeyboardHandler(); - this.resetKeyboardHandler(); - this.initEventListeners(); - if("getBattery" in navigator) {navigator.getBattery( - ).then(battery => {wrrld.batteryAPI = battery;});}; -}; - -WorldMorph.prototype.beepSound = document.createElement('audio'); -WorldMorph.prototype.beepSound.src = 'src/beep.wav'; +WorldMorph.prototype.init = function (aCanvas, +fillPage) {WorldMorph.uber.init.call(this); ( +this).color = new Color(205, 205, 205); (this +).alpha = 1; this.bounds = new Rectangle(0, +0, aCanvas.width, aCanvas.height); (this +).isVisible = true; this.isDraggable = false; +this.currentKey = null; this.worldCanvas = ( +aCanvas); this.worldCanvas.getContext("2d", { +willReadFrequently: true}); this.useFillPage = ( +fillPage); if (isNil(this.useFillPage)) {(this +).useFillPage = true;}; this.isDevMode = false; +this.broken = []; this.animations = []; (this.hand +) = new HandMorph(this); this.keyboardHandler = ( +null); this.keyboardFocus = null; this.cursor = ( +null); (this.lastEditedText) = null; (this +).activeMenu = null; this.activeHandle = ( +null); this.initKeyboardHandler(); ((this +).resetKeyboardHandler)(); (this +).initEventListeners(); if ( +"getBattery" in navigator) { +navigator.getBattery().then( +battery => {(this.batteryAPI +) = battery;});};}; + +WorldMorph.prototype.beepSound = document.createElement( +'audio'); WorldMorph.prototype.beepSound.src = 'src/beep.wav'; // World Morph display: -WorldMorph.prototype.fullDrawOn = function anonymous (aContext, aRect -) {WorldMorph.uber.fullDrawOn.call(this, aContext, aRect); -this.hand.fullDrawOn(aContext, aRect);}; +WorldMorph.prototype.fullDrawOn = function (aContext, aRect +) {WorldMorph.uber.fullDrawOn.call(this, aContext, aRect +); this.hand.fullDrawOn(aContext, aRect);}; WorldMorph.prototype.updateBroken = function () { var ctx = this.worldCanvas.getContext('2d'); @@ -11277,7 +10749,7 @@ menu = new MenuMorph(this, this.constructor.name || this.constructor.toString(). menu.addItem("demo...", 'userCreateMorph', 'sample morphs'); menu.addLine(); menu.addItem("hide all...", 'hideAll'); - menu.addItem("show all...", 'showAllHiddens'); + menu.addItem("show all...", 'showAll'); menu.addItem( "move all inside...", 'keepAllSubmorphsWithin', @@ -11506,32 +10978,16 @@ WorldMorph.prototype.userCreateMorph = function () { WorldMorph.prototype.toggleDevMode = function () {this.isDevMode = !this.isDevMode;}; -WorldMorph.prototype.hideAll = function () {this.children.forEach(child => child.hide());}; +WorldMorph.prototype.hideAll = function () { +this.children.forEach(child => child.hide());}; -WorldMorph.prototype.showAllHiddens = function () {this.forAllChildren(child => {if (!child.isVisible) {child.show();};});}; +WorldMorph.prototype.showAll = function ( +) {this.forAllChildren(child => child.show());}; WorldMorph.prototype.about = function () { - var versions = '', module; - - for (module in modules) { - if (Object.prototype.hasOwnProperty.call(modules, module)) { - versions += ('\n' + module + ' (' + modules[module] + ')'); - } - } - if (versions !== '') { - versions = '\n\nmodules:\n\n' + - 'morphic (' + morphicVersion + ')' + - versions; - } - - this.inform( - 'morphic.js\n\n' + - 'a lively Web GUI\ninspired by Squeak\n' + - morphicVersion + - '\n\nwritten by Jens M\u00F6nig\njens@moenig.org' + - versions - ); -}; +this.inform('morphic.js\n\na lively Web' + +' GUI\ninspired by Squeak\n\n\nwritten ' + +'by Jens Mönig\njens@moenig.org');}; WorldMorph.prototype.edit = function (aStringOrTextMorph) { if (this.lastEditedText === aStringOrTextMorph) { @@ -11623,4 +11079,140 @@ WorldMorph.prototype.stopEditing = function () { WorldMorph.prototype.toggleBlurredShadows = function anonymous () {useBlurredShadows = !useBlurredShadows;}; WorldMorph.prototype.toggleHolesDisplay = function () {MorphicPreferences.showHoles = !MorphicPreferences.showHoles; this.rerender();}; WorldMorph.prototype.togglePreferences = function () {if (MorphicPreferences === standardSettings -) {MorphicPreferences = touchScreenSettings;} else {MorphicPreferences = standardSettings;};}; /* Check this file out! */ \ No newline at end of file +) {MorphicPreferences = touchScreenSettings;} else {MorphicPreferences = standardSettings;};}; /* Check this file out! */ + +/* Saving script by default. */ var saveAs = saveAs || function(e) { + "use strict"; + if (typeof e === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { + return + } + var t = e.document + , n = function() { + return e.URL || e.webkitURL || e + } + , r = t.createElementNS("http://www.w3.org/1999/xhtml", "a") + , o = "download"in r + , a = function(e) { + var t = new MouseEvent("click"); + e.dispatchEvent(t) + } + , i = /constructor/i.test(e.HTMLElement) || e.safari + , f = /CriOS\/[\d]+/.test(navigator.userAgent) + , u = function(t) { + (e.setImmediate || e.setTimeout)(function() { + throw t + }, 0) + } + , s = "application/octet-stream" + , d = 1e3 * 40 + , c = function(e) { + var t = function() { + if (typeof e === "string") { + n().revokeObjectURL(e) + } else { + e.remove() + } + }; + setTimeout(t, d) + } + , l = function(e, t, n) { + t = [].concat(t); + var r = t.length; + while (r--) { + var o = e["on" + t[r]]; + if (typeof o === "function") { + try { + o.call(e, n || e) + } catch (a) { + u(a) + } + } + } + } + , p = function(e) { + if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)) { + return new Blob([String.fromCharCode(65279), e],{ + type: e.type + }) + } + return e + } + , v = function(t, u, d) { + if (!d) { + t = p(t) + } + var v = this, w = t.type, m = w === s, y, h = function() { + l(v, "writestart progress write writeend".split(" ")) + }, S = function() { + if ((f || m && i) && e.FileReader) { + var r = new FileReader; + r.onloadend = function() { + var t = f ? r.result : r.result.replace(/^data:[^;]*;/, "data:attachment/file;"); + var n = e.open(t, "_blank"); + if (!n) + e.location.href = t; + t = undefined; + v.readyState = v.DONE; + h() + } + ; + r.readAsDataURL(t); + v.readyState = v.INIT; + return + } + if (!y) { + y = n().createObjectURL(t) + } + if (m) { + e.location.href = y + } else { + var o = e.open(y, "_blank"); + if (!o) { + e.location.href = y + } + } + v.readyState = v.DONE; + h(); + c(y) + }; + v.readyState = v.INIT; + if (o) { + y = n().createObjectURL(t); + setTimeout(function() { + r.href = y; + r.download = u; + a(r); + h(); + c(y); + v.readyState = v.DONE + }); + return + } + S() + } + , w = v.prototype + , m = function(e, t, n) { + return new v(e,t || e.name || "download",n) + }; + if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { + return function(e, t, n) { + t = t || e.name || "download"; + if (!n) { + e = p(e) + } + return navigator.msSaveOrOpenBlob(e, t) + } + } + w.abort = function() {} + ; + w.readyState = w.INIT = 0; + w.WRITING = 1; + w.DONE = 2; + w.error = w.onwritestart = w.onprogress = w.onwrite = w.onabort = w.onerror = w.onwriteend = null; + return m +}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content); +if (typeof module !== "undefined" && module.exports) { + module.exports.saveAs = saveAs +} else if (typeof define !== "undefined" && define !== null && define.amd !== null) { + define("FileSaver.js", (() => saveAs)) +}; \ No newline at end of file diff --git a/src/motors.js b/src/motors.js index 4acb4ce..65b4187 100644 --- a/src/motors.js +++ b/src/motors.js @@ -7,11 +7,11 @@ written by Alessandro Moisés aless01pime@gmail.com - Copyright (C) 2022 by Alessandro Moisés + Copyleft (Ɔ) 2024 by Alessandro Moisés This file is part of Snap!. - Snap! is free software: you can redistribute it and/or modify + Snavanced! is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. @@ -40,17 +40,8 @@ */ -// Global settings ///////////////////////////////////////////////////// - -/*global modules, Process, contains*/ - -/*jshint esversion: 11*/ - -modules.motors = '2022-November-15'; - -// Global stuff - -/* You can contribute to add motors in Snap!, the blocks are implemented yet, but not the code of the blocks, please put your code here. :) */ +/* You can contribute to add motors in Snap!, the blocks are implemented +yet, but not the code of them, please put your code here. :) */ Process.prototype.motorOnAndWait = function anonymous (seconds) {}; diff --git a/src/objects.js b/src/objects.js index 48cb80f..f45bcf0 100644 --- a/src/objects.js +++ b/src/objects.js @@ -37,10 +37,10 @@ the following list shows the order in which all constructors are defined. Use this list to locate code in this document: + TimerFunction SpriteMorph SpriteHighlightMorph StageMorph - TimerFunction Costume SVG_Costume CostumeEditorMorph @@ -50,6 +50,8 @@ CellMorph WatcherMorph StagePrompterMorph + Project + Scene SpeechBubbleMorph* SpriteBubbleMorph @@ -61,9 +63,16 @@ ------- Ian Reynolds contributed initial porting of primitives from Squeak and sound handling + ///////////////////////////////////////////////////////////////////////// Achal Dave contributed research and prototyping for creating music using the Web Audio API + ///////////////////////////////////////////////////////////////////////// Yuan Yuan and Dylan Servilla contributed graphic effects for costumes + ///////////////////////////////////////////////////////////////////////// + scenes have been inspired by Ted Kaehlers's personal demos of HyperCard + and many discussions with Ted about the design and practice of HyperCard, + and by personal discussions with Wolfgang Slany about his design of + scenes in Catrobat/PocketCode, which I love and admire. */ @@ -76,24 +85,24 @@ CellMorph, WatcherMorph, StagePrompterMorph, Note, SpriteHighlightMorph; function TimerFunction () {if (isNil(new.target)) {throw Error( 'Please use the \"new\" operator.');} else {this.stopNow();};}; -TimerFunction.prototype.getTime = function anonymous () {if (this.state === 'paused') { -var result = (this.pauseTime - this.resumeTime);} else {var result = (Date.now() - -this.resumeTime);}; result = (isNaN(result) ? 0 : result); return result;}; +TimerFunction.prototype.getTime = function () {if (this.state === 'paused') { +var result = (this.pauseTime - this.resumeTime);} else {var result = (Date.now( +) - this.resumeTime);}; result = (isNaN(result) ? 0 : result); return result;}; -TimerFunction.prototype.startNow = function anonymous () {this.stopNow(); this.resumeNow();}; +TimerFunction.prototype.startNow = function () {this.stopNow(); this.resumeNow();}; -TimerFunction.prototype.pauseNow = function anonymous () {if (this.state === 'running') { -this.pauseTime = Date.now(); this.state = 'paused';};}; +TimerFunction.prototype.pauseNow = function () {if (this.state === 'running' +) {this.pauseTime = Date.now(); this.state = 'paused';};}; -TimerFunction.prototype.resumeNow = function anonymous () {if (this.state === 'paused') { -this.resumeTime = ((Date.now() - this.pauseTime) + this.resumeTime); this.state = 'running';};}; +TimerFunction.prototype.resumeNow = function () {if (this.state === 'paused') {this.resumeTime = ( +(Date.now() - this.pauseTime) + this.resumeTime); this.state = 'running';};}; -TimerFunction.prototype.stopNow = function anonymous () {this.startTime = Date.now(); +TimerFunction.prototype.stopNow = function () {this.startTime = Date.now(); this.pauseTime = this.startTime; this.resumeTime = this.pauseTime; this.state = 'paused';}; -TimerFunction.prototype.toString = function anonymous () {return ('timer function \(\) \{return ').concat((this.getTime() / 1000), '\;\}');}; +TimerFunction.prototype.toString = function () {return ('timer function \(\) \{return ').concat((this.getTime() / 1000), '\;\}');}; -TimerFunction.prototype.toCronoString = function anonymous (optionalNumber) {if (isNil(optionalNumber)) {var currentTime = this.getTime() / 1000;} else { +TimerFunction.prototype.toCronoString = function (optionalNumber) {if (isNil(optionalNumber)) {var currentTime = this.getTime() / 1000;} else { var currentTime = +optionalNumber;}; return ''.concat(((((currentTime / 3600) % 24) < 10) ? '0' : ''), Math.trunc((currentTime / 3600) % 24).toString(), 'H ', ((((currentTime / 60) % 60) < 10) ? '0' : ''), Math.trunc((currentTime / 60) % 60).toString(), 'M ', (((currentTime % 60) < 10) ? '0' : ''), Math.trunc(currentTime % 60).toString(), 'S ', ((((currentTime * 1000) % 1000) < 100) ? '0' : ''), ((((currentTime * 1000) % 1000) < 10) ? '0' : ''), @@ -108,7 +117,7 @@ aColor); result.addBack(new TextMorph(' RGBA (' + Math.round(aColor.r) + ', Math.round(aColor.b) + ', ' + (Math.round(aColor.a * 100) / 100) + ')')); result.add(new SymbolMorph('rectangle', MorphicPreferences.menuFontSize * 1.25)); return result;}; function BooleanImageMorph (bool) {return new SymbolMorph( (bool ? 'tick' : 'crok'), (MorphicPreferences.menuFontSize * SyntaxElementMorph.prototype.scale * 1.5), ( -bool ? new Color(0, 200, 0) : new Color(200, 0, 0)));}; /* These morphs represent some important objects.*/ +bool ? new Color(0, 200, 0) : new Color(200, 0, 0)));}; /* These morphs represent some important objects. */ // SpriteMorph ///////////////////////////////////////////////////////// @@ -128,14 +137,14 @@ SpriteMorph.prototype.categories = ['motion', 'motor', 'control', 'looks', 'sens motor : new Color((74 / 1.5), (108 / 1.5), (212 / 1.25)), looks : new Color(143, 86, 227), sound : new Color(207, 74, 217), pen : new Color(0, 161, 120), events : new Color(200, 131, 48), control : new Color(230, 168, 0), sensing : new Color(4, 148, 220), operators : new Color(98, 194, 19), variables : new Color(243, 118, 29), lists : new Color(217, 77, 17), other: (SyntaxElementMorph.prototype.rfColor).lighter().lighter(10), custom : new Color(243, 118, 29).darker().darker().darker().darker(), undefined: new Color(200, -0, 0)}; SpriteMorph.prototype.customCategories = new Map; SpriteMorph.prototype.allCategories = function anonymous () {return this.categories.concat(Array.from( -this.customCategories.keys()));}; SpriteMorph.prototype.allSortedCategories = function anonymous () {return this.sortedCategories.concat(Array.from(this.customCategories.keys( -)));}; SpriteMorph.prototype.blockColorFor = function (category) {return ((this.blockColor[category]) || (this.customCategories.get(category)) || (this.blockColor.other));}; -SpriteMorph.prototype.paletteColor = new Color(55, 55, 55); SpriteMorph.prototype.paletteTextColor = new Color(230, 230, 230, 1); SpriteMorph.prototype.sliderColor = SpriteMorph.prototype.paletteColor.lighter( +0, 0)}; SpriteMorph.prototype.customCategories = new Map; SpriteMorph.prototype.allCategories = function () {return this.categories.concat(Array.from((this.customCategories +).keys()));}; SpriteMorph.prototype.allSortedCategories = function () {return this.sortedCategories.concat(Array.from(this.customCategories.keys()));}; (SpriteMorph.prototype +).blockColorFor = function (category) {return ((this.blockColor[category]) || (this.customCategories.get(category)) || (this.blockColor.other));}; (SpriteMorph.prototype +).paletteColor = new Color(55, 55, 55); SpriteMorph.prototype.paletteTextColor = new Color(230, 230, 230, 1); SpriteMorph.prototype.sliderColor = SpriteMorph.prototype.paletteColor.lighter( 30); SpriteMorph.prototype.isCachingPrimitives = true; SpriteMorph.prototype.enableNesting = true; SpriteMorph.prototype.enableFirstClass = true; SpriteMorph.prototype.showingExtensions = false; SpriteMorph.prototype.useFlatLineEnds = false; SpriteMorph.prototype.penColorModel = 'hsv'; SpriteMorph.prototype.highlightColor = new Color(250, 200, 130); SpriteMorph.prototype.highlightBorder = 8; -SpriteMorph.prototype.bubbleColor = WHITE; SpriteMorph.prototype.bubbleFontSize = 14; SpriteMorph.prototype.bubbleCorner = 10; SpriteMorph.prototype.bubbleBorder = 3; -SpriteMorph.prototype.bubbleBorderColor = new Color(190, 190, 190); SpriteMorph.prototype.bubbleMaxTextWidth = 130; SpriteMorph.prototype.initBlocks = function anonymous () { +SpriteMorph.prototype.bubbleColor = WHITE; SpriteMorph.prototype.bubbleFontSize = 14; SpriteMorph.prototype.bubbleCorner = 10; SpriteMorph.prototype.bubbleBorder = 3; (SpriteMorph +).prototype.bubbleBorderColor = new Color(190, 190, 190); SpriteMorph.prototype.bubbleMaxTextWidth = 130; SpriteMorph.prototype.initBlocks = function () { SpriteMorph.prototype.blocks = { // Motion - Sprite @@ -539,7 +548,7 @@ SpriteMorph.prototype.blocks = { type: 'command', category: 'sound', spec: 'play %n Hz for %n secs', - defaults: [MIDSoundSystem.basicHertzValue, 2] + defaults: [256, 2] }, doSetInstrument: { type: 'command', @@ -602,7 +611,7 @@ SpriteMorph.prototype.blocks = { type: 'command', category: 'sound', spec: 'play frequency %n Hz', - defaults: [MIDSoundSystem.basicHertzValue] + defaults: [256] }, stopFreq: { type: 'command', @@ -765,7 +774,7 @@ SpriteMorph.prototype.blocks = { colorAttr: { type: 'reporter', category: 'pen', - spec: '%colorAttrs of color %clr', + spec: '%colorAttrs of %clr', defaults: [localize('hex')] }, clrFlags: { @@ -1228,7 +1237,7 @@ SpriteMorph.prototype.blocks = { type: 'command', category: 'sensing', spec: 'ask %s and wait', - defaults: [localize('what\'s your name?')] + defaults: [localize('What is your own name?')] }, getLastAnswer: { type: 'reporter', @@ -1748,6 +1757,46 @@ SpriteMorph.prototype.blocks = { spec: 'clone' }, + /* + // math.js Library + VariadicAddition : { + type : 'reporter', + category : 'operators', + spec : '%bignum + %bignum' + }, + HyperSubtraction : { + type : 'reporter', + category : 'operators', + spec : '%bignum − %bignum' + }, + VariadicBigMultiplication : { + type : 'reporter', + category : 'operators', + spec : '%bignum * %bignum' + }, + HyperBigDivision : { + type : 'reporter', + category : 'operators', + spec : '%bignum ÷ %bignum' + }, + HyperBigExponentiation : { + type : 'reporter', + category : 'operators', + spec : '%bignum ^ %bignum' + }, + HyperBigRadication : { + type : 'reporter', + category : 'operators', + spec : '%bignum √ %bignum' + }, + HyperBigLogarithm : { + type : 'reporter', + category : 'operators', + spec : '%bignum log %bignum' + }, + */ + + // Variables doSetVar: { type: 'command', @@ -2032,7 +2081,7 @@ SpriteMorph.prototype.blocks = { callMeWith: { type: 'reporter', category: 'random', - spec: 'Wow, you\'re a smart one. Now call ME %s !' + spec: 'Wow, you are a smart one. Now call ME %s !' }, runMeWith: { type: 'command', @@ -2672,12 +2721,11 @@ SpriteMorph.prototype.fixLayout = function () { stageScale = this.parent instanceof StageMorph ? this.parent.scale : 1; facing = this.rotationStyle ? this.heading : 90; - if (this.rotationStyle === 2) { - facing = 90; - if ((this.heading > 180 && (this.heading < 360)) - || (this.heading < 0 && (this.heading > -180))) { - isFlipped = true; - }; + if (this.rotationStyle === 2) {facing = 90; + this.heading = ((this.heading < 0) ? ( + 360 - (Math.abs(this.heading) % 360)) : ( + this.heading % 360)); isFlipped = !( + this.heading < 180); /* Very good! */ }; if (this.costume && !isLoadingCostume) { pic = isFlipped ? this.costume.flipped() : this.costume; @@ -2753,23 +2801,22 @@ SpriteMorph.prototype.render = function (ctx) { stageScale, handle; + ctx.imageSmoothingEnabled = false; isLoadingCostume = this.costume && typeof this.costume.loaded === 'function'; stageScale = this.parent instanceof StageMorph ? this.parent.scale : 1; facing = this.rotationStyle ? this.heading : 90; - if (this.rotationStyle === 2) { - facing = 90; - if ((this.heading > 180 && (this.heading < 360)) - || (this.heading < 0 && (this.heading > -180))) { - isFlipped = true; - } - } - if (this.costume && !isLoadingCostume) { - pic = isFlipped ? this.costume.flipped() : this.costume; - ctx.save(); + if (this.rotationStyle === 2) {facing = 90; + this.heading = ((this.heading < 0) ? ( + 360 - (Math.abs(this.heading) % 360)) : ( + this.heading % 360)); isFlipped = !( + this.heading < 180); /* Very good! */ + }; if (this.costume && !isLoadingCostume) { + pic = isFlipped ? this.costume.flipped() : this.costume; ctx.save(); ctx.scale(this.scale * stageScale, this.scale * stageScale); - ctx.translate(this.imageOffset.x, this.imageOffset.y); + ctx.translate(Math.round((this.imageOffset).x), + Math.round((this.imageOffset).y)); ctx.rotate(radians(facing - 90)); ctx.drawImage(pic.contents, 0, 0); ctx.restore(); @@ -2817,8 +2864,7 @@ SpriteMorph.prototype.getImageData = function () { 0, 0, Math.floor(ext.x), Math.floor(ext.y), 0, 0, newExtent.x, newExtent.y - ); - imageData = canvasContext.getImageData( + ); imageData = canvasContext.getImageData( 0, 0, newExtent.x, @@ -2960,7 +3006,7 @@ category = 'other', all = false) {var blocks = [], myself = this, varNames, inhe }; SnapExtensions.buttons.palette.forEach(buttonDescriptor => { if (buttonDescriptor.category === category) { blocks.push(this.customPaletteButton(buttonDescriptor)); - } + }; }); if (category === 'motion') { if (this instanceof StageMorph) { } else {blocks.push(this.subCategoryText('Motion')); @@ -3224,6 +3270,7 @@ category = 'other', all = false) {var blocks = [], myself = this, varNames, inhe blocks.push(block('scriptNamer')); blocks.push(block('blockComment')); blocks.push(block('scriptChanger')); + blocks.push('#'); // for debugging: /////////////// if (devMode) { @@ -3304,8 +3351,13 @@ category = 'other', all = false) {var blocks = [], myself = this, varNames, inhe } else if (category === 'operators') { - blocks.push(this.subCategoryText('Operators')); - blocks.push('-'); + if (!asABool(localStorage['-snap-setting-oldLambdaOn'])) { + blocks.push(this.subCategoryText(localize('Lambda'))); + blocks.push('-'); blocks.push(block('reifyScript')); + blocks.push(block('reifyReporter')); blocks.push( + block('reifyPredicate')); blocks.push('#'); (blocks + ).push('-');}; blocks.push((this.subCategoryText)( + 'Operators')); blocks.push('-'); blocks.push(block('reportVariadicSum')); blocks.push(block('reportDifference')); blocks.push(block('reportVariadicProduct')); @@ -3376,19 +3428,14 @@ category = 'other', all = false) {var blocks = [], myself = this, varNames, inhe blocks.push('-'); blocks.push(block('reportIsA')); blocks.push(block('reportTypeOf')); + if (asABool(localStorage['-snap-setting-oldLambdaOn'])) { blocks.push('-'); blocks.push(this.subCategoryText(localize('Lambda'))); blocks.push('-'); - if (asABool(localStorage['-snap-setting-oldLambdaOn'])) { blocks.push(block('reportScript')); blocks.push('#'); blocks.push(block('reify')); blocks.push('#'); - } else { - blocks.push(block('reifyScript')); - blocks.push(block('reifyReporter')); - blocks.push(block('reifyPredicate')); - blocks.push('#'); }; blocks.push('-'); if (this instanceof SpriteMorph) {blocks.push('-'); blocks.push(this.subCategoryText(localize('Cloning') @@ -3633,10 +3680,10 @@ SpriteMorph.prototype.categoryText = function (category) { SpriteMorph.prototype.devModeText = function () {var txt = new TextMorph(localize('development mode\ndebugging primitives:')); txt.fontSize = 9; txt.setColor(this.paletteTextColor); return txt;}; SpriteMorph.prototype.noExtensionsText = function () {var txt = new TextMorph(localize('There are no extensions added by now.')); txt.fontSize = 9; txt.setColor(this.paletteTextColor); return txt;}; -SpriteMorph.prototype.helpMenu = function anonymous () {var menu = new MenuMorph(this); menu.addItem('help...', 'showHelp'); return menu;}; +SpriteMorph.prototype.helpMenu = function () {var menu = new MenuMorph(this); menu.addItem('help...', 'showHelp'); return menu;}; -SpriteMorph.prototype.customBlockTemplatesForCategory = function anonymous (category, includeHidden) { -if (contains(Array.from(SpriteMorph.prototype.customCategories.keys()), category)) { +SpriteMorph.prototype.customBlockTemplatesForCategory = function (category, includeHidden +) {if (contains(Array.from(SpriteMorph.prototype.customCategories.keys()), category)) { var ide = this.parentThatIsA(IDE_Morph), blocks = [], isInherited = false, block, inheritedBlocks; function addCustomBlock(definition) {if ((!definition.isHelper || includeHidden) && definition.category === category) { block = definition.templateInstance(); if (isInherited) {block.ghost();}; blocks.push(block); @@ -3662,15 +3709,15 @@ category) ? localize(category[0].toUpperCase().concat(category.slice(1))) : cate };}; this.customBlocks.forEach(addCustomBlock); if (this.exemplar) {inheritedBlocks = this.inheritedBlocks(true); if (this.customBlocks.length && inheritedBlocks.length) {blocks.push('=');}; isInherited = true; inheritedBlocks.forEach(addCustomBlock);};}; return blocks;}; -SpriteMorph.prototype.makeBlockButton = function anonymous () {var button = new PushButtonMorph(this, 'makeBlock', 'Make a block'); +SpriteMorph.prototype.makeBlockButton = function () {var button = new PushButtonMorph(this, 'makeBlock', 'Make a block'); button.userMenu = this.helpMenu; button.selector = 'addCustomBlock'; button.showHelp = BlockMorph.prototype.showHelp; return button;}; -SpriteMorph.prototype.chooseExtensionButton = function anonymous () {var button = new PushButtonMorph(this, 'chooseExtension', 'Choose an extension'); +SpriteMorph.prototype.chooseExtensionButton = function () {var button = new PushButtonMorph(this, 'chooseExtension', 'Choose an extension'); button.userMenu = this.helpMenu; button.selector = 'addExtension'; button.showHelp = BlockMorph.prototype.showHelp; return button;}; /* Extensions. */ -SpriteMorph.prototype.chooseExtension = function anonymous () {var extensionsMenu = new MenuMorph(world.childThatIsA(IDE_Morph), +SpriteMorph.prototype.chooseExtension = function () {var extensionsMenu = new MenuMorph(world.childThatIsA(IDE_Morph), ((IDE_Morph.prototype.whiteExtensionsList.length === IDE_Morph.prototype.featureExtensions.length) ? 'All of the extensions are added.' -: 'Choose an extension...')); IDE_Morph.prototype.featureExtensions.forEach(function anonymous (ext) {if (!(contains( +: 'Choose an extension...')); IDE_Morph.prototype.featureExtensions.forEach(function (ext) {if (!(contains( IDE_Morph.prototype.whiteExtensionsList, ext[0]))) {extensionsMenu.addItem(ext[0], ext[1]);};}); extensionsMenu.popup(world, world.hand.bounds.origin); world.rerender();}; /* Extensions menu. */ @@ -4031,18 +4078,19 @@ strictly, types, varNames) {var blocks = [], blocksDict; ).map(spec => moreTextIn(spec)); return filtered.join(' ') + ' ' + slots.join(' '); }; function moreTextIn(aSlotSpec) { - var info = BlockMorph.prototype.labelParts[aSlotSpec] || {}, - menu = info.menu, - more; + var info = (BlockMorph.prototype).labelParts[aSlotSpec] || {}, + menu = info.menu, more; if (menu) { if (isString(menu)) { - menu = InputSlotMorph.prototype[menu](true); - }; more = Object.values(menu).map(entry => { - if (isNil(entry)) {return ''; } + menu = (InputSlotMorph.prototype)[menu + ](true);}; more = isNil(menu) ? null : ( + Object.values(menu)); if (!isNil(more + )) {more = more.map(entry => { + if (isNil(entry)) {return '';}; if (entry instanceof Array) { return localize(entry[0]); }; return entry.toString(); - }).join(' '); + }).join(' ');}; }; return [ more || '', localize(info.infix || ''), @@ -4081,8 +4129,8 @@ strictly, types, varNames) {var blocks = [], blocksDict; ); if (rel !== -1) { blocks.push([definition.templateInstance(), rel + '2']); - } - } + }; + }; }) ); // primitives blocksDict = SpriteMorph.prototype.blocks; @@ -4115,8 +4163,7 @@ strictly, types, varNames) {var blocks = [], blocksDict; 0])).filter(each => !this.isHidingBlock(each) && !this.isDisablingBlock(each) - ); - return blocks; + ); return blocks; }; SpriteMorph.prototype.searchBlocks = function ( @@ -4137,34 +4184,30 @@ SpriteMorph.prototype.searchBlocks = function ( focus; function showSelection() { - if (focus) {focus.destroy(); } - if (!selection || !scriptFocus) {return; } - focus = selection.outline( - MorphicPreferences.isFlat ? new Color(150, 200, 255) : WHITE, - 2 - ); + if (focus) {focus.destroy();}; + if (!selection || !scriptFocus) { + return;}; focus = selection.outline( + MorphicPreferences.isFlat ? new Color( + 150, 200, 255) : WHITE, 2); searchPane.contents.add(focus); focus.scrollIntoView(); - } - - function show(blocks) { + }; function show(blocks) { var x = searchPane.contents.left() + 5, y = (searchBar.bottom() + unit); blocksList = blocks; selection = null; if (blocks.length && scriptFocus) { selection = blocks[0]; - } - searchPane.contents.children = [searchPane.contents.children[0]]; - blocks.forEach(block => { - block.setPosition(new Point(x, y)); - searchPane.addContents(block); - y += block.height(); - y += unit * 0.3; - }); - showSelection(); + }; searchPane.contents.children = [ + searchPane.contents.children[0 + ]]; blocks.forEach(block => { + block.setPosition(new Point(x, + y)); searchPane.addContents( + block); y += block.height( + ); y += ((unit * 3) / 10); + }); showSelection(); searchPane.changed(); - } + }; searchPane.owner = this; searchPane.color = this.paletteColor; @@ -4174,8 +4217,7 @@ SpriteMorph.prototype.searchBlocks = function ( searchBar.contrast = 90; searchBar.setPosition( searchPane.contents.topLeft().add(new Point(10, 10)) - ); - searchBar.fixLayout(); + ); searchBar.fixLayout(); searchPane.accept = function () { var search; @@ -4183,28 +4225,26 @@ SpriteMorph.prototype.searchBlocks = function ( searchBar.cancel(); if (selection) { scriptFocus.insertBlock(selection); - } - if (ide) { + }; if (ide) { ide.recordUnsavedChanges(); - } + }; } else { search = searchBar.getValue(); if (search.length > 0) { show(myself.blocksMatching(search)); - } - } + }; + }; }; searchPane.reactToKeystroke = function (evt) { var idx, code = evt ? evt.keyCode : 0; switch (code) { case 38: // up arrow - if (!scriptFocus || !selection) {return; } + if (!scriptFocus || !selection) {return;}; idx = blocksList.indexOf(selection) - 1; if (idx < 0) { idx = blocksList.length - 1; - } - selection = blocksList[idx]; + }; selection = blocksList[idx]; showSelection(); return; case 40: // down arrow @@ -4650,20 +4690,17 @@ SpriteMorph.prototype.setVolume = function (num, noShadow) { this.getGainNode().gain.setValueAtTime( 1 / Math.pow(10, Math.log2(100 / this.volume)), this.audioContext().currentTime - ); - if (this instanceof StageMorph) { + ); if (this instanceof StageMorph) { return; - } - // propagate to children that inherit my volume + }; // propagate to children that inherit my volume if (!noShadow) { this.shadowAttribute('volume'); - } - this.instances.forEach(instance => { + }; this.instances.forEach(instance => { if (instance.cachedPropagation) { if (instance.inheritsAttribute('volume')) { instance.setVolume(num, true); - } - } + }; + }; }); }; @@ -4765,12 +4802,7 @@ SpriteMorph.prototype.playFreq = function (hz) { } else { gain.connect(ctx.destination); }; note.ended = false; - if (stage) { - stage.activeSounds.push(note); - stage.activeSounds = stage.activeSounds.filter(snd => - !snd.ended && !snd.terminated - ); - }; note.fader.gain.setValueCurveAtTime( + note.fader.gain.setValueCurveAtTime( note.fadeIn, ctx.currentTime, note.fadeTime @@ -4778,11 +4810,9 @@ SpriteMorph.prototype.playFreq = function (hz) { }; }; -SpriteMorph.prototype.stopFreq = function () { - if (this.freqPlayer) { - this.freqPlayer.stop(); - }; -}; +SpriteMorph.prototype.stopFreq = function ( +) {if (this.freqPlayer) {this.freqPlayer.stop(); +this.freqPlayer = null; /* Reminder to stop. */};}; // SpriteMorph user menu @@ -4890,29 +4920,29 @@ SpriteMorph.prototype.duplicate = function () { var ide = this.parentThatIsA(IDE_Morph); if (ide) { ide.duplicateSprite(this); - } + }; }; SpriteMorph.prototype.instantiate = function () { var ide = this.parentThatIsA(IDE_Morph); if (ide) { ide.instantiateSprite(this); - } + }; }; SpriteMorph.prototype.remove = function () { var ide = this.parentThatIsA(IDE_Morph); if (ide) { ide.removeSprite(this); - } + }; }; // SpriteMorph cloning /* Clones are permanent, partially shallow copies of sprites that appears - as icons in the corral. These can get deleted when are temporary and the - red stop button is pressed. Shallow-copying clones' scripts and costumes + as icons in the corral. These can be deleted when are temporary and when + the red stop button is pressed. Shallow-copying clones' scripts and costumes makes spawning very fast, so they can be used for particle system simulations. This speed-up, however, comes at the cost of some detrimental side effects: Changes to a costume or a script of the original sprite are @@ -4927,14 +4957,14 @@ SpriteMorph.prototype.remove = function () { costume in the original sprite has no effect on any of its clones. */ -// Permanent Clones (BYOB 3.1.1 & Snavanced!) +// Permanent Clones (BYOB 3.1.1 & Snavanced!) SpriteMorph.prototype.clonify = function (stage, immediately) {if (immediately instanceof SpriteMorph) {var object = immediately;} else if ((isNil(immediately)) || ((new Process).inputOption( immediately) === 'myself')) {var object = this;} else {var object = (world.children[0].stage.children.filter(child => (child.name === immediately)))[0];}; object.parts.forEach(part => part.clonify( stage)); stage.cloneCount += 1; object.cloneOriginName = (object.isTemporary ? object.cloneOriginName : object.name); object.isTemporary = true; object.name = ''; stage.add(object); object.endWarp();}; -SpriteMorph.prototype.spawn = function anonymous () {if (!this.isCorpse) {var myClone = this.fullCopy(true); myClone.gotoXY(this.xPosition(), this.yPosition()); -myClone.clonify(this.parentThatIsA(StageMorph), myClone); myClone.perpetuate(); return myClone;} else {throw new Error('You can\'t clone a deleted sprite.');};}; +SpriteMorph.prototype.spawn = function () {if (!this.isCorpse) {var myClone = this.fullCopy(true); myClone.gotoXY(this.xPosition(), this.yPosition()); (myClone +).clonify(this.parentThatIsA(StageMorph), myClone); myClone.perpetuate(); return myClone;} else {throw new Error('You can not clone a deleted sprite.');};}; // Temporary Clones (For compatibility) @@ -4951,11 +4981,11 @@ if (object.isCorpse) {throw Error('cannot operate on a deleted sprite');}; if (s null, // is clicked immediately // without yielding ) - ); - return clone; + ); return clone; }; -SpriteMorph.prototype.newClone = function (immediately) {var clone = this.createClone(immediately); if (isNil(clone)) {throw new Error('exceeding maximum number of clones');}; return clone;}; +SpriteMorph.prototype.newClone = function (immediately) {var clone = this.createClone(immediately +); if (isNil(clone)) {throw Error('Exceeding the maximum number of clones.');}; return clone;}; SpriteMorph.prototype.initClone = function (hats) { var stage = this.parentThatIsA(StageMorph); @@ -4966,9 +4996,8 @@ SpriteMorph.prototype.initClone = function (hats) { this, stage.isThreadSafe ) - ); - this.endWarp(); - } + ); this.endWarp(); + }; }; SpriteMorph.prototype.removeClone = function () { @@ -4979,14 +5008,12 @@ SpriteMorph.prototype.removeClone = function () { this.parts.slice().forEach(part => { this.detachPart(part); part.removeClone(); - }); - this.corpsify(); + }); this.corpsify(); this.instances.forEach(child => { if (child.isTemporary) { child.setExemplar(exemplar); }; - }); - this.destroy(); + }); this.destroy(); this.parent.cloneCount -= 1; }; }; @@ -5091,27 +5118,23 @@ SpriteMorph.prototype.setVisibility = function ( SpriteMorph.prototype.reportShown = function () { if (this.inheritsAttribute('shown?')) { return this.exemplar.reportShown(); - } - return this.isVisible; + }; return this.isVisible; }; // SpriteMorph pen color SpriteMorph.prototype.setColorDimension = function (idx, num) { - var x = this.xPosition(), - y = this.yPosition(), - n = +num; + var x = this.xPosition(), y = this.yPosition(), n = +num; idx = +idx; if (idx < 0 || idx > 3) {this.setSize(num);} if (idx === 0) { if (n < 0 || n > 100) { // wrap the hue n = (n < 0 ? 100 : 0) + n % 100; - } + }; } else { n = Math.min(100, Math.max(0, n)); - } - if (idx === 3) { + }; if (idx === 3) { this.color.a = 1 - n / 100; } else { this.cachedColorDimensions[idx] = n / 100; @@ -5119,19 +5142,16 @@ SpriteMorph.prototype.setColorDimension = function (idx, num) { this.color, this.cachedColorDimensions ); - } - if (!this.costume) { + }; if (!this.costume) { this.rerender(); - } - this.gotoXY(x, y); + }; this.gotoXY(x, y); }; SpriteMorph.prototype.getColorDimension = function (idx) { idx = +idx; if (idx === 3) { return (1 - this.color.a) * 100; - } - return (this.cachedColorDimensions[idx] || 0) * 100; + }; return (this.cachedColorDimensions[idx] || 0) * 100; }; SpriteMorph.prototype.changeColorDimension = function (idx, delta) { @@ -5148,63 +5168,61 @@ SpriteMorph.prototype.setColorRGBA = function (dta) { // - a 1 item list representing greyscale from 0-255 leaving alpha unchanged // - a 2 item list representing greyscale and alpha each from 0-255 // - a number representing greyscale from 0-255 leaving alpha unchanged - var clr = this.color.copy(), - num; + var clr = this.color.copy(), num; if (dta instanceof List) { switch (dta.length()) { case 1: num = Math.max(0, Math.min(+(dta.at(1)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.r = num; clr.g = num; clr.b = num; break; case 2: num = Math.max(0, Math.min(+(dta.at(1)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.r = num; clr.g = num; clr.b = num; num = Math.max(0, Math.min(+(dta.at(2)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.a = num / 255; break; case 3: num = Math.max(0, Math.min(+(dta.at(1)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.r = num; num = Math.max(0, Math.min(+(dta.at(2)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.g = num; num = Math.max(0, Math.min(+(dta.at(3)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.b = num; break; case 4: num = Math.max(0, Math.min(+(dta.at(1)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.r = num; num = Math.max(0, Math.min(+(dta.at(2)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.g = num; num = Math.max(0, Math.min(+(dta.at(3)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.b = num; num = Math.max(0, Math.min(+(dta.at(4)), 255)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.a = num / 255; break; default: return; - } + }; } else { num = Math.max(0, Math.min(+dta, 255)); if (isNaN(num)) {return; } clr.r = num; clr.g = num; clr.b = num; - } - this.setColor(clr); + }; this.setColor(clr); }; SpriteMorph.prototype.changeColorRGBA = function (dta) { @@ -5214,63 +5232,61 @@ SpriteMorph.prototype.changeColorRGBA = function (dta) { // - a 1 item list representing greyscale from 0-255 leaving alpha unchanged // - a 2 item list representing greyscale and alpha each from 0-255 // - a number representing greyscale from 0-255 leaving alpha unchanged - var clr = this.color.copy(), - num; + var clr = this.color.copy(), num; if (dta instanceof List) { switch (dta.length()) { case 1: num = +(dta.at(1)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.r = Math.max(0, Math.min(clr.r + num, 255)); clr.g = Math.max(0, Math.min(clr.g + num, 255)); clr.b = Math.max(0, Math.min(clr.b + num, 255)); break; case 2: num = +(dta.at(1)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.r = Math.max(0, Math.min(clr.r + num, 255)); clr.g = Math.max(0, Math.min(clr.g + num, 255)); clr.b = Math.max(0, Math.min(clr.b + num, 255)); num = +(dta.at(2)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.a = Math.max(0, Math.min((clr.a * 255) + num, 255)) / 255; break; case 3: num = +(dta.at(1)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.r = Math.max(0, Math.min(clr.r + num, 255)); num = +(dta.at(2)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.g = Math.max(0, Math.min(clr.g + num, 255)); num = +(dta.at(3)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.b = Math.max(0, Math.min(clr.b + num, 255)); break; case 4: num = +(dta.at(1)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.r = Math.max(0, Math.min(clr.r + num, 255)); num = +(dta.at(2)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.g = Math.max(0, Math.min(clr.g + num, 255)); num = +(dta.at(3)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.b = Math.max(0, Math.min(clr.b + num, 255)); num = +(dta.at(4)); - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.a = Math.max(0, Math.min((clr.a * 255) + num, 255)) / 255; break; default: return; - } + }; } else { num = +dta; - if (isNaN(num)) {return; } + if (isNaN(num)) {return;}; clr.r = Math.max(0, Math.min(clr.r + num, 255)); clr.g = Math.max(0, Math.min(clr.g + num, 255)); clr.b = Math.max(0, Math.min(clr.b + num, 255)); - } - this.setColor(clr); + }; this.setColor(clr); }; SpriteMorph.prototype.setColor = function (aColor) { @@ -6297,7 +6313,7 @@ SpriteMorph.prototype.doThink = function (data) { this.bubble(data, true); }; -SpriteMorph.prototype.bubble = function (data, isThought, isQuestion, isShouted, isWhispered) { +SpriteMorph.prototype.bubble = function (data, isThought, isQuestion, isShouting, isWhispering) { var bubble, stage = this.parentThatIsA(StageMorph); @@ -6308,8 +6324,8 @@ SpriteMorph.prototype.bubble = function (data, isThought, isQuestion, isShouted, stage, isThought, isQuestion, - isShouted, - isWhispered + isShouting, + isWhispering ); this.add(bubble); this.positionTalkBubble(); }; @@ -6597,7 +6613,7 @@ SpriteMorph.prototype.forward = function anonymous (steps, optDir) { var dest, dist = (steps * this.parent.scale || 0), direction = (( optDir.length() > 0) ? optDir.asArray()[0] : this.heading), dot = 0.1; if (direction instanceof Array) {if (direction[0] === 'random') { -direction = Process.prototype.reportBasicRandom(0, 360000) / 1000;}; +direction = Process.prototype.reportBasicRandom(0, 359999) / 1000;}; }; if (dist === 0 && this.isDown) {this.isDown = false; this.forward(( -dot / 2), optDir); this.isDown = true; this.forward(dot, optDir); this.isDown = false; this.forward((-dot / 2), optDir); this.isDown = true; @@ -6607,10 +6623,9 @@ dist), (direction - 180));}; this.shadowAttribute('x position' ); this.shadowAttribute('y position'); this.setPosition(dest); this.positionTalkBubble();}; /* The "forward" function is re-writed. */ -SpriteMorph.prototype.setHeading = function (degrees, noShadow) { - var x = this.xPosition(), - y = this.yPosition(), - dir = !isFinite(degrees) ? 0 : +degrees, +SpriteMorph.prototype.setHeading = function (degrees, noShadow +) {var x = this.xPosition(), y = this.yPosition(), + dir = (!isFinite(degrees) ? 0 : +degrees), turn = dir - this.heading; // apply to myself @@ -6621,23 +6636,17 @@ SpriteMorph.prototype.setHeading = function (degrees, noShadow) { this.positionTalkBubble(); } else { this.heading = ((+degrees % 360) + 360) % 360; - } - - // propagate to my parts + }; // propagate to my parts this.parts.forEach(part => { var pos = new Point(part.xPosition(), part.yPosition()), trg = pos.rotateBy(radians(turn), new Point(x, y)); if (part.rotatesWithAnchor) { part.turn(turn); - } - part.gotoXY(trg.x, trg.y); - }); - - // propagate to children that inherit my direction + }; part.gotoXY(trg.x, trg.y); + }); // propagate to children that inherit my direction if (!noShadow) { this.shadowAttribute('direction'); - }; - this.instances.forEach(instance => { + }; this.instances.forEach(instance => { if (instance.cachedPropagation) { if (instance.inheritsAttribute('direction')) { instance.setHeading(degrees, true); @@ -6646,8 +6655,8 @@ SpriteMorph.prototype.setHeading = function (degrees, noShadow) { }); }; -SpriteMorph.prototype.faceToXY = function anonymous (x, y) { -this.setHeading(this.angleToXY(x, y));}; /* Points to x and y. */ +SpriteMorph.prototype.faceToXY = function (x, +y) {this.setHeading(this.angleToXY(x, y));}; SpriteMorph.prototype.angleToXY = function (x, y) { var deltaX = (x - this.xPosition()) * this.parent.scale, @@ -6660,33 +6669,31 @@ SpriteMorph.prototype.angleToXY = function (x, y) { return angle + 90; }; -SpriteMorph.prototype.turn = function anonymous (degrees) {this.setHeading(this.heading + (+degrees || 0));}; +SpriteMorph.prototype.turn = function (degrees) { +this.setHeading(this.heading + (+degrees || 0));}; -SpriteMorph.prototype.turnLeft = function anonymous (degrees) {this.setHeading(this.heading - (+degrees || 0));}; +SpriteMorph.prototype.turnLeft = function (degrees) { +this.setHeading(this.heading - (+degrees || 0));}; -SpriteMorph.prototype.getPosition = function () {return new List([this.xPosition(), this.yPosition()]);}; +SpriteMorph.prototype.getPosition = function () { +return new List([this.xPosition(), this.yPosition()]);}; SpriteMorph.prototype.xPosition = function () { if (this.inheritsAttribute('x position')) { return this.exemplar.xPosition(); - } - - var stage = this.parentThatIsA(StageMorph); - - if (!stage && this.parent.grabOrigin) { // I'm currently being dragged + }; var stage = this.parentThatIsA(StageMorph); + if (!stage && this.parent.grabOrigin) {// I'm currently being dragged stage = this.parent.grabOrigin.origin; - } - if (stage) { + }; if (stage) { return (this.rotationCenter().x - stage.center().x) / stage.scale; - } - return this.rotationCenter().x; + }; return this.rotationCenter().x; }; SpriteMorph.prototype.yPosition = function () { if (this.inheritsAttribute('y position')) { return this.exemplar.yPosition(); }; var stage = this.parentThatIsA(StageMorph); - if (!stage && this.parent.grabOrigin) { // I'm currently being dragged + if (!stage && this.parent.grabOrigin) {// I'm currently being dragged stage = this.parent.grabOrigin.origin; }; if (stage) { return (stage.center().y - this.rotationCenter().y) / stage.scale; @@ -6701,25 +6708,16 @@ SpriteMorph.prototype.direction = function () { SpriteMorph.prototype.penSize = function () {return this.size;}; -SpriteMorph.prototype.gotoXY = function (x, y, justMe, noShadow) { - var stage = this.parentThatIsA(StageMorph), - newX, newY, dest; - - if (stage) { - if (!noShadow) { - this.shadowAttribute('x position'); - this.shadowAttribute('y position'); - }; x = !isFinite(+x) ? 0 : +x; - y = !isFinite(+y) ? 0 : +y; - newX = stage.center().x + x * stage.scale; - newY = stage.center().y - y * stage.scale; - if (this.costume) { - dest = new Point(newX, newY).subtract(this.rotationOffset); - } else { - dest = new Point(newX, newY).subtract(this.extent().divideBy(2)); - }; this.setPosition(dest, justMe); - this.positionTalkBubble(); -};}; +SpriteMorph.prototype.gotoXY = function (x, y, justMe, noShadow +) {var stage = this.parentThatIsA(StageMorph), newX, newY, dest; +if (stage) {if (!noShadow) {this.shadowAttribute('x position'); +this.shadowAttribute('y position');}; x = (!isFinite(+x) ? 0 : ( ++x)); y = !isFinite(+y) ? 0 : +y; newX = stage.center().x + ( +x * stage.scale); newY = (stage.center().y - (y * stage.scale)); +if (this.costume) {dest = (new Point(newX, newY)).subtract((this +).rotationOffset);} else {dest = new Point(newX, newY).subtract( +this.extent().divideBy(2));}; this.setPosition(dest, justMe); +this.positionTalkBubble();};}; /* This is so important. */ SpriteMorph.prototype.silentGotoXY = function (x, y, justMe) { // move without drawing, don't shadow coordinate attributes @@ -6735,16 +6733,18 @@ asANum(direction.at(1)) - 90)) : selectedDirection); this.gotoXY( (distance * Process.prototype.reportMonadic(['cos'], direction )));}; /* This block is very important for rendering. :~) */ -SpriteMorph.prototype.setXPosition = function (num) { -this.shadowAttribute('x position'); -this.gotoXY(+num || 0, this.yPosition(), false, true);}; +SpriteMorph.prototype.setXPosition = ( +function (num) {this.shadowAttribute( +'x position'); this.gotoXY(+num || 0, +this.yPosition(), false, true);}); SpriteMorph.prototype.changeXPosition = function (delta) { this.setXPosition(this.xPosition() + (+delta || 0));}; -SpriteMorph.prototype.setYPosition = function (num) { -this.shadowAttribute('y position'); -this.gotoXY(this.xPosition(), +num || 0, false, true);}; +SpriteMorph.prototype.setYPosition = ( +function (num) {this.shadowAttribute( +'y position'); this.gotoXY(this.xPosition( +), +num || 0, false, true);}); SpriteMorph.prototype.changeYPosition = function (delta) { this.setYPosition(this.yPosition() + (+delta || 0));}; @@ -6828,15 +6828,12 @@ SpriteMorph.prototype.setRotationCenter = function (absoluteCoordinate) { var delta, normal; if (!this.costume) { throw new Error('setting the rotation center requires a costume'); - } - this.shadowAttribute('costumes'); + }; this.shadowAttribute('costumes'); delta = absoluteCoordinate.subtract( new Point(this.xPosition(), this.yPosition()) ).divideBy(this.scale).rotateBy(radians(90 - this.heading)); normal = this.costume.rotationCenter.add(new Point(delta.x, -delta.y)); - this.costume.rotationCenter = normal; - this.changed(); - this.fixLayout(); + this.costume.rotationCenter = normal; this.changed(); this.fixLayout(); this.changed(); }; @@ -6863,85 +6860,66 @@ SpriteMorph.prototype.setPivot = function (worldCoordinate) { (worldCoordinate.x - cntr.x) / stage.scale, (cntr.y - worldCoordinate.y) / stage.scale ) - ); - if (ide) { + ); if (ide) { ide.recordUnsavedChanges(); - } - } + }; + }; }; // SpriteMorph dimension getters SpriteMorph.prototype.xCenter = function () { var stage = this.parentThatIsA(StageMorph); - if (!stage && this.parent.grabOrigin) { // I'm currently being dragged stage = this.parent.grabOrigin.origin; - } - if (stage) { + }; if (stage) { return (this.center().x - stage.center().x) / stage.scale; - } - return this.center().x; + }; return this.center().x; }; SpriteMorph.prototype.yCenter = function () { var stage = this.parentThatIsA(StageMorph); - if (!stage && this.parent.grabOrigin) { // I'm currently being dragged stage = this.parent.grabOrigin.origin; - } - if (stage) { + }; if (stage) { return (stage.center().y - this.center().y) / stage.scale; - } - return this.center().y; + }; return this.center().y; }; SpriteMorph.prototype.xLeft = function () { var stage = this.parentThatIsA(StageMorph); - if (!stage && this.parent.grabOrigin) { // I'm currently being dragged stage = this.parent.grabOrigin.origin; - } - if (stage) { + }; if (stage) { return (this.left() - stage.center().x) / stage.scale; - } - return this.left(); + }; return this.left(); }; SpriteMorph.prototype.xRight = function () { var stage = this.parentThatIsA(StageMorph); - if (!stage && this.parent.grabOrigin) { // I'm currently being dragged stage = this.parent.grabOrigin.origin; - } - if (stage) { + }; if (stage) { return (this.right() - stage.center().x) / stage.scale; - } - return this.right(); + }; return this.right(); }; SpriteMorph.prototype.yTop = function () { var stage = this.parentThatIsA(StageMorph); - if (!stage && this.parent.grabOrigin) { // I'm currently being dragged stage = this.parent.grabOrigin.origin; - } - if (stage) { + }; if (stage) { return (stage.center().y - this.top()) / stage.scale; - } - return this.top(); + }; return this.top(); }; SpriteMorph.prototype.yBottom = function () { var stage = this.parentThatIsA(StageMorph); - if (!stage && this.parent.grabOrigin) { // I'm currently being dragged stage = this.parent.grabOrigin.origin; - } - if (stage) { + }; if (stage) { return (stage.center().y - this.bottom()) / stage.scale; - } - return this.bottom(); + }; return this.bottom(); }; // SpriteMorph message broadcasting @@ -6984,9 +6962,8 @@ SpriteMorph.prototype.allHatBlocksForKey = function (key) { var choice = morph.inputs()[0].evaluate(), evt = choice instanceof Array ? choice[0] : choice; return evt === key || evt === 'any key'; - } - } - return false; + }; + }; return false; }); }; @@ -6997,8 +6974,7 @@ SpriteMorph.prototype.allHatBlocksForInteraction = function (interaction) { var choice = morph.inputs()[0].evaluate(); return (Process.prototype.inputOption(choice) === interaction); }; - }; - return false; + }; return false; }); }; @@ -7009,9 +6985,8 @@ SpriteMorph.prototype.allHatBlocksForUserEdit = function (spriteName) { var choice = morph.inputs()[0].evaluate(), evt = choice instanceof Array ? choice[0] : choice; return evt === spriteName || evt === 'anything'; - } - } - return false; + }; + }; return false; }); }; @@ -7022,8 +6997,7 @@ SpriteMorph.prototype.allGenericHatBlocks = function () { return this.scripts.children.filter(morph => { if (morph.selector) { return morph.selector === 'receiveCondition'; - } - return false; + }; return false; }); }; @@ -7032,18 +7006,14 @@ SpriteMorph.prototype.allScripts = function () { this.customBlocks.forEach(def => { if (def.body) { all.push(def.body.expression); - } - def.scripts.forEach(scr => all.push(scr)); - }); - if (this.globalBlocks) { + }; def.scripts.forEach(scr => all.push(scr)); + }); if (this.globalBlocks) { this.globalBlocks.forEach(def => { if (def.body) { all.push(def.body.expression); - } - def.scripts.forEach(scr => all.push(scr)); + }; def.scripts.forEach(scr => all.push(scr)); }); - } - return all; + }; return all; }; // SpriteMorph events @@ -7064,9 +7034,8 @@ SpriteMorph.prototype.receiveUserInteraction = function ( rightAway, threadSafe ) { - var stage = this.parentThatIsA(StageMorph), - procs = [], - hats; + var stage = this.parentThatIsA( + StageMorph), procs = [], hats; if (!stage) {return;}; // currently dragged hats = this.allHatBlocksForInteraction(interaction); hats.forEach(block => @@ -7080,8 +7049,7 @@ SpriteMorph.prototype.receiveUserInteraction = function ( rightAway, // immediately interaction === 'stopped' // atomic )) - ); - return procs; + ); return procs; }; SpriteMorph.prototype.mouseDoubleClick = function ( @@ -7096,13 +7064,13 @@ StageMorph); if (stage instanceof StageMorph) {return stage.getTimer();} else {r // SpriteMorph battery -SpriteMorph.prototype.getBatteryLevel = function anonymous () {return (isNil(this.world().batteryAPI) ? 0 : this.world().batteryAPI.level);}; -SpriteMorph.prototype.getBatteryIsCharging = function anonymous () {return (isNil(this.world().batteryAPI) ? 0 : this.world().batteryAPI.charging);}; +SpriteMorph.prototype.getBatteryLevel = function () {return (isNil(world.batteryAPI) ? 0 : world.batteryAPI.level);}; +SpriteMorph.prototype.getBatteryIsCharging = function () {return (isNil(world.batteryAPI) ? 0 : world.batteryAPI.charging);}; // SpriteMorph scenes -SpriteMorph.prototype.reportSceneName = function anonymous () {return (world.childThatIsA(IDE_Morph).scenes.at(this.reportSceneNumber()).name || localize('Untitled'));}; -SpriteMorph.prototype.reportSceneNumber = function anonymous () {return world.childThatIsA(IDE_Morph).scenes.indexOf(world.childThatIsA(IDE_Morph).scene);}; +SpriteMorph.prototype.reportSceneName = function () {return (world.childThatIsA(IDE_Morph).scenes.at(this.reportSceneNumber()).name || localize('Untitled'));}; +SpriteMorph.prototype.reportSceneNumber = function () {return world.childThatIsA(IDE_Morph).scenes.indexOf(world.childThatIsA(IDE_Morph).scene);}; // SpriteMorph loud? @@ -7120,8 +7088,7 @@ SpriteMorph.prototype.getLastMessage = function () { var stage = this.parentThatIsA(StageMorph); if (stage) { return stage.getLastMessage(); - }; - return ''; + }; return ''; }; // SpriteMorph user prompting @@ -8295,8 +8262,7 @@ SpriteMorph.prototype.allParts = function () { var result = [this]; this.parts.forEach(part => result = result.concat(part.allParts()) - ); - return result; + ); return result; }; SpriteMorph.prototype.allAnchors = function () { @@ -8304,8 +8270,7 @@ SpriteMorph.prototype.allAnchors = function () { var result = [this]; if (this.anchor !== null) { result = result.concat(this.anchor.allAnchors()); - } - return result; + }; return result; }; SpriteMorph.prototype.recordLayers = function () { @@ -8313,13 +8278,11 @@ SpriteMorph.prototype.recordLayers = function () { if (!stage) { this.layerCache = null; return; - } - this.layers = this.allParts(); + }; this.layers = this.allParts(); this.layers.forEach(part => { var bubble = part.talkBubble(); if (bubble) {bubble.hide(); } - }); - this.layers.sort((x, y) => + }); this.layers.sort((x, y) => stage.children.indexOf(x) < stage.children.indexOf(y) ? -1 : 1 ); @@ -8331,8 +8294,7 @@ SpriteMorph.prototype.restoreLayers = function () { sprite.comeToFront(); sprite.positionTalkBubble(); }); - } - this.layers = null; + }; this.layers = null; }; // SpriteMorph destroying @@ -8341,11 +8303,10 @@ SpriteMorph.prototype.destroy = function () { // make sure to sever all inheritance ties to other sprites if (this.anchor) { this.anchor.detachPart(this); - } - this.emancipate(); + }; this.emancipate(); if (!this.isTemporary) { this.prune(); - } + }; this.stopFreq(); SpriteMorph.uber.destroy.call(this); }; @@ -8368,8 +8329,8 @@ SpriteMorph.prototype.addHighlight = function (oldHighlight) { var isHidden = !this.isVisible, highlight; - if (isHidden) {this.show(); } - highlight = this.highlight( + if (isHidden) {this.show(); + }; highlight = this.highlight( oldHighlight ? oldHighlight.color : this.highlightColor, this.highlightBorder ); @@ -8805,19 +8766,17 @@ StageMorph.prototype.moveBy = function (delta) { // StageMorph rendering StageMorph.prototype.render = function (ctx) { - ctx.save(); - ctx.fillStyle = this.color.toString(); + ctx.imageSmoothingEnabled = false; ctx.save( + ); ctx.fillStyle = this.color.toString(); ctx.fillRect(0, 0, this.width(), this.height()); if (this.costume && !(this.costume.loaded instanceof Function)) { ctx.scale(this.scale, this.scale); ctx.drawImage( this.costume.contents, - (this.width() / this.scale - this.costume.width()) / 2, - (this.height() / this.scale - this.costume.height()) / 2 - ); - this.cachedImage = this.applyGraphicsEffects(this.cachedImage); - } - ctx.restore(); + Math.round((this.width() / this.scale - this.costume.width()) / 2), + Math.round((this.height() / this.scale - this.costume.height()) / 2) + ); this.cachedImage = this.applyGraphicsEffects(this.cachedImage); + }; ctx.restore(); this.version = Date.now(); // for observer optimization }; @@ -8994,8 +8953,7 @@ StageMorph.prototype.stopVideo = function() { this.projectionSource.stream.getTracks().forEach(track => track.stop() ); - } - this.videoMotion = null; + }; this.videoMotion = null; }; StageMorph.prototype.stopProjection = function() { @@ -9004,8 +8962,7 @@ StageMorph.prototype.stopProjection = function() { this.projectionSource.remove(); this.projectionSource = null; this.continuousProjection = false; - } - this.clearProjectionLayer(); + }; this.clearProjectionLayer(); }; StageMorph.prototype.projectionSnap = function() { @@ -9465,17 +9422,17 @@ StageMorph.prototype.fireUserEditEvent = function ( return procs; }; -StageMorph.prototype.fireGreenFlagEvent = function anonymous () {var procs = [], ide = this.parentThatIsA(IDE_Morph); ide.scene.restart(); this.lastAnswer = ''; this.children.concat( -this).forEach(morph => {if (isSnapObject(morph)) {morph.allHatBlocksFor('__shout__go__').forEach(block => procs.push(this.threads.startProcess(block, morph, this.isThreadSafe)));}}); -var dialog = world.children.filter(child => child instanceof DialogBoxMorph).filter(child => child.key === 'screenshotMaker'); if (dialog.length > 0) {dialog = dialog[0]; if (( -dialog.button2.labelString.color.g > 0) && (dialog.button1.labelString.name === 'pointRight')) {dialog.button1.action(); dialog.button1.fixLayout();};}; this.timerStart = Date.now(); return procs;}; -StageMorph.prototype.runPauseScripts = function anonymous () {this.receiveUserInteraction('paused', true, true); this.children.forEach(morph => {if (morph instanceof SpriteMorph) {morph.receiveUserInteraction( -'paused', true, true);}});}; StageMorph.prototype.runUnpauseScripts = function anonymous (receiver) {if (Process.prototype.reportIsA(receiver, ['agent'])) {receiver.receiveUserInteraction('unpaused', true, -true);} else {this.receiveUserInteraction('unpaused', true, true); this.children.forEach(morph => {if (morph instanceof SpriteMorph) {morph.receiveUserInteraction('unpaused', true, true);}});};}; -StageMorph.prototype.runStopScripts = function anonymous () {this.receiveUserInteraction('stopped', true, true); this.children.forEach(morph => {if (morph instanceof SpriteMorph) { -morph.receiveUserInteraction('stopped', true, true);}});}; StageMorph.prototype.removeAllClones = function anonymous () {var clones = this.children.filter(morph => ( -morph instanceof SpriteMorph && morph.isTemporary)); clones.forEach(clone => {this.threads.stopAllForReceiver(clone); clone.detachFromAnchor(); clone.corpsify(); clone.destroy();}); this.cloneCount = 0;}; -/* StageMorph important block events */ +StageMorph.prototype.fireGreenFlagEvent = function () {var procs = [], ide = this.parentThatIsA(IDE_Morph); ide.scene.restart(); this.lastAnswer = ''; ((this.children).concat(this)).forEach(morph => {if ( +isSnapObject(morph)) {morph.allHatBlocksFor('__shout__go__').forEach(block => procs.push(this.threads.startProcess(block, morph, this.isThreadSafe)));}}); var dialog = world.children.filter(child => ( +child instanceof DialogBoxMorph)).filter(child => child.key === 'screenshotMaker'); if (dialog.length > 0) {dialog = dialog[0]; if ((dialog.button2.labelString.color.g > 0) && ((dialog.button1 +).labelString.name === 'pointRight')) {dialog.button1.action(); dialog.button1.fixLayout();};}; this.timerStart = Date.now(); return procs;}; StageMorph.prototype.runPauseScripts = function ( +) {this.receiveUserInteraction('paused', true, true); this.children.forEach(morph => {if (morph instanceof SpriteMorph) {morph.receiveUserInteraction('paused', true, true);};});}; +StageMorph.prototype.runUnpauseScripts = function (receiver) {if (Process.prototype.reportIsA(receiver, ['agent'])) {receiver.receiveUserInteraction('unpaused', true, true); +} else {this.receiveUserInteraction('unpaused', true, true); this.children.forEach(morph => {if (morph instanceof SpriteMorph) {morph.receiveUserInteraction('unpaused', +true, true);}});};}; StageMorph.prototype.runStopScripts = function () {this.receiveUserInteraction('stopped', true, true); this.children.forEach(morph => {if ( +morph instanceof SpriteMorph) {morph.receiveUserInteraction('stopped', true, true);}});}; StageMorph.prototype.removeAllClones = function () {var clones = (this +).children.filter(morph => ((morph instanceof SpriteMorph) && morph.isTemporary)); clones.forEach(clone => {this.threads.stopAllForReceiver(clone); +clone.detachFromAnchor(); clone.corpsify(); clone.destroy();}); this.cloneCount = 0;}; /* StageMorph important block events. */ StageMorph.prototype.editScripts = function () { var ide = this.parentThatIsA(IDE_Morph), @@ -9494,8 +9451,7 @@ StageMorph.prototype.editScripts = function () { } } else { scripts.focus.moveBy(new Point(50, 50)); - } - scripts.focus.fixLayout(); + }; scripts.focus.fixLayout(); }; // StageMorph controlling generic WHEN hats @@ -9507,7 +9463,7 @@ StageMorph.prototype.pauseGenericHatBlocks = function () { this.enableCustomHatBlocks = true; this.threads.pauseCustomHatBlocks = true; ide.controlBar.stopButton.refresh(); - } + }; }; // StageMorph block templates @@ -9947,14 +9903,14 @@ StageMorph.prototype.doPlaySound = SpriteMorph.prototype.doPlaySound; StageMorph.prototype.stopAllActiveSounds = function ( -restarting) {this.activeSounds.forEach(audio => ((( -typeof audio.stop) === 'function') ? audio.stop( -) : ((asABool(restarting) || ((typeof audio.pause -) === 'function')) ? audio.pause() : nop()))); -this.activeSounds.forEach(audio => (isNil( -audio.remove) ? nop() : audio.remove())); if ( -this.microphone.modifier && this.microphone.isReady -) {this.microphone.stop();}; this.activeSounds = [];}; +) {this.activeSounds.forEach(audio => (((typeof (audio +).stop) === 'function') ? audio.stop() : (((typeof ( +audio.pause)) === 'function') ? audio.pause() : nop( +)))); this.activeSounds.forEach(audio => (isNil((audio +).remove) ? nop() : audio.remove())); if ((this.microphone +).modifier && this.microphone.isReady) {(this.microphone +).stop();}; this.children.forEach(child => isSnapObject( +child) ? child.stopFreq() : nop()); this.stopFreq();}; StageMorph.prototype.pauseAllActiveSounds = function () { this.activeSounds.forEach(audio => (((typeof audio.pause @@ -10250,8 +10206,8 @@ SpriteBubbleMorph.uber = SpeechBubbleMorph.prototype; // SpriteBubbleMorph instance creation: -function SpriteBubbleMorph(data, stage, isThought, isQuestion, isShouted, isWhispered) { - this.init(data, stage, isThought, isQuestion, isShouted, isWhispered); +function SpriteBubbleMorph(data, stage, isThought, isQuestion, isShouting, isWhispering) { + this.init(data, stage, isThought, isQuestion, isShouting, isWhispering); } SpriteBubbleMorph.prototype.init = function ( @@ -10259,16 +10215,16 @@ SpriteBubbleMorph.prototype.init = function ( stage, isThought, isQuestion, - isShouted, - isWhispered + isShouting, + isWhispering ) { var sprite = SpriteMorph.prototype; this.stage = stage; this.scale = stage ? stage.scale : 1; this.data = data; this.isQuestion = isQuestion; - this.isShouted = isShouted; - this.isWhispered = isWhispered; + this.isShouting = isShouting; + this.isWhispering = isWhispering; SpriteBubbleMorph.uber.init.call( this, @@ -10284,18 +10240,20 @@ SpriteBubbleMorph.prototype.init = function ( this.rerender(); }; +SpriteBubbleMorph.prototype.oldStep = SpriteBubbleMorph.prototype.step +SpriteBubbleMorph.prototype.step = function () {this.oldStep(); if ( +this.isShouting) {this.changed(); this.fixLayout(); this.rerender();};}; + // SpriteBubbleMorph contents formatting SpriteBubbleMorph.prototype.dataAsMorph = function (data) { - var contents, - sprite = SpriteMorph.prototype, - isText, - img, - scaledImg, - width; + var contents, sprite = SpriteMorph.prototype, + isText, img, scaledImg, width; if (data instanceof Morph) { if (isSnapObject(data)) { - img = data.thumbnail(new Point(40, 40)); + img = data.thumbnail(new Point( + (40 * (asANum(this.isShouting) + 1)), + (40 * (asANum(this.isShouting) + 1)))); contents = new Morph; contents.isCachingImage = true; contents.bounds.setWidth(img.width); @@ -10305,11 +10263,13 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) { contents.step = function () { if (this.version !== data.version) { img = data.thumbnail(new Point( - 40, 40), this.cachedImage); + (40 * (asANum(this.isShouting) + 1)), + (40 * (asANum(this.isShouting) + 1 + ))), this.cachedImage); this.cachedImage = img; this.version = data.version; this.changed(); - } + }; }; } else { contents = data; @@ -10317,10 +10277,10 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) { } else if (isString(data)) { isText = true; contents = new TextMorph(data, - (this.isShouted ? (sprite.bubbleFontSize * this.scale * 1.5) : (sprite.bubbleFontSize * this.scale)), + (sprite.bubbleFontSize * this.scale * (asANum(this.isShouting) + 1)), null, // fontStyle - !this.isWhispered, // bold - this.isWhispered, // italic + this.isShouting, // bold + this.isWhispering, // italic 'center' // position ); contents.acceptedFontName = ((localStorage['-snap-setting-language' ] === 'tok') ? 'blockTokiPonaFont' : 'blockGlobalFont'); @@ -10333,7 +10293,7 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) { contents.userMenu = function () { var menu = new MenuMorph(this), ide = this.parentThatIsA(IDE_Morph)|| - this.world().childThatIsA(IDE_Morph); + world.childThatIsA(IDE_Morph); if (ide.isAppMode ) {return;}; @@ -10348,8 +10308,8 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) { }; } else if (data instanceof Color) { - img = ColorImageMorph(data.copy()).fullImage(); - contents = new Morph; + img = ColorImageMorph(data.copy() + ).fullImage(); contents = new Morph; contents.isCachingImage = true; contents.bounds.setWidth(img.width); contents.bounds.setHeight(img.height); @@ -10361,21 +10321,20 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) { contents.selectForEdit = function () { var script = SpriteMorph.prototype.blockForSelector('getColor'), prepare = script.prepareToBeGrabbed, - ide = this.parentThatIsA(IDE_Morph) || - this.world().childThatIsA(IDE_Morph); + ide = (this.parentThatIsA(IDE_Morph) || + this.world().childThatIsA(IDE_Morph)); script.children[1].setColor(data.copy()); script.isDraggable = true; - script.prepareToBeGrabbed = function (hand) { - prepare.call(this, hand); + script.prepareToBeGrabbed = function ( + hand) {prepare.call(this, hand); hand.grabOrigin = { origin: ide.palette, position: ide.palette.center() - }; - this.prepareToBeGrabbed = prepare; + }; this.prepareToBeGrabbed = prepare; }; - if (ide.isAppMode) {return; } + if (ide.isAppMode) {return;}; script.setPosition(this.position()); return script; }; @@ -10571,11 +10530,13 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) { return script; }; } else { - contents = new TextMorph((isNil(data) ? '' : ((data.textRepresentation === undefined) ? data.toString() : data.textRepresentation)), - (this.isShouted ? (sprite.bubbleFontSize * this.scale * 1.5) : (sprite.bubbleFontSize * this.scale)), + contents = new TextMorph((isNil(data) ? '' : (isNil( + data.textRepresentation) ? data.toString() : getText( + data.textRepresentation, data))), (sprite.bubbleFontSize * ( + this.scale * (asANum(this.isShouting) + 1))), null, // fontStyle - !this.isWhispered, // bold - this.isWhispered, // italic + !this.isShouting, // bold + this.isWhispering, // italic 'center' // position ); contents.acceptedFontName = ((localStorage['-snap-setting-language' ] === 'tok') ? 'blockTokiPonaFont' : 'blockGlobalFont'); @@ -10607,9 +10568,10 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) { width = Math.max( contents.width(), sprite.bubbleCorner * 2 * this.scale - ); - if (isText) { - width = Math.min(width, sprite.bubbleMaxTextWidth * this.scale); + ); if (isText) { + width = Math.min(width, + sprite.bubbleMaxTextWidth * (asANum(this.isShouting) + 1) * this.scale + ); }; contents.setWidth(width); } else if (!(data instanceof List)) { // scale contents image @@ -10627,7 +10589,9 @@ SpriteBubbleMorph.prototype.dataAsMorph = function (data) { // SpriteBubbleMorph scaling -SpriteBubbleMorph.prototype.setScale = function (scale) {this.scale = scale; this.changed(); this.fixLayout(); this.rerender();}; +SpriteBubbleMorph.prototype.setScale = function ( +scale) {this.scale = scale; this.changed(); +this.fixLayout(); this.rerender();}; // SpriteBubbleMorph layout: @@ -10639,8 +10603,7 @@ SpriteBubbleMorph.prototype.fixLayout = function () { this.contentsMorph instanceof TableFrameMorph)) { this.contentsMorph.destroy(); this.contentsMorph = this.dataAsMorph(this.data); - } - this.add(this.contentsMorph); + }; this.add(this.contentsMorph); // scale my settings this.edge = sprite.bubbleCorner * this.scale; @@ -10662,7 +10625,7 @@ SpriteBubbleMorph.prototype.fixLayout = function () { this.padding || this.edge, this.border + this.padding + 1 ) - )); + )); this.normalExtent = this.extent().divideBy(this.scale); }; // Costume ///////////////////////////////////////////////////////////// @@ -11366,7 +11329,7 @@ Sound.prototype.toDataURL = function () {return this.audio.src;}; // Note instance creation function Note(pitch) { - this.pitch = ((pitch === 0) ? 0 : pitch) || MIDSoundSystem.basicLogarithmicValue; + this.pitch = ((pitch === 0) ? 0 : pitch) || 59.760344731969152; this.frequency = null; // alternative for playing a non-note frequency this.setupContext(); this.oscillator = null; // the instrument this.fader = null; // gain node for suppressing clicks @@ -11425,7 +11388,7 @@ Note.prototype.play = function (type, gainNode, pannerNode) { this.oscillator.stop = this.oscillator.noteOff; }; this.setInstrument(type); this.oscillator.frequency.value = isNil(this.frequency) ? - Math.pow(2, (this.pitch - MIDSoundSystem.basicLogarithmicValue) / 12) * MIDSoundSystem.basicHertzValue : this.frequency; + Math.pow(2, (this.pitch - 59.760344731969152) / 12) * 256 : this.frequency; this.oscillator.connect(this.fader); this.fader.connect(gainNode); if (pannerNode) { @@ -11653,8 +11616,8 @@ Microphone.prototype.stepAudio = function (event) { ); // note: if (this.pitch > 0) { this.note = ( - 12 * (Math.log(this.pitch / MIDSoundSystem.basicHertzValue) / Math.log(2)) - ) + MIDSoundSystem.basicLogarithmicValue; + 12 * (Math.log(this.pitch / 256) / Math.log(2)) + ) + 59.760344731969152; }; this.isReady = true; this.isStarted = false; }; @@ -12039,9 +12002,7 @@ CellMorph.prototype.createContents = function () { origin: ide.palette, position: ide.palette.center() }; this.prepareToBeGrabbed = prepare; - }; - - if (ide.isAppMode) {return;}; + }; if (ide.isAppMode) {return;}; icon.setCenter(this.center()); return icon; }; if (this.contentsMorph.isDraggable) { @@ -12063,35 +12024,29 @@ CellMorph.prototype.createContents = function () { false, // bold true, // italic 'center' - ); - this.contentsMorph.setColor(WHITE); + ); this.contentsMorph.setColor(WHITE); } else { this.contentsMorph = new ListWatcherMorph( this.contents, this ); - } - } - this.contentsMorph.isDraggable = false; + }; + }; this.contentsMorph.isDraggable = false; } else { this.contentsMorph = new TextMorph( (isNil(this.contents) ? '' : (( this.contents.textRepresentation === undefined - ) ? this.contents.toString() : this.contents.textRepresentation)), - fontSize, - null, - true, - false, - 'center' - ); - if (this.isEditable && (isNil(this.contents.textRepresentation) || !isNil(this.contents.enableEditing))) { - this.contentsMorph.isEditable = true; + ) ? this.contents.toString() : getText( + this.contents.textRepresentation, this.contents + ))), fontSize, null, true, false, 'center' + ); if (this.isEditable && (isNil( + this.contents.textRepresentation + ) || !isNil(this.contents.enableEditing)) + ) {this.contentsMorph.isEditable = true; this.contentsMorph.enableSelecting(); - } - this.contentsMorph.setColor(WHITE); - } - this.add(this.contentsMorph); - } + }; this.contentsMorph.setColor(WHITE); + }; this.add(this.contentsMorph); + }; }; // CellMorph drawing: @@ -13074,5 +13029,195 @@ StagePrompterMorph.prototype.fixLayout = function () { // StagePrompterMorph events: -StagePrompterMorph.prototype.mouseClickLeft = function anonymous () {this.inputField.edit( -);}; StagePrompterMorph.prototype.accept = function anonymous () {this.isDone = true;}; \ No newline at end of file +StagePrompterMorph.prototype.mouseClickLeft = function () { +this.inputField.edit();}; (StagePrompterMorph.prototype +).accept = function () {this.isDone = true;}; + +// Project ///////////////////////////////////////////////////////// + +// I am a container for a set of one or more Snap! scenes, +// the IDE operates on an instance of me + +// Project instance creation: + +function Project (scenes, current) {var projectScene; this.scenes = (scenes || new List); +this.currentScene = current; this.name = null; this.notes = null; this.thumbnail = null; +projectScene = this.scenes.at(1); if (projectScene) {this.name = projectScene.name; (this +).notes = projectScene.notes; this.thumbnail = normalizeCanvas(projectScene.stage.thumbnail( +SnapSerializer.prototype.thumbnailSize));}; this.sceneIdx = null; this.trash = [];}; (Project +).prototype.initialize = function () {this.currentScene = this.scenes.at(+(this.sceneIdx) || 1 +); return this;}; Project.prototype.addDefaultScene = function () {var scene = new Scene; +scene.addDefaultSprite(); this.scenes.add(scene);}; + +// Scene ///////////////////////////////////////////////////////// + +// I am a container for a Snap! stage, scene-global variables +// and its associated settings. +// I can be used as a slide in a presentation, a chapter in a narrative, +// a level in a game, etc. + +// Scene instance creation: + +function Scene(aStageMorph) { + this.name = ''; this.notes = ''; + this.globalVariables = aStageMorph ? + aStageMorph.globalVariables() : new VariableFrame; + this.stage = aStageMorph || new StageMorph(this.globalVariables); + this.hasUnsavedEdits = false; + this.unifiedPalette = false; + this.showCategories = true; + this.showPaletteButtons = true; + + // cached IDE state + this.sprites = new List; + this.currentSprite = null; + + // global settings (shared) + this.hiddenPrimitives = {}; + this.codeMappings = {}; + this.codeHeaders = {}; + this.customCategories = new Map; + + // global settings (copied) + this.enableCodeMapping = false; + this.enableInheritance = true; + this.enableSublistIDs = false; + this.enablePenLogging = false; + this.useFlatLineEnds = false; + this.enableLiveCoding = false; + this.enableHyperOps = true; + this.disableClickToRun = false; + this.penColorModel = 'hsv'; + + // for deserializing - do not persist + this.spritesDict = {}; + this.targetStage = null; + this.spriteIdx = null; + + // for undeleting sprites - do not persist + this.trash = []; +}; + +Scene.prototype.initialize = function () { + // initialize after deserializing + // only to be called by store + var objs = this.stage.children.filter( + child => child instanceof SpriteMorph + ); objs.sort((x, y) => x.idx - y.idx); + this.sprites = new List(objs); + if (this.spriteIdx === null && this.sprites.length() > 0) { + this.currentSprite = this.sprites.at(1); + } else if (this.spriteIdx === 0) { + this.currentSprite = this.stage; + } else { + this.currentSprite = (this.sprites.at( + this.spriteIdx) || this.stage); + }; return this; +}; + +Scene.prototype.addDefaultSprite = function anonymous () {var sprite = new SpriteMorph(this.globalVariables +); sprite.setPosition(this.stage.center().subtract(sprite.extent().divideBy(2))); this.stage.add(sprite); +this.sprites.add(sprite); this.currentSprite = sprite; return sprite;}; /* New sprite to the stage. */ + +// Scene - capturing global state locally: + +Scene.prototype.captureGlobalSettings = function () { + this.hiddenPrimitives = StageMorph.prototype.hiddenPrimitives; + this.codeMappings = StageMorph.prototype.codeMappings; + this.codeHeaders = StageMorph.prototype.codeHeaders; + this.enableCodeMapping = StageMorph.prototype.enableCodeMapping; + this.enableInheritance = StageMorph.prototype.enableInheritance; + this.enableSublistIDs = StageMorph.prototype.enableSublistIDs; + this.enablePenLogging = StageMorph.prototype.enablePenLogging; + this.useFlatLineEnds = SpriteMorph.prototype.useFlatLineEnds; + this.enableLiveCoding = Process.prototype.enableLiveCoding; + this.enableHyperOps = Process.prototype.enableHyperOps; + this.customCategories = SpriteMorph.prototype.customCategories; + this.disableClickToRun = ThreadManager.prototype.disableClickToRun; + this.penColorModel = SpriteMorph.prototype.penColorModel; +}; + +Scene.prototype.applyGlobalSettings = function () { + StageMorph.prototype.hiddenPrimitives = this.hiddenPrimitives; + StageMorph.prototype.codeMappings = this.codeMappings; + StageMorph.prototype.codeHeaders = this.codeHeaders; + StageMorph.prototype.enableCodeMapping = this.enableCodeMapping; + StageMorph.prototype.enableInheritance = this.enableInheritance; + StageMorph.prototype.enableSublistIDs = this.enableSublistIDs; + StageMorph.prototype.enablePenLogging = this.enablePenLogging; + SpriteMorph.prototype.useFlatLineEnds = this.useFlatLineEnds; + Process.prototype.enableLiveCoding = this.enableLiveCoding; + Process.prototype.enableHyperOps = this.enableHyperOps; + SpriteMorph.prototype.customCategories = this.customCategories; + ThreadManager.prototype.disableClickToRun = this.disableClickToRun; + SpriteMorph.prototype.penColorModel = this.penColorModel; +}; + +// Scene ops: + +Scene.prototype.updateTrash = function () {this.trash = this.trash.filter(sprite => sprite.isCorpse);}; + +Scene.prototype.restart = function () { + var ide; window.speechSynthesis.cancel(); + this.stage.threads.pauseCustomHatBlocks = false; + this.stage.stopAllActiveSounds(); (this.stage + ).clearEffects(); (this.stage.threads + ).resumeAll(this.stage); this.stage.keysPressed = { + }; this.stage.threads.stopAll(); (this.stage + ).timerProcedure.stopNow(); world.children.filter( + function (child) {if (child instanceof DialogBoxMorph + ) {return (child.key).includes('debug') && contains( + this.stage.threads.processes, child.process);} else { + return false;};}).forEach(function (child) {child.destroy( + );}); if (this.stage.projectionSource) { + this.stage.stopProjection();}; + this.stage.children.forEach(morph => { + if (morph.stopTalking) { + morph.stopTalking(); + }; if (morph.clearEffects + ) {morph.clearEffects();}; + }); this.stage.removeAllClones(); + ide = this.stage.parentThatIsA(IDE_Morph); + if (ide) { + ide.controlBar.pauseButton.refresh(); + ide.controlBar.stopButton.refresh(); + }; this.stage.timerProcedure.startNow(); +}; + +Scene.prototype.stop = function (forGood) { + var ide; window.speechSynthesis.cancel(); + if (this.stage.enableCustomHatBlocks || forGood) { + this.stage.threads.pauseCustomHatBlocks = forGood ? true + : !this.stage.threads.pauseCustomHatBlocks; + } else { + this.stage.threads.pauseCustomHatBlocks = false; + }; this.stage.stopAllActiveSounds(); (this.stage + ).clearEffects(); this.stage.threads.resumeAll( + this.stage); this.stage.keysPressed = { + }; this.stage.runStopScripts(); + this.stage.threads.stopAll(); + this.stage.timerProcedure.stopNow(); + world.children.filter(function ( + child) {if (child instanceof DialogBoxMorph + ) {return (child.key).includes('debug' + ) && contains(this.stage.threads.processes, + child.process);} else {return false;};} + ).forEach(function (child) {child.destroy( + );}); if (this.stage.projectionSource) { + this.stage.stopProjection();}; (this.stage + ).children.forEach(morph => {if ((morph + ).stopTalking) {morph.stopTalking(); + }; if (morph.clearEffects) {(morph + ).clearEffects();};}); (this.stage + ).removeAllClones(); ide = (this.stage + ).parentThatIsA(IDE_Morph); if (ide) { + ide.controlBar.pauseButton.refresh(); + ide.controlBar.stopButton.refresh();}; + var dialog = world.children.filter(child => ( + child instanceof DialogBoxMorph)).filter((child + ) => child.key === 'screenshotMaker'); if ((dialog + ).length > 0) {dialog = dialog[0]; if (((dialog + ).button2.labelString.color.g > 0) && (((dialog + ).button1).labelString.name === 'circleSolid')) { + dialog.button1.action(); dialog.button1.fixLayout();};}; +}; \ No newline at end of file diff --git a/src/scenes.js b/src/scenes.js deleted file mode 100644 index 6910b44..0000000 --- a/src/scenes.js +++ /dev/null @@ -1,240 +0,0 @@ -/* - - scenes.js - - multi-scene support for Snap! - - written by Jens Mönig - jens@moenig.org - - Copyright (C) 2023 by Jens Mönig - - This file is part of Snap!. - - Snap! is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as - published by the Free Software Foundation, either version 3 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - - prerequisites: - -------------- - needs morphic.js and objects.js - - toc - --- - the following list shows the order in which all constructors are - defined. Use this list to locate code in this document: - - Project - Scene - - credits - ------- - scenes have been inspired by Ted Kaehlers's personal demos of HyperCard - and many discussions with Ted about the design and practice of HyperCard, - and by personal discussions with Wolfgang Slany about his design of - scenes in Catrobat/PocketCode, which I love and admire. - -*/ - -/*global modules, VariableFrame, StageMorph, SpriteMorph, Process, List, -normalizeCanvas, SnapSerializer, Costume, ThreadManager, IDE_Morph*/ - -// Project ///////////////////////////////////////////////////////// - -// I am a container for a set of one or more Snap! scenes, -// the IDE operates on an instance of me - -// Project instance creation: - -function Project (scenes, current) {var projectScene; this.scenes = (scenes || new List); this.currentScene = current; this.name = null; this.notes = null; this.thumbnail = null; projectScene = this.scenes.at(1); -if (projectScene) {this.name = projectScene.name; this.notes = projectScene.notes; this.thumbnail = normalizeCanvas(projectScene.stage.thumbnail(SnapSerializer.prototype.thumbnailSize));}; this.sceneIdx = null; -this.trash = [];}; Project.prototype.initialize = function anonymous () {this.currentScene = this.scenes.at(+this.sceneIdx || 1); return this;}; Project.prototype.addDefaultScene = function anonymous () { -var scene = new Scene; scene.addDefaultSprite(); this.scenes.add(scene);}; - -// Scene ///////////////////////////////////////////////////////// - -// I am a container for a Snap! stage, scene-global variables -// and its associated settings. -// I can be used as a slide in a presentation, a chapter in a narrative, -// a level in a game, etc. - -// Scene instance creation: - -function Scene(aStageMorph) { - this.name = ''; this.notes = ''; - this.globalVariables = aStageMorph ? - aStageMorph.globalVariables() : new VariableFrame; - this.stage = aStageMorph || new StageMorph(this.globalVariables); - this.hasUnsavedEdits = false; - this.unifiedPalette = false; - this.showCategories = true; - this.showPaletteButtons = true; - - // cached IDE state - this.sprites = new List; - this.currentSprite = null; - - // global settings (shared) - this.hiddenPrimitives = {}; - this.codeMappings = {}; - this.codeHeaders = {}; - this.customCategories = new Map; - - // global settings (copied) - this.enableCodeMapping = false; - this.enableInheritance = true; - this.enableSublistIDs = false; - this.enablePenLogging = false; - this.useFlatLineEnds = false; - this.enableLiveCoding = false; - this.enableHyperOps = true; - this.disableClickToRun = false; - this.penColorModel = 'hsv'; - - // for deserializing - do not persist - this.spritesDict = {}; - this.targetStage = null; - this.spriteIdx = null; - - // for undeleting sprites - do not persist - this.trash = []; -}; - -Scene.prototype.initialize = function () { - // initialize after deserializing - // only to be called by store - var objs = this.stage.children.filter( - child => child instanceof SpriteMorph - ); objs.sort((x, y) => x.idx - y.idx); - this.sprites = new List(objs); - if (this.spriteIdx === null && this.sprites.length() > 0) { - this.currentSprite = this.sprites.at(1); - } else if (this.spriteIdx === 0) { - this.currentSprite = this.stage; - } else { - this.currentSprite = (this.sprites.at( - this.spriteIdx) || this.stage); - }; return this; -}; - -Scene.prototype.addDefaultSprite = function anonymous () {var sprite = new SpriteMorph(this.globalVariables -); sprite.setPosition(this.stage.center().subtract(sprite.extent().divideBy(2))); this.stage.add(sprite); -this.sprites.add(sprite); this.currentSprite = sprite; return sprite;}; /* New sprite to the stage. */ - -// Scene - capturing global state locally: - -Scene.prototype.captureGlobalSettings = function () { - this.hiddenPrimitives = StageMorph.prototype.hiddenPrimitives; - this.codeMappings = StageMorph.prototype.codeMappings; - this.codeHeaders = StageMorph.prototype.codeHeaders; - this.enableCodeMapping = StageMorph.prototype.enableCodeMapping; - this.enableInheritance = StageMorph.prototype.enableInheritance; - this.enableSublistIDs = StageMorph.prototype.enableSublistIDs; - this.enablePenLogging = StageMorph.prototype.enablePenLogging; - this.useFlatLineEnds = SpriteMorph.prototype.useFlatLineEnds; - this.enableLiveCoding = Process.prototype.enableLiveCoding; - this.enableHyperOps = Process.prototype.enableHyperOps; - this.customCategories = SpriteMorph.prototype.customCategories; - this.disableClickToRun = ThreadManager.prototype.disableClickToRun; - this.penColorModel = SpriteMorph.prototype.penColorModel; -}; - -Scene.prototype.applyGlobalSettings = function () { - StageMorph.prototype.hiddenPrimitives = this.hiddenPrimitives; - StageMorph.prototype.codeMappings = this.codeMappings; - StageMorph.prototype.codeHeaders = this.codeHeaders; - StageMorph.prototype.enableCodeMapping = this.enableCodeMapping; - StageMorph.prototype.enableInheritance = this.enableInheritance; - StageMorph.prototype.enableSublistIDs = this.enableSublistIDs; - StageMorph.prototype.enablePenLogging = this.enablePenLogging; - SpriteMorph.prototype.useFlatLineEnds = this.useFlatLineEnds; - Process.prototype.enableLiveCoding = this.enableLiveCoding; - Process.prototype.enableHyperOps = this.enableHyperOps; - SpriteMorph.prototype.customCategories = this.customCategories; - ThreadManager.prototype.disableClickToRun = this.disableClickToRun; - SpriteMorph.prototype.penColorModel = this.penColorModel; -}; - -// Scene ops: - -Scene.prototype.updateTrash = function () {this.trash = this.trash.filter(sprite => sprite.isCorpse);}; - -Scene.prototype.restart = function () { - var ide; window.speechSynthesis.cancel(); - this.stage.threads.pauseCustomHatBlocks = false; - this.stage.stopAllActiveSounds(true); - this.stage.children.map(function anonymous (sprite) { - if (sprite instanceof SpriteMorph) {sprite.stopFreq( - );};}); this.stage.clearEffects(); - this.stage.stopFreq(); - this.stage.keysPressed = {}; - this.stage.threads.stopAll(); - this.stage.timerProcedure.stopNow(); - world.children.filter(function ( - child) {if (child instanceof DialogBoxMorph - ) {return (child.key).includes('debug' - ) && contains(this.stage.threads.processes, - child.process);} else {return false;};} - ).forEach(function (child) {child.destroy( - );}); if (this.stage.projectionSource) { - this.stage.stopProjection(); - }; this.stage.children.forEach(morph => { - if (morph.stopTalking) { - morph.stopTalking(); - }; if (morph.clearEffects - ) {morph.clearEffects();}; - }); this.stage.removeAllClones(); - ide = this.stage.parentThatIsA(IDE_Morph); - if (ide) { - ide.controlBar.pauseButton.refresh(); - ide.controlBar.stopButton.refresh(); - }; this.stage.timerProcedure.startNow(); -}; - -Scene.prototype.stop = function (forGood) { - var ide; window.speechSynthesis.cancel(); - if (this.stage.enableCustomHatBlocks || forGood) { - this.stage.threads.pauseCustomHatBlocks = forGood ? true - : !this.stage.threads.pauseCustomHatBlocks; - } else { - this.stage.threads.pauseCustomHatBlocks = false; - }; this.stage.stopAllActiveSounds(); - this.stage.children.map(function anonymous (sprite) { - if (sprite instanceof SpriteMorph) {sprite.stopFreq( - );};}); this.stage.clearEffects(); - this.stage.stopFreq(); - this.stage.threads.resumeAll(this.stage); - this.stage.keysPressed = {}; - this.stage.runStopScripts(); - this.stage.threads.stopAll(); - this.stage.timerProcedure.stopNow(); - world.children.filter(function ( - child) {if (child instanceof DialogBoxMorph - ) {return (child.key).includes('debug' - ) && contains(this.stage.threads.processes, - child.process);} else {return false;};} - ).forEach(function (child) {child.destroy( - );}); if (this.stage.projectionSource) { - this.stage.stopProjection(); - }; this.stage.children.forEach(morph => { - if (morph.stopTalking) { - morph.stopTalking(); - }; if (morph.clearEffects - ) {morph.clearEffects();}; - }); this.stage.removeAllClones(); - ide = this.stage.parentThatIsA(IDE_Morph); - if (ide) { - ide.controlBar.pauseButton.refresh(); - ide.controlBar.stopButton.refresh(); - }; -}; \ No newline at end of file diff --git a/src/store.js b/src/store.js index 5b45424..399b877 100644 --- a/src/store.js +++ b/src/store.js @@ -7,7 +7,7 @@ written by Jens Mönig jens@moenig.org - Copyright (C) 2023 by Jens Mönig + Copyright (C) 2024 by Jens Mönig This file is part of Snap!. @@ -49,22 +49,6 @@ */ -/*global modules, XML_Element, VariableFrame, StageMorph, SpriteMorph, console, -WatcherMorph, Point, CustomBlockDefinition, Context, ReporterBlockMorph, Sound, -CommandBlockMorph, detect, CustomCommandBlockMorph, CustomReporterBlockMorph, -Color, List, newCanvas, Costume, Audio, IDE_Morph, ScriptsMorph, ArgLabelMorph, -BlockMorph, ArgMorph, InputSlotMorph, TemplateSlotMorph, CommandSlotMorph, -FunctionSlotMorph, MultiArgMorph, ColorSlotMorph, nop, CommentMorph, isNil, -localize, SVG_Costume, MorphicPreferences, Process, isSnapObject, Variable, -SyntaxElementMorph, BooleanSlotMorph, normalizeCanvas, contains, Scene, -Project*/ - -/*jshint esversion: 6*/ - -// Global stuff //////////////////////////////////////////////////////// - -modules.store = '2023-September-10'; modules.ypr = modules.store; - // XML_Serializer /////////////////////////////////////////////////////// /* I am an abstract prototype for my heirs. @@ -669,9 +653,7 @@ SnapSerializer.prototype.loadBlocks = function (xmlString, targetStage) { SnapSerializer.prototype.loadBlocksModel = function (model, targetStage) { // public - answer a new dictionary of custom block definitions // represented by the given already parsed XML Node - var stage; - - this.scene = new Scene; + var stage; this.scene = new Scene; this.scene.targetStage = targetStage; // for secondary block def look-up stage = this.scene.stage; model.palette = model.childNamed('palette'); @@ -679,25 +661,16 @@ SnapSerializer.prototype.loadBlocksModel = function (model, targetStage) { this.loadPalette(model.palette).forEach((value, key) => SpriteMorph.prototype.customCategories.set(key, value) ); - } - model.removeChild(model.palette); + }; model.removeChild(model.palette); this.loadCustomBlocks(stage, model, true); // global this.populateCustomBlocks(stage, model, true); // global model.local = model.childNamed('local'); if (model.local) { this.loadCustomBlocks(stage, model.local, false); // not global this.populateCustomBlocks( stage, model.local, false); // not global - } - this.objects = {}; - stage.globalBlocks.forEach(def => def.receiver = null); - this.objects = {}; - this.scene = new Scene(); - this.mediaDict = {}; - return { - global : stage.globalBlocks, - local : stage.customBlocks - }; -}; + }; this.objects = {}; stage.globalBlocks.forEach(def => def.receiver = null); + this.objects = {}; this.scene = new Scene; this.mediaDict = {}; return { + global : stage.globalBlocks, local : stage.customBlocks};}; SnapSerializer.prototype.loadSprites = function (xmlString, ide) { // public - import a set of sprites represented by xmlString @@ -711,44 +684,33 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) { model = this.parse(xmlString); if (+model.attributes.version > this.version) { throw 'Module uses newer version of Serializer'; - } - model.childrenNamed('sprite').forEach(model => { + }; model.childrenNamed('sprite').forEach(model => { var sprite = new SpriteMorph(scene.globalVariables); if (model.attributes.id) { this.objects[model.attributes.id] = sprite; - } - if (model.attributes.name) { + }; if (model.attributes.name) { sprite.name = ide.newSpriteName(model.attributes.name); scene.spritesDict[sprite.name] = sprite; - } - if (model.attributes.color) { + }; if (model.attributes.color) { sprite.color = this.loadColor(model.attributes.color); sprite.cachedColorDimensions = sprite.color[sprite.penColorModel](); - } - if (model.attributes.pen) { + }; if (model.attributes.pen) { sprite.penPoint = model.attributes.pen; - } - if (model.attributes.volume) { + }; if (model.attributes.volume) { sprite.volume = +model.attributes.volume; - } - if (model.attributes.pan) { + }; if (model.attributes.pan) { sprite.pan = +model.attributes.pan; - } - scene.stage.add(sprite); - ide.sprites.add(sprite); + }; scene.stage.add(sprite); ide.sprites.add(sprite); sprite.scale = parseFloat(model.attributes.scale || '1'); sprite.rotationStyle = parseFloat( - model.attributes.rotation || '1' - ); - sprite.isDraggable = model.attributes.draggable !== 'false'; - sprite.isVisible = model.attributes.hidden !== 'true'; + model.attributes.rotation || '1'); + sprite.setDraggableTo(model.attributes.draggable !== 'false' + ); sprite.isVisible = model.attributes.hidden !== 'true'; sprite.heading = parseFloat(model.attributes.heading) || 0; - sprite.gotoXY(+model.attributes.x || 0, +model.attributes.y || 0); - this.loadObject(sprite, model); - sprite.fixLayout(); - sprite.pauseGenericHatBlocks(); - }); + sprite.gotoXY(+model.attributes.x || 0, +((model.attributes + ).y) || 0); this.loadObject(sprite, model); (sprite + ).fixLayout(); sprite.pauseGenericHatBlocks();}); // restore inheritance and nesting associations scene.stage.children.forEach(sprite => { @@ -756,29 +718,24 @@ SnapSerializer.prototype.loadSprites = function (xmlString, ide) { if (sprite.inheritanceInfo) { // only sprites can inherit exemplar = scene.spritesDict[ sprite.inheritanceInfo.exemplar - ]; - if (exemplar) { - sprite.setExemplar(exemplar); - } - } - if (sprite.nestingInfo) { // only sprites may have nesting info + ]; if (exemplar) {sprite.setExemplar(exemplar);}; + }; if (sprite.nestingInfo) { // only sprites may have nesting info anchor = scene.spritesDict[sprite.nestingInfo.anchor]; if (anchor) { anchor.attachPart(sprite); - } - sprite.rotatesWithAnchor = (sprite.nestingInfo.synch === 'true'); - } - }); - scene.stage.children.forEach(sprite => { + }; sprite.rotatesWithAnchor = ( + sprite.nestingInfo.synch === 'true' + );};} ); (scene.stage + ).children.forEach(sprite => { delete sprite.inheritanceInfo; - if (sprite.nestingInfo) { // only sprites may have nesting info - sprite.nestingScale = +(sprite.nestingInfo.scale || sprite.scale); + if (sprite.nestingInfo) { + sprite.nestingScale = +( + (sprite.nestingInfo.scale + ) || sprite.scale); delete sprite.nestingInfo; - } - }); - - this.objects = {}; - this.scene = new Scene(); + }; + }); this.objects = {}; + this.scene = new Scene; this.mediaDict = {}; ide.stage.fixLayout(); @@ -1273,14 +1230,11 @@ migrateToVariadic = false, migrateInverse = false, skip; ) : new CustomReporterBlockMorph( info, info.type === 'predicate', - false - ); + false); }; if (isNil(block)) { block = this.obsoleteBlock(isReporter, false, model.attributes.s); - }; block.isDraggable = true; - inputs = block.inputs(); var i = 0, j = 0, child; - while (j < model.children.length) { - child = model.children[j]; + }; block.isDraggable = true; inputs = block.inputs(); var i = 0, j = 0, + child; while (j < model.children.length) {child = model.children[j]; if (child.tag === 'variables') { this.loadVariables(block.variables, child, object); } else if (child.tag === 'comment') { @@ -1463,7 +1417,7 @@ SnapSerializer.prototype.loadValue = function (model, object) { record(); return v; } - v = new List(); + v = new List; record(); v.contents = model.childrenNamed('item').map(item => { var value = item.children[0]; @@ -1503,8 +1457,8 @@ SnapSerializer.prototype.loadValue = function (model, object) { v.rotationStyle = parseFloat( model.attributes.rotation || '1' ); - v.isDraggable = model.attributes.draggable !== 'false'; - v.isVisible = model.attributes.hidden !== 'true'; + v.setDraggableTo(model.attributes.draggable !== 'false' + ); v.isVisible = model.attributes.hidden !== 'true'; v.heading = parseFloat(model.attributes.heading) || 0; v.gotoXY(+model.attributes.x || 0, +model.attributes.y || 0); this.loadObject(v, model); @@ -2389,9 +2343,8 @@ List.prototype.toXML = function (serializer, mediaContext) { }; Context.prototype.toXML = function (serializer) { - if (this.isContinuation) { // continuations are transient in Snap! - return ''; - }; return serializer.format( + if (this.isContinuation) {return ''; + }; return serializer.format( '%%' + '%%%%', this.inputs.reduce( diff --git a/src/symbols.js b/src/symbols.js index 247d3cb..3484312 100644 --- a/src/symbols.js +++ b/src/symbols.js @@ -931,7 +931,7 @@ SymbolMorph.prototype.renderSymbolStage = function (ctx, color, inverted) { h2 = h / 2; if (inverted) { - ctx.fillStyle = color.darker(25).toString(); + ctx.fillStyle = color.darker(50).toString(); ctx.fillRect(0, 0, w, h); ctx.fillStyle = color.toString(); @@ -940,7 +940,7 @@ SymbolMorph.prototype.renderSymbolStage = function (ctx, color, inverted) { ctx.fillStyle = color.toString(); ctx.fillRect(0, 0, w, h); - ctx.fillStyle = color.darker(25).toString(); + ctx.fillStyle = color.darker(50).toString(); ctx.fillRect(w2, 0, w2, h2); }; return ctx; }; diff --git a/src/tables.js b/src/tables.js index 77c53f7..4882320 100644 --- a/src/tables.js +++ b/src/tables.js @@ -7,7 +7,7 @@ written by Jens Mönig jens@moenig.org - Copyright (C) 2023 by Jens Mönig + Copyright (C) 2024 by Jens Mönig This file is part of Snap!. @@ -73,8 +73,6 @@ CostumeIconMorph, SoundIconMorph, localize*/ /*jshint esversion: 6*/ -modules.tables = '2023-September-10'; - var Table; var TableCellMorph; var TableMorph; @@ -97,9 +95,8 @@ function Table (cols, rows) { this.contents = new Array(+rows); for (var i = 0; i < rows; i += 1) { this.contents[i] = new Array(+cols); - }; - this.lastChanged = Date.now(); -} + }; this.lastChanged = Date.now(); +}; // Table testing: @@ -122,8 +119,8 @@ Table.prototype.get = function (col, row) { return this.rowName(row); } else if (!row) { return this.colName(col); - } - if (col > this.colCount || row > this.rowCount) {return null; } + }; if ((col > this.colCount) || ( + row > this.rowCount)) {return null;}; return (this.contents[row - 1] || [])[col - 1]; }; @@ -137,8 +134,7 @@ Table.prototype.col = function(col) { i; for (i = 0; i < this.rowCount; i += 1) { dta.push(this.contents[i][c]); - } - return dta; + }; return dta; }; Table.prototype.colName = function (col) { @@ -179,8 +175,8 @@ Table.prototype.set = function (data, col, row) { Table.prototype.setRows = function (rowsArray, colNames, rowNames) { this.contents = rowsArray; - if (colNames) {this.colNames = colNames; } - if (rowNames) {this.rowNames = rowNames; } + if (colNames) {this.colNames = colNames;}; + if (rowNames) {this.rowNames = rowNames;}; this.changed(); }; @@ -189,11 +185,10 @@ Table.prototype.setCols = function (colsArray, colNames, rowNames) { for (c = 0; c < this.colCount; c += 1) { for (r = 0; r < this.rowCount; r += 1) { this.contents[r][c] = colsArray[c][r]; - } - } - if (colNames) {this.colNames = colNames; } - if (rowNames) {this.rowNames = rowNames; } - this.changed(); + }; + }; if (colNames) {this.colNames = colNames; + }; if (rowNames) {this.rowNames = rowNames; + }; this.changed(); }; Table.prototype.setColNames = function (array) { @@ -223,8 +218,7 @@ Table.prototype.addRow = function (array, name) { this.contents[this.rowCount] = array; } else { this.contents[this.rowCount] = new Array(this.rowCount); - } - this.rowNames[this.rowCount] = name; + }; this.rowNames[this.rowCount] = name; this.rowCount += 1; this.changed(); }; @@ -234,9 +228,8 @@ Table.prototype.addCol = function (array, name) { if (array) { for (i = 0; i < this.col; i += 1) { this.contents[i][this.colCount] = array[i]; - } - } - this.colNames[this.colCount] = name; + }; + }; this.colNames[this.colCount] = name; this.colCount += 1; this.changed(); }; @@ -282,15 +275,14 @@ TableCellMorph.prototype.listSymbol = function () { SyntaxElementMorph.prototype.fontSize, SpriteMorph.prototype.blockColor.lists.darker(50) ); - } - return this.cachedListSymbol.getImage(); + }; return this.cachedListSymbol.getImage(); }; // TableCellMorph instance creation: function TableCellMorph(data, extent, isLabel) { this.init(data, extent, isLabel); -} +}; TableCellMorph.prototype.init = function (data, extent, isLabel) { // additional properties: @@ -310,8 +302,7 @@ TableCellMorph.prototype.setData = function (data, extent) { this.data = data; if (extent && (!extent.eq(this.extent()))) { this.bounds.setExtent(extent); - } - this.rerender(); + }; this.rerender(); }; TableCellMorph.prototype.getData = function () { @@ -345,8 +336,7 @@ TableCellMorph.prototype.render = function (ctx) { if (this.shouldBeList()) { BoxMorph.prototype.outlinePath.call( this, ctx, SyntaxElementMorph.prototype.corner + 1, 0 - ); - ctx.fill(); + ); ctx.fill(); } else if (this.isOvershooting()) { this.raggedBoxPath(ctx); ctx.fill(); @@ -388,12 +378,14 @@ TableCellMorph.prototype.dataRepresentation = function (dta) { if (!isNil(dta)) { if (dta instanceof Morph) { if (isSnapObject(dta)) { - return dta.thumbnail(new Point(40, 40), null, true); // no watchers + return dta.thumbnail( + new Point(40, 40), + null, true); } else { return dta.fullImage(); }; } else if (!isNil(dta.textRepresentation)) { - return dta.textRepresentation; + return getText(dta.textRepresentation, dta); } else if (typeof dta === 'number') { return dta.toString(); } else if (isString(dta)) { diff --git a/src/threads.js b/src/threads.js index f68b61b..feb34a1 100644 --- a/src/threads.js +++ b/src/threads.js @@ -62,47 +62,46 @@ isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, BLACK, TableFrameMorph, ColorSlotMorph, isSnapObject, newCanvas, Symbol, SVG_Costume, SnapExtensions, AlignmentMorph, TextMorph, Cloud*/ -var Numeral = function anonymous (number, base) {number = asANum(number); numeral = new Number(asANum(number)); numeral.base = base; numeral.textRepresentation = ''; if ((base < 2) || (base > 36)) {throw Error( -'You put in here an illegal base!');}; var dividend = Math.trunc(Math.abs(number)), showChar = ((char) => ((char < 10) ? char : String.fromCharCode(char + 55)).toString()); while (!(dividend < base)) { -numeral.textRepresentation = (showChar(dividend % base)).concat(numeral.textRepresentation); dividend = Math.trunc(dividend / base);}; numeral.alphabetic = ((Math.sign(number) == -1) ? '-' : '' -).concat(showChar(dividend), numeral.textRepresentation); numeral.textRepresentation = (numeral.alphabetic).concat('\(', base, '\)'); numeral.isAlphanumerical = true; return numeral;}, -ComplexNumber = function anonymous (real, imag) {try {var number = new Number(asANum(real));} catch (err1) {var number = 0;}; number.isComplex = true; try {number.i = asANum(imag); +var Numeral = function (number, base) {number = asANum(number); numeral = new Number(asANum(number)); numeral.base = base; numeral.textRepresentation = ''; if ((base < 2) || (base > 36)) { +throw Error('You put in here an illegal base!');}; var dividend = Math.trunc(Math.abs(number)), showChar = (char => ((char < 10) ? char : String.fromCharCode(char + 55)).toString()); while ( +!(dividend < base)) {numeral.textRepresentation = (showChar(dividend % base)).concat(numeral.textRepresentation); dividend = Math.trunc(dividend / base);}; numeral.alphabetic = ((Math.sign( +number) == -1) ? '-' : '').concat(showChar(dividend), numeral.textRepresentation); numeral.textRepresentation = (numeral.alphabetic).concat('\(', base, '\)'); numeral.isAlphanumerical = true; +return numeral;}, ComplexNumber = function (real, imag) {try {var number = new Number(asANum(real));} catch (err1) {var number = 0;}; number.isComplex = true; try {number.i = asANum(imag); } catch (error) {number.i = 0;}; var imaginaryRepresentation = ((Math.abs(number.i) == 1) ? ((number.i > 0) ? 'i' : '-i') : (number.i).toString().concat('i')); number.textRepresentation = ( (number == 0) ? ((number.i == 0) ? '0' : imaginaryRepresentation) : number.toString().concat(((number.i > 0) ? '+' : ''), ((number.i == 0) ? '' : imaginaryRepresentation))); if ((+(number.i -) == 0) && (+number < Infinity)) {number.enableEditing = true;}; return number;}, asAComplexNum = function anonymous (n) {var real = +(asANum(n)); try {var imag = (isNil(n.i) ? 0 : +(asANum( -n.i)));} catch (error) {var imag = 0;}; return (new ComplexNumber(real, imag));}; ThreadManager, Process, Context, Variable, VariableFrame; /* I did this very super high effort to the Snavanced! mod. :~) */ -const NONNUMBERS = [true, false, '']; (function () {for (var i = 9; i <= 13; i += 1) {NONNUMBERS.push(String.fromCharCode(i));}; NONNUMBERS.push( -String.fromCharCode(160)); /* "zum Schneckengang verdorben, was Adlerflug geworden wäre" collecting edge-cases that somebody complained about on -Github. Folks, take it easy and keep it fun, okay? This type of things like this is patently ugly and slows Snap!. Thanks, for this. :-( */})(); +) == 0) && (+number < Infinity)) {number.enableEditing = true;}; return number;}, asAComplexNum = function (n) {var real = +(asANum(n)); try {var imag = (isNil(n.i) ? 0 : +(asANum(n.i)) +);} catch (error) {var imag = 0;}; return (new ComplexNumber(real, imag));}; ThreadManager, Process, Context, Variable, VariableFrame; const NONNUMBERS = [true, false, '']; (() => {for ( +var i = 9; i <= 13; i += 1) {NONNUMBERS.push(String.fromCharCode(i));}; NONNUMBERS.push(String.fromCharCode(160)); /* "zum Schneckengang verdorben, was Adlerflug geworden wäre" collecting +edge-cases that somebody complained about on Github. Folks, take it easy and keep it fun, okay? This type of things like this is patently ugly and slows Snap!. Thanks, for this. :-( */})(); function gammaFunction (x) { function gammaln(z) { - if (z>=1.5 && z<2.5) { + if (z >= 1.5 && z < 2.5) { lg=Math.log(helper(z)); - } else if (z>=2.5) { - lg=0; z1=z; - while (z1>=2.5) { - lg=lg+Math.log(z1-1); - z1=z1-1; - }; lg=lg+Math.log(helper(z1)); - } else if (z==1) { - lg=0; - } else { - lg=0; z1=z; - while (z1<1.5) { - lg=lg-Math.log(z1); - z1=z1+1; + } else if (z >= 2.5) { + lg = 0; z1 = z; + while (z1 >= 2.5) { + lg = lg + Math.log(z1 - 1); + z1 = z1 - 1; }; lg = lg + Math.log(helper(z1)); + } else if (z == 1) { + lg = 0; + } else { + lg = 0; z1 = z; + while (z1 < 1.5) { + lg = lg - Math.log(z1); + z1 = z1 + 1; + }; lg = lg + Math.log(helper(z1)); }; return lg; }; function helper(z) { var p = [0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7 - ]; var g = 7; z -= 1; var a = p[0], t = z + g + 0.5; + ]; var g = 7; z -= 1; var a = p[0], t = z + g + 0.5; for (var i = 1; i < p.length; i++) { a += p[i] / (z + i); - }; return Math.sqrt(2 * Math.PI) * Math.pow(t, (z + 0.5)) * Math.exp(-t) * a; -}; var result = Math.exp(gammaln(x)); return (isNaN(result) ? 0 : result);}; + }; return Math.sqrt(2 * Math.PI) * Math.pow(t, (z + 0.5)) * Math.exp(-t +) * a;}; var result = Math.exp(gammaln(x)); return (isNaN(result) ? 0 : result);}; function snapEquals(a, b) {if (isNil(a) || isNil(b)) { return a === b;}; if (a.equalTo || b.equalTo) {if ( @@ -150,7 +149,7 @@ function invoke( if (action instanceof Context) { if (receiver) { // optional action = proc.reportContextFor(receiver); - }; proc.initializeFor(action, (contextArgs || new List)); + }; proc.initializeFor(action, (contextArgs || new List)); } else if (action instanceof BlockMorph) { proc.topBlock = action; if (receiver) { @@ -161,7 +160,7 @@ function invoke( }; } else { throw new Error('expecting a receiver but getting ' + receiver); - }; proc.context = new Context( + }; proc.context = new Context( null, action.blockSequence( ), proc.homeContext); } else if (action.evaluate) { @@ -175,7 +174,7 @@ function invoke( throw new Error('expecting a block or ring but getting ' + action); }; if (suppressErrors) { proc.isCatchingErrors = false; - }; while (proc.isRunning()) { + }; while (proc.isRunning()) { if (deadline && (Date.now() > deadline)) { throw (new Error( localize( @@ -183,9 +182,8 @@ function invoke( "a synchronous Snap! script has timed out") ) ); - }; proc.runStep(deadline); - }; return returnContext ? proc.homeContext : proc.homeContext.inputs[0]; -}; + }; proc.runStep(deadline); + }; return returnContext ? proc.homeContext : proc.homeContext.inputs[0];}; // ThreadManager /////////////////////////////////////////////////////// @@ -220,13 +218,14 @@ ThreadManager.prototype.startProcess = function ( if (active) { if (isThreadSafe) { return active; - }; active.stop(); + }; active.stop(); active.canBroadcast = true; this.removeTerminatedProcesses(); - }; newProc = new Process(top, receiver, callback, isClicked); - newProc.exportResult = exportResult; - newProc.isClicked = isClicked || false; - newProc.isAtomic = atomic || false; + }; newProc = new Process(top, receiver, + callback, isClicked); (newProc.exportResult + ) = exportResult; newProc.isClicked = ( + isClicked || false); (newProc.isAtomic + ) = atomic || false; // in case an optional variable frame has been passed, // copy it into the new outer context. @@ -238,7 +237,7 @@ ThreadManager.prototype.startProcess = function ( newProc.context.outerContext.variables.vars[ vName] = variables.vars[vName] ); - }; // show a highlight around the running stack + }; // show a highlight around the running stack // if there are more than one active processes for // a block, display the thread count next to it glow = top.getHighlight(); @@ -247,20 +246,19 @@ ThreadManager.prototype.startProcess = function ( glow.updateReadout(); } else { top.addHighlight(); - }; this.processes.push(newProc); - if (rightAway) {newProc.runStep();}; - return newProc; -}; + }; this.processes.push(newProc); + if (rightAway) {newProc.runStep( + );}; return newProc;}; ThreadManager.prototype.stopAll = function (excpt) {this.processes.forEach( proc => {if (proc !== excpt) {proc.stop();};});}; /* Useful for you. :~) */ ThreadManager.prototype.stopAllForReceiver = function (rcvr, excpt) {this.processes.forEach(proc => {if -(proc.homeContext.receiver === rcvr && proc !== excpt) {proc.stop(); if (rcvr.isTemporary) {proc.isDead = true;}}});}; +(proc.homeContext.receiver === rcvr && proc !== excpt) {proc.stop(); if (rcvr.isTemporary) {proc.isDead = true;};};});}; ThreadManager.prototype.stopAllForBlock = function (aTopBlock) {this.processesForBlock(aTopBlock, true).forEach(proc => proc.stop());}; ThreadManager.prototype.stopProcess = function (block, receiver) {var active = this.findProcess(block, receiver); if (active) {active.stop();};}; -ThreadManager.prototype.pauseAll = function anonymous (stage) {window.speechSynthesis.pause(); this.processes.forEach(proc => (proc.root instanceof BlockMorph -) ? ((proc.root.selector === 'receiveInteraction') ? ((proc.root.inputs()[0].evaluate() === 'paused') ? null : proc.pause()) : proc.pause()) : proc.pause()); +ThreadManager.prototype.pauseAll = function (stage) {window.speechSynthesis.pause(); this.processes.forEach(proc => (proc.root instanceof BlockMorph) ? ( +(proc.root.selector === 'receiveInteraction') ? ((proc.root.inputs()[0].evaluate() === 'paused') ? null : proc.pause()) : proc.pause()) : proc.pause()); world.childThatIsA(StageMorph).runPauseScripts(); if (stage) {stage.pauseAllActiveSounds();};}; /* The tts will be paused in any cirmcunstance too! :o */ ThreadManager.prototype.isPaused = function anonymous () {return detect(this.processes, (proc => proc.isPaused)) !== null;}; ThreadManager.prototype.resumeAll = function anonymous (stage) {window.speechSynthesis.resume(); this.processes.forEach( @@ -373,17 +371,13 @@ ThreadManager.prototype.processesForBlock = function (block, only) { }; ThreadManager.prototype.doWhen = function (block, receiver, stopIt) { - if (this.pauseCustomHatBlocks) {return; } - if ((!block) || this.findProcess(block, receiver)) { - return; - }; var pred = block.inputs()[0], world, test; - if (block.removeHighlight()) { - world = block.world(); - if (world) { - world.hand.destroyTemporaries(); - }; - }; if (stopIt) {return;}; - try { + if (this.pauseCustomHatBlocks) {return;}; + if ((!block) || this.findProcess(block, + receiver)) {return;}; var pred = (block + ).inputs()[0], test; if ((block + ).removeHighlight()) {if (world + ) {world.hand.destroyTemporaries(); + };}; if (stopIt) {return;}; try { test = invoke( pred, null, @@ -419,17 +413,13 @@ ThreadManager.prototype.doWhen = function (block, receiver, stopIt) { }; }; -ThreadManager.prototype.toggleSingleStepping = function () { - Process.prototype.enableSingleStepping = - !Process.prototype.enableSingleStepping; +ThreadManager.prototype.toggleSingleStepping = function ( + ) {(Process.prototype.enableSingleStepping + ) = !(Process.prototype.enableSingleStepping); if (!Process.prototype.enableSingleStepping) { this.processes.forEach(proc => { - if (!proc.isPaused) { - proc.unflash(); - }; - }); - }; -}; + if (!(proc.isPaused)) { + proc.unflash();};});};}; ThreadManager.prototype.clickFrameFor = function (block) { // private - answer a variable frame or null containing upvar declarations @@ -438,13 +428,11 @@ ThreadManager.prototype.clickFrameFor = function (block) { if (block instanceof HatBlockMorph) { if (block.selector === 'receiveKey' || block.selector === 'receiveMessage') { - name = block.inputs()[1].evaluate()[0]; + name = (((block.inputs())[1]).evaluate())[0]; if (name) { - frame = new VariableFrame(); + frame = new VariableFrame; frame.addVar(name, ''); - return frame; - }; -};}; return null;}; + return frame;};};}; return null;}; // Process ///////////////////////////////////////////////////////////// @@ -467,7 +455,7 @@ ThreadManager.prototype.clickFrameFor = function (block) { whenever the process runs into a timeout. a Process runs for a receiver, i.e. a sprite or the stage or any - blocks-scriptable object that we'll introduce. + blocks-scriptable object that we will introduce. structure: @@ -532,9 +520,10 @@ function Process (topBlock, receiver, onComplete, yieldFirst) { this.isShowingResult = false; this.errorFlag = false; this.context = null; - this.homeContext = new Context(null, null, null, receiver); - this.lastYield = Date.now(); - this.isFirstStep = true; + this.homeContext = new Context( + null, null, null, receiver); + this.lastYield = Date.now( + ); this.isFirstStep = true; this.isAtomic = false; this.prompter = null; this.httpRequest = null; @@ -552,22 +541,20 @@ function Process (topBlock, receiver, onComplete, yieldFirst) { this.canBroadcast = true; // used to control "when I am stopped" if (topBlock) { - this.homeContext.variables.parentFrame = - this.homeContext.receiver.variables; + (this.homeContext.variables.parentFrame + ) = this.homeContext.receiver.variables; this.context = new Context( null, - topBlock.blockSequence(), - this.homeContext - ); if (yieldFirst) { - this.pushContext('doYield'); // highlight top block - }; - }; -}; + topBlock.blockSequence( + ), this.homeContext + ); if (yieldFirst) { + this.pushContext('doYield'); + };};}; // Process accessing -Process.prototype.isRunning = function anonymous () { -return !this.readyToTerminate && (this.context || this.isPaused);}; +Process.prototype.isRunning = function () {return !((this +).readyToTerminate) && (this.context || this.isPaused);}; // Process entry points @@ -601,10 +588,8 @@ Process.prototype.runStep = function (deadline) { this.homeContext.receiver && this.homeContext.receiver.endWarp) { this.homeContext.receiver.endWarp(); - }; - return; - }; - this.evaluateContext(); + }; return; + }; this.evaluateContext(); }; this.stepFrameCount = 0; @@ -615,35 +600,31 @@ Process.prototype.runStep = function (deadline) { // make sure to redraw atomic things if (this.isAtomic && this.homeContext.receiver && - this.homeContext.receiver.endWarp) { - this.homeContext.receiver.endWarp(); + this.homeContext.receiver.endWarp + ) {this.homeContext.receiver.endWarp(); this.homeContext.receiver.startWarp(); - }; - - if (this.readyToTerminate) { - while (this.context) { - this.popContext(); - }; + }; if (this.readyToTerminate + ) {while (this.context + ) {this.popContext();}; if (this.homeContext.receiver) { if (this.homeContext.receiver.endWarp) { // pen optimization this.homeContext.receiver.endWarp(); }; - }; - }; -}; + };};}; -Process.prototype.stop = function anonymous () {this.readyToYield = true; this.readyToTerminate = true; this.errorFlag = false; if (this.context) {this.context.stopMusic();}; this.canBroadcast = false;}; +Process.prototype.stop = function () {this.errorFlag = false; (this.readyToTerminate +) = true; this.readyToYield = true; this.canBroadcast = false; if (this.context) {(this +).context.stopMusic();}; if (isSnapObject(this.receiver)) {(this.receiver).stopFreq();};}; -Process.prototype.stopTheScript = function anonymous (aScript) {myObj = this.receiver; world.children[0].stage.threads.processes.map(function anonymous (process) {var block = (process.root || process.topBlock); -if ((block instanceof HatBlockMorph) || (block instanceof DefinitorBlockMorph)) {if ((aScript = block) && (process.receiver === myObj)) {process.stop(); return process;} else {return process;};} else { -return process;};});}; Process.prototype.stopTheMessage = function anonymous (aMessage) {try {/* This block stops the current hats of the selected message, when this block stops the selected message hats, these -hats have to quit it's other JS processes. */ var stg = world.children[0].stage; stg.lastMessage = ''; myObj = this.receiver; stg.threads.processes.map(function anonymous (process) {var block = -process.context.expression.topBlock(); if ((block instanceof HatBlockMorph) && (block.selector === 'receiveMessage') && (block.inputs()[0].evaluate() === (aMessage || null)) && (process.receiver === myObj)) { -process.stop(); return process;} else {return process;};}); /* This is a "stop broadcasting of %message" block, you can see the code of this block. Uses working JS.*/} catch (err) {/* When an error appears, the "stop broadcasting of %message" block, make the block to stop, but, if there is a block above, has no effect. */};}; +Process.prototype.stopTheScript = function (aScript) {myObj = this.receiver; world.children[0].stage.threads.processes.map(function (process) {var block = (process.root || process.topBlock +); if ((block instanceof HatBlockMorph) || (block instanceof DefinitorBlockMorph)) {if ((aScript = block) && (process.receiver === myObj)) {process.stop(); return process;} else {return ( +process);};} else {return process;};});}; Process.prototype.stopTheMessage = function (aMessage) {try {var stg = world.children[0].stage; stg.lastMessage = ''; myObj = this.receiver; +stg.threads.processes.map(function (process) {var block = process.context.expression.topBlock(); if ((block instanceof HatBlockMorph) && (block.selector === 'receiveMessage' +) && (block.inputs()[0].evaluate() === (aMessage || null))) && (process.receiver === myObj)) {process.stop(); return process;} else {return process;};});} catch (err) {};}; -Process.prototype.pause = function () {if (this.readyToTerminate) {return;}; this.isPaused = true; this.flashPausedContext(); if (this.context && this.context.startTime) {this.pauseOffset = -Date.now() - this.context.startTime;};}; Process.prototype.resume = function () {if (!this.enableSingleStepping) {this.unflash();}; this.isPaused = false; this.pauseOffset = null;}; +Process.prototype.pause = function () {if (this.readyToTerminate) {return;}; this.isPaused = true; this.flashPausedContext(); if (this.context && this.context.startTime) {(this.pauseOffset +) = (Date.now() - this.context.startTime);};}; Process.prototype.resume = function () {if (!(this.enableSingleStepping)) {this.unflash();}; this.isPaused = false; this.pauseOffset = null;}; Process.prototype.pauseStep = function () {this.lastYield = Date.now(); if (this.context && this.context.startTime) {this.context.startTime = this.lastYield - this.pauseOffset;};}; @@ -660,29 +641,33 @@ Process.prototype.evaluateContext = function () { // by how much time has elapsed since the last yield, but since // looking up the system time is surprisingly costly only look it // up every 100 frames. + this.frameCount += 1; this.stepFrameCount += 1; if (this.stepFrameCount > 100) { - this.currentTime = Date.now(); - this.stepFrameCount = 0; - }; if (this.context.tag === 'exit') { - this.expectReport(); - }; if (exp instanceof Array) { - return this.evaluateSequence(exp); - }; if (exp instanceof MultiArgMorph) { - return this.evaluateMultiSlot(exp, exp.inputs().length); - }; if (exp instanceof ArgLabelMorph) { - return this.evaluateArgLabel(exp); - }; if (exp instanceof ArgMorph || exp.bindingID) { - return this.evaluateInput(exp); - }; if (exp instanceof BlockMorph) { - return this.evaluateBlock(exp, exp.inputs().length); - }; if (isString(exp)) { - return this[exp].apply(this, this.context.inputs); - }; if (exp instanceof Variable) { // special case for empty reporter rings - this.returnValueToParentContext(exp.value); - }; this.popContext(); // default: just ignore it -}; + this.currentTime = Date.now( + ); this.stepFrameCount = 0; + }; if (this.context.tag === 'exit' + ) {this.expectReport();}; if ( + exp instanceof Array) {return ( + this.evaluateSequence(exp));}; if ( + exp instanceof MultiArgMorph) { + return this.evaluateMultiSlot( + exp, exp.inputs().length);}; if ( + exp instanceof ArgLabelMorph) { + return this.evaluateArgLabel(exp + );}; if ((exp instanceof ArgMorph + ) || exp.bindingID) {return (this + ).evaluateInput(exp);}; if ( + exp instanceof BlockMorph) { + return this.evaluateBlock(exp, + exp.inputs().length);}; if ( + isString(exp)) {return (this[ + exp]).apply(this, (this + ).context.inputs);}; if ( + exp instanceof Variable) { + this.returnValueToParentContext( + exp.value);}; this.popContext();}; Process.prototype.evaluateBlock = function (block, argCount) { var rcvr, inputs, selector = block.selector; @@ -729,66 +714,64 @@ Process.prototype.evaluateBlock = function (block, argCount) { }; }; -/* Process: Beep Sound */ Process.prototype.playBeep = function anonymous () {var beep = WorldMorph.prototype.beepSound; if (beep instanceof Audio) {beep.currentTime = 0; -beep.play();}; if ((world.children.filter(child => child instanceof FlashMorph) < 1) && asABool(localStorage['-snap-setting-flashScreenInBeep'])) {new FlashMorph;};}; +Process.prototype.playBeep = function () {var beep = WorldMorph.prototype.beepSound; if (beep instanceof Audio) {beep.currentTime = 0; beep.play();}; +if ((world.children.filter(child => child instanceof FlashMorph) < 1) && asABool(localStorage['-snap-setting-flashScreenInBeep'])) {new FlashMorph;};}; // Process: Primitive Extensions (for libraries etc.) -Process.prototype.doApplyExtension = function (prim, args) {this.reportApplyExtension(prim, args);}; +Process.prototype.doApplyExtension = function (prim, +args) {this.reportApplyExtension(prim, args);}; Process.prototype.reportApplyExtension = function (prim, args) { var ext = SnapExtensions.primitives.get(prim); if (isNil(ext)) { throw new Error(localize('missing / unspecified extension') + ': ' + prim); - }; return ext.apply( + }; return ext.apply( this.blockReceiver(), args.itemsArray().concat([this]) - ); -}; - -Process.prototype.doPauseThread = function anonymous () {var myself = this; if (!myself.debugDialog) {myself.debugDialog = new DialogBoxMorph; myself.debugDialog.setPicture(myself.topBlock.fullImage()); -myself.debugDialog.labelString = myself.blockReceiver().name + ' ^'; myself.debugDialog.addButton(function anonymous () {this.isDestroyed = true; this.destroy();}, new SymbolMorph('pointRight', 12)); -myself.debugDialog.addButton(function () {myself.stop(); this.destroy();}, new SymbolMorph('rectangle', 12)); myself.debugDialog.key = ('debug - ' + Date.now()); myself.debugDialog.process = myself; -myself.debugDialog.createLabel(); myself.debugDialog.fixLayout(); myself.debugDialog.popUp(world); myself.isOnDebug = true; myself.pushContext('doYield'); myself.pushContext();} else {if ( -!myself.debugDialog.isDestroyed) {myself.pushContext('doYield'); myself.pushContext();} else {myself.debugDialog = null;};};}; Process.prototype.reportInPause = function (input) {var myself = this; -if (!myself.debugDialog) {myself.debugDialog = new DialogBoxMorph; myself.debugDialog.setPicture(myself.topBlock.fullImage()); myself.debugDialog.labelString = myself.blockReceiver().name + ' ^'; -myself.debugDialog.addButton(function anonymous () {this.isDestroyed = true; this.destroy();}, new SymbolMorph('pointRight', 12)); myself.debugDialog.addButton(function () {myself.stop(); -this.destroy();}, new SymbolMorph('rectangle', 12)); myself.debugDialog.key = ('debug - ' + Date.now()); myself.debugDialog.process = myself; myself.debugDialog.createLabel(); myself.debugDialog.fixLayout( -); myself.debugDialog.popUp(world); myself.isOnDebug = true; myself.pushContext('doYield'); myself.pushContext();} else {if (!myself.debugDialog.isDestroyed) {this.context.inputs = []; -myself.pushContext('doYield'); myself.pushContext();} else {myself.debugDialog = null; myself.returnValueToParentContext(input);};};}; Process.prototype.durationOf = function anonymous (action) {if (action instanceof CommandBlockMorph) {if (!this.context.startTime) {this.context.startTime = Date.now();}; if (this.context.isOnlyToOnce) {delete this.context.isOnlyToOnce; return (Date.now() - this.context.startTime -) / 1000;} else {this.context.isOnlyToOnce = true; this.pushContext(action.blockSequence()); this.pushContext('doYield'); this.pushContext();};} else {return 0;};}; -Process.prototype.reportLocalStorage = function anonymous () {return new List(new Array(new List(Object.keys(localStorage)), new List(Object.values(localStorage))));}; -Process.prototype.blockComment = nop; Process.prototype.doIgnoreValue = nop; Process.prototype.scriptNamer = function anonymous (name, action) {action = action.at(1); if (action instanceof CommandBlockMorph -) {if (this.context.isOnlyToOnce) {delete this.context.isOnlyToOnce;} else {this.context.isOnlyToOnce = true; this.pushContext(action.blockSequence()); this.pushContext('doYield'); this.pushContext();};}; -}; Process.prototype.scriptChanger = function anonymous (option, block, selector) {if (!(block instanceof Context)) {block = this.reify(null, new List);}; if (block.expression instanceof BlockMorph) {if ( -selector.length() > 0) {selector = selector.at(1);} else {selector = block.expression.selector;};} else {return block;}; var result = Process.prototype.reportBlockAttribute(['sequence'], block).map( -block => Process.prototype.basicScriptChanger(Process.prototype.inputOption(option), block, selector)); if (result.length() < 2) {result = result.at(1);}; return result;}; -Process.prototype.basicScriptChanger = function anonymous (option, block, selector) {if (option === 'commandize') {if (block.expression.isCustomBlock) {var aDefinition = copy(block.expression.definition); -aDefinition.type = 'command'; var aBlock = new CustomCommandBlockMorph(aDefinition);} else {var aBlock = new CommandBlockMorph;};} else if (contains(['reporterize', 'predicatize', 'arrowize'], option)) { -if (block.expression.isCustomBlock) {var aDefinition = copy(block.expression.definition); aDefinition.type = ((option === 'predicatize') ? 'predicate' : ((option === 'arrowize') ? 'arrow' : 'reporter')); -var aBlock = new CustomReporterBlockMorph(aDefinition);} else {var aBlock = new ReporterBlockMorph((option === 'predicatize'), (option === 'arrowize'));};} else if (option === 'hatize') { -var aBlock = new HatBlockMorph;} else if (option === 'definitize') {var aBlock = new DefinitorBlockMorph;} else if (option === 'ringize') {var aBlock = new RingMorph;} else { -var aBlock = new JaggedBlockMorph;}; var i = 0; if (!(block.expression.isCustomBlock)) {aBlock.selector = selector;}; aBlock.setSpec('block'); aBlock.children[aBlock.children.length - 1 -].destroy(); aBlock.category = block.expression.category; while (i < block.expression.children.length) {if (block.expression.isCustomBlock) {aBlock.children[i] = block.expression.children[ -i].fullCopy();} else {aBlock.add(block.expression.children[i].fullCopy());}; i++;}; aBlock.blockSpec = block.expression.blockSpec; aBlock.fixLayout(); aBlock.fixBlockColor(); return ( -aBlock instanceof CommandBlockMorph) ? Process.prototype.reportScript(new List, aBlock) : Process.prototype.reify(aBlock, new List);}; /* This is so cool! Please use it! :~) */ - -Process.prototype.reportVariadicAnd = function anonymous (inputs) {this.assertType(inputs, 'list'); if (inputs.length() > 2) {return this.reportAnd(inputs.at(1), this.reportVariadicAnd(inputs.cdr()));} else if ( -inputs.length() > 1) {return this.reportAnd(inputs.at(1), inputs.at(2));} else if (inputs.length() > 0) {return asABool(inputs.at(1));} else {return true;};}; Process.prototype.reportAnd = function anonymous ( -input1, input2) {if (input1 instanceof List) {input1 = this.reportVariadicAnd(input1);}; if (input2 instanceof List) {input2 = this.reportVariadicAnd(input2);}; return asABool(this.reportBasicAnd(input1, input2) -);}; Process.prototype.reportBasicAnd = function anonymous (input1, input2) {return +((Math.sign(Math.abs(input1)) + Math.sign(Math.abs(input2))) > 1);}; -Process.prototype.reportVariadicOr = function anonymous (inputs) {this.assertType(inputs, 'list'); if (inputs.length() > 2) {return this.reportOr(inputs.at(1), this.reportVariadicOr(inputs.cdr()));} else if ( -inputs.length() > 1) {return this.reportOr(inputs.at(1), inputs.at(2));} else if (inputs.length() > 0) {return asABool(inputs.at(1));} else {return false;};}; Process.prototype.reportOr = function anonymous ( -input1, input2) {if (input1 instanceof List) {input1 = this.reportVariadicOr(input1);}; if (input2 instanceof List) {input2 = this.reportVariadicOr(input2);}; return asABool(this.reportBasicOr(input1, input2) -);}; Process.prototype.reportBasicOr = function anonymous (input1, input2) {return +((Math.sign(Math.abs(input1)) + Math.sign(Math.abs(input2))) > 0);}; -Process.prototype.reportOnlyOne = function anonymous (inputs) {return (inputs.filter(input => (input === true)).length === 1);}; -/* Isn't variadic "xor" but is useful in some cases but "xor" isn't an associative operator. Only the arrays are to use here. */ -Process.prototype.reportXor = function anonymous (input1, input2) {this.assertType(input1, ['nothing', 'number', 'Boolean']); -this.assertType(input2, ['nothing', 'number', 'Boolean']); return asABool(this.reportBasicXor(input1, input2));}; -Process.prototype.reportBasicXor = function anonymous (input1, input2) {return +(Math.abs(Math.sign(Math.abs( -input1)) - Math.sign(Math.abs(input2))) > 0);}; Process.prototype.reportNot = function anonymous (input) { -myself = this; return ((input instanceof List) ? (input.fullCopy().map(item => myself.reportNot(item)) -) : asABool(myself.reportBasicNot(input)));}; Process.prototype.reportBasicNot = function anonymous ( + );}; + +Process.prototype.doPauseThread = function () {var myself = this; if (!(myself.debugDialog)) {myself.debugDialog = new DialogBoxMorph; myself.debugDialog.setPicture(myself.topBlock.fullImage( +)); myself.debugDialog.labelString = myself.blockReceiver().name + ' ^'; myself.debugDialog.addButton(function () {this.isDestroyed = true; this.destroy();}, new SymbolMorph('pointRight', 12) +); myself.debugDialog.addButton(function () {myself.stop(); this.destroy();}, new SymbolMorph('rectangle', 12)); myself.debugDialog.key = ('debug - ' + Date.now()); (myself.debugDialog.process +) = myself; myself.debugDialog.createLabel(); myself.debugDialog.fixLayout(); myself.debugDialog.popUp(world); myself.isOnDebug = true; myself.pushContext('doYield'); myself.pushContext(); +} else {if (!(myself.debugDialog.isDestroyed)) {myself.pushContext('doYield'); myself.pushContext();} else {myself.debugDialog = null;};};}; Process.prototype.reportInPause = function (input +) {var myself = this; if (!myself.debugDialog) {myself.debugDialog = new DialogBoxMorph; myself.debugDialog.setPicture(myself.topBlock.fullImage()); myself.debugDialog.labelString = ((myself +).blockReceiver().name + ' ^'); myself.debugDialog.addButton(function anonymous () {this.isDestroyed = true; this.destroy();}, new SymbolMorph('pointRight', 12)); myself.debugDialog.addButton( +function () {myself.stop(); this.destroy();}, new SymbolMorph('rectangle', 12)); myself.debugDialog.key = ('debug - ' + Date.now()); myself.debugDialog.process = myself; (myself.debugDialog +).createLabel(); myself.debugDialog.fixLayout(); myself.debugDialog.popUp(world); myself.isOnDebug = true; myself.pushContext('doYield'); myself.pushContext();} else {if (!((myself.debugDialog +).isDestroyed)) {this.context.inputs = []; myself.pushContext('doYield'); myself.pushContext();} else {myself.debugDialog = null; myself.returnValueToParentContext(input);};};}; (Process +).prototype.durationOf = function (action) {if (action instanceof CommandBlockMorph) {if (!(this.context.startTime)) {this.context.startTime = Date.now();}; if (this.context.isOnlyToOnce) { +delete this.context.isOnlyToOnce; return (Date.now() - this.context.startTime) / 1000;} else {this.context.isOnlyToOnce = true; this.pushContext(action.blockSequence()); this.pushContext( +'doYield'); this.pushContext();};} else {return 0;};}; Process.prototype.reportLocalStorage = function () {return new List([new List(Object.keys(localStorage)), new List(Object.values( +localStorage))]);}; Process.prototype.blockComment = nop; Process.prototype.doIgnoreValue = nop; Process.prototype.scriptNamer = function (name, action) {action = action.at(1); if ( +action instanceof CommandBlockMorph) {if (this.context.isOnlyToOnce) {delete this.context.isOnlyToOnce;} else {this.context.isOnlyToOnce = true; this.pushContext(action.blockSequence()); +this.pushContext('doYield'); this.pushContext();};};}; Process.prototype.scriptChanger = function anonymous (option, block, selector) {if (!(block instanceof Context)) {block = this.reify( +null, new List);}; if (block.expression instanceof BlockMorph) {if (selector.length() > 0) {selector = selector.at(1);} else {selector = block.expression.selector;};} else {return block; +}; var result = Process.prototype.reportBlockAttribute(['sequence'], block).map(block => Process.prototype.basicScriptChanger(Process.prototype.inputOption(option), block, selector)); +if (result.length() < 2) {result = result.at(1);}; return result;}; Process.prototype.basicScriptChanger = function anonymous (option, block, selector) {if (option === 'commandize') { +if (block.expression.isCustomBlock) {var aDefinition = copy(block.expression.definition); aDefinition.type = 'command'; var aBlock = new CustomCommandBlockMorph(aDefinition);} else { +var aBlock = new CommandBlockMorph;};} else if (contains(['reporterize', 'predicatize', 'arrowize'], option)) {if (block.expression.isCustomBlock) {var aDefinition = copy((block +).expression.definition); aDefinition.type = ((option === 'predicatize') ? 'predicate' : ((option === 'arrowize') ? 'arrow' : 'reporter')); var aBlock = new CustomReporterBlockMorph( +aDefinition);} else {var aBlock = new ReporterBlockMorph((option === 'predicatize'), (option === 'arrowize'));};} else if (option === 'definitize') {var aBlock = new DefinitorBlockMorph; +} else if (option === 'hatize') {var aBlock = new HatBlockMorph;} else if (option === 'ringize') {var aBlock = new RingMorph;} else {var aBlock = new JaggedBlockMorph;}; var i = 0; if (!( +block.expression.isCustomBlock)) {aBlock.selector = selector;}; aBlock.setSpec('block'); aBlock.children[aBlock.children.length - 1].destroy(); aBlock.category = block.expression.category; +while (i < block.expression.children.length) {if (block.expression.isCustomBlock) {aBlock.children[i] = block.expression.children[i].fullCopy();} else {aBlock.add((block +).expression.children[i].fullCopy());}; i++;}; aBlock.blockSpec = block.expression.blockSpec; aBlock.fixLayout(); aBlock.fixBlockColor(); return (( +aBlock instanceof CommandBlockMorph) ? Process.prototype.reportScript(new List, aBlock) : Process.prototype.reify(aBlock));}; + +Process.prototype.reportVariadicAnd = function (inputs) {this.assertType(inputs, 'list'); if (inputs.length() > 2) {return this.reportAnd(inputs.at(1), this.reportVariadicAnd(inputs.cdr()));} else if ( +inputs.length() > 1) {return this.reportAnd(inputs.at(1), inputs.at(2));} else if (inputs.length() > 0) {return asABool(inputs.at(1));} else {return true;};}; Process.prototype.reportAnd = function ( +input1, input2) {if (input1 instanceof List) {input1 = this.reportVariadicAnd(input1);}; if (input2 instanceof List) {input2 = this.reportVariadicAnd(input2);}; return asABool(this.reportBasicAnd(input1, +input2));}; Process.prototype.reportBasicAnd = function (input1, input2) {return +((Math.sign(Math.abs(input1)) + Math.sign(Math.abs(input2))) > 1);}; Process.prototype.reportVariadicOr = function (inputs +) {this.assertType(inputs, 'list'); if (inputs.length() > 2) {return this.reportOr(inputs.at(1), this.reportVariadicOr(inputs.cdr()));} else if (inputs.length() > 1) {return this.reportOr(inputs.at(1), +inputs.at(2));} else if (inputs.length() > 0) {return asABool(inputs.at(1));} else {return false;};}; Process.prototype.reportOr = function (input1, input2) {if (input1 instanceof List) {input1 = (this +).reportVariadicOr(input1);}; if (input2 instanceof List) {input2 = this.reportVariadicOr(input2);}; return asABool(this.reportBasicOr(input1, input2));}; Process.prototype.reportBasicOr = function ( +input1, input2) {return +((Math.sign(Math.abs(input1)) + Math.sign(Math.abs(input2))) > 0);}; Process.prototype.reportOnlyOne = function (inputs) {return (inputs.filter(input => (input === true) +).length === 1);}; /* Isn't variadic "xor" but is useful in some cases but "xor" isn't an associative operator. Only the arrays are to use here. */ Process.prototype.reportXor = function (input1, +input2) {this.assertType(input1, ['nothing', 'number', 'Boolean']); this.assertType(input2, ['nothing', 'number', 'Boolean']); return asABool(this.reportBasicXor(input1, input2));}; (Process +).prototype.reportBasicXor = function (input1, input2) {return +(Math.abs(Math.sign(Math.abs(input1)) - Math.sign(Math.abs(input2))) > 0);}; Process.prototype.reportNot = function (input) { +myself = this; return ((input instanceof List) ? (input.fullCopy().map(item => myself.reportNot(item))) : asABool(myself.reportBasicNot(input)));}; Process.prototype.reportBasicNot = function ( input) {return (1 - Math.sign(Math.abs(input)));}; /* Any of the boolean operators are better. */ // Process: Special Forms Blocks Primitives @@ -827,8 +810,7 @@ Process.prototype.evaluateMultiSlot = function (multiSlot, argCount) { this.returnValueToParentContext(new List(inputs)); this.popContext(); }; - }; -}; + };}; Process.prototype.evaluateArgLabel = function (argLabel) { // perform the ID function on an ArgLabelMorph element @@ -838,8 +820,7 @@ Process.prototype.evaluateArgLabel = function (argLabel) { } else { this.returnValueToParentContext(inputs[0]); this.popContext(); - }; -}; + };}; Process.prototype.evaluateInput = function (input) { // evaluate the input unless it is bound to an implicit parameter @@ -868,8 +849,7 @@ Process.prototype.evaluateInput = function (input) { ans = this.reify(ans, new List); }; }; - }; this.returnValueToParentContext(ans); this.popContext(); -}; + }; this.returnValueToParentContext(ans); this.popContext();}; Process.prototype.evaluateSequence = function (arr) { var pc = this.context.pc, @@ -988,53 +968,58 @@ Process.prototype.evaluateNextInputSet = function (element) { }; }; -Process.prototype.doYield = function () {this.popContext(); if (!this.isAtomic) {this.readyToYield = true;};}; - -Process.prototype.expectReport = function () {this.handleError(new Error("The result is missing..."));}; +Process.prototype.doYield = function () {this.popContext(); if (!this.isAtomic) {this.readyToYield = true;}; +}; Process.prototype.expectReport = function () {this.handleError(new Error('The result is missing...'));}; // Process Exception Handling -Process.prototype.launchError = function (contents) {throw Error(contents, {cause: 'user'});}; Process.prototype.throwError = function (error, element) {var ide = this.homeContext.receiver.parentThatIsA( -IDE_Morph); this.stop(); this.errorFlag = true; this.topBlock.addErrorHighlight(); if (ide.isAppMode) {ide.showMessage(localize(error.name) + '\n' + error.message);} else {this.topBlock.showBubble( -this.errorBubble(error, element), this.exportResult, this.receiver);};}; Process.prototype.tryCatch = function anonymous (action, exception, errVarName) {var next = this.context.continuation(); -this.handleError = function anonymous (error) {this.resetErrorHandling(); if (!(exception instanceof Context)) {exception = this.reify(SpriteMorph.prototype.blockForSelector('doIgnoreValue'), -new List);}; if (exception.expression instanceof CommandBlockMorph) {exception.expression = exception.expression.blockSequence();} else {exception.expression = [exception.expression];}; -exception.pc = 0; exception.outerContext.variables.addVar(errVarName); exception.outerContext.variables.setVar(errVarName, error.message); this.context = exception; this.evaluate( -next, new List, true);}; this.evaluate(action, new List, true);}; Process.prototype.resetErrorHandling = function anonymous () {this.handleError = this.throwError;}; -Process.prototype.resetErrorHandling(); Process.prototype.commandObsolete = (() => {throw Error('This block isn\'t defined.');}); -Process.prototype.reporterObsolete = Process.prototype.commandObsolete; Process.prototype.errorBubble = function (error, -element) {var errorMorph = new AlignmentMorph('column', 5), errorIsNested = this.topBlock.isCustomBlock, -errorPrefix = errorIsNested ? `${localize('Inside a custom block')}\n` : '', errorMessage = new TextMorph( -`${errorPrefix}${localize(error.name)}\n${localize(error.message)}`, SyntaxElementMorph.prototype.fontSize), -blockToShow = element; errorMorph.add(errorMessage); if (errorIsNested && error.cause !== 'user') {if ( -blockToShow.selector === 'reportGetVar') {/* if I am a single variable, show my caller in the output */ -blockToShow = blockToShow.parent;}; errorMorph.children[0].text += `\n${localize('The question came up at')}`; -errorMorph.children[0].fixLayout(); errorMorph.add(blockToShow.fullCopy());}; errorMorph.fixLayout(); return errorMorph;}; +Process.prototype.launchError = function (contents) {throw Error(contents, {cause: 'user'});}; Process.prototype.throwError = function (error, element) {var ide = (this.homeContext.receiver).parentThatIsA( +IDE_Morph); this.stop(); this.errorFlag = true; this.topBlock.addErrorHighlight(); if (ide.isAppMode) {ide.showMessage(localize(error.name) + '\n' + error.message);} else {this.topBlock.showBubble((this +).errorBubble(error, element), this.exportResult, this.receiver);};}; Process.prototype.tryCatch = function (action, exception, errVarName) {var next = this.context.continuation(); (this.handleError +) = function (error) {this.resetErrorHandling(); if (!(exception instanceof Context)) {exception = this.reify(SpriteMorph.prototype.blockForSelector('doIgnoreValue'), new List);}; if ((exception +).expression instanceof CommandBlockMorph) {exception.expression = exception.expression.blockSequence();} else {exception.expression = [exception.expression];}; exception.pc = 0; (exception +).outerContext.variables.addVar(errVarName); exception.outerContext.variables.setVar(errVarName, error.message); this.context = exception; this.evaluate(next, new List, true);}; this.evaluate( +action, new List, true);}; Process.prototype.resetErrorHandling = function () {this.handleError = this.throwError;}; Process.prototype.resetErrorHandling(); Process.prototype.commandObsolete = ( +() => {throw Error('This block isn\'t defined.');}); Process.prototype.reporterObsolete = Process.prototype.commandObsolete; Process.prototype.errorBubble = function (error, element) { +var errorMorph = new AlignmentMorph('column', 5), errorIsNested = this.topBlock.isCustomBlock, errorPrefix = errorIsNested ? `${localize('Inside a custom block')}\n` : '', errorMessage = ( +new TextMorph(`${errorPrefix}${localize(error.name)}\n${localize(error.message)}`, SyntaxElementMorph.prototype.fontSize)), blockToShow = element; errorMorph.add(errorMessage); if ( +errorIsNested && error.cause !== 'user') {if (blockToShow instanceof BlockMorph) {if (blockToShow.selector === 'reportGetVar') {blockToShow = blockToShow.parent;}; errorMorph.children[ +0].text += `\n${localize('The question came up at')}`; errorMorph.children[0].fixLayout(); errorMorph.add(blockToShow.fullCopy());};}; errorMorph.fixLayout(); return errorMorph;}; // Process Lambda primitives -Process.prototype.reify = function (topBlock, parameterNames, isCustomBlock) {var context = new Context(null, null, (this.context ? this.context.outerContext : null -)), i = 0; if (topBlock) {context.expression = this.enableLiveCoding || this.enableSingleStepping ? topBlock : topBlock.fullCopy(); context.expression.show(); if ( -!isCustomBlock && !(parameterNames.length())) {context.expression.allEmptySlots().forEach(slot => {i += 1; if (slot instanceof MultiArgMorph) {slot.bindingID = Symbol.for( -'arguments');} else {slot.bindingID = i;};}); context.emptySlots = i;};} else {context.expression = this.enableLiveCoding || this.enableSingleStepping ? [this.context.expression -] : [this.context.expression.fullCopy()];}; context.inputs = parameterNames.itemsArray(); context.receiver = this.context ? this.context.receiver : this.receiver; -context.origin = context.receiver; return context;}; Process.prototype.reportScript = function (parameterNames, topBlock) {var context = this.reify((( -topBlock instanceof Morph) ? topBlock.fullCopy() : null), parameterNames); context.selector = 'reportScript'; return context;}; -Process.prototype.reifyScript = function (topBlock, parameterNames) {var context = this.reportScript(parameterNames, topBlock); -context.selector = 'reifyScript'; return context;}; Process.prototype.reifyReporter = function (topBlock, parameterNames) { -var context = this.reify(topBlock, parameterNames); context.selector = 'reifyReporter'; return context;}; -Process.prototype.reifyPredicate = function (topBlock, parameterNames) {var context = this.reify( -topBlock, parameterNames); context.selector = 'reifyPredicate'; return context;}; +Process.prototype.reify = function (topBlock, parameterNames, isCustomBlock) { +var context = new Context(null, null, (this.context ? (this.context.outerContext +) : null)), i = 0; if (isNil(parameterNames)) {parameterNames = new List;}; if ( +topBlock) {context.expression = this.enableLiveCoding || (this.enableSingleStepping +) ? topBlock : topBlock.fullCopy(); context.expression.show(); if (!(isCustomBlock +) && !(parameterNames.length())) {context.expression.allEmptySlots().forEach((slot +) => {i += 1; if (slot instanceof MultiArgMorph) {slot.bindingID = Symbol.for( +'arguments');} else {slot.bindingID = i;};}); context.emptySlots = i;};} else { +context.expression = this.enableLiveCoding || this.enableSingleStepping ? [(this +).context.expression] : [this.context.expression.fullCopy()];}; context.inputs = ( +parameterNames.itemsArray()); context.receiver = this.context ? (this.context.receiver +) : this.receiver; context.origin = context.receiver; return context;}; (Process +).prototype.reportScript = function (parameterNames, topBlock) {var context = (this +).reify(((topBlock instanceof Morph) ? topBlock.fullCopy() : null), parameterNames); +context.selector = 'reportScript'; return context;}; (Process.prototype.reifyScript +) = function (topBlock, parameterNames) {var context = this.reportScript(parameterNames, +topBlock); context.selector = 'reifyScript'; return context;}; (Process.prototype +).reifyReporter = function (topBlock, parameterNames) {var context = this.reify( +topBlock, parameterNames); context.selector = 'reifyReporter'; return context; +}; Process.prototype.reifyPredicate = function (topBlock, parameterNames) { +var context = this.reify(topBlock, parameterNames); (context +).selector = 'reifyPredicate'; return context;}; // First Class Colors -Process.prototype.getColor = function anonymous ( -data) {if (this.reportTypeOf(data) === 'color') { -return data;} else {throw Error('This isn\'t a color.' -);};}; Process.prototype.makeColor = function anonymous ( -r, g, b, a) {return new Color(r, g, b, a.asArray()[0]);}; -Process.prototype.colorAttr = function anonymous (attr, -data) {if (this.inputOption(attr) === 'hex') {return ( +Process.prototype.getColor = function (data) {if ( +this.reportTypeOf(data) === 'color') {return data; +} else {throw Error('This isn\'t a color.');};}; +Process.prototype.makeColor = function (r, g, b, +a) {return new Color(r, g, b, a.asArray()[0]);}; +Process.prototype.colorAttr = function (attr, data +) {if (this.inputOption(attr) === 'hex') {return ( '#' + (this.reportNumberWithMoreDigits(this.reportNumeralText( this.reportNewNumeral(data.r, 16)), 2)).concat( this.reportNumberWithMoreDigits(this.reportNumeralText( @@ -1053,7 +1038,7 @@ this.inputOption(attr) === 'A') {return this.getColor(data 'B', data)]);} else if (this.inputOption(attr) === 'RGBA') { return new List((this.colorAttr('RGB', data).asArray()).concat([ this.colorAttr('A', data)]));} else {return null;};}; -Process.prototype.clrFlags = function anonymous (flag, +Process.prototype.clrFlags = function (flag, data, num) {num = Math.min(Math.max(+num, 0), 100); if ( !(this.inputOption(flag) === 'saturate') && (+num === 0 )) {return this.getColor(data);} else {if (this.inputOption( @@ -1069,18 +1054,19 @@ to, percent) => (from + ((to - from) * (percent / 100)))), luminosity = ( (this.colorAttr('R', data) * 0.2989) + (this.colorAttr('G', data) * 0.5870 ) + (this.colorAttr('B', data) * 0.1141)); return new Color(lerp(luminosity, data.r, num), lerp(luminosity, data.g, num), lerp(luminosity, data.b, num), -data.a);} else {return data;};};}; Process.prototype.mixColors = function anonymous ( +data.a);} else {return data;};};}; Process.prototype.mixColors = function ( inputs) {this.assertType(inputs, 'list'); var result = inputs.fullCopy().asArray( -).map(function anonymous (clr0) {return [clr0.r, clr0.g, clr0.b, clr0.a];}).reduce( -function anonymous (clr1, clr2) {return [(clr1[0] + clr2[0]), (clr1[1] + clr2[1]), -(clr1[2] + clr2[2]), (clr1[3] + clr2[3])];}); return new Color((result[0] / inputs.length( -)), (result[1] / inputs.length()), (result[2] / inputs.length()), (result[3] / inputs.length( -)));}; Process.prototype.mixClrsAt = function anonymous (color1, color2, percent) { -percent = Math.min(Math.max(+percent, 0), 100); return new Color(((color1.r * ( -1 - (percent / 100))) + (color2.r * (percent / 100))), ((color1.g * (1 - ( -percent / 100))) + (color2.g * (percent / 100))), ((color1.b * (1 - ( -percent / 100))) + (color2.b * (percent / 100))), ((color1.a * ( -1 - (percent / 100))) + (color2.a * (percent / 100))));}; +).map(function (clr0) {return [clr0.r, clr0.g, clr0.b, clr0.a];}).reduce( +function (clr1, clr2) {return [(clr1[0] + clr2[0]), (clr1[1] + clr2[1]), +(clr1[2] + clr2[2]), (clr1[3] + clr2[3])];}); return new Color((result[0 +] / inputs.length()), (result[1] / inputs.length()), (result[2] / inputs.length( +)), (result[3] / inputs.length()));}; Process.prototype.mixClrsAt = function ( +color1, color2, percent) {percent = Math.min(Math.max(+percent, 0), 100); +return new Color(((color1.r * (1 - (percent / 100))) + (color2.r * ( +percent / 100))), ((color1.g * (1 - (percent / 100))) + (color2.g * ( +percent / 100))), ((color1.b * (1 - (percent / 100))) + (color2.b * ( +percent / 100))), ((color1.a * (1 - (percent / 100))) + (color2.a * ( +percent / 100))));}; // Manage Custom Categories @@ -1112,8 +1098,8 @@ return (args.fullCopy().asArray())[0];} else {return context;};};}; + localize('1 input, but getting') + ' ' + args.length() ); - } else if (args.fullCopy().asArray().length === 1 - ) {return (args.fullCopy().asArray())[0];};};}; + } else if (args.fullCopy().asArray().length === 1 + ) {return (args.fullCopy().asArray())[0];};};}; var outer = new Context(null, null, context.outerContext), caller = this.context.parentContext, exit, runnable, expr, cont = this.context.rawContinuation(!isCommand), i, value, @@ -1124,7 +1110,7 @@ return (args.fullCopy().asArray())[0];} else {return context;};};}; context.expression, outer, context.receiver - ); runnable.isCustomCommand = isCommand; + ); runnable.isCustomCommand = isCommand; this.context.parentContext = runnable; if (context.expression instanceof ReporterBlockMorph) { @@ -1198,14 +1184,11 @@ return (args.fullCopy().asArray())[0];} else {return context;};};}; outer.receiver ); exit.tag = 'exit'; runnable.parentContext = exit; - }; - }; - }; -}; + };};};}; Process.prototype.fork = function anonymous (context, args) {if (context instanceof Context) {if (this.readyToTerminate) {return;}; var proc = new Process, stage = this.homeContext.receiver.parentThatIsA( -StageMorph); proc.instrument = this.instrument; proc.receiver = this.receiver; proc.initializeFor(context, args); stage.threads.processes.push(proc);} else if (context instanceof Function) {throw Error( -'Forking JavaScript functions is not available.\nIf do you wanna to launch one,\nplease put it in a \"\[run\] %cmd\" block\nand put them in the launch %cmd block.');};}; +StageMorph); proc.instrument = this.instrument; proc.receiver = this.receiver; proc.initializeFor(context, args); stage.threads.processes.push(proc);} else if (context instanceof Function) { +throw Error('Forking JavaScript functions is not available.\nIf do you want to launch one,\nplease put it in a \"\[run\] %cmd\" block\nand put them in the launch %cmd block.');};}; Process.prototype.initializeFor = function (context, args) { // used by Process.fork() and global invoke() @@ -1213,7 +1196,7 @@ Process.prototype.initializeFor = function (context, args) { throw new Error( 'continuations cannot be forked' ); - }; if (!(context instanceof Context)) { + }; if (!(context instanceof Context)) { throw new Error( localize('expecting a') + ' ' + localize('ring') + ' ' + @@ -1225,7 +1208,7 @@ Process.prototype.initializeFor = function (context, args) { context.expression, outer), parms = args.itemsArray(), - i, value; + i, value; // remember the receiver this.context = context.receiver; @@ -1245,7 +1228,7 @@ Process.prototype.initializeFor = function (context, args) { if (!isNil(parms[i])) { value = parms[i]; }; outer.variables.addVar(context.inputs[i], value); - }; // assign implicit parameters if there are no formal ones + }; // assign implicit parameters if there are no formal ones if (context.inputs.length === 0) { // in case there is only one input // assign it to all empty slots @@ -1267,23 +1250,21 @@ Process.prototype.initializeFor = function (context, args) { ); }; }; - }; if (runnable.expression instanceof CommandBlockMorph) { - runnable.expression = runnable.expression.blockSequence(); + }; if (runnable.expression instanceof CommandBlockMorph) { + runnable.expression = runnable.expression.blockSequence(); }; this.homeContext = new Context; // context.outerContext; this.homeContext.receiver = context.outerContext.receiver; - this.topBlock = context.expression; - this.context = runnable; -}; + this.topBlock = context.expression; this.context = runnable;}; -Process.prototype.execute = function anonymous (choice, context, args) {if (this.inputOption(choice) === 'run' -) {this.doRun(context, args);}; if (this.inputOption(choice) === 'launch') {this.fork(context, args);};}; +Process.prototype.execute = function (choice, context, args) {if (this.inputOption(choice) === 'run') { +this.doRun(context, args);}; if (this.inputOption(choice) === 'launch') {this.fork(context, args);};}; // Process introspection -Process.prototype.reportThisContext = function anonymous () {var sym = Symbol.for('self'), frame = this.context.variables.silentFind(sym), ctx; if ( -frame) {return copy(frame.vars[sym].value);} else {ctx = this.topBlock.reify();}; ctx.outerContext = this.context.outerContext; if (ctx.outerContext -) {ctx.variables.parentFrame = ctx.outerContext.variables;}; if (!this.isAtomic && this.context.expression.parent?.selector === 'execute' -) {/* assume direct recursion of a command block, yield to ensure smooth animations */ this.readyToYield = true;}; return ctx;}; +Process.prototype.reportThisContext = function () {var sym = Symbol.for('self'), frame = this.context.variables.silentFind( +sym), ctx; if (frame) {return copy(frame.vars[sym].value);} else {ctx = (this.topBlock).reify();}; ctx.outerContext = (this +).context.outerContext; if (ctx.outerContext) {ctx.variables.parentFrame = ctx.outerContext.variables;}; if (!((this +).isAtomic) && this.context.expression.parent?.selector === 'execute') {this.readyToYield = true;}; return ctx;}; Process.prototype.reportThisCaller = function anonymous () { var sym = Symbol.for('caller'), @@ -1314,9 +1295,8 @@ Process.prototype.reportThisContinuation = function anonymous () { null, 'popContext' ); - }; cont.isContinuation = true; - return cont; -}; + }; cont.isContinuation = true; + return cont;}; Process.prototype.reportThisInputs = function () { var sym = Symbol.for('arguments'), @@ -1465,14 +1445,14 @@ Process.prototype.evaluateCustomBlock = function () { // Process variables primitives Process.prototype.doDeclareVariables = function (varNames) { -var varFrame = this.context.outerContext.variables; /* º_º */ -varNames.itemsArray().forEach(name => varFrame.addVar(name));}; +var varFrame = this.context.outerContext.variables; ((varNames +).itemsArray()).forEach(name => varFrame.addVar(name));}; Process.prototype.doSetVar = function (varName, value) {var varFrame = this.context.variables, name = varName; if (name instanceof Context) {if (name.expression.selector === 'reportGetVar' -) {name.variables.setVar(name.expression.blockSpec, value, this.blockReceiver()); return;}; -this.doSet(name, value); return;}; if (name instanceof Array) {this.doSet(name, value); -return;}; varFrame.setVar(name, value, this.blockReceiver());}; +) {name.variables.setVar(name.expression.blockSpec, value, this.blockReceiver()); return; +}; this.doSet(name, value); return;}; if (name instanceof Array) {this.doSet(name, +value); return;}; varFrame.setVar(name, value, this.blockReceiver());}; Process.prototype.doChangeVar = function (varName, value) {var varFrame = this.context.variables, name = varName; if (name instanceof Context) {if (name.expression.selector === 'reportGetVar') { @@ -1502,9 +1482,8 @@ Process.prototype.doShowVar = function (varName, context) { } else { this.blockReceiver().changeBlockVisibility(name.expression, false); return; - } - } - if (this.homeContext.receiver) { + }; + }; if (this.homeContext.receiver) { stage = this.homeContext.receiver.parentThatIsA(StageMorph); if (stage) { target = varFrame.silentFind(name); @@ -1545,8 +1524,8 @@ Process.prototype.doShowVar = function (varName, context) { stage.add(watcher); watcher.fixLayout(); watcher.rerender(); - } - } + }; + }; }; Process.prototype.doHideVar = function (varName, context) { @@ -1564,13 +1543,11 @@ Process.prototype.doHideVar = function (varName, context) { } else { this.blockReceiver().changeBlockVisibility(name.expression, true); return; - } - } - if (!name) { + }; + }; if (!name) { this.doRemoveTemporaries(); return; - } - if (this.homeContext.receiver) { + }; if (this.homeContext.receiver) { stage = this.homeContext.receiver.parentThatIsA(StageMorph); if (stage) { target = varFrame.find(name); @@ -1585,10 +1562,10 @@ Process.prototype.doHideVar = function (varName, context) { watcher.destroy(); } else { watcher.hide(); - } - } - } - } + }; + }; + }; + }; }; Process.prototype.doRemoveTemporaries = function () { @@ -1620,14 +1597,13 @@ this.evaluate(this.reportAttributeOf(context, sprite), args);}; /* These block p // Process speech synthesis primitives -Process.prototype.doSpeakAndWait = function anonymous (msg) {var myself = this; if (!(myself.tts instanceof SpeechSynthesisUtterance)) {myself.tts = new SpeechSynthesisUtterance(msg.toString()); -myself.tts.pitch = +myself.receiver.speakingPitch; myself.tts.rate = +myself.receiver.speakingSpeed; myself.tts.lang = myself.receiver.speakingLanguage; myself.speakingDone = false; myself.tts.onend = ( -() => {myself.speakingDone = true;}); window.speechSynthesis.speak(myself.tts);}; if (!myself.speakingDone) {myself.pushContext('doYield'); myself.pushContext();} else {delete myself.tts;};}; -/* Now you can put speaking in scripts and we are being more compatible for "Scratch 3.0". :) */ Process.prototype.doSetSpeakingPitch = function anonymous (pitch) {this.receiver.speakingPitch = [ -1, 0.5, 1.5, 0, 2][Object.keys(InputSlotMorph.prototype.speakingPitchMenu()).indexOf(pitch.toString())];}; Process.prototype.doSetSpeakingSpeed = function anonymous (speed) { -this.receiver.speakingSpeed = [4, 2, 1, 0.5, 0.25][Object.keys(InputSlotMorph.prototype.speakingSpeedMenu()).indexOf(speed.toString())];}; /* These inputs are important to speak. */ -Process.prototype.doSetSpeakingLanguage = function anonymous (language) {this.receiver.speakingLanguage = ['ar', 'zh-TW', 'dk', 'nl', 'en-GB', 'en-US', 'fr', 'de', 'el', 'bn', 'is', 'it', -'ja', 'kr', 'no', 'pl', 'pt', 'pt-BR', 'ro', 'ru', 'es-AR', 'es-MX', 'sv', 'tr', 'cy'][Object.keys(InputSlotMorph.prototype.speakingLanguageMenu()).indexOf(language.toString())];}; +Process.prototype.doSpeakAndWait = function anonymous (msg) {var myself = this; if (!(myself.tts instanceof SpeechSynthesisUtterance)) {myself.tts = new SpeechSynthesisUtterance(msg.toString( +)); myself.tts.pitch = +myself.receiver.speakingPitch; myself.tts.rate = +myself.receiver.speakingSpeed; myself.tts.lang = myself.receiver.speakingLanguage; myself.speakingDone = false; (myself +).tts.onend = (() => {myself.speakingDone = true;}); window.speechSynthesis.speak(myself.tts);}; if (!(myself.speakingDone)) {myself.pushContext('doYield'); myself.pushContext();} else {delete ( +myself.tts);};}; Process.prototype.doSetSpeakingPitch = function (pitch) {this.receiver.speakingPitch = [1, 0.5, 1.5, 0, 2][Object.keys(InputSlotMorph.prototype.speakingPitchMenu()).indexOf((pitch +).toString())];}; Process.prototype.doSetSpeakingSpeed = function (speed) {this.receiver.speakingSpeed = [4, 2, 1, 0.5, 0.25][Object.keys(InputSlotMorph.prototype.speakingSpeedMenu()).indexOf( +speed.toString())];}; Process.prototype.doSetSpeakingLanguage = function (language) {this.receiver.speakingLanguage = ['ar', 'zh-TW', 'dk', 'nl', 'en-GB', 'en-US', 'fr', 'de', 'el', 'bn', 'is', +'it', 'ja', 'kr', 'no', 'pl', 'pt', 'pt-BR', 'ro', 'ru', 'es-AR', 'es-MX', 'sv', 'tr', 'cy'][Object.keys(InputSlotMorph.prototype.speakingLanguageMenu()).indexOf(language.toString())];}; // Process lists primitives @@ -1645,19 +1621,15 @@ Process.prototype.doDeleteFromList = function (index, list) { this.assertType(list, 'list'); if (list.type) { list = this.shadowListAttribute(list); - } - if (this.inputOption(index) === 'all') { + }; if (this.inputOption(index) === 'all') { return list.clear(); - } - if (index === '') { + }; if (index === '') { return null; - } - if (this.inputOption(index) === 'last') { + }; if (this.inputOption(index) === 'last') { idx = list.length(); } else if (isNaN(+this.inputOption(index))) { return null; - } - list.remove(idx); + }; list.remove(idx); }; Process.prototype.doInsertInList = function (element, index, list) { @@ -1666,17 +1638,13 @@ Process.prototype.doInsertInList = function (element, index, list) { if (list.type) { this.assertType(element, list.type); list = this.shadowListAttribute(list); - } - if (index === '') { + }; if (index === '') { return null; - } - if (this.inputOption(index) === 'any') { + }; if (this.inputOption(index) === 'any') { idx = this.reportBasicRandom(1, list.length() + 1); - } - if (this.inputOption(index) === 'last') { + }; if (this.inputOption(index) === 'last') { idx = list.length() + 1; - } - list.add(element, idx); + }; list.add(element, idx); }; Process.prototype.doReplaceInList = function (index, list, element) { @@ -2211,16 +2179,13 @@ Process.prototype.reportIfElse = function (block) { }; this.pushContext(expression); }; // Processing related primitives -Process.prototype.doStopThis = function (choice) {var ide = world.children[0]; switch (this.inputOption(choice)) {case 'this scene': case 'all': ide.scene.stop(); -ide.scene.stage.timerProcedure.stopNow(); var dialog = world.children.filter(child => child instanceof DialogBoxMorph).filter(child => child.key === 'screenshotMaker' -); if (dialog.length > 0) {dialog = dialog[0]; if ((dialog.button2.labelString.color.g > 200) && (dialog.button1.labelString.name === 'circleSolid')) {dialog.button1.action( -); dialog.button1.fixLayout();};}; break; case 'this scene and restart': ide.scene.stop(); ide.runScripts(); break; case 'all scenes': ide.scenes.map(function anonymous (scn) { -scn.stop(true); scn.stage.timerProcedure.stopNow();}); break; case 'this sprite': ide.stage.threads.stopAllForReceiver(this.context.outerContext.receiver, this); this.stop(); if ( -this.blockReceiver() instanceof SpriteMorph) {this.blockReceiver().stopTalking();}; break; case 'this script': this.stop(); break; case 'this block': this.doStopBlock(); break; -case 'this scene but this script': case 'all but this script': ide.stage.threads.stopAll(this); break; case 'this sprite but this script': case 'other scripts in sprite': -ide.stage.threads.stopAllForReceiver(this.context.outerContext.receiver, this); break; default: nop();};}; Process.prototype.runScript = function anonymous (action) {if ( -action instanceof CommandBlockMorph) {if (!this.context.startTime) {this.context.startTime = Date.now();}; if (this.context.isOnlyToOnce) {delete this.context.isOnlyToOnce; -} else {this.context.isOnlyToOnce = true; this.pushContext(action.blockSequence()); this.pushContext('doYield'); this.pushContext();};};}; /* This is so cool!!! :-) */ +Process.prototype.doStopThis = function (choice) {var ide = world.children[0]; switch (this.inputOption(choice)) {case 'this scene': case 'all': ide.scene.stop(); break; case 'this scene and restart': +(ide.scene).restart(); ide.runScripts(); break; case 'all scenes': ide.scenes.forEach(scn => scn.stop(true)); break; case 'this sprite': ide.stage.threads.stopAllForReceiver((this.context.outerContext +).receiver, this); this.stop(); if (this.blockReceiver() instanceof SpriteMorph) {this.blockReceiver().stopTalking();}; break; case 'this script': this.stop(); break; case 'this block': this.doStopBlock( +); break; case 'this scene but this script': case 'all but this script': ide.stage.threads.stopAll(this); break; case 'this sprite but this script': case 'other scripts in sprite': (ide.stage.threads +).stopAllForReceiver(this.context.outerContext.receiver, this); break; default: nop();};}; Process.prototype.runScript = function (action) {if ((action) instanceof CommandBlockMorph +) {if (!this.context.startTime) {this.context.startTime = Date.now();}; if (this.context.isOnlyToOnce) {delete this.context.isOnlyToOnce;} else {this.context.isOnlyToOnce = true; +this.pushContext(action.blockSequence()); this.pushContext('doYield'); this.pushContext();};};}; // Atomic Functions: The atomic functions are functions that are running all of the blocks inside them all at once. In BYOB, only appears as an option menu for the custom blocks. @@ -2278,7 +2243,7 @@ proc.root.inputs()[0].evaluate() === 'paused') ? null : proc.pause( )) : proc.pause()) : proc.pause()); myObj.receiveUserInteraction('paused', true, true);}; world.childThatIsA(IDE_Morph).controlBar.pauseButton.refresh();}; -Process.prototype.doResumeOptions = function anonymous (choice) {var ide = world.children[0]; if (Process.prototype.inputOption(choice) === 'this scene') {ide.stage.threads.resumeAll( +Process.prototype.doResumeOptions = function (choice) {var ide = world.children[0]; if (Process.prototype.inputOption(choice) === 'this scene') {ide.stage.threads.resumeAll( ide.stage); ide.stage.timerProcedure.resumeNow(); ide.controlBar.pauseButton.refresh(); ide.stage.resumeAllActiveSounds(); world.children.filter(function anonymous (child) {if ( child instanceof DialogBoxMorph) {return (child.key).includes('debug');} else {return false;};}).forEach(function anonymous (child) {child.destroy();});} else {var myself = this; ide.stage.threads.processes.forEach(proc => ((proc.receiver === myself.receiver) ? proc.resume() : nop())); ide.stage.runUnpauseScripts(this.receiver);}; @@ -2446,7 +2411,7 @@ Process.prototype.reportKeep = function (predicate, list) { this.context.accumulator.source.cdr(); } if (this.context.accumulator.remaining === 0) { - this.context.accumulator.end.rest = new List(); + this.context.accumulator.end.rest = new List; this.returnValueToParentContext( this.context.accumulator.target.cdr() ); @@ -2825,8 +2790,7 @@ if (secs.length() > 0) { if ((Date.now() - this.context.startTime) >= (secs * 1000)) { this.blockReceiver().stopTalking(); return null; - } - this.pushContext('doYield'); + }; this.pushContext('doYield'); this.pushContext(); } else { this.blockReceiver().bubble(data, (option === 'think'), false, (option === 'shout'), (option === 'whisper')); @@ -2850,12 +2814,12 @@ Process.prototype.doThinkFor = function (data, secs) { }; if ((Date.now() - this.context.startTime) >= (secs * 1000)) { this.blockReceiver().stopTalking(); return null; - }; this.pushContext('doYield'); - this.pushContext(); -}; + }; this.pushContext('doYield'); + this.pushContext();}; -Process.prototype.blockReceiver = function anonymous () {return (this.context ? (this.context.receiver || this.homeContext.receiver -) : (this.homeContext.receiver || this.receiver));}; /* In some cirmcunstances is a beautiful function, just use and try it. :-) */ +Process.prototype.blockReceiver = function () {return ( +this.context ? ((this.context.receiver || (this.homeContext +).receiver)) : (this.homeContext.receiver || this.receiver));}; // Process sound primitives (interpolated) @@ -2895,7 +2859,7 @@ this.context.activeAudio), 1); this.context.activeAudio = null; this.context.activeAudio), 1); this.context.activeAudio.remove(); this.context.activeAudio = null; - }; return null; + }; return null; }; this.pushContext('doYield'); this.pushContext(); };};}; @@ -2910,7 +2874,7 @@ Process.prototype.doStopAllSounds = function () { thread.popContext(); }; }; - }); stage.stopAllActiveSounds(true); + }); stage.stopAllActiveSounds(); }; }; @@ -3545,16 +3509,12 @@ Process.prototype.hyperZip = function (baseOp, a, b) { result = new Array(len); for (i = 0; i < len; i += 1) { result[i] = this.hyperZip(baseOp, a[i], b[i]); - } - return new List(result); - } + }; return new List(result); + }; return a.map(each => this.hyperZip(baseOp, each, b)); - } - if (b instanceof List) { + }; if (b instanceof List) { return b.map(each => this.hyperZip(baseOp, a, each)); - } - return baseOp(a, b); -}; + }; return baseOp(a, b);}; Process.prototype.packCoordinates = function (list) { // convert all numerical 2-item sub-lists into a variable to they @@ -3707,8 +3667,8 @@ number, optional) {var power = (10 ** (isNil(optional ) < 0) ? -result : +result);}; Process.prototype.reportRandom = function anonymous (a, b, c) { -return ((c === 'without rounding') ? (a + (Math.random() * ( -b - a))) : this.hyperDyadic(this.reportBasicRandom, a, b));}; +return ((c === 'without rounding') ? ((+a) + (Math.random() * ( ++b - +a))) : this.hyperDyadic(this.reportBasicRandom, a, b));}; Process.prototype.reportBasicRandom = function (min, max) {var floor = Math.min( +min, +max), ceil = Math.max(+min, +max); if (!((floor % 1) == 0) || !((ceil % 1 @@ -3755,7 +3715,7 @@ x = a; y = b;}; return [y, x][asANum(x > y)];}; Process.prototype.reportConstrainToClamp = ((value, min1, max1, min2, max2) => Process.prototype.reportComplexSum(Process.prototype.reportComplexProduct( Process.prototype.reportComplexQuotient(Process.prototype.reportComplexDifference(value, min1), Process.prototype.reportComplexDifference(max1, min1)), Process.prototype.reportComplexDifference(max2, min2)), min1)); Process.prototype.reportInterpolate = ((min, max, force) => Process.prototype.reportComplexSum( -min, Process.prototype.reportComplexProduct(Process.prototype.reportComplexDifference(max, min), force))); /* These primitives are base on "Penguin's Mod"-likes. :~) */ +min, Process.prototype.reportComplexProduct(Process.prototype.reportComplexDifference(max, min), force))); /* These primitives are base on "PenguinMod"-likes. :~) */ Process.prototype.reportAnEulerNumberPower = ((power, acurracy) => ((((+(asANum(acurracy))) + (+(asANum(power)))) / (+(asANum(acurracy)))) ** (+(asANum(acurracy))))); @@ -3777,15 +3737,15 @@ n)).toString(); return Process.prototype.reportJoinWords(Process.prototype.repor // Process logic primitives - hyper-dyadic / monadic where applicable -Process.prototype.reportLessThan = function anonymous (a, b) {return this.hyperDyadic(this.reportBasicLessThan, a, b);}; +Process.prototype.reportLessThan = function (a, b) {return this.hyperDyadic(this.reportBasicLessThan, a, b);}; -Process.prototype.reportLessThanOrEquals = function anonymous (a, b) {return this.hyperDyadic(((a, b) => !this.reportBasicGreaterThan(a, b)), a, b);}; +Process.prototype.reportLessThanOrEquals = function (a, b) {return this.hyperDyadic(((a, b) => !this.reportBasicGreaterThan(a, b)), a, b);}; Process.prototype.reportBasicLessThan = function (a, b) {var x = +a, y = +b; if (isNaN(x) || isNaN(y)) {x = a; y = b;}; return (x < y);}; -Process.prototype.reportGreaterThan = function anonymous (a, b) {return this.hyperDyadic(this.reportBasicGreaterThan, a, b);}; +Process.prototype.reportGreaterThan = function (a, b) {return this.hyperDyadic(this.reportBasicGreaterThan, a, b);}; -Process.prototype.reportGreaterThanOrEquals = function anonymous (a, b) {return this.hyperDyadic(((a, b) => !this.reportBasicLessThan(a, b)), a, b);}; +Process.prototype.reportGreaterThanOrEquals = function (a, b) {return this.hyperDyadic(((a, b) => !this.reportBasicLessThan(a, b)), a, b);}; Process.prototype.reportBasicGreaterThan = function (a, b) {var x = +a, y = +b; if (isNaN(x) || isNaN(y)) {x = a; y = b;}; return (x > y);}; @@ -3808,15 +3768,15 @@ Process.prototype.reportIsIdentical = function (a, b) {var tag = 'idTag'; if (is this.isImmutable(a) || this.isImmutable(b)) {return snapEquals(a, b);}; function clear () {if (Object.prototype.hasOwnProperty.call(a, tag)) {delete a[tag];}; if (Object.prototype.hasOwnProperty.call(b, tag)) { delete b[tag];}}; clear(); a[tag] = Date.now(); if (b[tag] === a[tag]) {clear(); return true;}; clear(); return false;}; /* Added the comparison of colors in the "snapEquals" function. Now is much better. :-) */ -Process.prototype.isImmutable = function anonyumous (obj) {var type = this.reportTypeOf( -obj); return contains(['nothing', 'Boolean', 'text', 'number', 'undefined'], type);}; +Process.prototype.isImmutable = function (obj) {var type = this.reportTypeOf(obj +); return contains(['nothing', 'Boolean', 'text', 'number', 'undefined'], type);}; -Process.prototype.reportBoolean = function anonymous (b) {return b;}; +Process.prototype.reportBoolean = (b => b); -Process.prototype.reportRound = function anonymous (n, optional) {var myself = this; if (n instanceof List) {return new List(n.asArray().map(input => myself.reportRound(input, optional)));} else {try {if ( +Process.prototype.reportRound = function (n, optional) {var myself = this; if (n instanceof List) {return new List(n.asArray().map(input => myself.reportRound(input, optional)));} else {try {if ( n.i === undefined) {n = new ComplexNumber(n);};} catch (err1) {n = new ComplexNumber;}; return new ComplexNumber(myself.reportBasicRound(+n, optional), myself.reportBasicRound(+(n.i), optional));};}; -Process.prototype.reportBasicRound = function anonymous (n, optional) {if (optional.asArray().length > 0) {if (optional.asArray()[0] > 0) {return Math.round( +Process.prototype.reportBasicRound = function (n, optional) {if (optional.asArray().length > 0) {if (optional.asArray()[0] > 0) {return Math.round( +n * Math.pow(10, optional.asArray()[0])) / Math.pow(10, optional.asArray()[0]);} else {return Math.round(+n);};} else {return Math.round(+n);};}; // Process - hyper-monadic text primitive @@ -3826,7 +3786,7 @@ con => con[0]), values = ide.mathConstants().map(con => con[1]);}; return (conta Process.prototype.reportMonadic = function anonymous (fname, n) {if (this.enableHyperOps) {if (n instanceof List) {return n.map(each => this.reportMonadic(fname, each));};}; function abs (num) {return ( +num < 0) ? -num : +num;}; function sign (num) {if (num === 0) {return 0;} else {return Process.prototype.reportBasicQuotient(num, abs(num));};}; function sin (x) {x = Process.prototype.reportBasicModulus( -x, 360); var y = Process.prototype.fixSimpleNumber(sign(180 - x)); x = radians(Process.prototype.fixSimpleNumber(abs(((((+x / 2) + 45) % 90) - 45) * 2))); var answer = Math.sin(/* Taking faster time. */ +x, 360); var y = Process.prototype.fixSimpleNumber(sign(180 - x)); x = radians(Process.prototype.fixSimpleNumber(abs(((((+x / 2) + 45) % 90) - 45) * 2))); /* Taking faster time. */ var answer = Math.sin( Process.prototype.reportBasicProduct(Process.prototype.reportRound(x, new List([15])), y)); return (isNaN(answer) ? 0 : answer);}; function circ (x) {x = Process.prototype.reportBasicQuotient(+x, 90); return Process.prototype.fixSimpleNumber(Math.sqrt(1 - ((Process.prototype.reportBasicModulus(+x, 2) - 1) ** 2))) * (-2 * ((Process.prototype.reportBasicModulus(+x, 4) > 2) - 0.5));}; function complexRadians ( degrees) {return Process.prototype.reportComplexProduct(degrees, Process.prototype.reportComplexQuotient(Math.PI, 180));}; function complexDegrees (radians) {return Process.prototype.reportComplexProduct(radians, @@ -3879,8 +3839,8 @@ Process.prototype.reportComplexQuotient(180, Math.PI));}; switch (this.inputOpti var poweredPhi = Process.prototype.reportComplexPower(Process.prototype.reportConstants(['φ Phi']), n); return Process.prototype.reportComplexQuotient(Process.prototype.reportComplexDifference(poweredPhi, Process.prototype.reportComplexProduct(Process.prototype.reportMonadic(['ccos'], Process.prototype.reportComplexProduct(180, n)), Process.prototype.reportComplexQuotient(1, poweredPhi))), Math.sqrt(5)); case 'luc': - var phi = Process.prototype.reportConstants(['φ Phi']); return Process.prototype.reportComplexSum(/* There is my own Lucas in my yard... */ - Process.prototype.reportComplexPower(phi, n), Process.prototype.reportComplexPower(-phi, Process.prototype.reportComplexDifference(0, n))); + var poweredPhi = Process.prototype.reportComplexPower(Process.prototype.reportConstants(['φ Phi']), n); return Process.prototype.reportComplexSum(poweredPhi, + Process.prototype.reportComplexProduct(Process.prototype.reportMonadic(['ccos'], Process.prototype.reportComplexProduct(180, n)), Process.prototype.reportComplexQuotient(1, poweredPhi))); break; case 'nep': return Process.prototype.reportComplexProduct(23025851, Process.prototype.reportComplexDifference(7, Process.prototype.reportComplexLogarithm(10, n))); @@ -4063,9 +4023,7 @@ Process.prototype.reportTextFunction = function (fname, string) {var x = (isNil( case 'hex sha512 hash': result = hex_sha512(x); break; - }; - return result; -}; + }; return result;}; Process.prototype.reportJoin = function (a, b) {var x = (isNil(a) ? '' : a).toString(), y = (isNil(b) ? '' : b).toString(); return x.concat(y);}; @@ -4076,21 +4034,16 @@ Process.prototype.reportJoinWords = function (aList) { return ((blocks instanceof Context) ? ((blocks.expression instanceof CommandBlockMorph ) ? this.reportScript(new List(blocks.inputs), blocks.expression) : this.reify( blocks.expression, new List(blocks.inputs))) : blocks); - } - return aList.asText(); - } - return (aList || '').toString(); -}; + }; return aList.asText();}; + return (aList || '').toString();}; Process.prototype.isAST = function (aList) { var first = aList.at(1); if (first instanceof Context) { return true; - } - if (first instanceof List) { + }; if (first instanceof List) { return first.at(1) instanceof Context; - } - return false; + }; return false; }; // Process string ops - hyper-monadic/dyadic @@ -4127,12 +4080,7 @@ Process.prototype.reportTextAttribute = function (choice, text) { case 'lower case': return this.hyperDyadic( str => isString(str) ? str.toLowerCase() : str, - text - ); - default: - return 0; - }; -}; + text); default: return 0;};}; Process.prototype.reportStringSize = function (data) { return this.hyperDyadic( @@ -4141,11 +4089,10 @@ Process.prototype.reportStringSize = function (data) { // proposed scheme by Michael to address text with emojis, has // memory issue when the stringd get very large: // str => isNil(data) ? 0 : Array.from(str.toString()).length, - data - ); -}; + data);}; -Process.prototype.reportTextContains = function (string1, string2) {if (string2.length > 0) {return string1.includes(string2);} else {return false;};}; +Process.prototype.reportTextContains = function (string1, string2) {if ( +string2.length > 0) {return string1.includes(string2);} else {return false;};}; Process.prototype.reportUnicode = function (string) { /* special case to report a list of numbers for a @@ -4155,20 +4102,16 @@ Process.prototype.reportUnicode = function (string) { if (this.enableHyperOps) { if (string instanceof List) { return string.map(each => this.reportUnicode(each)); - } - str = isNil(string) ? '\u0000' : string.toString(); + }; str = isNil(string) ? '\u0000' : string.toString(); unicodeList = str.split(''); if (unicodeList.length > 1) { return this.reportUnicode(new List(unicodeList)); - } + }; } else { str = isNil(string) ? '\u0000' : string.toString(); - } - if (str.codePointAt) { - /* support for Unicode in newer browsers. */ + }; if (str.codePointAt) { return str.codePointAt(0) || 0; - } - return (str.charCodeAt(0) || 0); + }; return str.charCodeAt(0) || 0; }; Process.prototype.reportUnicodeAsLetter = function (num) { @@ -4332,23 +4275,15 @@ Process.prototype.rawParseCSV = function (text, delim) { } // remove the last record, if it is empty - if (records[records.length - 1].length === 1 && - records[records.length - 1][0] === '') - { - records.pop(); - } + if ((records[records.length - 1].length === 1 + ) && (records[records.length - 1][0] === '' + )) {records.pop();}; - // convert arrays to Snap! Lists records = new List( records.map(row => new List(row)) - ); - - // for backwards compatibility return the first row if it is the only one - if (records.length() === 1) { + ); if (records.length() === 1) { return records.at(1); - } - return records; -}; + }; return records;}; Process.prototype.parseJSON = function (string) { // Bernat's original Snapi contribution @@ -4374,47 +4309,32 @@ Process.prototype.parseJSON = function (string) { ).includes('\)')) {try {return new Color(jsonObject.split(',')[0 ].split('rgba\(')[1], jsonObject.split(',')[1], jsonObject.split( ',')[2], jsonObject.split(',')[3].split('\)')[0]);} catch (error - ) {return jsonObject;};} else {return jsonObject;}; - } else { - return jsonObject; - } - } - - return listify(JSON.parse(string)); -}; + ) {return jsonObject;};} else {return jsonObject;};} else { + return jsonObject;};}; return listify(JSON.parse(string));}; // Process syntax analysis -Process.prototype.assemble = function (blocks) { - var first; - if (!(blocks instanceof List)) { - return blocks; - } - first = blocks.at(1); - if (first instanceof Context) { - return first.copyWithInputs( - blocks.cdr().map(each => this.assemble(each)) - ); - } - if (blocks.isEmpty()) { - return blocks; - } - if (this.reportIsA(blocks.at(1), 'number')) { - return blocks.map(each => this.assemble(each)); - } - return blocks.map(each => this.assemble(each)).itemsArray().reduce( - (a, b) => a.copyWithNext(b) - ); -}; +Process.prototype.assemble = function (blocks +) {var first; if (!(blocks instanceof List) +) {return blocks;}; first = blocks.at(1); +if (first instanceof Context) {return (first +).copyWithInputs(blocks.cdr().map(each => ( +this.assemble(each))));}; if (blocks.isEmpty( +)) {return blocks;}; if (this.reportIsA((blocks +).at(1), 'number')) {return blocks.map((each +) => this.assemble(each));}; return blocks.map( +each => this.assemble(each)).itemsArray( +).reduce((a, b) => a.copyWithNext(b));}; // Process debugging -Process.prototype.doAlert = function (data) {alert(data);}; -Process.prototype.doPrompt = function (data, answer) {return prompt(data,answer);}; -Process.prototype.doConfirm = function (data) {return confirm(data);}; +Process.prototype.doAlert = function (data) {alert(data); +}; Process.prototype.doPrompt = function (data, answer) { +return prompt(data,answer);}; (Process.prototype.doConfirm +) = function (data) {return confirm(data);}; -Process.prototype.doOptionToConsole = function (option, data) {var script = new Function(['string'],'console.' -+ option + '\(string\)'); if (contains(['log', 'info', 'debug', 'warn', 'error'], option)) {script(data);}}; +Process.prototype.doOptionToConsole = function (option, data) {var script = new Function(['string'], ('console.' +) + option + '\(string\)'); if (contains(['log', 'info', 'debug', 'warn', 'error'], option)) {script(data);}}; // Process motion primitives @@ -4424,13 +4344,11 @@ Process.prototype.getOtherObject = function (name, thisObj, stageObj) { // deal with first-class sprites if (isSnapObject(name)) { - return name; - } + return name;}; if (this.inputOption(name) === 'myself') { return thisObj; - } - var stage = isNil(stageObj) ? + }; var stage = isNil(stageObj) ? thisObj.parentThatIsA(StageMorph) : stageObj, thatObj = null; if (stage) { @@ -4447,10 +4365,8 @@ Process.prototype.getOtherObject = function (name, thisObj, stageObj) { morph => morph instanceof SpriteMorph && morph.name === name ); - } - } - return thatObj; -}; + }; + }; return thatObj;}; Process.prototype.getObjectsNamed = function (name, thisObj, stageObj) { // private, find all sprites and their clones indicated @@ -4467,15 +4383,10 @@ Process.prototype.getObjectsNamed = function (name, thisObj, stageObj) { if (stage) { // find the corresponding sprite on the stage - those = stage.children.filter(check); - if (!those.length) { - // check if a sprite in question is currently being - // dragged around - those = stage.world().hand.children.filter(check); - }; - }; - return those; -}; + those = stage.children.filter( + check); if (!(those.length)) { + those = (stage.world().hand.children + ).filter(check);};}; return those;}; Process.prototype.setHeading = function anonymous (direction) {var myself = this.blockReceiver( ); if (myself) {if (this.inputOption(direction) === 'random') {direction = this.reportBasicRandom( @@ -4505,15 +4416,10 @@ Process.prototype.doFaceTowards = function (name) { thisObj.faceToXY( thatObj.xPosition(), thatObj.yPosition() - ); - }; - }; - }; -}; + );};};};}; Process.prototype.doGotoObject = function (name) { - var thisObj = this.blockReceiver(), - thatObj, stage; +var thisObj = this.blockReceiver(), thatObj, stage; if (thisObj) { if (this.inputOption(name) === 'center') { @@ -4522,9 +4428,8 @@ Process.prototype.doGotoObject = function (name) { thisObj.gotoXY(this.reportMouseX(), this.reportMouseY()); } else if (this.inputOption(name) === 'random position') { stage = thisObj.parentThatIsA(StageMorph); - if (stage) { - thisObj.setCenter(new Point( - this.reportBasicRandom(stage.left(), stage.right()), + if (stage) {thisObj.setCenter(new Point( + this.reportBasicRandom(stage.left(), stage.right()), this.reportBasicRandom(stage.top(), stage.bottom()) )); } @@ -4535,41 +4440,34 @@ Process.prototype.doGotoObject = function (name) { name.at(2) ); return; - } - thatObj = this.getOtherObject(name, this.homeContext.receiver); + }; thatObj = this.getOtherObject(name, this.homeContext.receiver); if (thatObj) { thisObj.gotoXY( thatObj.xPosition(), thatObj.yPosition() ); - } - } - } -}; + }; + }; + };}; // Process layering primitives -Process.prototype.goToLayer = function (name) { - var option = this.inputOption(name), - thisObj = this.blockReceiver(); - if (thisObj instanceof SpriteMorph) { - if (option === 'front') { - thisObj.comeToFront(); - } else if (option === 'back') { - thisObj.goToBack(); - } - } -}; +Process.prototype.goToLayer = function ( +name) {var option = this.inputOption(name +), thisObj = this.blockReceiver(); if ( +thisObj instanceof SpriteMorph) {if ( +option === 'front') {thisObj.comeToFront( +);} else if (option === 'back') { +thisObj.goToBack();};};}; // Process scene primitives -Process.prototype.doSwitchToScene = function (id, transmission) {var rcvr = this.blockReceiver(), idx = 0, message = this.inputOption(transmission.at(1)), ide, scenes, num, scene; this.assertAlive(rcvr); -this.assertType(message, ['text', 'number', 'Boolean', 'list']); if (message instanceof List) {if (message.canBeJSON()) {message = message.deepMap(leaf => leaf);} else {throw new Error(localize( -'cannot send media,\nsprites or procedures\nto another scene'));}}; if (this.readyToTerminate) {return;}; ide = rcvr.parentThatIsA(IDE_Morph); scenes = ide.scenes; if (id instanceof Array) { -switch (this.inputOption(id)) {case 'next': idx = scenes.indexOf(ide.scene) + 1; if (idx > scenes.length()) {idx = 1;}; break; case 'previous': idx = scenes.indexOf(ide.scene) - 1; if (idx < 1) { -idx = scenes.length();}; break; case 'last': idx = scenes.length(); break; case 'random': idx = this.reportBasicRandom(1, scenes.length()); break;}; this.stop(); ide.switchToScene(scenes.at(idx), null, message); -return;}; scene = detect(scenes.itemsArray(), scn => scn.name === id); if (scene === null) {num = parseFloat(id); if (isNaN(num)) {return;}; scene = scenes.at(num);}; this.stop(); ide.switchToScene(scene, null, -message);}; +Process.prototype.doSwitchToScene = function (id, transmission) {var rcvr = this.blockReceiver(), idx = 0, message = this.inputOption(transmission.at(1)), ide, scenes, num, scene; this.assertAlive(rcvr); (this +).assertType(message, ['text', 'number', 'Boolean', 'list']); if (message instanceof List) {if (message.canBeJSON()) {message = message.deepMap(leif => leif);} else {throw new Error(localize('cannot send ' + ( +'media,\nsprites or procedures\nto another scene')));}}; if (this.readyToTerminate) {return;}; ide = rcvr.parentThatIsA(IDE_Morph); scenes = ide.scenes; if (id instanceof Array) {switch (this.inputOption(id)) { +case 'next': idx = scenes.indexOf(ide.scene) + 1; if (idx > scenes.length()) {idx = 1;}; break; case 'previous': idx = scenes.indexOf(ide.scene) - 1; if (idx < 1) {idx = scenes.length();}; break; case 'last': +idx = scenes.length(); break; case 'random': idx = this.reportBasicRandom(1, scenes.length()); break;}; this.stop(); ide.switchToScene(scenes.at(idx), null, message); return;}; scene = detect((scenes +).itemsArray(), scn => scn.name === id); if (scene === null) {num = parseFloat(id); if (isNaN(num)) {return;}; scene = scenes.at(num);}; this.stop(); ide.switchToScene(scene, null, message);}; // Process color primitives @@ -4876,8 +4774,7 @@ Process.prototype.reportRelationTo = function (relation, name) { name = this.packCoordinates(name); }; return this.hyperDyadic( (rel, nam) => this.reportBasicRelationTo(rel, nam), - relation, - name + relation, name ); }; return this.reportBasicRelationTo(relation, name); }; @@ -4895,8 +4792,7 @@ Process.prototype.reportBasicRelationTo = function (relation, name) { return this.reportDirectionTo(name); }; if (this.reportTypeOf(rel) === 'number') { return this.reportRayLengthTo(name, +rel); - }; return 0; -}; + }; return 0;}; Process.prototype.isCoordinate = function (data) { return data instanceof List && @@ -4905,31 +4801,18 @@ Process.prototype.isCoordinate = function (data) { this.reportTypeOf(data.at(2)) === 'number'; }; -Process.prototype.reportDistanceTo = function (name) { - var thisObj = this.blockReceiver(), - thatObj, stage, rc, point; - - if (thisObj) { - rc = thisObj.rotationCenter(); - point = rc; - if (this.inputOption(name) === 'mouse-pointer') { - point = thisObj.world().hand.position(); - } else if (this.inputOption(name) === 'center') { - return new Point(thisObj.xPosition(), thisObj.yPosition()) - .distanceTo(ZERO); - } else if (name instanceof List) { - return new Point(thisObj.xPosition(), thisObj.yPosition()) - .distanceTo(new Point(name.at(1), name.at(2))); - } - stage = thisObj.parentThatIsA(StageMorph); - thatObj = this.getOtherObject(name, thisObj, stage); - if (thatObj) { - point = thatObj.rotationCenter(); - } - return rc.distanceTo(point) / stage.scale; - } - return 0; -}; +Process.prototype.reportDistanceTo = function (name) {var thisObj = ( +this).blockReceiver(), thatObj, stage, rc, point; if (thisObj) {rc = ( +thisObj).rotationCenter(); point = rc; if (this.inputOption(name) === ( +'mouse-pointer')) {point = thisObj.world().hand.position();} else if ( +this.inputOption(name) === 'center') {return new Point((thisObj +).xPosition(), thisObj.yPosition()).distanceTo(ZERO);} else if ( +name instanceof List) {return new Point(thisObj.xPosition(), +thisObj.yPosition()).distanceTo(new Point(name.at(1), name.at( +2)));}; stage = thisObj.parentThatIsA(StageMorph); thatObj = ( +this).getOtherObject(name, thisObj, stage); if (thatObj) { +point = thatObj.rotationCenter();}; return (rc.distanceTo( +point) / stage.scale);}; return 0;}; Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { // raycasting edge detection - answer the distance between the asking @@ -4938,12 +4821,12 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { // an optional relative angle in degrees var thisObj = this.blockReceiver(), thatObj, stage, rc, targetBounds, - intersections = [], dir, a, b, x, - y, top, bottom, left, right, - circa, hSect, vSect, point, - hit, temp, width, imageData; - - circa = (num) => Math.round(num * 10000000) / 10000000; // good enough + intersections = [], dir, a, b, + x, y, top, bottom, left, right, + circa = (num => (Math.round( + num * 10000000) / 10000000) + ), hSect, vSect, point, hit, + temp, width, imageData; hSect = (yLevel) => { var theta = radians(dir); @@ -4961,8 +4844,8 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { ) { if (x >= left && x <= right) { intersections.push(new Point(x, yLevel)); - } - } + }; + }; }; vSect = (xLevel) => { @@ -4980,8 +4863,8 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { ) { if (y >= top && y <= bottom) { intersections.push(new Point(xLevel, y)); - } - } + }; + }; }; if (!thisObj) {return -1;}; @@ -5008,7 +4891,7 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { vSect(right); if (intersections.length < 2) { return -1; - } + }; } else { hSect(top); hSect(bottom); @@ -5016,8 +4899,7 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { vSect(right); if (intersections.length < 2) { return -1; - } - // sort + }; // sort if (dir !== 90) { if (Math.sign(rc.x - intersections[0].x) !== Math.sign(intersections[0].x - intersections[1].x) || @@ -5027,9 +4909,9 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { temp = intersections[0]; intersections[0] = intersections[1]; intersections[1] = temp; - } - } - } + }; + }; + }; // for debugging: /* @@ -5040,7 +4922,8 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { // convert intersections to local bitmap coordinates of the target intersections = intersections.map(point => - point.subtract(targetBounds.origin).floorDivideBy(stage.scale) + point.subtract(targetBounds.origin + ).floorDivideBy(stage.scale) ); // get image data @@ -5052,13 +4935,9 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { function alphaAt(imageData, width, x, y) { var idx = y * width + x; return imageData[idx] && 0x000000FF; // alpha - } - - function isOpaque(x, y) { + }; function isOpaque(x, y) { return alphaAt(imageData, width, x, y) > 0; - } - - function scan(testFunc, x0, y0, x1, y1) { + }; function scan(testFunc, x0, y0, x1, y1) { // Bresenham's algorithm var dx = Math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1, @@ -5070,21 +4949,18 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { while (true) { if (testFunc(x0, y0)) { return new Point(x0 * stage.scale, y0 * stage.scale); - } - if (x0 === x1 && y0 === y1) { - return -1; // not found - } - e2 = 2 * err; + }; if (x0 === x1 && y0 === y1) { + return -1; + }; e2 = 2 * err; if (e2 > dy) { err += dy; x0 += sx; - } - if (e2 < dx) { + }; if (e2 < dx) { err += dx; y0 += sy; - } - } - } + }; + }; + }; hit = scan( isOpaque, @@ -5092,39 +4968,31 @@ Process.prototype.reportRayLengthTo = function (name, relativeAngle = 0) { intersections[0].y, intersections[1].x, intersections[1].y - ); - if (hit === -1) {return hit; } - return rc.distanceTo(hit.add(targetBounds.origin)) / stage.scale; + ); if (hit === -1) {return hit;}; + return (rc.distanceTo(hit.add( + targetBounds.origin)) / ( + stage.scale)); }; Process.prototype.reportDirectionTo = function (name) { - var thisObj = this.blockReceiver(), - thatObj; + var thisObj = this.blockReceiver(), thatObj; if (thisObj) { if (this.inputOption(name) === 'mouse-pointer') { return thisObj.angleToXY(this.reportMouseX(), this.reportMouseY()); - } - if (this.inputOption(name) === 'center') { + }; if (this.inputOption(name) === 'center') { return thisObj.angleToXY(0, 0); - } - if (name instanceof List) { + }; if (name instanceof List) { return thisObj.angleToXY( - name.at(1), - name.at(2) - ); - } - thatObj = this.getOtherObject(name, this.homeContext.receiver); + name.at(1), name.at(2)); + }; thatObj = this.getOtherObject(name, this.homeContext.receiver); if (thatObj) { return thisObj.angleToXY( thatObj.xPosition(), thatObj.yPosition() ); - } - return thisObj.direction(); - } - return 0; -}; + }; return thisObj.direction(); + }; return 0;}; Process.prototype.doEditCostume = function (input) {if (this.context.costumeDialog instanceof DialogBoxMorph) {if (this.context.costumeDialog.isDestroyed) {if (this.context.costumeDialog.isReplaced) { this.context.costumeDialog = this.context.costumeDialog.replacement; this.pushContext('doYield'); this.pushContext();} else {delete this.context.costumeDialog;};} else {this.pushContext('doYield'); @@ -5193,9 +5061,7 @@ Process.prototype.reportBasicBlockAttribute = function (attribute, block) { break; default: return ''; - break; - }; -}; + break;};}; /* // Process - Block attributes, DEFINE and introspection prims @@ -6048,16 +5914,10 @@ case 'blocks': return new List( }; Process.prototype.reportObject = function (name) { - // hyper-monadic if (this.enableHyperOps) { if (name instanceof List) { return name.map(each => this.reportObject(each)); - } - } - - var thisObj = this.blockReceiver(), - thatObj, - stage; + };}; var thisObj = this.blockReceiver(), thatObj, stage; if (thisObj) { this.assertAlive(thisObj); @@ -6065,16 +5925,14 @@ Process.prototype.reportObject = function (name) { if (stage.name === name) { thatObj = stage; } else if (name === 'allSprites') { - stage = thisObj.parentThatIsA(StageMorph); return new List(stage.children.filter(each => each instanceof SpriteMorph)); + stage = thisObj.parentThatIsA(StageMorph + ); return new List(stage.children.filter( + each => each instanceof SpriteMorph)); } else { - thatObj = this.getOtherObject(name, thisObj, stage); - } - if (thatObj) { + thatObj = this.getOtherObject(name, + thisObj, stage);}; if (thatObj) { this.assertAlive(thatObj); - } - return thatObj; - } -}; + }; return thatObj;};}; Process.prototype.doSet = function (attribute, value) {var name, rcvr, ide; rcvr = this.blockReceiver(); this.assertAlive(rcvr); if (!((attribute instanceof Context) || (attribute instanceof Array)) || (attribute instanceof Context && !(attribute.expression.selector === 'reportGet'))) {if (attribute.expression.selector === 'xPosition') {rcvr.setXPosition(value);} else if (attribute.expression.selector === 'yPosition') { @@ -6109,9 +5967,7 @@ rcvr.costumes.asArray()[value - 1]);} else if (attribute.expression.selector === rcvr.release(); } else { rcvr.perpetuate(); - } - break; - case 'name': + }; break; case 'name': case 'my name': this.assertType(rcvr, ['sprite', 'stage']); this.assertType(value, ['text', 'number']); @@ -6119,12 +5975,10 @@ rcvr.costumes.asArray()[value - 1]);} else if (attribute.expression.selector === if (ide) { rcvr.setName( ide.newSpriteName(value.toString(), rcvr) - ); - ide.spriteBar.nameField.setContents( + ); ide.spriteBar.nameField.setContents( ide.currentSprite.name.toString() ); - } - break; + }; break; case 'dangling?': case 'my dangling?': this.assertType(rcvr, 'sprite'); @@ -6145,8 +5999,7 @@ rcvr.costumes.asArray()[value - 1]);} else if (attribute.expression.selector === each.refresh(); } }); - } - rcvr.version = Date.now(); + }; rcvr.version = Date.now(); break; case 'rotation style': case 'my rotation style': @@ -6167,8 +6020,7 @@ rcvr.costumes.asArray()[value - 1]);} else if (attribute.expression.selector === each.refresh(); } }); - } - rcvr.version = Date.now(); + }; rcvr.version = Date.now(); break; case 'rotation x': case 'my rotation x': @@ -6189,38 +6041,25 @@ rcvr.costumes.asArray()[value - 1]);} else if (attribute.expression.selector === throw new Error( '"' + localize(name) + '" ' + localize('is read-only') ); - } -}}; + };};}; Process.prototype.reportContextFor = function (context, otherObj) { - var result = copy(context), - receiverVars, - rootVars; - - if (otherObj instanceof Context) { - result.outerContext = otherObj.outerContext; - result.variables.parentFrame = otherObj.outerContext.variables; - result.receiver = otherObj.receiver; - return result; - }; - result.receiver = otherObj; - if (!result.outerContext) { - result.outerContext = new Context; - result.variables.parentFrame = result.outerContext.variables; - } - result.outerContext = copy(result.outerContext); - result.outerContext.variables = copy(result.outerContext.variables); - result.outerContext.receiver = otherObj; - if (result.outerContext.variables.parentFrame) { - rootVars = result.outerContext.variables.parentFrame; - receiverVars = copy(otherObj.variables); - receiverVars.parentFrame = rootVars; - result.outerContext.variables.parentFrame = receiverVars; - } else { - result.outerContext.variables.parentFrame = otherObj.variables; - } - return result; -}; +var result = copy(context), receiverVars, rootVars; if ((otherObj +) instanceof Context) {result.outerContext = otherObj.outerContext; +result.variables.parentFrame = otherObj.outerContext.variables; +result.receiver = otherObj.receiver; return result;}; (result +).receiver = otherObj; if (!(result.outerContext)) {(result +).outerContext = new Context; (result.variables.parentFrame +) = result.outerContext.variables;}; result.outerContext = ( +copy(result.outerContext)); result.outerContext.variables = ( +copy(result.outerContext.variables)); (result.outerContext +).receiver = otherObj; if ((result.outerContext.variables +).parentFrame) {rootVars = (result.outerContext.variables +).parentFrame; receiverVars = copy(otherObj.variables); +receiverVars.parentFrame = rootVars; (result.outerContext +).variables.parentFrame = receiverVars;} else {(result +).outerContext.variables.parentFrame = otherObj.variables; +}; return result;}; Process.prototype.reportMousePosition = function () { var world, pos; @@ -6229,10 +6068,8 @@ Process.prototype.reportMousePosition = function () { if (world) { pos = this.homeContext.receiver.snapPoint(world.hand.position()); return new List([pos.x, pos.y]); - } - } - return ''; -}; + }; + }; return new List([0, 0]);}; Process.prototype.reportMouseX = function () { var world; @@ -6240,10 +6077,8 @@ Process.prototype.reportMouseX = function () { world = this.homeContext.receiver.world(); if (world) { return this.homeContext.receiver.snapPoint(world.hand.position()).x; - } - } - return 0; -}; + }; + }; return 0;}; Process.prototype.reportMouseY = function () { var world; @@ -6251,15 +6086,14 @@ Process.prototype.reportMouseY = function () { world = this.homeContext.receiver.world(); if (world) { return this.homeContext.receiver.snapPoint(world.hand.position()).y; - } - } - return 0; -}; + }; + }; return 0;}; -Process.prototype.reportMouseButton = function anonymous (button) {var world; -if (this.homeContext.receiver) {world = this.homeContext.receiver.world(); -if (world) {return world.hand.mouseButton === this.inputOption(button); -};}; return false;}; +Process.prototype.reportMouseButton = function ( +button) {var world; if (this.homeContext.receiver +) {world = this.homeContext.receiver.world(); if ( +world) {return world.hand.mouseButton === (this +).inputOption(button);};}; return false;}; Process.prototype.reportKeyPressed = function (keyString) { // hyper-monadic @@ -6276,15 +6110,17 @@ Process.prototype.reportKeyPressed = function (keyString) { ); } return stage.keysPressed[keyString] !== undefined; - } - } - return false; -}; + }; + }; return false;}; -Process.prototype.doChangeTimer = function (option) {var stage; if (this.homeContext.receiver) { -stage = this.homeContext.receiver.parentThatIsA(StageMorph); if (stage) {stage.changeTimer(option);};};}; -Process.prototype.doSetTimer = function (option, value) {var stage; if (this.homeContext.receiver) { -stage = this.homeContext.receiver.parentThatIsA(StageMorph); if (stage) {stage.setTimer(option, value);};};}; +Process.prototype.doChangeTimer = function (option) { +var stage; if (this.homeContext.receiver) {stage = ( +this.homeContext.receiver.parentThatIsA(StageMorph)); +if (stage) {stage.changeTimer(option);};};}; (Process +).prototype.doSetTimer = function (option, value) { +var stage; if (this.homeContext.receiver) {stage = ( +this.homeContext.receiver.parentThatIsA(StageMorph) +); if (stage) {stage.setTimer(option, value);};};}; // Process Dates and times in Snap Process.prototype.reportDate = function (datefn) { @@ -6314,8 +6150,8 @@ Process.prototype.reportDate = function (datefn) { // Process battery manager api primitive -Process.prototype.getBatteryChargingTime = function anonymous (option) {return (isNil(world.batteryAPI) ? 0 : (( -this.inputOption(option) === 'charging') ? world.batteryAPI.chargingTime : world.batteryAPI.dischargingTime));}; +Process.prototype.getBatteryChargingTime = function (option) {return (isNil(world.batteryAPI) ? 0 : (((this +).inputOption(option) === 'charging') ? world.batteryAPI.chargingTime : world.batteryAPI.dischargingTime));}; // Process video motion detection primitives @@ -6721,14 +6557,12 @@ Process.prototype.reportPentrailsAsSVG = function () { throw new Error (localize( 'there are currently no\nvectorizable pen trail segments' )); - } - svg = stage.trailsLogAsSVG(); + }; svg = stage.trailsLogAsSVG(); this.context.accumulator = { img : new Image, rot : svg.rot, ready : false - }; - acc = this.context.accumulator; + }; acc = this.context.accumulator; acc.img.onload = () => acc.ready = true; acc.img.src = 'data:image/svg+xml,' + svg.src; acc.img.rot = svg.rotationShift; @@ -6737,23 +6571,19 @@ Process.prototype.reportPentrailsAsSVG = function () { rcvr = this.blockReceiver(); if (rcvr instanceof SpriteMorph) { offset = new Point(rcvr.xPosition(), -rcvr.yPosition()); - } - this.returnValueToParentContext( + }; this.returnValueToParentContext( new SVG_Costume( this.context.accumulator.img, this.blockReceiver().newCostumeName(localize('Costume')), this.context.accumulator.rot.translateBy(offset) ) - ); - return; - } - this.pushContext(); -}; + ); return; + }; this.pushContext();}; // Process constant input options -Process.prototype.inputOption = function anonymous (data -) {return ((data instanceof Array) ? data[0] : data);}; +Process.prototype.inputOption = function (data) { +return (data instanceof Array) ? data[0] : data;}; // Process stack @@ -6769,11 +6599,9 @@ Process.prototype.pushContext = function (expression, outerContext) { }; Process.prototype.popContext = function () { - if (this.context) { - this.context.stopMusic(); - } - this.context = this.context ? this.context.parentContext : null; -}; +if (this.context) {this.context.stopMusic( +);}; this.context = (this.context ? (this +).context.parentContext : null);}; Process.prototype.returnValueToParentContext = function anonymous (value) {if (!(value === undefined)) {var target = (this.context ? (this.context.parentContext || this.homeContext) : this.homeContext ); target.addInput(value); /* if the script has been clicked on by the user in visible stepping mode, show the result of evaluating a reporter in a speech balloon. Thanks, Vic! */ /* Finished. */ if ( @@ -6815,25 +6643,23 @@ Process.prototype.flashPausedContext = function () { flashable.expression.flash(); flashable.isFlashing = true; this.flashingContext = flashable; - } + }; }; Process.prototype.doInterrupt = function () { this.popContext(); if (!this.isAtomic) { this.isInterrupted = true; - } + }; }; Process.prototype.doIdle = function (secs) { if (!this.context.startTime) { this.context.startTime = Date.now(); - } - if ((Date.now() - this.context.startTime) < (secs * 1000)) { + }; if ((Date.now() - this.context.startTime) < (secs * 1000)) { this.pushContext('doInterrupt'); return; - } - this.popContext(); + }; this.popContext(); }; Process.prototype.unflash = function () { @@ -6841,7 +6667,7 @@ Process.prototype.unflash = function () { this.flashingContext.expression.unflash(); this.flashingContext.isFlashing = false; this.flashingContext = null; - } + }; }; // Process: Compile (as of yet simple) block scripts to JS @@ -6863,20 +6689,17 @@ Process.prototype.getVarNamed = function (name) { // first check script vars, then global ones var frame = this.homeContext.variables.silentFind(name) || this.context.variables.silentFind(name), - value; - if (frame) { + value; if (frame) { value = frame.vars[name].value; return (value === 0 ? 0 : value === false ? false : value === '' ? '' : value || 0); // don't return null - } - throw new Error( + }; throw new Error( localize('a variable of name \'') + name + localize('\'\ndoes not exist in this context') - ); -}; + );}; Process.prototype.setVarNamed = function (name, value) { // private - special form for compiled expressions @@ -6891,11 +6714,10 @@ Process.prototype.setVarNamed = function (name, value) { + name + localize('\'\ndoes not exist in this context') ); - } - frame.vars[name].value = value; -}; + }; frame.vars[name].value = value;}; -Process.prototype.incrementVarNamed = function (name, delta) {this.setVarNamed(name, this.getVarNamed(name) + (+delta));}; +Process.prototype.incrementVarNamed = function (name, delta) { +this.setVarNamed(name, +(this.getVarNamed(name)) + (+delta));}; // Process: Atomic HOFs using experimental JIT-compilation @@ -6939,10 +6761,8 @@ Process.prototype.reportAtomicMap = function (reporter, list) { } if (formalParameterCount > 2) { parms.push(list); - } - result.push( - invoke( - func, + }; result.push( + invoke(func, new List(parms), null, null, @@ -6950,10 +6770,7 @@ Process.prototype.reportAtomicMap = function (reporter, list) { null, this.capture(reporter) // process ) - ); - } - return new List(result); -}; + );}; return new List(result);}; Process.prototype.reportAtomicKeep = function (reporter, list) { // if the reporter uses formal parameters instead of implicit empty slots @@ -7085,9 +6902,7 @@ Process.prototype.reportAtomicCombine = function (list, reporter) { list, reporter.expression.selector ); - } - - result = ''; + }; result = ''; src = list.itemsArray(); len = src.length; if (reporter.constructor.name === 'Function') { @@ -7095,10 +6910,9 @@ Process.prototype.reportAtomicCombine = function (list, reporter) { if (reporter instanceof Context) { formalParameterCount = reporter.inputs.length;}; - if (len === 0) { - return result; - } - result = src[0]; + if (len === 0) { + return result; + }; result = src[0]; // try compiling the reporter into generic JavaScript // fall back to the morphic reporter if unsuccessful @@ -7107,7 +6921,7 @@ Process.prototype.reportAtomicCombine = function (list, reporter) { } catch (err) { console.log(err.message); func = reporter; - } + }; // iterate over the data in a single frame: // to do: Insert some kind of user escape mechanism @@ -7128,9 +6942,7 @@ Process.prototype.reportAtomicCombine = function (list, reporter) { null, this.capture(reporter) // process ); - } - return result; -}; + }; return result;}; Process.prototype.reportAtomicSort = function (list, predicate) { this.assertType(predicate, ['command', 'reporter', 'predicate']); @@ -7156,8 +6968,7 @@ Process.prototype.reportAtomicSort = function (list, predicate) { this.capture(predicate) // process ) - 0.5) * 2) ) - ); -}; + );}; Process.prototype.reportAtomicGroup = function (list, reporter) { this.assertType(reporter, ['command', 'reporter', 'predicate']); @@ -7219,18 +7030,17 @@ for (i = 0; i < len; i += 1) { dict.set(data[i], dict.get(data[i]) + 1); } else { dict.set(data[i], 1); - } -} -dict.forEach(function (value, key) { + }; +}; dict.forEach(function (value, key) { result.push(new List([key, value])); -}); -return new List(result);}; +}); return new List(result);}; -Process.prototype.callMeWith = function anonymous (string) {if ((typeof string) === 'string') {if (string.toLowerCase() === 'please') {if (this.blockReceiver() instanceof StageMorph) {return 'first drag me from' + -' the stage into a sprite, then call me again!';} else {return this.reify(SpriteMorph.prototype.blockForSelector('runMeWith'), new List);};} else {return 'call me with \"please\", please!';};} else { -return 'come on, call me with \"please\"!';};}; Process.prototype.runMeWith = function anonymous (name) {if (this.blockReceiver() instanceof SpriteMorph) {if ((typeof name) === 'string') { -if (name.length > 0) {this.blockReceiver().bubble(name + '! Nice talking to you :-) Congratulations for ' + 'figuring out this little riddle. You are now a certified lambdaist!' -);} else {this.blockReceiver().bubble('Run me with your name!');};};};}; /* Now enjoy this class, guy. :-) */ +Process.prototype.callMeWith = function (string) {if ((typeof string) === 'string') {if (string.toLowerCase() === 'please') {if (this.blockReceiver( +) instanceof StageMorph) {return 'first drag me from the stage into a sprite, then call me again!';} else {return this.reify((SpriteMorph.prototype +).blockForSelector('runMeWith'), new List);};} else {return 'call me with \"please\", please!';};} else {return 'come on, call me with \"please\"!'; +};}; Process.prototype.runMeWith = function (name) {if (this.blockReceiver() instanceof SpriteMorph) {if ((typeof name) === 'string') {if ((name +).length > 0) {this.blockReceiver().bubble(name + ('! Nice talking to you :~) Congratulations for figuring out this little riddle. You are now ' +) + 'a certified lambdaist!');} else {this.blockReceiver().bubble('Run me with your name!');};};};}; /* Now enjoy this class, guy. :-) */ // Context ///////////////////////////////////////////////////////////// @@ -7272,70 +7082,73 @@ if (name.length > 0) {this.blockReceiver().bubble(name + '! Nice talking to you accumulator slot for collecting data from reentrant visits */ -function Context(parentContext, expression, outerContext, receiver) {/* :~) */ this.selector = ('reify' -).concat(asABool(localStorage['-snap-setting-oldLambdaOn']) ? '' : 'Reporter'); this.outerContext = ( -outerContext || null); this.parentContext = (parentContext || null); this.expression = (expression || [ -SpriteMorph.prototype.blockForSelector(this.selector)]); this.receiver = (receiver || null); this.origin = -(receiver || null); this.variables = new VariableFrame; if (this.outerContext) {this.variables.parentFrame = -this.outerContext.variables; this.receiver = this.outerContext.receiver;}; this.inputs = []; this.pc = 0; -this.isContinuation = false; this.startTime = null; this.activeSends = null; this.activeAudio = null; -this.activeNote = null; this.isCustomBlock = false; this.isCustomCommand = null; this.emptySlots = 0; -this.tag = null; this.isFlashing = false; this.accumulator = null; this.version = null;}; -Context.prototype.toString = function () {var expr = this.expression; if (expr instanceof Array) { -if (expr.length > 0) {expr = '[' + expr[0] + ']';};}; return 'Context >> ' + expr + ' ' + this.variables;}; -Context.prototype.getBYOB = function () {var aBlock = new CommandBlockMorph; aBlock.category = 'control'; -aBlock.setSpec('BY %r B'); aBlock.fixLayout(); aBlock.fixBlockColor(); return (new Context(null, aBlock.fullCopy()) -);}; Context.prototype.visual = function () {if (asABool(localStorage['-snap-setting-oldLambdaOn'])) {if ( -this.isContinuation) {if (this.expression instanceof Array) {var aBlock = this.expression[this.pc].fullCopy( -);} else if (this.expression instanceof Morph) {var aBlock = this.beDraggable().fullCopy();} else {var aBlock = ( -new Context).beDraggable();};} else if ((this.selector === 'reify') && (this.inputs.length > 0) && !( -this.expression instanceof Morph)) {var aBlock = new CommandBlockMorph; aBlock.setSpec('input names:'); -this.inputs.forEach(function anonymous (name) {aBlock.add((function anonymous (spec) {var aVar = new ReporterBlockMorph; -aVar.category = 'variables'; aVar.fixBlockColor(); aVar.setSpec(spec); return aVar;})(name));}); -aBlock.fixBlockColor(); var otherBlock = SpriteMorph.prototype.blockForSelector('doReport'); -otherBlock.fixLayout(); aBlock.add(otherBlock);} else if (this.expression instanceof InputSlotMorph) { -var aBlock = this.beDraggable().blockSlot().nestedBlock().fullCopy();} else if ( -this.expression instanceof BooleanSlotMorph) {var aBlock = this.beDraggable().blockSlot().nestedBlock( -).fullCopy();} else if (this.expression instanceof ReporterBlockMorph) {if (this.inputs.length > 0) { -var aBlock = new CommandBlockMorph; aBlock.setSpec('input names:'); this.inputs.forEach( -function anonymous (name) {aBlock.add((function anonymous (spec) {var aVar = new ReporterBlockMorph; -aVar.category = 'variables'; aVar.fixBlockColor(); aVar.setSpec(spec); return aVar;})(name));}); -aBlock.fixBlockColor(); var otherBlock = SpriteMorph.prototype.blockForSelector('doReport'); -otherBlock.children.pop(); otherBlock.add(this.expression.fullCopy()); otherBlock.children[1].fixBlockColor(); -otherBlock.fixLayout(); aBlock.add(otherBlock);} else if (this.expression.selector === 'reportScript') { -var aBlock = SpriteMorph.prototype.blockForSelector('doReport'); aBlock.children.pop(); -aBlock.add(this.expression.fullCopy()); aBlock.children[1].fixBlockColor(); -} else {var aBlock = this.expression.fullCopy(); aBlock.fixBlockColor();}; -} else if (this.expression instanceof CommandBlockMorph) {if (this.inputs.length > 0) { -var aBlock = new CommandBlockMorph; aBlock.setSpec('input names:'); this.inputs.forEach( -function (name) {aBlock.add((function (spec) {var aVar = new ReporterBlockMorph; -aVar.category = 'variables'; aVar.fixBlockColor(); aVar.setSpec(spec); return aVar; -})(name));}); aBlock.fixBlockColor(); aBlock.add(this.expression.fullCopy());} else {if ( -this.expression.selector === 'doReport') {if (this.expression.children[1] instanceof ReporterBlockMorph -) {var aBlock = this.expression.children[1].fullCopy();} else {var aBlock = this.expression.fullCopy();}; -} else {var aBlock = this.expression.fullCopy();};};} else {var aBlock = this.beDraggable().fullCopy();}; -aBlock.highlight = function (color, blur, border) {var highlight = new BlockHighlightMorph; -border = border * SyntaxElementMorph.prototype.scale; var fb = this.fullBounds(); var edge = border; -highlight.bounds.setExtent(fb.extent().add(edge * 2)); highlight.holes = [highlight.bounds]; -highlight.color = color; highlight.cachedImage = this.highlightImage(color, border); -highlight.setPosition(fb.origin.subtract(new Point(edge, edge))); return highlight;}; -aBlock.addBack(aBlock.highlight(SyntaxElementMorph.prototype.rfColor, 0, 0)); -aBlock.fixBlockColor(); aBlock.fixLayout(); aBlock.fixLabelColor(); return aBlock;} else { -return this.beDraggable();};}; Context.prototype.image = function () {return this.visual().fullImage( -);}; Context.prototype.beDraggable = function () {if (asABool(localStorage['-snap-setting-oldLambdaOn'])) { -if (this.expression instanceof Array) {if (this.isContinuation) {var aBlock = SpriteMorph.prototype.blockForSelector( -(this.expression[this.pc] instanceof CommandBlockMorph) ? 'reportScript' : 'reify');} else { -var aBlock = SpriteMorph.prototype.blockForSelector(this.selector);}; if (aBlock.selector === 'reportScript' -) {var thatParameters = aBlock.inputNamesElement(); var thatC = aBlock.blockSlot();} else {var thatParameters = aBlock.inputNamesElement(); -var thatC = aBlock.blockSlot();}; this.inputs.forEach(function (input) {thatParameters.addInput(input);}); if (( -this.expression[this.pc] instanceof Morph) && this.isContinuation) {thatC.nestedBlock(this.expression[this.pc -].fullCopy());};} else if (!(this.expression instanceof Morph)) {var aBlock = SpriteMorph.prototype.blockForSelector( -'reportScript'); var thatParameters = aBlock.inputNamesElement(); this.inputs.forEach(function (input) {thatParameters.addInput( -input);});} else if (this.expression instanceof InputSlotMorph) {var aBlock = SpriteMorph.prototype.blockForSelector('reportScript'); -var thatParameters = aBlock.inputNamesElement(); this.inputs.forEach(function (input) {thatParameters.addInput(input);}); -var otherBlock = SpriteMorph.prototype.blockForSelector('doReport'); otherBlock.children.pop().parent = null; -otherBlock.add(this.expression.fullCopy()); otherBlock.fixLayout(); aBlock.blockSlot().nestedBlock(otherBlock); -aBlock.fixLayout();} else if (this.expression instanceof BooleanSlotMorph) {var aBlock = SpriteMorph.prototype.blockForSelector( +function Context(parentContext, expression, outerContext, receiver) {this.selector = ('reify').concat( +asABool(localStorage['-snap-setting-oldLambdaOn']) ? '' : 'Reporter'); this.outerContext = ((outerContext +) || null); this.parentContext = (parentContext || null); this.expression = (expression || [(SpriteMorph +).prototype.blockForSelector(this.selector)]); this.receiver = (receiver || null); this.origin = ((receiver +) || null); this.variables = new VariableFrame; if (this.outerContext) {this.variables.parentFrame = (this +).outerContext.variables; this.receiver = this.outerContext.receiver;}; this.inputs = []; this.pc = 0; (this +).isContinuation = false; this.startTime = null; this.activeSends = null; this.activeAudio = null; (this +).activeNote = null; this.isCustomBlock = false; this.isCustomCommand = null; this.emptySlots = 0; (this.tag +) = null; this.isFlashing = false; this.accumulator = null; this.version = null;}; (Context.prototype.toString +) = function () {var expr = this.expression; if (expr instanceof Array) {if (expr.length > 0) {expr = '[' + ( +expr[0]) + ']';};}; return 'Context >> ' + expr + ' ' + this.variables;}; Context.prototype.getBYOB = function ( +) {var aBlock = new CommandBlockMorph; aBlock.category = 'control'; aBlock.setSpec('BY %r B'); aBlock.fixLayout( +); aBlock.fixBlockColor(); return new Context(null, aBlock.fullCopy());}; Context.prototype.visual = function ( +) {if (asABool(localStorage['-snap-setting-oldLambdaOn'])) {if (this.isContinuation) {if ((this.expression +) instanceof Array) {var aBlock = this.expression[this.pc].fullCopy();} else if ((this.expression +) instanceof Morph) {var aBlock = this.beDraggable().fullCopy();} else {var aBlock = (new Context +).beDraggable();};} else if ((this.selector === 'reify') && (this.inputs.length > 0) && !((this +).expression instanceof Morph)) {var aBlock = new CommandBlockMorph; aBlock.setSpec('input names:'); +this.inputs.forEach(function (name) {aBlock.add((function (spec) {var aVar = new ReporterBlockMorph; +aVar.category = 'variables'; aVar.fixBlockColor(); aVar.setSpec(spec); return aVar;})(name));} +); aBlock.fixBlockColor(); var otherBlock = SpriteMorph.prototype.blockForSelector('doReport'); +otherBlock.fixLayout(); aBlock.add(otherBlock);} else if (this.expression instanceof InputSlotMorph +) {var aBlock = this.beDraggable().blockSlot().nestedBlock().fullCopy();} else if ((this.expression +) instanceof BooleanSlotMorph) {var aBlock = this.beDraggable().blockSlot().nestedBlock().fullCopy(); +} else if (this.expression instanceof ReporterBlockMorph) {if (this.inputs.length > 0) {var aBlock = ( +new CommandBlockMorph); aBlock.setSpec('input names:'); this.inputs.forEach(function (name) {aBlock.add( +(function (spec) {var aVar = new ReporterBlockMorph; aVar.category = 'variables'; aVar.fixBlockColor( +); aVar.setSpec(spec); return aVar;})(name));}); aBlock.fixBlockColor(); var otherBlock = (SpriteMorph +).prototype.blockForSelector('doReport'); otherBlock.children.pop(); otherBlock.add((this.expression +).fullCopy()); otherBlock.children[1].fixBlockColor(); otherBlock.fixLayout(); aBlock.add(otherBlock +);} else if (this.expression.selector === 'reportScript') {var aBlock = (SpriteMorph.prototype +).blockForSelector('doReport'); aBlock.children.pop(); aBlock.add(this.expression.fullCopy() +); aBlock.children[1].fixBlockColor();} else {var aBlock = this.expression.fullCopy(); (aBlock +).fixBlockColor();};} else if (this.expression instanceof CommandBlockMorph) {if ((this.inputs +).length > 0) {var aBlock = new CommandBlockMorph; aBlock.setSpec('input names:'); (this.inputs +).forEach(function (name) {aBlock.add((function (spec) {var aVar = new ReporterBlockMorph; (aVar +).category = 'variables'; aVar.fixBlockColor(); aVar.setSpec(spec); return aVar;})(name));}); +aBlock.fixBlockColor(); aBlock.add(this.expression.fullCopy());} else {if ((this.expression.selector +) === 'doReport') {if (this.expression.children[1] instanceof ReporterBlockMorph) {var aBlock = (this +).expression.children[1].fullCopy();} else {var aBlock = this.expression.fullCopy();};} else { +var aBlock = this.expression.fullCopy();};};} else {var aBlock = this.beDraggable().fullCopy(); +}; aBlock.highlight = function (color, blur, border) {var highlight = new BlockHighlightMorph; +border = border * SyntaxElementMorph.prototype.scale; var fb = this.fullBounds(); var edge = ( +border); highlight.bounds.setExtent(fb.extent().add(edge * 2)); highlight.holes = [(highlight +).bounds]; highlight.color = color; highlight.cachedImage = this.highlightImage(color, border); +highlight.setPosition(fb.origin.subtract(new Point(edge, edge))); return highlight;}; (aBlock +).addBack(aBlock.highlight(SyntaxElementMorph.prototype.rfColor, 0, 0)); aBlock.fixBlockColor(); +aBlock.fixLayout(); aBlock.fixLabelColor(); return aBlock;} else {return this.beDraggable();};}; +Context.prototype.image = function () {return (this.visual()).fullImage();}; (Context.prototype +).beDraggable = function () {if (asABool(localStorage['-snap-setting-oldLambdaOn'])) {if ((this +).expression instanceof Array) {if (this.isContinuation) {var aBlock = (SpriteMorph.prototype +).blockForSelector((this.expression[this.pc] instanceof CommandBlockMorph) ? ('reportScript' +) : 'reify');} else {var aBlock = SpriteMorph.prototype.blockForSelector(this.selector);}; +if (aBlock.selector === 'reportScript') {var thatParameters = aBlock.inputNamesElement(); +var thatC = aBlock.blockSlot();} else {var thatParameters = aBlock.inputNamesElement(); +var thatC = aBlock.blockSlot();}; this.inputs.forEach(function (input) {(thatParameters +).addInput(input);}); if ((this.expression[this.pc] instanceof Morph) && this.isContinuation +) {thatC.nestedBlock(this.expression[this.pc].fullCopy());};} else if (!((this.expression +) instanceof Morph)) {var aBlock = SpriteMorph.prototype.blockForSelector('reportScript'); +var thatParameters = aBlock.inputNamesElement(); this.inputs.forEach(function (input) { +thatParameters.addInput(input);});} else if (this.expression instanceof InputSlotMorph) { +var aBlock = SpriteMorph.prototype.blockForSelector('reportScript'); var thatParameters = ( +aBlock.inputNamesElement()); this.inputs.forEach(function (input) {thatParameters.addInput( +input);}); var otherBlock = SpriteMorph.prototype.blockForSelector('doReport'); (otherBlock +).children.pop().parent = null; otherBlock.add(this.expression.fullCopy()); (otherBlock +).fixLayout(); aBlock.blockSlot().nestedBlock(otherBlock); aBlock.fixLayout();} else if ( +this.expression instanceof BooleanSlotMorph) {var aBlock = SpriteMorph.prototype.blockForSelector( 'reify'); var thatParameters = aBlock.inputNamesElement(); this.inputs.forEach(function (input) {thatParameters.addInput(input);}); if (this.expression.evaluate() === true) {var otherBlock = SpriteMorph.prototype.blockForSelector('reportTrue', true); } else if (this.expression.evaluate() === false) {var otherBlock = SpriteMorph.prototype.blockForSelector('reportFalse', true); @@ -7463,8 +7276,8 @@ Context.prototype.continuation = function (isReporter) { this.emptySlots = 1; }; }; Context.prototype.addInput = function (input) {this.inputs.push(input);}; -Context.prototype.stopMusic = function () {if (this.activeNote) {this.activeNote.stop(); -this.activeNote = null;};}; Context.prototype.lastFlashable = function () { +Context.prototype.stopMusic = function () {if (this.activeNote) {this.activeNote.stop( +); this.activeNote = null;};}; Context.prototype.lastFlashable = function () { // for single-stepping when pausing if (this.expression instanceof SyntaxElementMorph && !(this.expression instanceof CommandSlotMorph)) { diff --git a/src/video.js b/src/video.js index e4307df..c457ff3 100644 --- a/src/video.js +++ b/src/video.js @@ -36,12 +36,6 @@ */ -/*global modules, StageMorph*/ - -// Global stuff //////////////////////////////////////////////////////// - -modules.video = '2019-May-22'; - var VideoMotion; // VideoMotion ///////////////////////////////////////////////////////////////// @@ -59,13 +53,13 @@ function VideoMotion(width, height) { this.lastAnalyzedFrame = 0; this.motionAmount = 0; this.motionDirection = 0; - this.imageBuffer = new ArrayBuffer(this.width * this.height * 2); + this.imageBuffer = new ArrayBuffer( + this.width * this.height * 2); this.curr = new Uint8ClampedArray( this.imageBuffer, 0, this.width * this.height - ); - this.prev = new Uint8ClampedArray( + ); this.prev = new Uint8ClampedArray( this.imageBuffer, this.width * this.height, this.width * this.height @@ -387,4 +381,4 @@ VideoMotion.prototype.getLocalMotion = function(aSprite) { } return bounds; } -}; +}; \ No newline at end of file diff --git a/src/widgets.js b/src/widgets.js index b272af7..09f447f 100644 --- a/src/widgets.js +++ b/src/widgets.js @@ -77,16 +77,9 @@ */ -var PushButtonMorph; -var ToggleButtonMorph; -var TabMorph; -var ToggleMorph; -var ToggleElementMorph; -var DialogBoxMorph; -var AlignmentMorph; -var InputFieldMorph; -var PianoMenuMorph; -var PianoKeyMorph; +var PushButtonMorph, ToggleElementMorph, ToggleButtonMorph, +DialogBoxMorph, AlignmentMorph, InputFieldMorph, TabMorph, +PianoMenuMorph, PianoKeyMorph, ToggleMorph; // PushButtonMorph ///////////////////////////////////////////////////// @@ -100,23 +93,20 @@ PushButtonMorph.uber = TriggerMorph.prototype; // PushButtonMorph preferences settings: -PushButtonMorph.prototype.fontSize = 10; -PushButtonMorph.prototype.fontStyle = 'sans-serif'; -PushButtonMorph.prototype.labelColor = BLACK; -PushButtonMorph.prototype.labelShadowColor = WHITE; -PushButtonMorph.prototype.labelShadowOffset = new Point(1, 1); - -PushButtonMorph.prototype.color = new Color(220, 220, 220); -PushButtonMorph.prototype.pressColor = new Color(115, 180, 240); -PushButtonMorph.prototype.highlightColor - = PushButtonMorph.prototype.pressColor.lighter(50); -PushButtonMorph.prototype.outlineColor = new Color(30, 30, 30); +PushButtonMorph.prototype.fontSize = 10; (PushButtonMorph +).prototype.fontStyle = 'sans-serif'; (PushButtonMorph +).prototype.labelColor = BLACK; (PushButtonMorph.prototype +).labelShadowColor = WHITE; (PushButtonMorph.prototype +).labelShadowOffset = new Point(1, 1); (PushButtonMorph +).prototype.color = new Color(220, 220, 220); (PushButtonMorph +).prototype.pressColor = new Color(115, 180, 240); +PushButtonMorph.prototype.highlightColor = ( +PushButtonMorph).prototype.pressColor.lighter(50); PushButtonMorph.prototype.outlineGradient = false; -PushButtonMorph.prototype.contrast = 60; - -PushButtonMorph.prototype.edge = 2; -PushButtonMorph.prototype.corner = 5; -PushButtonMorph.prototype.outline = 1; +PushButtonMorph.prototype.outlineColor = new Color( +30, 30, 30, 0.5); PushButtonMorph.prototype.contrast = 60; +PushButtonMorph.prototype.edge = 2; (PushButtonMorph.prototype +).corner = 5; PushButtonMorph.prototype.outline = 1; PushButtonMorph.prototype.padding = 3; // PushButtonMorph instance creation: @@ -135,15 +125,11 @@ function PushButtonMorph( environment, hint ); -} +}; PushButtonMorph.prototype.init = function ( - target, - action, - labelString, - environment, - hint -) { +target, action, labelString, environment, +hint) { // additional properties: this.is3D = false; // for "flat" design exceptions this.target = target || null; @@ -160,11 +146,8 @@ PushButtonMorph.prototype.init = function ( // override inherited properites: this.color = PushButtonMorph.prototype.color; - this.createLabel(); - this.fixLayout(); - this.rerender(); - - this.cursorStyle = 'pointer'; + this.createLabel(); this.fixLayout(); (this + ).rerender(); this.cursorStyle = 'pointer'; }; // PushButtonMorph layout: @@ -183,9 +166,8 @@ PushButtonMorph.prototype.fixLayout = function () { this.label.rawHeight() : this.label.height(), this.labelMinExtent.y ) + padding - ); - this.label.setCenter(this.center()); - } + ); this.label.setCenter(this.center()); + }; }; // PushButtonMorph events @@ -194,7 +176,7 @@ PushButtonMorph.prototype.mouseDownLeft = function () { PushButtonMorph.uber.mouseDownLeft.call(this); if (this.label) { this.label.setCenter(this.center().add(1)); - } + }; }; PushButtonMorph.prototype.mouseClickLeft = function () { @@ -202,31 +184,32 @@ PushButtonMorph.prototype.mouseClickLeft = function () { PushButtonMorph.uber.mouseClickLeft.call(this); if (this.label) { this.label.setCenter(this.center()); - } + }; }; PushButtonMorph.prototype.mouseLeave = function () { PushButtonMorph.uber.mouseLeave.call(this); if (this.label) { this.label.setCenter(this.center()); - } + }; }; // PushButtonMorph drawing: -PushButtonMorph.prototype.render = function (ctx) { - if (this.userState === 'highlight') { - this.drawOutline(ctx); - this.drawBackground(ctx, this.highlightColor); - this.drawEdges( - ctx, - this.highlightColor, +PushButtonMorph.prototype.render = function ( + ctx) {var isFlat = MorphicPreferences.isFlat && !this.is3D; + if (this.userState === 'highlight' + ) {this.drawOutline(ctx + ); this.drawBackground( + ctx, (isFlat ? (this.highlightColor).lighter(this.contrast) : this.highlightColor) + ); this.drawEdges( + ctx, this.highlightColor, this.highlightColor.lighter(this.contrast), this.highlightColor.darker(this.contrast) ); } else if (this.userState === 'pressed') { this.drawOutline(ctx); - this.drawBackground(ctx, this.pressColor); + this.drawBackground(ctx, (isFlat ? (this.pressColor).lighter(this.contrast) : this.pressColor)); this.drawEdges( ctx, this.pressColor, @@ -235,21 +218,20 @@ PushButtonMorph.prototype.render = function (ctx) { ); } else { this.drawOutline(ctx); - this.drawBackground(ctx, this.color); + this.drawBackground(ctx, (isFlat ? (this.color).lighter(this.contrast) : this.color)); this.drawEdges( ctx, this.color, this.color.lighter(this.contrast), this.color.darker(this.contrast) ); - } -}; + };}; PushButtonMorph.prototype.drawOutline = function (ctx) { var outlineStyle, isFlat = MorphicPreferences.isFlat && !this.is3D; - if (!this.outline) {return null; } + if (this.outline) { if (this.outlineGradient) { outlineStyle = ctx.createLinearGradient( 0, @@ -261,27 +243,23 @@ PushButtonMorph.prototype.drawOutline = function (ctx) { outlineStyle.addColorStop(1, (isFlat ? this.outlineColor.darker().toString() : 'white')); } else { outlineStyle = this.outlineColor.toString(); - } - ctx.fillStyle = outlineStyle; + }; ctx.fillStyle = outlineStyle; ctx.beginPath(); this.outlinePath( ctx, - this.corner, - 0 - ); - ctx.closePath(); - ctx.fill(); + this.corner, 0 + ); ctx.closePath(); + ctx.fill();}; }; PushButtonMorph.prototype.drawBackground = function (ctx, color) { ctx.fillStyle = color.toString(); ctx.beginPath(); - this.outlinePath( - ctx, - Math.max(this.corner - this.outline, 0), - this.outline - ); - ctx.closePath(); + this.outlinePath(ctx, + Math.max((this.corner + ) - this.outline, 0 + ), this.outline); + ctx.closePath(); ctx.fill(); ctx.lineWidth = this.outline; }; @@ -291,8 +269,7 @@ PushButtonMorph.prototype.drawEdges = function ( color, topColor, bottomColor -) { - if (MorphicPreferences.isFlat && !this.is3D) {return;}; +) {if (!(MorphicPreferences.isFlat && !(this.is3D))) { var minInset = Math.max(this.corner, this.outline + this.edge), w = this.width(), h = this.height(), @@ -300,10 +277,8 @@ PushButtonMorph.prototype.drawEdges = function ( // top: gradient = ctx.createLinearGradient( - 0, - this.outline, - 0, - this.outline + this.edge + 0, this.outline, + 0, this.outline + this.edge ); gradient.addColorStop(0, topColor.toString()); gradient.addColorStop(1, color.toString()); @@ -399,10 +374,9 @@ PushButtonMorph.prototype.drawEdges = function ( h - this.corner, Math.max(this.corner - this.outline - this.edge / 2, 0), radians(0), - radians(90), - false - ); - ctx.stroke(); + radians(90 + ), false + ); ctx.stroke(); // right: gradient = ctx.createLinearGradient( @@ -410,18 +384,14 @@ PushButtonMorph.prototype.drawEdges = function ( 0, w - this.outline - this.edge, 0 - ); - gradient.addColorStop(0, bottomColor.toString()); - gradient.addColorStop(1, color.toString()); + ); gradient.addColorStop(0, bottomColor.toString( + )); gradient.addColorStop(1, color.toString()); - ctx.strokeStyle = gradient; - ctx.lineCap = 'round'; - ctx.lineWidth = this.edge; - ctx.beginPath(); - ctx.moveTo(w - this.outline - this.edge / 2, minInset); - ctx.lineTo(w - this.outline - this.edge / 2, h - minInset); - ctx.stroke(); -}; + ctx.strokeStyle = gradient; ctx.lineCap = 'round'; + ctx.lineWidth = this.edge; ctx.beginPath( + ); ctx.moveTo(w - this.outline - this.edge / 2, + minInset); ctx.lineTo(w - this.outline - this.edge / 2, + h - minInset); ctx.stroke();};}; PushButtonMorph.prototype.outlinePath = BoxMorph.prototype.outlinePath; @@ -430,14 +400,12 @@ PushButtonMorph.prototype.createLabel = function () { if (this.label !== null) { this.label.destroy(); - } - if (this.labelString instanceof SymbolMorph) { + }; if (this.labelString instanceof SymbolMorph) { this.label = this.labelString.fullCopy(); if (shading) { this.label.shadowOffset = this.labelShadowOffset; this.label.shadowColor = this.labelShadowColor; - } - this.label.color = this.labelColor; + }; this.label.color = this.labelColor; } else { this.label = new StringMorph( localize(this.labelString), @@ -450,8 +418,7 @@ PushButtonMorph.prototype.createLabel = function () { this.labelShadowColor, this.labelColor ); - } - this.add(this.label); + }; this.add(this.label); }; PushButtonMorph.prototype.updateLabelColors = function () { @@ -462,9 +429,8 @@ PushButtonMorph.prototype.updateLabelColors = function () { if (shading) { this.label.shadowOffset = this.labelShadowOffset; this.label.shadowColor = this.labelShadowColor; - } - this.label.fixLayout(true); // just me - } + }; this.label.fixLayout(true); // just me + }; }; // PushButtonMorph states @@ -473,16 +439,14 @@ PushButtonMorph.prototype.disable = function () { this.isDisabled = true; this.forAllChildren(child => child.alpha = 0.3 - ); - this.rerender(); + ); this.rerender(); }; PushButtonMorph.prototype.enable = function () { this.isDisabled = false; this.forAllChildren(child => child.alpha = 1 - ); - this.rerender(); + ); this.rerender(); }; // ToggleButtonMorph /////////////////////////////////////////////////////// @@ -555,57 +519,38 @@ ToggleButtonMorph.prototype.init = function ( // initialize inherited properties: ToggleButtonMorph.uber.init.call( - this, - target, - action, - labelString, - environment, - hint - ); + this, target, action, labelString, + environment, hint); // override default colors if others are specified - if (colors) { - this.color = colors[0]; + if (colors) {this.color = colors[0 + ]; this.pressColor = colors[2]; this.highlightColor = colors[1]; - this.pressColor = colors[2]; - } - - this.refresh(); - this.rerender(); + }; this.refresh(); this.rerender(); }; // ToggleButtonMorph events ToggleButtonMorph.prototype.mouseEnter = function () { - var contents = this.hint instanceof Function ? this.hint() : this.hint; - if (!this.state || this.hasNeutralBackground) { - this.userState = 'highlight'; - this.rerender(); - } - if (contents) { - this.bubbleHelp(contents); - } -}; +var contents = this.hint instanceof Function ? this.hint( +) : this.hint; if (!this.state || this.hasNeutralBackground +) {this.userState = 'highlight'; this.rerender(); +}; if (contents) {this.bubbleHelp(contents);};}; ToggleButtonMorph.prototype.mouseLeave = function () { if (!this.state || this.hasNeutralBackground) { this.userState = 'normal'; this.rerender(); - } - if (this.schedule) { + }; if (this.schedule) { this.schedule.isActive = false; - } - if (this.hint) { - this.world().hand.destroyTemporaries(); - } + }; if (this.hint) { + (world.hand + ).destroyTemporaries(); + }; }; -ToggleButtonMorph.prototype.mouseDownLeft = function () { - if (!this.state) { - this.userState = 'pressed'; - this.rerender(); - } -}; +ToggleButtonMorph.prototype.mouseDownLeft = function () {if ( +!this.state) {this.userState = 'pressed'; this.rerender();};}; ToggleButtonMorph.prototype.mouseClickLeft = function () { if (!this.state) { @@ -938,7 +883,7 @@ function TabMorph( // TabMorph layout: TabMorph.prototype.fixLayout = function () { - if (this.label !== null) { + if (!isNil(this.label)) { this.updateLabelColors(); this.setExtent(new Point( this.label.width() @@ -946,22 +891,17 @@ TabMorph.prototype.fixLayout = function () { + this.corner * 3 + this.edge * 2, (this.label instanceof StringMorph ? - this.label.rawHeight() : this.label.height()) - + this.padding * 2 - + this.edge - )); - this.label.setCenter(this.center()); - } -}; + this.label.rawHeight() : this.label.height()) + + (this.padding * 2) + this.edge + )); this.label.setCenter(this.center());};}; // TabMorph action: TabMorph.prototype.refresh = function () { if (this.state) { // bring to front if (this.parent) { - this.parent.add(this); - } - } + this.parent.add( + this);};}; TabMorph.uber.refresh.call(this); }; @@ -1054,7 +994,7 @@ function ToggleMorph( element, builder ); -} +}; ToggleMorph.prototype.init = function ( style, @@ -1071,10 +1011,10 @@ ToggleMorph.prototype.init = function ( this.padding = 1; style = style || 'checkbox'; this.corner = (style === 'checkbox' ? - 0 : fontHeight(this.fontSize) / 2 + this.outline + this.padding); - this.state = false; - this.query = query || (() => true); - this.tick = null; + 0 : (fontHeight(this.fontSize) / 2 + ) + this.outline + this.padding); + this.state = false; this.query = ( + query || (() => true)); this.tick = null; this.captionString = labelString || null; this.labelAlignment = 'right'; this.element = element || null; @@ -1086,12 +1026,12 @@ ToggleMorph.prototype.init = function ( this, target, action, - (style === 'checkbox' ? '\u2713' : '\u25CF'), + (style === 'checkbox' + ) ? '\u2713' : '\u25CF', environment, hint - ); - this.fixLayout(); - this.refresh(); + ); this.fixLayout( + ); this.refresh(); }; // ToggleMorph layout: @@ -1105,20 +1045,17 @@ ToggleMorph.prototype.fixLayout = function () { this.bounds.setWidth(Math.max(this.width(), this.height())); this.bounds.setHeight(Math.max(this.width(), this.height())); this.tick.setCenter(this.center()); - } - if (this.state) { + }; if (this.state) { this.tick.show(); } else { this.tick.hide(); - } - if (this.toggleElement && (this.labelAlignment === 'right')) { + }; if (this.toggleElement && (this.labelAlignment === 'right')) { y = this.top() + (this.height() - this.toggleElement.height()) / 2; this.toggleElement.setPosition(new Point( this.right() + padding, y )); - } - if (this.label !== null) { + }; if (this.label !== null) { y = this.top() + (this.height() - this.label.height()) / 2; if (this.labelAlignment === 'right') { this.label.setPosition(new Point( @@ -1134,8 +1071,8 @@ ToggleMorph.prototype.fixLayout = function () { this.left() - this.label.width() - padding, y )); - } - } + }; + }; }; ToggleMorph.prototype.createLabel = function () { @@ -1147,9 +1084,9 @@ ToggleMorph.prototype.createLabel = function () { localize(this.captionString), this.fontSize, this.fontStyle, - true - ); - this.add(this.label); + true); + this.add( + this.label); } } if (this.tick === null) { @@ -1157,12 +1094,11 @@ ToggleMorph.prototype.createLabel = function () { localize(this.labelString), this.fontSize, this.fontStyle, - true, - false, - false, - shading ? new Point(1, 1) : null, - new Color(240, 240, 240) - ); + true, false, + false, (shading + ) ? new Point(1, 1 + ) : null, new Color( + 240, 240, 240)); this.add(this.tick); } if (this.toggleElement === null) { @@ -1194,16 +1130,15 @@ ToggleMorph.prototype.createLabel = function () { this.toggleElement.cachedImage = this.element; } this.add(this.toggleElement); - } - } + }; + }; }; // ToggleMorph action: -ToggleMorph.prototype.trigger = function () { - ToggleMorph.uber.trigger.call(this); - this.refresh(); -}; +ToggleMorph.prototype.trigger = function ( +) {ToggleMorph.uber.trigger.call(this +); this.refresh();}; ToggleMorph.prototype.refresh = function () { /* @@ -1219,16 +1154,14 @@ ToggleMorph.prototype.refresh = function () { this.state = this.query.call(this.target); } else { // assume it's a String this.state = this.target[this.query](); - } - if (this.state) { + }; if (this.state) { this.tick.show(); } else { this.tick.hide(); - } - if (this.toggleElement && this.toggleElement.refresh && + }; if (this.toggleElement && this.toggleElement.refresh && !this.toggleElement.isToggleLabel) { this.toggleElement.refresh(); - } + }; }; // ToggleMorph events @@ -1342,7 +1275,7 @@ ToggleElementMorph.prototype.render = function (ctx) { this.shadowOffset, this.userState === 'normal' ? 0 : this.shadowAlpha ); - } + }; }; this.color = this.element.color; @@ -1361,19 +1294,16 @@ ToggleElementMorph.prototype.render = function (ctx) { if (this.element.doWithAlpha) { ctx.drawImage( this.element.doWithAlpha( - 1, - () => { + 1, () => { shadow(); return this.element.fullImage(); - } - ), - 0, - 0 + }), 0, 0 ); - } else { - shadow(); - ctx.drawImage(this.element.fullImage(), 0, 0); - } + } else {shadow(); + ctx.drawImage( + (this.element + ).fullImage( + ), 0, 0);}; // reset element this.element.removeShadow(); @@ -1406,8 +1336,8 @@ ToggleElementMorph.prototype.createLabel = function () { this.fontSize, this.fontStyle, true - ); - this.add(this.label); + ); this.add( + this.label); y = this.top() + (this.height() - this.label.height()) / 2; if (this.labelAlignment === 'right') { this.label.setPosition(new Point( @@ -1419,8 +1349,8 @@ ToggleElementMorph.prototype.createLabel = function () { this.left() - this.label.width(), y )); - } - } + }; + }; }; // ToggleElementMorph action @@ -1493,9 +1423,9 @@ DialogBoxMorph.prototype.instances = {}; // prevent multiple instances // DialogBoxMorph instance creation: -function DialogBoxMorph(target, action, environment) { - this.init(target, action, environment); -}; +function DialogBoxMorph(target, action, +environment) {this.init(target, +action, environment);}; DialogBoxMorph.prototype.init = function (target, action, environment) { // additional properties: @@ -1817,7 +1747,7 @@ DialogBoxMorph.prototype.promptVector = function ( if (msg) { bdy.add(labelText(msg)); - } + }; bdy.add(inp); @@ -1967,7 +1897,7 @@ DialogBoxMorph.prototype.promptRGB = function ( if (!this.key) { this.key = 'RGB' + title; - } + }; this.popUp(world); }; DialogBoxMorph.prototype.promptRGBA = function ( @@ -2007,7 +1937,7 @@ DialogBoxMorph.prototype.promptRGB = function ( MorphicPreferences.isFlat ? null : new Point(1, 1), WHITE // shadowColor ); - } + }; function constrainRGB (num) {return Math.max(0, Math.min(num, 255));}; function constrainAlpha (num) {return Math.max(0, Math.min(num, 1));}; @@ -2074,17 +2004,14 @@ picker.mouseClickLeft = (() => picker.spawnRGBAEditorDialog(picker)); bdy.fixLayout(); this.labelString = title; - this.createLabel(); - if (pic) {this.setPicture(pic); } - - this.addBody(bdy); - - this.addButton('ok', 'OK'); - - this.addButton('cancel', 'Cancel'); - this.fixLayout(); - - this.edit = function () {field.edit();}; + this.createLabel(); if ( + pic) {this.setPicture(pic + );}; this.addBody(bdy); + this.addButton('ok', 'OK' + ); this.addButton('cancel', + 'Cancel'); this.fixLayout(); + this.edit = function ( + ) {field.edit();}; this.getInput = function () { return { @@ -2093,363 +2020,8 @@ picker.mouseClickLeft = (() => picker.spawnRGBAEditorDialog(picker)); }; }; - if (!this.key) {this.key = 'category' + title;}; - - this.popUp(world); -}; - -DialogBoxMorph.prototype.promptCredentials = function ( - title, - purpose, - tosURL, - tosLabel, - prvURL, - prvLabel, - checkBoxLabel, - world, - pic, - msg -) { - var usr = new InputFieldMorph, - bmn, - byr, - emlLabel, - eml = new InputFieldMorph, - pw1 = new InputFieldMorph, - pw2 = new InputFieldMorph, - opw = new InputFieldMorph, - agree = false, - chk, - dof = new AlignmentMorph('row', 4), - mCol = new AlignmentMorph('column', 2), - yCol = new AlignmentMorph('column', 2), - inp = new AlignmentMorph('column', 2), - lnk = new AlignmentMorph('row', 4), - bdy = new AlignmentMorph('column', this.padding), - years = {}, - currentYear = new Date().getFullYear(), - firstYear = currentYear - 20, - myself = this; - - function labelText(string) { - return new TextMorph( - localize(string), - 10, - null, // style - false, // bold - null, // italic - null, // alignment - null, // width - null, // font name - MorphicPreferences.isFlat ? null : new Point(1, 1), - WHITE // shadowColor - ); - } - - function linkButton(label, url) { - var btn = new PushButtonMorph( - myself, - () => window.open(url), - ' ' + localize(label) + ' ' - ); - btn.fontSize = 10; - btn.corner = myself.buttonCorner; - btn.edge = myself.buttonEdge; - btn.outline = myself.buttonOutline; - btn.outlineColor = myself.buttonOutlineColor; - btn.outlineGradient = myself.buttonOutlineGradient; - btn.padding = myself.buttonPadding; - btn.contrast = myself.buttonContrast; - btn.fixLayout(); - return btn; - } - - function age() { - var today = new Date().getFullYear() + new Date().getMonth() / 12, - year = +byr.getValue() || 0, - monthName = bmn.getValue(), - month, - birthday; - if (monthName instanceof Array) { // translatable - monthName = monthName[0]; - } - if (isNaN(year)) { - year = 0; - } - month = [ - 'January', - 'February', - 'March', - 'April', - 'May', - 'June', - 'July', - 'August', - 'September', - 'October', - 'November', - 'December' - ].indexOf(monthName); - if (isNaN(month)) { - month = 0; - } - birthday = year + month / 12; - return today - birthday; - } - - bmn = new InputFieldMorph( - null, // text - false, // numeric? - { - 'January' : ['January'], - 'February' : ['February'], - 'March' : ['March'], - 'April' : ['April'], - 'May' : ['May'], - 'June' : ['June'], - 'July' : ['July'], - 'August' : ['August'], - 'September' : ['September'], - 'October' : ['October'], - 'November' : ['November'], - 'December' : ['December'] - }, - true // read-only - ); - for (currentYear; currentYear > firstYear; currentYear -= 1) { - years[currentYear.toString() + ' '] = currentYear; - } - years[firstYear + ' ' + localize('or before')] = '< ' + currentYear; - byr = new InputFieldMorph( - null, // text - false, // numeric? - years, - true // read-only - ); - - inp.alignment = 'left'; - inp.setColor(this.color); - bdy.setColor(this.color); - - mCol.alignment = 'left'; - mCol.setColor(this.color); - yCol.alignment = 'left'; - yCol.setColor(this.color); - - usr.setWidth(200); - bmn.setWidth(100); - byr.contents().minWidth = 80; - byr.setWidth(80); - eml.setWidth(200); - pw1.setWidth(200); - pw2.setWidth(200); - opw.setWidth(200); - pw1.contents().text.toggleIsPassword(); - pw2.contents().text.toggleIsPassword(); - opw.contents().text.toggleIsPassword(); - - if (purpose === 'login') { - inp.add(labelText('User name:')); - inp.add(usr); - } - - if (purpose === 'signup') { - inp.add(labelText('User name:')); - inp.add(usr); - mCol.add(labelText('Birth date:')); - mCol.add(bmn); - yCol.add(labelText('year:')); - yCol.add(byr); - dof.add(mCol); - dof.add(yCol); - inp.add(dof); - emlLabel = labelText('foo'); - inp.add(emlLabel); - inp.add(eml); - inp.add(labelText('Password:')); - inp.add(pw1); - inp.add(labelText('Repeat Password:')); - inp.add(pw2); - } - - if (purpose === 'login') { - inp.add(labelText('Password:')); - inp.add(pw1); - } - - if (purpose === 'changePassword') { - inp.add(labelText('Old password:')); - inp.add(opw); - inp.add(labelText('New password:')); - inp.add(pw1); - inp.add(labelText('Repeat new password:')); - inp.add(pw2); - } - - if (purpose === 'resetPassword' || purpose === 'resendVerification') { - inp.add(labelText('User name:')); - inp.add(usr); - } - - if (msg) { - bdy.add(labelText(msg)); - } - - bdy.add(inp); - - if (tosURL || prvURL) { - bdy.add(lnk); - } - if (tosURL) { - lnk.add(linkButton(tosLabel, tosURL)); - } - if (prvURL) { - lnk.add(linkButton(prvLabel, prvURL)); - } - - if (checkBoxLabel) { - chk = new ToggleMorph( - 'checkbox', - this, - () => agree = !agree, // action, - checkBoxLabel, - () => agree //query - ); - chk.edge = this.buttonEdge / 2; - chk.outline = this.buttonOutline / 2; - chk.outlineColor = this.buttonOutlineColor; - chk.outlineGradient = this.buttonOutlineGradient; - chk.contrast = this.buttonContrast; - chk.fixLayout(); - bdy.add(chk); - } - - dof.fixLayout(); - mCol.fixLayout(); - yCol.fixLayout(); - inp.fixLayout(); - lnk.fixLayout(); - bdy.fixLayout(); - - this.labelString = title; - this.createLabel(); - if (pic) {this.setPicture(pic); } - - this.addBody(bdy); - - this.addButton('ok', 'OK'); - this.addButton('cancel', 'Cancel'); - this.fixLayout(); - - function validInputs() { - var checklist, - empty, - em = eml.getValue(); - - function indicate(morph, string) { - var bubble = new SpeechBubbleMorph(localize(string)); - bubble.isPointingRight = false; - bubble.fixLayout(); - bubble.popUp( - world, - morph.leftCenter().subtract(new Point(bubble.width() + 2, 0)) - ); - if (morph.edit) { - morph.edit(); - } - } - - if (purpose === 'login') { - checklist = [usr, pw1]; - } else if (purpose === 'signup') { - checklist = [usr, bmn, byr, eml, pw1, pw2]; - } else if (purpose === 'changePassword') { - checklist = [opw, pw1, pw2]; - } else if (purpose === 'resetPassword' || - purpose === 'resendVerification') { - checklist = [usr]; - } - - empty = detect( - checklist, - inp => !inp.getValue() - ); - if (empty) { - indicate(empty, 'please fill out\nthis field'); - return false; - } - if (purpose === 'signup') { - if (usr.getValue().length < 4) { - indicate(usr, 'User name must be four\ncharacters or longer'); - return false; - } - if (em.indexOf(' ') > -1 || em.indexOf('@') === -1 - || em.indexOf('.') === -1 || em.length < 5) { - indicate(eml, 'please provide a valid\nemail address'); - return false; - } - } - if (purpose === 'changePassword' || purpose === 'signup') { - if (pw1.getValue().length < 6) { - indicate(pw1, 'password must be six\ncharacters or longer'); - return false; - } - if (pw1.getValue() !== pw2.getValue()) { - indicate(pw2, 'passwords do\nnot match'); - return false; - } - } - if (purpose === 'signup') { - if (!agree) { - indicate(chk, 'please agree to\nthe TOS'); - return false; - } - } - return true; - } - - this.accept = function () { - if (validInputs()) { - DialogBoxMorph.prototype.accept.call(myself); - } - }; - - this.edit = function () { - if (purpose === 'changePassword') { - opw.edit(); - } else { // 'signup', 'login', 'resetPassword', 'resendVerification' - usr.edit(); - } - }; - - this.getInput = function () { - return { - username: usr.getValue(), - email: eml.getValue(), - oldpassword: opw.getValue(), - password: pw1.getValue(), - passwordRepeat: pw2.getValue(), - choice: agree - }; - }; - - this.reactToChoice = function () { - if (purpose === 'signup') { - emlLabel.changed(); - emlLabel.text = age() <= 13 ? - 'E-mail address of parent or guardian:' - : 'E-mail address:'; - emlLabel.text = localize(emlLabel.text); - emlLabel.fixLayout(); - emlLabel.rerender(); - } - }; - - this.reactToChoice(); // initialize e-mail label - - if (!this.key) { - this.key = 'credentials' + title + purpose; - } + if (!this.key) {this.key = ( + 'category').concat(title);}; this.popUp(world); }; @@ -2476,52 +2048,37 @@ DialogBoxMorph.prototype.accept = function () { if (this.action) { if (typeof this.target === 'function') { if (typeof this.action === 'function') { - this.target.call(this.environment, this.action.call()); - } else { - this.target.call(this.environment, this.action); - } + this.target.call(this.environment, + this.action.call());} else { + this.target.call(this.environment, + this.action);}; } else { if (typeof this.action === 'function') { this.action.call(this.target, this.getInput()); } else { // assume it's a String this.target[this.action](this.getInput()); - } - } - } - this.destroy(); + }; + }; + }; this.destroy(); }; -DialogBoxMorph.prototype.withKey = function (key) { - this.key = key; - return this; -}; +DialogBoxMorph.prototype.withKey = function ( +key) {this.key = key; return this;}; -DialogBoxMorph.prototype.popUp = function (world) { - if (world) { - if (this.key) { - if (this.instances[world.stamp]) { - if (this.instances[world.stamp][this.key]) { - this.instances[world.stamp][this.key].destroy(); - } - this.instances[world.stamp][this.key] = this; - } else { - this.instances[world.stamp] = {}; - this.instances[world.stamp][this.key] = this; - } - } - world.add(this); - world.keyboardFocus = this; - this.setCenter(world.center()); - this.edit(); - } -}; +DialogBoxMorph.prototype.popUp = function ( +world) {if (world) {if (this.key) {if ((this +).instances[0]) {if ((this.instances[0])[( +this).key]) {(this.instances[0])[this.key +].destroy();}; (this.instances[0])[(this +).key] = this;} else {this.instances[ +0] = {}; (this.instances[0])[this.key +] = this;};}; world.add(this); (world +).keyboardFocus = this; this.setCenter( +world.center()); this.edit();};}; -DialogBoxMorph.prototype.destroy = function () { - DialogBoxMorph.uber.destroy.call(this); - if (this.key) { - delete this.instances[this.key]; - } -}; +DialogBoxMorph.prototype.destroy = function ( +) {DialogBoxMorph.uber.destroy.call(this); +if (this.key) {(this.instances).pop();};}; DialogBoxMorph.prototype.ok = function () { this.accept(); @@ -2535,15 +2092,14 @@ DialogBoxMorph.prototype.edit = function () { this.children.forEach(c => { if (c.edit) { c.edit(); - } + }; }); }; DialogBoxMorph.prototype.getInput = function () { if (this.body instanceof InputFieldMorph) { return this.body.getValue(); - } - return null; + }; return null; }; DialogBoxMorph.prototype.justDropped = function (hand) { @@ -2552,7 +2108,6 @@ DialogBoxMorph.prototype.justDropped = function (hand) { }; DialogBoxMorph.prototype.destroy = function () { - var world = this.world(); world.keyboardFocus = null; world.hand.destroyTemporaries(); DialogBoxMorph.uber.destroy.call(this); @@ -2567,13 +2122,12 @@ DialogBoxMorph.prototype.normalizeSpaces = function (string) { if (flag) { ans += c; flag = false; - } + }; } else { ans += c; flag = true; - } - } - return ans.trim(); + }; + }; return ans.trim(); }; // DialogBoxMorph submorph construction @@ -2583,39 +2137,32 @@ DialogBoxMorph.prototype.createLabel = function () { if (this.label) { this.label.destroy(); - } - if (this.labelString) { + }; if (this.labelString) { this.label = new StringMorph( - localize(this.labelString), - this.titleFontSize, - this.fontStyle, - true, - false, - false, + localize(this.labelString + ), this.titleFontSize, + this.fontStyle, true, + false, false, shading ? new Point(2, 1) : null, this.titleBarColor.darker(this.contrast) - ); - this.label.color = this.titleTextColor; + ); this.label.color = this.titleTextColor; this.label.fixLayout(); this.add(this.label); - } + }; }; -DialogBoxMorph.prototype.createButtons = function () { - if (this.buttons) { +DialogBoxMorph.prototype.createButtons = ( + function () {if (this.buttons) { this.buttons.destroy(); - } - this.buttons = new AlignmentMorph('row', this.padding); - this.add(this.buttons); -}; + }; this.buttons = new AlignmentMorph('row', + this.padding); this.add(this.buttons); +}); DialogBoxMorph.prototype.addButton = function (action, label) { - var button = new PushButtonMorph( - this, - action || 'ok', - ((label instanceof SymbolMorph) ? label : - ' ' + localize((label || 'OK')) + ' ') - ); button.fontSize = this.buttonFontSize; + var button = new PushButtonMorph(this, (action || 'ok' + ), ((label instanceof SymbolMorph) ? label : ( + ' ' + localize((label || 'OK')) + ' ')) + ); button.fontSize = this.buttonFontSize; button.corner = this.buttonCorner; button.edge = this.buttonEdge; button.outline = this.buttonOutline; @@ -3237,7 +2784,7 @@ InputFieldMorph.prototype.dropDownMenu = function () { } } if (menu.items.length > 0) { - menu.popUpAtHand(this.world()); + menu.popUpAtHand(world); } else { return null; } diff --git a/src/xml.js b/src/xml.js index 761d65a..a2f85cc 100644 --- a/src/xml.js +++ b/src/xml.js @@ -63,18 +63,9 @@ */ -/*global modules, detect, Node, isNil*/ - -/*jshint esversion: 6*/ - -// Global stuff //////////////////////////////////////////////////////// - -modules.xml = '2021-July-05'; - // Declarations -var ReadStream; -var XML_Element; +var ReadStream, XML_Element; // ReadStream //////////////////////////////////////////////////////////// @@ -83,9 +74,8 @@ var XML_Element; // ReadStream instance creation: function ReadStream(arrayOrString) { - this.contents = arrayOrString || ''; - this.index = 0; -} +this.contents = arrayOrString || ''; +this.index = 0;}; // ReadStream constants: @@ -100,8 +90,7 @@ ReadStream.prototype.next = function (count) { element = this.contents[this.index]; this.index += 1; return element; - } - start = this.index; + }; start = this.index; this.index += count; return this.contents.slice(start, this.index); }; @@ -163,7 +152,7 @@ XML_Element.prototype.indentation = ' '; function XML_Element(tag, contents, parent) { this.init(tag, contents, parent); -} +}; XML_Element.prototype.init = function (tag, contents, parent) { // additional properties: @@ -191,10 +180,8 @@ XML_Element.prototype.require = function (tagName, fallback) { } if (!isNil(fallback)) { return fallback; - } - throw new Error('Missing required element <' + tagName + '>!'); - } - return child; + }; throw new Error('Missing required element <' + tagName + '>!'); + }; return child; }; XML_Element.prototype.childNamed = function (tagName) { @@ -214,11 +201,9 @@ XML_Element.prototype.parentNamed = function (tagName) { // including myself if (this.tag === tagName) { return this; - } - if (!this.parent) { + }; if (!this.parent) { return null; - } - return this.parent.parentNamed(tagName); + }; return this.parent.parentNamed(tagName); }; // XML_Element output: @@ -234,9 +219,8 @@ XML_Element.prototype.toString = function (isFormatted, indentationLevel) { if (isFormatted) { for (i = 0; i < level; i += 1) { indent += this.indentation; - } - result += indent; - } + }; result += indent; + }; // opening tag result += ('<' + this.tag); @@ -246,8 +230,8 @@ XML_Element.prototype.toString = function (isFormatted, indentationLevel) { if (Object.prototype.hasOwnProperty.call(this.attributes, key) && this.attributes[key]) { result += ' ' + key + '="' + this.escape(this.attributes[key]) + '"'; - } - } + }; + }; // contents, subnodes, and closing tag if (!this.contents.length && !this.children.length) { @@ -258,22 +242,16 @@ XML_Element.prototype.toString = function (isFormatted, indentationLevel) { this.children.forEach(element => { if (isFormatted) { result += '\n'; - } - result += element.toString(isFormatted, level + 1); - }); - if (isFormatted && this.children.length) { + }; result += element.toString(isFormatted, level + 1); + }); if (isFormatted && this.children.length) { result += ('\n' + indent); - } - result += ''; - } - return result; + }; result += ''; + }; return result; }; XML_Element.prototype.escape = function (string, ignoreQuotes) { var src = isNil(string) ? '' : string.toString(), - result = '', - i, - ch; + result = '', i, ch; for (i = 0; i < src.length; i += 1) { ch = src[i]; switch (ch) { @@ -300,9 +278,8 @@ XML_Element.prototype.escape = function (string, ignoreQuotes) { break; default: result += ch; - } - } - return result; + }; + }; return result; }; XML_Element.prototype.unescape = function (string) { @@ -343,30 +320,26 @@ XML_Element.prototype.parseStream = function (stream) { stream.skipSpace(); if (stream.next() !== '=') { throw new Error('Expected "=" after attribute name'); - } - stream.skipSpace(); + }; stream.skipSpace(); ch = stream.next(); if (ch !== '"' && ch !== "'") { throw new Error('Expected single- or double-quoted attribute value'); - } - value = stream.upTo(ch); + }; value = stream.upTo(ch); stream.skip(1); stream.skipSpace(); this.attributes[key] = this.unescape(value); ch = stream.peek(); - } + }; // empty tag: if (ch === '/') { stream.skip(); if (stream.next() !== '>') { throw new Error('Expected ">" after "/" in empty tag'); - } - return; - } - if (stream.next() !== '>') { + }; return; + }; if (stream.next() !== '>') { throw new Error('Expected ">" after tag name and attributes'); - } + }; // contents and children while (!stream.atEnd()) { @@ -376,16 +349,276 @@ XML_Element.prototype.parseStream = function (stream) { stream.skip(); if (stream.word() !== this.tag) { throw new Error('Expected to close ' + this.tag); - } - stream.upTo('>'); + }; stream.upTo('>'); stream.skip(); this.contents = this.unescape(this.contents); return; - } - child = new XML_Element(null, null, this); + }; child = new XML_Element(null, null, this); child.parseStream(stream); } else { this.contents += ch; + }; + }; +}; + +/* + * DOMParser JS extension + * 2012-09-04 + * + * By Eli Grey, https://eligrey.com + * Public domain. + * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + */ + +/*! @source https://gist.github.com/1129031 */ +/*global document, DOMParser*/ + +(function(DOMParser) { + "use strict"; + + var proto = DOMParser.prototype, + nativeParse = proto.parseFromString; + + // Firefox/Opera/IE throw errors on unsupported types + try { + // WebKit returns null on unsupported types + if ((new DOMParser).parseFromString("", "text/html")) { + // text/html parsing is natively supported + return; + }; + } catch (ex) {console.error(ex);}; + +proto.parseFromString = function(markup, type) { + if (/^\s*text\/html\s*(?:;|$)/i.test(type)) { + var doc = document.implementation.createHTMLDocument(""); + if (markup.toLowerCase().indexOf(' -1) { + doc.documentElement.innerHTML = markup; + } else { + doc.body.innerHTML = markup; + }; + return doc; + } else { + return nativeParse.apply(this, arguments); + }; + }; +}(DOMParser)); + +/** +* Object assign is required, so ensure that browsers know how to execute this method +* +* @method Object.assign +* @returns {Function} +*/ +if (typeof Object.assign != 'function') { + // Must be writable: true, enumerable: false, configurable: true + Object.defineProperty(Object, "assign", { + value: function assign(target, varArgs) { // .length of function is 2 + 'use strict'; + if (target == null) { // TypeError if undefined or null + throw new TypeError('Cannot convert undefined or null to object'); + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } } - } + } + return to; + }, + writable: true, + configurable: true + }); }; + +/** +* Object to convert XML into a structured JSON object +* +* @method xmlToJson +* @returns [object Object] +*/ +var xmlToJson = (function () { + var self = this; + + /** + * Adds an object value to a parent object + * + * @method addToParent + * @param {Object} parent + * @param {String} nodeName + * @param {Mixed} obj + * @returns none + */ + self.addToParent = function (parent, nodeName, obj) { + // If this is the first or only instance of the node name, assign it as + // an object on the parent. + if (!parent[nodeName]) { + parent[nodeName] = obj; + } + // Else the parent knows about other nodes of the same name + else { + // If the parent has a property with the node name, but it is not an array, + // store the contents of that property, convert the property to an array, and + // assign what was formerly an object on the parent to the first member of the + // array + if (!Array.isArray(parent[nodeName])) { + var tmp = parent[nodeName]; + parent[nodeName] = []; + parent[nodeName].push(tmp); + } + + // Push the current object to the collection + parent[nodeName].push(obj); + } + }; + + self.convertXMLStringToDoc = function (str) { + var xmlDoc = null; + + if (str && typeof str === 'string') { + // Create a DOMParser + var parser = new DOMParser; + + // Use it to turn your xmlString into an XMLDocument + xmlDoc = parser.parseFromString(str, 'application/xml'); + } + + return xmlDoc; + } + + /** + * Validates if an data is an XMLDocument + * + * @method isXML + * @param {Mixed} data + * @returns {Boolean} + */ + self.isXML = function (data) { + var documentElement = (data ? data.ownerDocument || data : 0).documentElement; + + return documentElement ? documentElement.nodeName.toLowerCase() !== 'html' : false; + }; + + /** + * Reads through a node's attributes and assigns the values to a new object + * + * @method parseAttributes + * @param {XMLNode} node + * @returns {Object} + */ + self.parseAttributes = function (node) { + var attributes = node.attributes, + obj = {}; + + // If the node has attributes, assign the new object properties + // corresponding to each attribute + if (node.hasAttributes()) { + for (var i = 0; i < attributes.length; i++) { + obj[attributes[i].name] = self.parseValue(attributes[i].value); + } + } + + // return the new object + return obj; + }; + + /** + * Rips through child nodes and parses them + * + * @method parseChildren + * @param {Object} parent + * @param {XMLNodeMap} childNodes + * @returns none + */ + self.parseChildren = function (parent, childNodes) { + // If there are child nodes... + if (childNodes.length > 0) { + // Loop over all the child nodes + for (var i = 0; i < childNodes.length; i++) { + // If the child node is a XMLNode, parse the node + if (childNodes[i].nodeType == 1) { + self.parseNode(parent, childNodes[i]); + } + } + } + }; + + /** + * Converts a node into an object with properties + * + * @method parseNode + * @param {Object} parent + * @param {XMLNode} node + * @returns {Object} + */ + self.parseNode = function (parent, node) { + var nodeName = node.nodeName, + obj = Object.assign({}, self.parseAttributes(node)), + tmp = null; + + // If there is only one text child node, there is no need to process the children + if (node.childNodes.length == 1 && node.childNodes[0].nodeType == 3) { + // If the node has attributes, then the object will already have properties. + // Add a new property 'text' with the value of the text content + if (node.hasAttributes()) { + obj['text'] = self.parseValue(node.childNodes[0].nodeValue); + } + // If there are no attributes, then the parent[nodeName] property value is + // simply the interpreted textual content + else { + obj = self.parseValue(node.childNodes[0].nodeValue); + } + } + // Otherwise, there are child XMLNode elements, so process them + else { + self.parseChildren(obj, node.childNodes); + } + + // Once the object has been processed, add it to the parent + self.addToParent(parent, nodeName, obj) + + // Return the parent + return parent; + }; + + /** + * Interprets a value and converts it to Boolean, Number or String based on content + * + * @method parseValue + * @param {Mixed} val + * @returns {Mixed} + */ + this.parseValue = function (val) { + // Create a numeric value from the passed parameter + var num = ((contains(['', '\n', null], val)) ? 0 : asANum(val.trim())); + + // If the value is 'true' or 'false', parse it as a Boolean and return it + if (contains(['true', 'false'], val.toLowerCase())) { + return (val.toLowerCase() === 'true'); + }; + + // If the num parsed to a Number, return the numeric value + // Else if the valuse passed has no length (an attribute without value) return null, + // Else return the param as is + return ((isNaN(num)) ? val.trim() : ((val.trim() === '') ? {} : ( + Process.prototype.reportIsA(val, ['number']) ? num : val.trim()))); + }; + + // Expose the API + return { + parse: function (xml) { + if (xml && typeof xml === 'string') { + xml = self.convertXMLStringToDoc(xml); + } + return (xml && self.isXML(xml)) ? self.parseNode({}, xml.firstChild) : null; + } + } +})(); \ No newline at end of file diff --git a/src/xmlToJson.js b/src/xmlToJson.js deleted file mode 100644 index 6c2b4c6..0000000 --- a/src/xmlToJson.js +++ /dev/null @@ -1,274 +0,0 @@ -modules.xmlToJson = '2023-Febraury-11'; - -/* - * DOMParser HTML extension - * 2012-09-04 - * - * By Eli Grey, https://eligrey.com - * Public domain. - * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. - */ - -/*! @source https://gist.github.com/1129031 */ -/*global document, DOMParser*/ - -(function(DOMParser) { - "use strict"; - - var proto = DOMParser.prototype, - nativeParse = proto.parseFromString; - - // Firefox/Opera/IE throw errors on unsupported types - try { - // WebKit returns null on unsupported types - if ((new DOMParser).parseFromString("", "text/html")) { - // text/html parsing is natively supported - return; - }; - } catch (ex) {}; - -proto.parseFromString = function(markup, type) { - if (/^\s*text\/html\s*(?:;|$)/i.test(type)) { - var doc = document.implementation.createHTMLDocument(""); - if (markup.toLowerCase().indexOf(' -1) { - doc.documentElement.innerHTML = markup; - } - else { - doc.body.innerHTML = markup; - } - return doc; - } else { - return nativeParse.apply(this, arguments); - } - }; -}(DOMParser)); - -/** -* Object assign is required, so ensure that browsers know how to execute this method -* -* @method Object.assign -* @returns {Function} -*/ -if (typeof Object.assign != 'function') { - // Must be writable: true, enumerable: false, configurable: true - Object.defineProperty(Object, "assign", { - value: function assign(target, varArgs) { // .length of function is 2 - 'use strict'; - if (target == null) { // TypeError if undefined or null - throw new TypeError('Cannot convert undefined or null to object'); - } - - var to = Object(target); - - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; - - if (nextSource != null) { // Skip over if undefined or null - for (var nextKey in nextSource) { - // Avoid bugs when hasOwnProperty is shadowed - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to; - }, - writable: true, - configurable: true - }); -} - - -/** -* Object to convert XML into a structured JSON object -* -* @method xmlToJson -* @returns [object Object] -*/ -var xmlToJson = (function () { - var self = this; - - - /** - * Adds an object value to a parent object - * - * @method addToParent - * @param {Object} parent - * @param {String} nodeName - * @param {Mixed} obj - * @returns none - */ - self.addToParent = function (parent, nodeName, obj) { - // If this is the first or only instance of the node name, assign it as - // an object on the parent. - if (!parent[nodeName]) { - parent[nodeName] = obj; - } - // Else the parent knows about other nodes of the same name - else { - // If the parent has a property with the node name, but it is not an array, - // store the contents of that property, convert the property to an array, and - // assign what was formerly an object on the parent to the first member of the - // array - if (!Array.isArray(parent[nodeName])) { - var tmp = parent[nodeName]; - parent[nodeName] = []; - parent[nodeName].push(tmp); - } - - // Push the current object to the collection - parent[nodeName].push(obj); - } - }; - - - - - self.convertXMLStringToDoc = function (str) { - var xmlDoc = null; - - if (str && typeof str === 'string') { - // Create a DOMParser - var parser = new DOMParser; - - // Use it to turn your xmlString into an XMLDocument - xmlDoc = parser.parseFromString(str, 'application/xml'); - } - - return xmlDoc; - } - - - /** - * Validates if an data is an XMLDocument - * - * @method isXML - * @param {Mixed} data - * @returns {Boolean} - */ - self.isXML = function (data) { - var documentElement = (data ? data.ownerDocument || data : 0).documentElement; - - return documentElement ? documentElement.nodeName.toLowerCase() !== 'html' : false; - }; - - - /** - * Reads through a node's attributes and assigns the values to a new object - * - * @method parseAttributes - * @param {XMLNode} node - * @returns {Object} - */ - self.parseAttributes = function (node) { - var attributes = node.attributes, - obj = {}; - - // If the node has attributes, assign the new object properties - // corresponding to each attribute - if (node.hasAttributes()) { - for (var i = 0; i < attributes.length; i++) { - obj[attributes[i].name] = self.parseValue(attributes[i].value); - } - } - - // return the new object - return obj; - }; - - - /** - * Rips through child nodes and parses them - * - * @method parseChildren - * @param {Object} parent - * @param {XMLNodeMap} childNodes - * @returns none - */ - self.parseChildren = function (parent, childNodes) { - // If there are child nodes... - if (childNodes.length > 0) { - // Loop over all the child nodes - for (var i = 0; i < childNodes.length; i++) { - // If the child node is a XMLNode, parse the node - if (childNodes[i].nodeType == 1) { - self.parseNode(parent, childNodes[i]); - } - } - } - }; - - - /** - * Converts a node into an object with properties - * - * @method parseNode - * @param {Object} parent - * @param {XMLNode} node - * @returns {Object} - */ - self.parseNode = function (parent, node) { - var nodeName = node.nodeName, - obj = Object.assign({}, self.parseAttributes(node)), - tmp = null; - - // If there is only one text child node, there is no need to process the children - if (node.childNodes.length == 1 && node.childNodes[0].nodeType == 3) { - // If the node has attributes, then the object will already have properties. - // Add a new property 'text' with the value of the text content - if (node.hasAttributes()) { - obj['text'] = self.parseValue(node.childNodes[0].nodeValue); - } - // If there are no attributes, then the parent[nodeName] property value is - // simply the interpreted textual content - else { - obj = self.parseValue(node.childNodes[0].nodeValue); - } - } - // Otherwise, there are child XMLNode elements, so process them - else { - self.parseChildren(obj, node.childNodes); - } - - // Once the object has been processed, add it to the parent - self.addToParent(parent, nodeName, obj) - - // Return the parent - return parent; - }; - - - /** - * Interprets a value and converts it to Boolean, Number or String based on content - * - * @method parseValue - * @param {Mixed} val - * @returns {Mixed} - */ - this.parseValue = function (val) { - // Create a numeric value from the passed parameter - var num = ((contains(['', '\n', null], val)) ? 0 : asANum(val.trim())); - - // If the value is 'true' or 'false', parse it as a Boolean and return it - if (contains(['true', 'false'], val.toLowerCase())) { - return (val.toLowerCase() === 'true'); - }; - - // If the num parsed to a Number, return the numeric value - // Else if the valuse passed has no length (an attribute without value) return null, - // Else return the param as is - return ((isNaN(num)) ? val.trim() : ((val.trim() === '') ? {} : ( - Process.prototype.reportIsA(val, ['number']) ? num : val.trim()))); - }; - - // Expose the API - return { - parse: function (xml) { - if (xml && typeof xml === 'string') { - xml = self.convertXMLStringToDoc(xml); - } - return (xml && self.isXML(xml)) ? self.parseNode({}, xml.firstChild) : null; - } - } -})(); \ No newline at end of file