From 98d78fbce8b196a279e5a9e88944305e96bf95db Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford <cwillisf@media.mit.edu> Date: Tue, 29 Aug 2017 15:46:26 -0700 Subject: [PATCH] Convert example extension to ES5 --- src/examples/extensions/.eslintrc.js | 1 + src/examples/extensions/example-extension.js | 429 ++++++++++--------- 2 files changed, 216 insertions(+), 214 deletions(-) diff --git a/src/examples/extensions/.eslintrc.js b/src/examples/extensions/.eslintrc.js index f84dadeb6..15e7ebc28 100644 --- a/src/examples/extensions/.eslintrc.js +++ b/src/examples/extensions/.eslintrc.js @@ -1,4 +1,5 @@ module.exports = { + extends: ['scratch'], // no ES6 env: { worker: true }, diff --git a/src/examples/extensions/example-extension.js b/src/examples/extensions/example-extension.js index e9aeba53f..804faccaa 100644 --- a/src/examples/extensions/example-extension.js +++ b/src/examples/extensions/example-extension.js @@ -1,229 +1,230 @@ -class ExampleExtension { - /** - * @return {object} This extension's metadata. - */ - getInfo () { - return { - // Required: the machine-readable name of this extension. - // Will be used as the extension's namespace. Must not contain a '.' character. - id: 'someBlocks', - - // Optional: the human-readable name of this extension as string. - // This and any other string to be displayed in the Scratch UI may either be - // a string or a call to `intlDefineMessage`; a plain string will not be - // translated whereas a call to `intlDefineMessage` will connect the string - // to the translation map (see below). The `intlDefineMessage` call is - // similar to `defineMessages` from `react-intl` in form, but will actually - // call some extension support code to do its magic. For example, we will - // internally namespace the messages such that two extensions could have - // messages with the same ID without colliding. - // See also: https://github.com/yahoo/react-intl/wiki/API#definemessages - name: 'Some Blocks', - - // Optional: URI for an icon for this extension. Data URI OK. - // If not present, use a generic icon. - // TODO: what file types are OK? All web images? Just PNG? - iconURI: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAFCAAAAACyOJm3AAAAFklEQVQYV2P4DwMMEMgAI/+DE' + - 'UIMBgAEWB7i7uidhAAAAABJRU5ErkJggg==', - - // Optional: Link to documentation content for this extension. - // If not present, offer no link. - docsURI: 'https://....', - - // Required: the list of blocks implemented by this extension, - // in the order intended for display. - blocks: [ - { - opcode: 'example-noop', - blockType: Scratch.BlockType.COMMAND, - blockAllThreads: false, - text: 'do nothing', - func: 'noop' - }, - { - opcode: 'example-conditional', - blockType: Scratch.BlockType.CONDITIONAL, - branchCount: 4, - isTerminal: true, - blockAllThreads: false, - text: 'choose [BRANCH]', - arguments: { - BRANCH: { - type: Scratch.ArgumentType.NUMBER, - defaultValue: 1 - } - }, - func: 'noop' +var ExampleExtension = function () { +}; + +/** + * @return {object} This extension's metadata. + */ +ExampleExtension.prototype.getInfo = function () { + return { + // Required: the machine-readable name of this extension. + // Will be used as the extension's namespace. Must not contain a '.' character. + id: 'someBlocks', + + // Optional: the human-readable name of this extension as string. + // This and any other string to be displayed in the Scratch UI may either be + // a string or a call to `intlDefineMessage`; a plain string will not be + // translated whereas a call to `intlDefineMessage` will connect the string + // to the translation map (see below). The `intlDefineMessage` call is + // similar to `defineMessages` from `react-intl` in form, but will actually + // call some extension support code to do its magic. For example, we will + // internally namespace the messages such that two extensions could have + // messages with the same ID without colliding. + // See also: https://github.com/yahoo/react-intl/wiki/API#definemessages + name: 'Some Blocks', + + // Optional: URI for an icon for this extension. Data URI OK. + // If not present, use a generic icon. + // TODO: what file types are OK? All web images? Just PNG? + iconURI: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAFCAAAAACyOJm3AAAAFklEQVQYV2P4DwMMEMgAI/+DE' + + 'UIMBgAEWB7i7uidhAAAAABJRU5ErkJggg==', + + // Optional: Link to documentation content for this extension. + // If not present, offer no link. + docsURI: 'https://....', + + // Required: the list of blocks implemented by this extension, + // in the order intended for display. + blocks: [ + { + opcode: 'example-noop', + blockType: Scratch.BlockType.COMMAND, + blockAllThreads: false, + text: 'do nothing', + func: 'noop' + }, + { + opcode: 'example-conditional', + blockType: Scratch.BlockType.CONDITIONAL, + branchCount: 4, + isTerminal: true, + blockAllThreads: false, + text: 'choose [BRANCH]', + arguments: { + BRANCH: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: 1 + } }, - { - // Required: the machine-readable name of this operation. - // This will appear in project JSON. Must not contain a '.' character. - opcode: 'myReporter', // becomes 'someBlocks.myReporter' - - // Required: the kind of block we're defining, from a predefined list: - // 'command' - a normal command block, like "move {} steps" - // 'reporter' - returns a value, like "direction" - // 'Boolean' - same as 'reporter' but returns a Boolean value - // 'hat' - starts a stack if its value is truthy - // 'conditional' - control flow, like "if {}" or "repeat {}" - // A 'conditional' block may return the one-based index of a branch - // to run, or it may return zero/falsy to run no branch. Each time a - // child branch finishes, the block is called again. This is only a - // slight change to the current model for control flow blocks, and is - // also compatible with returning true/false for an "if" or "repeat" - // block. - // TODO: Consider Blockly-like nextStatement, previousStatement, and - // output attributes as an alternative. Those are more flexible, but - // allow bad combinations. - blockType: Scratch.BlockType.REPORTER, - - // Required for conditional blocks, ignored for others: the number of - // child branches this block controls. An "if" or "repeat" block would - // specify a branch count of 1; an "if-else" block would specify a - // branch count of 2. - // TODO: should we support dynamic branch count for "switch"-likes? - branchCount: 0, - - // Optional, default false: whether or not this block ends a stack. - // The "forever" and "stop all" blocks would specify true here. - isTerminal: true, - - // Optional, default false: whether or not to block all threads while - // this block is busy. This is for things like the "touching color" - // block in compatibility mode, and is only needed if the VM runs in a - // worker. We might even consider omitting it from extension docs... - blockAllThreads: false, - - // Required: the human-readable text on this block, including argument - // placeholders. Argument placeholders should be in [MACRO_CASE] and - // must be [ENCLOSED_WITHIN_SQUARE_BRACKETS]. - text: 'letter [LETTER_NUM] of [TEXT]', - - // Required: describe each argument. - // Note that this is an array: the order of arguments will be used - arguments: { - // Required: the ID of the argument, which will be the name in the - // args object passed to the implementation function. - LETTER_NUM: { - // Required: type of the argument / shape of the block input - type: Scratch.ArgumentType.NUMBER, - - // Optional: the default value of the argument - defaultValue: 1 - }, - - // Required: the ID of the argument, which will be the name in the - // args object passed to the implementation function. - TEXT: { - // Required: type of the argument / shape of the block input - type: Scratch.ArgumentType.STRING, - - // Optional: the default value of the argument - defaultValue: 'text' - } + func: 'noop' + }, + { + // Required: the machine-readable name of this operation. + // This will appear in project JSON. Must not contain a '.' character. + opcode: 'myReporter', // becomes 'someBlocks.myReporter' + + // Required: the kind of block we're defining, from a predefined list: + // 'command' - a normal command block, like "move {} steps" + // 'reporter' - returns a value, like "direction" + // 'Boolean' - same as 'reporter' but returns a Boolean value + // 'hat' - starts a stack if its value is truthy + // 'conditional' - control flow, like "if {}" or "repeat {}" + // A 'conditional' block may return the one-based index of a branch + // to run, or it may return zero/falsy to run no branch. Each time a + // child branch finishes, the block is called again. This is only a + // slight change to the current model for control flow blocks, and is + // also compatible with returning true/false for an "if" or "repeat" + // block. + // TODO: Consider Blockly-like nextStatement, previousStatement, and + // output attributes as an alternative. Those are more flexible, but + // allow bad combinations. + blockType: Scratch.BlockType.REPORTER, + + // Required for conditional blocks, ignored for others: the number of + // child branches this block controls. An "if" or "repeat" block would + // specify a branch count of 1; an "if-else" block would specify a + // branch count of 2. + // TODO: should we support dynamic branch count for "switch"-likes? + branchCount: 0, + + // Optional, default false: whether or not this block ends a stack. + // The "forever" and "stop all" blocks would specify true here. + isTerminal: true, + + // Optional, default false: whether or not to block all threads while + // this block is busy. This is for things like the "touching color" + // block in compatibility mode, and is only needed if the VM runs in a + // worker. We might even consider omitting it from extension docs... + blockAllThreads: false, + + // Required: the human-readable text on this block, including argument + // placeholders. Argument placeholders should be in [MACRO_CASE] and + // must be [ENCLOSED_WITHIN_SQUARE_BRACKETS]. + text: 'letter [LETTER_NUM] of [TEXT]', + + // Required: describe each argument. + // Note that this is an array: the order of arguments will be used + arguments: { + // Required: the ID of the argument, which will be the name in the + // args object passed to the implementation function. + LETTER_NUM: { + // Required: type of the argument / shape of the block input + type: Scratch.ArgumentType.NUMBER, + + // Optional: the default value of the argument + defaultValue: 1 }, - // Optional: a string naming the function implementing this block. - // If this is omitted, use the opcode string. - func: 'myReporter', + // Required: the ID of the argument, which will be the name in the + // args object passed to the implementation function. + TEXT: { + // Required: type of the argument / shape of the block input + type: Scratch.ArgumentType.STRING, - // Optional: list of target types for which this block should appear. - // If absent, assume it applies to all builtin targets -- that is: - // ['sprite', 'stage'] - filter: ['someBlocks.wedo2', 'sprite', 'stage'] - }, - { - opcode: 'example-Boolean', - blockType: Scratch.BlockType.BOOLEAN, - text: 'return true', - func: 'returnTrue' - }, - { - opcode: 'example-hat', - blockType: Scratch.BlockType.HAT, - text: 'after forever', - func: 'returnFalse' + // Optional: the default value of the argument + defaultValue: 'text' + } }, + + // Optional: a string naming the function implementing this block. + // If this is omitted, use the opcode string. + func: 'myReporter', + + // Optional: list of target types for which this block should appear. + // If absent, assume it applies to all builtin targets -- that is: + // ['sprite', 'stage'] + filter: ['someBlocks.wedo2', 'sprite', 'stage'] + }, + { + opcode: 'example-Boolean', + blockType: Scratch.BlockType.BOOLEAN, + text: 'return true', + func: 'returnTrue' + }, + { + opcode: 'example-hat', + blockType: Scratch.BlockType.HAT, + text: 'after forever', + func: 'returnFalse' + }, + { + // Another block... + } + ], + + // Optional: define extension-specific menus here. + menus: { + // Required: an identifier for this menu, unique within this extension. + menuA: [ + // Static menu: list items which should appear in the menu. { - // Another block... - } - ], + // Required: the value of the menu item when it is chosen. + value: 'itemId1', - // Optional: define extension-specific menus here. - menus: { - // Required: an identifier for this menu, unique within this extension. - menuA: [ - // Static menu: list items which should appear in the menu. - { - // Required: the value of the menu item when it is chosen. - value: 'itemId1', - - // Optional: the human-readable label for this item. - // Use `value` as the text if this is absent. - text: 'Item One' - }, + // Optional: the human-readable label for this item. + // Use `value` as the text if this is absent. + text: 'Item One' + }, - // The simplest form of a list item is a string which will be used as - // both value and text. - 'itemId2' - ], + // The simplest form of a list item is a string which will be used as + // both value and text. + 'itemId2' + ], - // Dynamic menu: a string naming a function which returns an array as above. - // Called each time the menu is opened. - menuB: 'getItemsForMenuB' - }, + // Dynamic menu: a string naming a function which returns an array as above. + // Called each time the menu is opened. + menuB: 'getItemsForMenuB' + }, - // Optional: translations - translation_map: { - de: { - 'extensionName': 'Einige Blöcke', - 'myReporter': 'Buchstabe [LETTER_NUM] von [TEXT]', - 'myReporter.TEXT_default': 'Text', - 'menuA_item1': 'Artikel eins', + // Optional: translations + translation_map: { + de: { + 'extensionName': 'Einige Blöcke', + 'myReporter': 'Buchstabe [LETTER_NUM] von [TEXT]', + 'myReporter.TEXT_default': 'Text', + 'menuA_item1': 'Artikel eins', - // Dynamic menus can be translated too - 'menuB_example': 'Beispiel', + // Dynamic menus can be translated too + 'menuB_example': 'Beispiel', - // This message contains ICU placeholders (see `myReporter()` below) - 'myReporter.result': 'Buchstabe {LETTER_NUM} von {TEXT} ist {LETTER}.' - }, - it: { - // ... - } + // This message contains ICU placeholders (see `myReporter()` below) + 'myReporter.result': 'Buchstabe {LETTER_NUM} von {TEXT} ist {LETTER}.' }, - - // Optional: list new target type(s) provided by this extension. - targetTypes: [ - 'wedo2', // automatically transformed to 'someBlocks.wedo2' - 'speech' // automatically transformed to 'someBlocks.speech' - ] - }; - } - - /** - * Implement myReporter. - * @param {object} args - the block's arguments. - * @property {number} LETTER_NUM - the string value of the argument. - * @property {string} TEXT - the string value of the argument. - * @returns {string} a string which includes the block argument value. - */ - myReporter (args) { - // Note: this implementation is not Unicode-clean; it's just here as an example. - const result = args.TEXT.charAt(args.LETTER_NUM); - - return ['Letter ', args.LETTER_NUM, ' of ', args.TEXT, ' is ', result, '.'].join(''); - } - - noop () { - } - - returnTrue () { - return true; - } - - returnFalse () { - return false; - } -} + it: { + // ... + } + }, + + // Optional: list new target type(s) provided by this extension. + targetTypes: [ + 'wedo2', // automatically transformed to 'someBlocks.wedo2' + 'speech' // automatically transformed to 'someBlocks.speech' + ] + }; +}; + +/** + * Implement myReporter. + * @param {object} args - the block's arguments. + * @property {number} LETTER_NUM - the string value of the argument. + * @property {string} TEXT - the string value of the argument. + * @returns {string} a string which includes the block argument value. + */ +ExampleExtension.prototype.myReporter = function (args) { + // Note: this implementation is not Unicode-clean; it's just here as an example. + const result = args.TEXT.charAt(args.LETTER_NUM); + + return ['Letter ', args.LETTER_NUM, ' of ', args.TEXT, ' is ', result, '.'].join(''); +}; + +ExampleExtension.prototype.noop = function () { +}; + +ExampleExtension.prototype.returnTrue = function () { + return true; +}; + +ExampleExtension.prototype.returnFalse = function () { + return false; +}; Scratch.extensions.register(new ExampleExtension()); -- GitLab