diff --git a/.prettierignore b/.prettierignore index bf200a37bc..8ab97fd3c9 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,8 @@ -# All examples, codelabs, etc. -examples/* +# Examples, codelabs, etc. +**/acorn_interpreter.js +examples/interpreter-demo/acorn.js +examples/interpreter-demo/diff_match_patch.js +examples/interpreter-demo/interpreter.js node_modules/* codelabs/* gh-pages/* @@ -7,6 +10,8 @@ gh-pages/* # All build artifacts, etc. **/dist/* **/build/* +examples/blockly-svelte/public/bundle.js +examples/blockly-angular/.angular **/node_modules/* **/CHANGELOG.md CHANGELOG.md diff --git a/codelabs/custom_generator/custom_generator.md b/codelabs/custom_generator/custom_generator.md index e4039bfa58..34ab94ac6a 100644 --- a/codelabs/custom_generator/custom_generator.md +++ b/codelabs/custom_generator/custom_generator.md @@ -35,7 +35,7 @@ This codelab will demonstrate how to add code to the Blockly sample app to creat ### The application -Use the (`npx @blockly/create-package app`)[https://www.npmjs.com/package/@blockly/create-package) command to create a standalone application that contains a sample setup of Blockly, including custom blocks and a display of the generated code and output. +Use the [`npx @blockly/create-package app`](https://www.npmjs.com/package/@blockly/create-package) command to create a standalone application that contains a sample setup of Blockly, including custom blocks and a display of the generated code and output. 1. Run `npx @blockly/create-package app custom-generator-codelab`. This will create a blockly application in the folder `custom-generator-codelab`. 1. `cd` into the new directory: `cd custom-generator-codelab`. 1. Run `npm start` to start the server and run the sample application. diff --git a/eslint.config.js b/eslint.config.js index 70e662e70c..84f26d89ae 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -19,11 +19,28 @@ const compat = new FlatCompat(); module.exports = [ { ignores: [ - 'examples/', 'codelabs/', 'gh-pages/', + 'examples/backpack-demo', + 'examples/blockly-angular', + 'examples/blockly-react', + 'examples/blockly-rtc', + 'examples/blockly-vue3', + 'examples/context-menu-codelab', + 'examples/custom-dialogs-demo', + 'examples/custom-toolbox-codelab', + 'examples/devsite-demo', + 'examples/devsite-landing-demo', + 'examples/getting-started-codelab', + 'examples/interpreter-demo', + 'examples/pitch-field-demo', + 'examples/sample-app-ts', + 'examples/theme-extension-codelab', + 'examples/turtle-field-demo', + 'examples/validation-and-warnings-codelab', '**/dist/', '**/build/', + 'examples/blockly-svelte/public/bundle.js', // specific examples that are sometimes copied into plugins 'plugins/dev-create/templates/sample-app', 'plugins/dev-create/templates/sample-app-ts', diff --git a/examples/README.md b/examples/README.md index d68bbf48c4..d5063079cb 100644 --- a/examples/README.md +++ b/examples/README.md @@ -7,44 +7,44 @@ to include and extend the [Blockly](http://github.com/google/blockly) library. ### Usage Demos -- [``backpack-demo``](backpack-demo/): A demo of two Blockly instances with a shared backpack. -- [``custom-dialogs-demo``](custom-dialogs-demo/): A demo overriding Blockly browser dialogs with custom implementations. -- [``custom-tooltips-demo``](custom-tooltips-demo/): An example of using a custom tooltip renderer. -- [``fixed-demo``](fixed-demo/): A demo injecting Blockly into a page as a fixed element. -- [``generator-demo``](generator-demo/): A demo of generating code from blocks and running it in a sandboxed JavaScript interpreter -- [``graph-demo``](graph-demo/): A demo of giving instant feedback as blocks are changed. -- [``headless-demo``](headless-demo/): A demo of generating Python code from JSON with no graphics. -- [``interpreter-demo``](interpreter-demo/): A demo of executing code step-by-step with a sandboxed JavaScript interpreter. -- [``max-blocks-demo``](max-blocks-demo/): A demo limiting the total number of blocks allowed for academic exercises. -- [``mirror-demo``](mirror-demo/): A demo using two Blockly instances connected as leader-follower. -- [``pitch-field-demo``](pitch-field-demo/): A demo of creating custom block fields. -- [``resizable-demo``](resizable-demo/): A demo of injecting Blockly into a page as a resizable element. -- [``rtl-demo``](rtl-demo/): A demo of what Blockly looks like in right-to-left mode (for Arabic and Hebrew). -- [``single-direction-scroll-demo``](single-direction-scroll-demo/): A demo of configuring single-direction scrollbars. -- [``toolbox-demo``](toolbox-demo/): A demo of a complex category structure for the toolbox. -- [``turtle-field-demo``](turtle-field-demo/): A demo of creating custom block fields. +- [`backpack-demo`](backpack-demo/): A demo of two Blockly instances with a shared backpack. +- [`custom-dialogs-demo`](custom-dialogs-demo/): A demo overriding Blockly browser dialogs with custom implementations. +- [`custom-tooltips-demo`](custom-tooltips-demo/): An example of using a custom tooltip renderer. +- [`fixed-demo`](fixed-demo/): A demo injecting Blockly into a page as a fixed element. +- [`generator-demo`](generator-demo/): A demo of generating code from blocks and running it in a sandboxed JavaScript interpreter +- [`graph-demo`](graph-demo/): A demo of giving instant feedback as blocks are changed. +- [`headless-demo`](headless-demo/): A demo of generating Python code from JSON with no graphics. +- [`interpreter-demo`](interpreter-demo/): A demo of executing code step-by-step with a sandboxed JavaScript interpreter. +- [`max-blocks-demo`](max-blocks-demo/): A demo limiting the total number of blocks allowed for academic exercises. +- [`mirror-demo`](mirror-demo/): A demo using two Blockly instances connected as leader-follower. +- [`pitch-field-demo`](pitch-field-demo/): A demo of creating custom block fields. +- [`resizable-demo`](resizable-demo/): A demo of injecting Blockly into a page as a resizable element. +- [`rtl-demo`](rtl-demo/): A demo of what Blockly looks like in right-to-left mode (for Arabic and Hebrew). +- [`single-direction-scroll-demo`](single-direction-scroll-demo/): A demo of configuring single-direction scrollbars. +- [`toolbox-demo`](toolbox-demo/): A demo of a complex category structure for the toolbox. +- [`turtle-field-demo`](turtle-field-demo/): A demo of creating custom block fields. ### Codelabs The [Blockly Codelabs](https://blocklycodelabs.dev/) refer to this example code. -- [``context-menu-codelab``](context-menu-codelab/): Starter code and completed code for the [codelab](https://blocklycodelabs.dev/codelabs/context-menu-option/index.html) on context menu options. -- [``custom-toolbox-codelab``](custom-toolbox-codelab/): Starter code and completed code for the [codelab](https://blocklycodelabs.dev/codelabs/custom_toolbox/index.html) on how to customize your toolbox. -- [``getting-started-codelab``](getting-started-codelab/): Code for the [Blockly getting started codelab](https://blocklycodelabs.dev/codelabs/getting-started/index.html). -- [``theme-extension-codelab``](theme-extension-codelab/): Starter code and completed code for the [codelab](https://blocklycodelabs.dev/codelabs/theme-extension-identifier/index.html) on applying themes. -- [``validation-and-warnings-codelab``](validation-and-warnings-codelab/): Starter code and completed code for the [codelab](https://blocklycodelabs.dev/codelabs/validation-and-warnings/index.html) on validating blocks and displaying warnings. +- [`context-menu-codelab`](context-menu-codelab/): Starter code and completed code for the [codelab](https://blocklycodelabs.dev/codelabs/context-menu-option/index.html) on context menu options. +- [`custom-toolbox-codelab`](custom-toolbox-codelab/): Starter code and completed code for the [codelab](https://blocklycodelabs.dev/codelabs/custom_toolbox/index.html) on how to customize your toolbox. +- [`getting-started-codelab`](getting-started-codelab/): Code for the [Blockly getting started codelab](https://blocklycodelabs.dev/codelabs/getting-started/index.html). +- [`theme-extension-codelab`](theme-extension-codelab/): Starter code and completed code for the [codelab](https://blocklycodelabs.dev/codelabs/theme-extension-identifier/index.html) on applying themes. +- [`validation-and-warnings-codelab`](validation-and-warnings-codelab/): Starter code and completed code for the [codelab](https://blocklycodelabs.dev/codelabs/validation-and-warnings/index.html) on validating blocks and displaying warnings. ### Integrating Blockly -- [``blockly-angular-sample``](blockly-angular/): Blockly in an Angular project, defines an Angular Blockly Component. -- [``blockly-react-sample``](blockly-react/): Blockly in a React project, defines a React Blockly Component. -- [``blockly-svelte-sample``](blockly-svelte/): Blockly in a Svelte project, defines a Svelte Blockly Component. -- [``blockly-vue3-sample``](blockly-vue3/): Blockly in a Vue3 project, defines a Vue Blockly Component. -- [``blockly-parcel``](blockly-parcel/): Using Blockly with Parcel. +- [`blockly-angular-sample`](blockly-angular/): Blockly in an Angular project, defines an Angular Blockly Component. +- [`blockly-react-sample`](blockly-react/): Blockly in a React project, defines a React Blockly Component. +- [`blockly-svelte-sample`](blockly-svelte/): Blockly in a Svelte project, defines a Svelte Blockly Component. +- [`blockly-vue3-sample`](blockly-vue3/): Blockly in a Vue3 project, defines a Vue Blockly Component. +- [`blockly-parcel`](blockly-parcel/): Using Blockly with Parcel. ### Real-time Collaboration -- [``blockly-rtc``](blockly-rtc/): Real-time collaboration environment on top of the Blockly framework. +- [`blockly-rtc`](blockly-rtc/): Real-time collaboration environment on top of the Blockly framework. ## Prerequisites @@ -57,6 +57,7 @@ cd npm install npm run start ``` + Browse to http://localhost:3000 You may need to refer to a sample's README for further setup and running instructions. @@ -68,17 +69,19 @@ You may need to refer to a sample's README for further setup and running instruc ``` npm run boot ``` -This will run ``npm install`` on every example. + +This will run `npm install` on every example. ### Maintenance ``` npm run update ``` -This will run ``npm update`` on every example. +This will run `npm update` on every example. ``` npm run audit ``` -This will run ``npm audit fix`` on every example. + +This will run `npm audit fix` on every example. diff --git a/examples/backpack-demo/index.html b/examples/backpack-demo/index.html index c871803e8e..ff2e33c0f3 100644 --- a/examples/backpack-demo/index.html +++ b/examples/backpack-demo/index.html @@ -1,38 +1,40 @@ - + - - - Blockly Demo: Backpack - - - - - - - - - -

This is a demo of two Blockly instances with a custom Backpack "sharing" Backpack contents.

+ + + Blockly Demo: Backpack + + + + + + + + + +

+ This is a demo of two Blockly instances with a custom Backpack "sharing" + Backpack contents. +

- - - - - -
-
-
-
-
- - + + + + + +
+
+
+
+
+ diff --git a/examples/backpack-demo/index.js b/examples/backpack-demo/index.js index 901a4194de..99a5dd64cf 100644 --- a/examples/backpack-demo/index.js +++ b/examples/backpack-demo/index.js @@ -8,203 +8,200 @@ * @fileoverview Backpack demo initialization. */ const toolbox = { - 'kind': 'categoryToolbox', - 'contents': [ + kind: 'categoryToolbox', + contents: [ { - 'kind': 'category', - 'name': 'Logic', - 'categorystyle': 'logic_category', - 'contents': [ + kind: 'category', + name: 'Logic', + categorystyle: 'logic_category', + contents: [ { - 'kind': 'block', - 'type': 'controls_if' + kind: 'block', + type: 'controls_if', }, { - 'kind': 'block', - 'type': 'logic_compare' + kind: 'block', + type: 'logic_compare', }, { - 'kind': 'block', - 'type': 'logic_operation' + kind: 'block', + type: 'logic_operation', }, { - 'kind': 'block', - 'type': 'logic_negate' + kind: 'block', + type: 'logic_negate', }, { - 'kind': 'block', - 'type': 'logic_boolean' - } - ] + kind: 'block', + type: 'logic_boolean', + }, + ], }, { - 'kind': 'category', - 'name': 'Loops', - 'categorystyle': 'loop_category', - 'contents': [ - { - 'kind': 'block', - 'type': 'controls_repeat_ext', - 'inputs': { - 'TIMES': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 10 - } + kind: 'category', + name: 'Loops', + categorystyle: 'loop_category', + contents: [ + { + kind: 'block', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, + }, }, - } + }, }, }, { - 'kind': 'block', - 'type': 'controls_flow_statements' - } - ] + kind: 'block', + type: 'controls_flow_statements', + }, + ], }, { - 'kind': 'category', - 'name': 'Math', - 'categorystyle': 'math_category', - 'contents': [ - { - 'kind': 'block', - 'type': 'math_number', - 'fields': { - 'NUM': 123 - } - }, - { - 'kind': 'block', - 'type': 'math_arithmetic', - 'inputs': { - 'A': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1 - } - } + kind: 'category', + name: 'Math', + categorystyle: 'math_category', + contents: [ + { + kind: 'block', + type: 'math_number', + fields: { + NUM: 123, + }, + }, + { + kind: 'block', + type: 'math_arithmetic', + inputs: { + A: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, + }, + B: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, + }, + }, }, - 'B': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1 - } - } - } - } - }, - { - 'kind': 'block', - 'type': 'math_single', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 9 - } - } - } }, }, { - 'kind': 'block', - 'type': 'math_number_property', - 'inputs': { - 'NUMBER_TO_CHECK': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 0 - } - } - } + kind: 'block', + type: 'math_single', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 9, + }, + }, + }, + }, + }, + { + kind: 'block', + type: 'math_number_property', + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, + }, + }, + }, }, - } - ] + }, + ], }, { - 'kind': 'category', - 'name': 'Text', - 'categorystyle': 'text_category', - 'contents': [ + kind: 'category', + name: 'Text', + categorystyle: 'text_category', + contents: [ { - 'kind': 'block', - 'type': 'text' + kind: 'block', + type: 'text', }, { - 'kind': 'block', - 'type': 'text_multiline' + kind: 'block', + type: 'text_multiline', }, { 'kind': 'label', 'text': 'Input/Output:', - 'web-class': 'ioLabel' - }, - { - 'kind': 'block', - 'type': 'text_print', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc' - } - } - } + 'web-class': 'ioLabel', + }, + { + kind: 'block', + type: 'text_print', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, }, }, { - 'kind': 'block', - 'type': 'text_prompt_ext', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc' - } - } - } - } - } - ] + kind: 'block', + type: 'text_prompt_ext', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + ], }, { - 'kind': 'category', - 'name': 'Variables', - 'categorystyle': 'variable_category', - 'custom': 'VARIABLE' + kind: 'category', + name: 'Variables', + categorystyle: 'variable_category', + custom: 'VARIABLE', }, { - 'kind': 'category', - 'name': 'Functions', - 'categorystyle': 'procedure_category', - 'custom': 'PROCEDURE' - } - ] + kind: 'category', + name: 'Functions', + categorystyle: 'procedure_category', + custom: 'PROCEDURE', + }, + ], }; - function init() { // Inject primary workspace. - const primaryWorkspace = Blockly.inject('primaryDiv', - { - media: './node_modules/blockly/media/', - toolbox: toolbox, - trashcan: true, - }); + const primaryWorkspace = Blockly.inject('primaryDiv', { + media: './node_modules/blockly/media/', + toolbox: toolbox, + trashcan: true, + }); // Inject secondary workspace. - const secondaryWorkspace = Blockly.inject('secondaryDiv', - { - media: './node_modules/blockly/media/', - toolbox: toolbox, - trashcan: true, - }); + const secondaryWorkspace = Blockly.inject('secondaryDiv', { + media: './node_modules/blockly/media/', + toolbox: toolbox, + trashcan: true, + }); // Add backpacks const primaryBackpack = new NotificationBackpack(primaryWorkspace); @@ -227,7 +224,8 @@ function init() { targetBackpack = secondaryBackpack; contents = primaryBackpack.getContents(); console.log('second workspace backpack updated'); - } else { // secondaryWorkspace.id === event.workspaceId + } else { + // secondaryWorkspace.id === event.workspaceId targetBackpack = primaryBackpack; contents = secondaryBackpack.getContents(); console.log('first workspace backpack updated'); diff --git a/examples/backpack-demo/notification_backpack.js b/examples/backpack-demo/notification_backpack.js index 914255a87e..e51d04d14a 100644 --- a/examples/backpack-demo/notification_backpack.js +++ b/examples/backpack-demo/notification_backpack.js @@ -8,7 +8,6 @@ * @fileoverview Backpack with a notification. */ - class NotificationBackpack extends Backpack { /** * Constructor for a backpack. @@ -90,34 +89,39 @@ class NotificationBackpack extends Backpack { */ createNotificationSvg_() { this.countSvg_ = Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.G, {'opacity': 0}, this.svgGroup_); + Blockly.utils.Svg.G, + {opacity: 0}, + this.svgGroup_, + ); const circleRadius = this.WIDTH_ / 4; Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.CIRCLE, - { - 'cx': this.WIDTH_ * 4 / 5, - 'cy': this.HEIGHT_ / 4, - 'fill': this.countSvgColour_, - 'r': circleRadius, - 'stroke': '#888', - 'stroke-width': 1, - }, - this.countSvg_); + Blockly.utils.Svg.CIRCLE, + { + 'cx': (this.WIDTH_ * 4) / 5, + 'cy': this.HEIGHT_ / 4, + 'fill': this.countSvgColour_, + 'r': circleRadius, + 'stroke': '#888', + 'stroke-width': 1, + }, + this.countSvg_, + ); this.countSvgText_ = Blockly.utils.dom.createSvgElement( - Blockly.utils.Svg.TEXT, - { - 'dominant-baseline': 'central', - 'fill': this.countSvgTextColour_, - 'font-family': 'sans-serif', - 'font-size': '0.75em', - 'font-weight': '600', - 'height': circleRadius * 2, - 'text-anchor': 'middle', - 'width': circleRadius * 2, - 'x': this.WIDTH_ * 4 / 5, - 'y': this.HEIGHT_ / 4, - }, - this.countSvg_); + Blockly.utils.Svg.TEXT, + { + 'dominant-baseline': 'central', + 'fill': this.countSvgTextColour_, + 'font-family': 'sans-serif', + 'font-size': '0.75em', + 'font-weight': '600', + 'height': circleRadius * 2, + 'text-anchor': 'middle', + 'width': circleRadius * 2, + 'x': (this.WIDTH_ * 4) / 5, + 'y': this.HEIGHT_ / 4, + }, + this.countSvg_, + ); } /** @@ -130,8 +134,10 @@ class NotificationBackpack extends Backpack { this.countSvgText_.textContent = '!'; this.countSvg_.setAttribute('opacity', '1'); } else { - this.countSvgText_.textContent = this.notificationCount_ > 99 ? - '99+' : this.notificationCount_.toString(); + this.countSvgText_.textContent = + this.notificationCount_ > 99 + ? '99+' + : this.notificationCount_.toString(); } this.countSvg_.setAttribute('opacity', '1'); } else { @@ -202,7 +208,7 @@ class NotificationBackpack extends Backpack { return true; } return false; - },); + }); // Count added items. const added = contents.filter((item) => { const isAdded = this.contents_.indexOf(item) === -1; @@ -220,6 +226,6 @@ class NotificationBackpack extends Backpack { this.cachedRemovedContent_.push(...removed); this.cachedAddedContent_.push(...added); this.notificationCount_ = - this.cachedRemovedContent_.length + this.cachedAddedContent_.length; + this.cachedRemovedContent_.length + this.cachedAddedContent_.length; } } diff --git a/examples/blockly-angular/README.md b/examples/blockly-angular/README.md index 12ee3a0fe4..ca7596bc41 100644 --- a/examples/blockly-angular/README.md +++ b/examples/blockly-angular/README.md @@ -18,4 +18,4 @@ npm run start ## Browse -Open [http://localhost:3000/](http://localhost:3000/) \ No newline at end of file +Open [http://localhost:3000/](http://localhost:3000/) diff --git a/examples/blockly-angular/angular.json b/examples/blockly-angular/angular.json index d61d3ff232..f7a257b4ce 100644 --- a/examples/blockly-angular/angular.json +++ b/examples/blockly-angular/angular.json @@ -28,9 +28,7 @@ "output": "./media/" } ], - "styles": [ - "src/styles.css" - ], + "styles": ["src/styles.css"], "scripts": [] }, "configurations": { @@ -95,9 +93,7 @@ "output": "./media/" } ], - "styles": [ - "src/styles.css" - ], + "styles": ["src/styles.css"], "scripts": [] } }, diff --git a/examples/blockly-angular/e2e/protractor.conf.js b/examples/blockly-angular/e2e/protractor.conf.js index 73e4e6806c..6980303bdd 100644 --- a/examples/blockly-angular/e2e/protractor.conf.js +++ b/examples/blockly-angular/e2e/protractor.conf.js @@ -2,18 +2,16 @@ // Protractor configuration file, see link for more information // https://github.com/angular/protractor/blob/master/lib/config.ts -const { SpecReporter } = require('jasmine-spec-reporter'); +const {SpecReporter} = require('jasmine-spec-reporter'); /** * @type { import("protractor").Config } */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - 'browserName': 'chrome' + browserName: 'chrome', }, directConnect: true, baseUrl: 'http://localhost:4200/', @@ -21,12 +19,14 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); - } -}; \ No newline at end of file + jasmine + .getEnv() + .addReporter(new SpecReporter({spec: {displayStacktrace: true}})); + }, +}; diff --git a/examples/blockly-angular/e2e/src/app.e2e-spec.ts b/examples/blockly-angular/e2e/src/app.e2e-spec.ts index c053b1d6a4..e185f0b588 100644 --- a/examples/blockly-angular/e2e/src/app.e2e-spec.ts +++ b/examples/blockly-angular/e2e/src/app.e2e-spec.ts @@ -1,5 +1,5 @@ -import { AppPage } from './app.po'; -import { browser, logging } from 'protractor'; +import {AppPage} from './app.po'; +import {browser, logging} from 'protractor'; describe('workspace-project App', () => { let page: AppPage; @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry), + ); }); }); diff --git a/examples/blockly-angular/e2e/src/app.po.ts b/examples/blockly-angular/e2e/src/app.po.ts index 5776aa9eb8..9fcda38ed9 100644 --- a/examples/blockly-angular/e2e/src/app.po.ts +++ b/examples/blockly-angular/e2e/src/app.po.ts @@ -1,4 +1,4 @@ -import { browser, by, element } from 'protractor'; +import {browser, by, element} from 'protractor'; export class AppPage { navigateTo() { diff --git a/examples/blockly-angular/e2e/tsconfig.json b/examples/blockly-angular/e2e/tsconfig.json index c92199cfd6..dbf470a054 100644 --- a/examples/blockly-angular/e2e/tsconfig.json +++ b/examples/blockly-angular/e2e/tsconfig.json @@ -4,10 +4,6 @@ "outDir": "../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "jasminewd2", - "node" - ] + "types": ["jasmine", "jasminewd2", "node"] } } diff --git a/examples/blockly-angular/karma.conf.js b/examples/blockly-angular/karma.conf.js index 8b9bf5385e..93c4874eea 100644 --- a/examples/blockly-angular/karma.conf.js +++ b/examples/blockly-angular/karma.conf.js @@ -10,15 +10,15 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage-istanbul-reporter'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, coverageIstanbulReporter: { dir: require('path').join(__dirname, './coverage/blockly-angular-sample'), reports: ['html', 'lcovonly', 'text-summary'], - fixWebpackSourcePaths: true + fixWebpackSourcePaths: true, }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -27,6 +27,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/examples/blockly-angular/src/app/app.component.html b/examples/blockly-angular/src/app/app.component.html index c03db0a7f4..44f39b5f4f 100644 --- a/examples/blockly-angular/src/app/app.component.html +++ b/examples/blockly-angular/src/app/app.component.html @@ -1,6 +1,9 @@ -
-

Welcome to {{title}}!

- Angular Logo +
+

Welcome to {{ title }}!

+ Angular Logo
- \ No newline at end of file + diff --git a/examples/blockly-angular/src/app/app.component.spec.ts b/examples/blockly-angular/src/app/app.component.spec.ts index 4d41549207..ed32a2bda1 100644 --- a/examples/blockly-angular/src/app/app.component.spec.ts +++ b/examples/blockly-angular/src/app/app.component.spec.ts @@ -1,12 +1,10 @@ -import { TestBed, waitForAsync } from '@angular/core/testing'; -import { AppComponent } from './app.component'; +import {TestBed, waitForAsync} from '@angular/core/testing'; +import {AppComponent} from './app.component'; describe('AppComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [ - AppComponent - ], + declarations: [AppComponent], }).compileComponents(); })); @@ -26,6 +24,8 @@ describe('AppComponent', () => { const fixture = TestBed.createComponent(AppComponent); fixture.detectChanges(); const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Welcome to blockly-angular-sample!'); + expect(compiled.querySelector('h1').textContent).toContain( + 'Welcome to blockly-angular-sample!', + ); }); }); diff --git a/examples/blockly-angular/src/app/app.component.ts b/examples/blockly-angular/src/app/app.component.ts index 8951eb4048..1b8125b934 100644 --- a/examples/blockly-angular/src/app/app.component.ts +++ b/examples/blockly-angular/src/app/app.component.ts @@ -1,9 +1,9 @@ -import { Component } from '@angular/core'; +import {Component} from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', - styleUrls: ['./app.component.css'] + styleUrls: ['./app.component.css'], }) export class AppComponent { title = 'blockly-angular-sample'; diff --git a/examples/blockly-angular/src/app/app.module.ts b/examples/blockly-angular/src/app/app.module.ts index 6755f90950..4be796f706 100644 --- a/examples/blockly-angular/src/app/app.module.ts +++ b/examples/blockly-angular/src/app/app.module.ts @@ -1,19 +1,14 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; +import {BrowserModule} from '@angular/platform-browser'; +import {NgModule} from '@angular/core'; -import { AppComponent } from './app.component'; -import { BlocklyComponent } from './blockly/blockly.component'; +import {AppComponent} from './app.component'; +import {BlocklyComponent} from './blockly/blockly.component'; @NgModule({ - declarations: [ - AppComponent, - BlocklyComponent - ], - imports: [ - BrowserModule - ], + declarations: [AppComponent, BlocklyComponent], + imports: [BrowserModule], providers: [], bootstrap: [AppComponent], - exports: [BlocklyComponent] + exports: [BlocklyComponent], }) -export class AppModule { } +export class AppModule {} diff --git a/examples/blockly-angular/src/app/blockly/blockly.component.css b/examples/blockly-angular/src/app/blockly/blockly.component.css index 194d31577a..60624f92e1 100644 --- a/examples/blockly-angular/src/app/blockly/blockly.component.css +++ b/examples/blockly-angular/src/app/blockly/blockly.component.css @@ -1,6 +1,6 @@ #blocklyDiv { - height: 50%; - width: 100%; - position: absolute; - bottom: 0; -} \ No newline at end of file + height: 50%; + width: 100%; + position: absolute; + bottom: 0; +} diff --git a/examples/blockly-angular/src/app/blockly/blockly.component.spec.ts b/examples/blockly-angular/src/app/blockly/blockly.component.spec.ts index 2169a7577b..59a0924a85 100644 --- a/examples/blockly-angular/src/app/blockly/blockly.component.spec.ts +++ b/examples/blockly-angular/src/app/blockly/blockly.component.spec.ts @@ -1,6 +1,6 @@ -import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; -import { BlocklyComponent } from './blockly.component'; +import {BlocklyComponent} from './blockly.component'; describe('BlocklyComponent', () => { let component: BlocklyComponent; @@ -8,9 +8,8 @@ describe('BlocklyComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [ BlocklyComponent ] - }) - .compileComponents(); + declarations: [BlocklyComponent], + }).compileComponents(); })); beforeEach(() => { diff --git a/examples/blockly-angular/src/app/blockly/blockly.component.ts b/examples/blockly-angular/src/app/blockly/blockly.component.ts index e325e910f2..e660f1b06b 100644 --- a/examples/blockly-angular/src/app/blockly/blockly.component.ts +++ b/examples/blockly-angular/src/app/blockly/blockly.component.ts @@ -21,19 +21,18 @@ * @author samelh@google.com (Sam El-Husseini) */ -import { Component, OnInit } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import * as Blockly from 'blockly'; -import { BlocklyOptions } from 'blockly'; +import {BlocklyOptions} from 'blockly'; @Component({ selector: 'app-blockly', templateUrl: './blockly.component.html', - styleUrls: ['./blockly.component.css'] + styleUrls: ['./blockly.component.css'], }) export class BlocklyComponent implements OnInit { - - constructor() { } + constructor() {} ngOnInit() { const blocklyDiv = document.getElementById('blocklyDiv'); @@ -97,13 +96,13 @@ export class BlocklyComponent implements OnInit { fields: { VAR: { name: 'text', - } + }, }, }, }, }, - } - ] + }, + ], }; Blockly.inject(blocklyDiv, { @@ -113,9 +112,9 @@ export class BlocklyComponent implements OnInit { move: { scrollbars: true, drag: true, - wheel: true + wheel: true, }, - toolbox + toolbox, } as BlocklyOptions); } } diff --git a/examples/blockly-angular/src/environments/environment.prod.ts b/examples/blockly-angular/src/environments/environment.prod.ts index 3612073bc3..c9669790be 100644 --- a/examples/blockly-angular/src/environments/environment.prod.ts +++ b/examples/blockly-angular/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/examples/blockly-angular/src/environments/environment.ts b/examples/blockly-angular/src/environments/environment.ts index 7b4f817adb..99c3763cad 100644 --- a/examples/blockly-angular/src/environments/environment.ts +++ b/examples/blockly-angular/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/examples/blockly-angular/src/index.html b/examples/blockly-angular/src/index.html index cac4a405d9..663a2a6e4a 100644 --- a/examples/blockly-angular/src/index.html +++ b/examples/blockly-angular/src/index.html @@ -1,14 +1,14 @@ - - - BlocklyAngularSample - + + + BlocklyAngularSample + - - - - - - + + + + + + diff --git a/examples/blockly-angular/src/main.ts b/examples/blockly-angular/src/main.ts index c7b673cf44..c8a4ca7360 100644 --- a/examples/blockly-angular/src/main.ts +++ b/examples/blockly-angular/src/main.ts @@ -1,12 +1,13 @@ -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import {enableProdMode} from '@angular/core'; +import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; -import { AppModule } from './app/app.module'; -import { environment } from './environments/environment'; +import {AppModule} from './app/app.module'; +import {environment} from './environments/environment'; if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/examples/blockly-angular/src/polyfills.ts b/examples/blockly-angular/src/polyfills.ts index e484510fc7..3eb385e4d5 100644 --- a/examples/blockly-angular/src/polyfills.ts +++ b/examples/blockly-angular/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js'; // Included with Angular CLI. - +import 'zone.js'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/examples/blockly-angular/src/styles.css b/examples/blockly-angular/src/styles.css index cb01ccd824..1028ac0851 100644 --- a/examples/blockly-angular/src/styles.css +++ b/examples/blockly-angular/src/styles.css @@ -1,5 +1,6 @@ /* You can add global styles to this file, and also import other style files */ -html, body { - margin: 0; -} \ No newline at end of file +html, +body { + margin: 0; +} diff --git a/examples/blockly-angular/src/test.ts b/examples/blockly-angular/src/test.ts index 06aa8e41d9..2c4bba5537 100644 --- a/examples/blockly-angular/src/test.ts +++ b/examples/blockly-angular/src/test.ts @@ -1,14 +1,14 @@ // This file is required by karma.conf.js and loads recursively all the .spec and framework files import 'zone.js/dist/zone-testing'; -import { getTestBed } from '@angular/core/testing'; +import {getTestBed} from '@angular/core/testing'; import { BrowserDynamicTestingModule, - platformBrowserDynamicTesting + platformBrowserDynamicTesting, } from '@angular/platform-browser-dynamic/testing'; // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, - platformBrowserDynamicTesting() + platformBrowserDynamicTesting(), ); diff --git a/examples/blockly-angular/tsconfig.app.json b/examples/blockly-angular/tsconfig.app.json index f758d9820d..29f5f5864e 100644 --- a/examples/blockly-angular/tsconfig.app.json +++ b/examples/blockly-angular/tsconfig.app.json @@ -4,11 +4,6 @@ "outDir": "./out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/examples/blockly-angular/tsconfig.json b/examples/blockly-angular/tsconfig.json index 68f3fa6d1a..fdaaf14e36 100644 --- a/examples/blockly-angular/tsconfig.json +++ b/examples/blockly-angular/tsconfig.json @@ -11,13 +11,8 @@ "moduleResolution": "node", "importHelpers": true, "target": "ES2022", - "typeRoots": [ - "node_modules/@types" - ], - "lib": [ - "es2018", - "dom" - ], + "typeRoots": ["node_modules/@types"], + "lib": ["es2018", "dom"], "useDefineForClassFields": false }, "angularCompilerOptions": { diff --git a/examples/blockly-angular/tsconfig.spec.json b/examples/blockly-angular/tsconfig.spec.json index 6400fde7d5..430cf757ce 100644 --- a/examples/blockly-angular/tsconfig.spec.json +++ b/examples/blockly-angular/tsconfig.spec.json @@ -2,17 +2,8 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] }, - "files": [ - "src/test.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.spec.ts", - "src/**/*.d.ts" - ] + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/examples/blockly-react/package-lock.json b/examples/blockly-react/package-lock.json index 2e9b533312..d5a3224727 100644 --- a/examples/blockly-react/package-lock.json +++ b/examples/blockly-react/package-lock.json @@ -7,7 +7,6 @@ "": { "name": "blockly-react-sample", "version": "0.0.0", - "hasInstallScript": true, "dependencies": { "@blockly/field-date": "^8.0.0", "blockly": "^10.0.0", diff --git a/examples/blockly-react/public/index.html b/examples/blockly-react/public/index.html index b91e8cc96f..d77b3e4e8e 100644 --- a/examples/blockly-react/public/index.html +++ b/examples/blockly-react/public/index.html @@ -1,4 +1,4 @@ - + diff --git a/examples/blockly-react/src/App.js b/examples/blockly-react/src/App.js index 845c2691c5..0d5f860503 100644 --- a/examples/blockly-react/src/App.js +++ b/examples/blockly-react/src/App.js @@ -26,56 +26,58 @@ import './App.css'; import logo from './logo.svg'; -import BlocklyComponent, { Block, Value, Field, Shadow } from './Blockly'; +import BlocklyComponent, {Block, Value, Field, Shadow} from './Blockly'; import './blocks/customblocks'; import './generator/generator'; function App(props) { - return ( -
-
- logo - +
+ logo + `}> - - - - - - - - - 10 - - - - - - - - - - - - text - - - - -
-
- ); + + + + + + + + + 10 + + + + + + + + + + + + text + + + + + +
+ ); } export default App; diff --git a/examples/blockly-react/src/Blockly/BlocklyComponent.css b/examples/blockly-react/src/Blockly/BlocklyComponent.css index 0f9e032ba9..60624f92e1 100644 --- a/examples/blockly-react/src/Blockly/BlocklyComponent.css +++ b/examples/blockly-react/src/Blockly/BlocklyComponent.css @@ -3,4 +3,4 @@ width: 100%; position: absolute; bottom: 0; -} \ No newline at end of file +} diff --git a/examples/blockly-react/src/Blockly/BlocklyComponent.jsx b/examples/blockly-react/src/Blockly/BlocklyComponent.jsx index 86a5a03603..bda1551bbb 100644 --- a/examples/blockly-react/src/Blockly/BlocklyComponent.jsx +++ b/examples/blockly-react/src/Blockly/BlocklyComponent.jsx @@ -21,52 +21,51 @@ * @author samelh@google.com (Sam El-Husseini) */ - import React from 'react'; - import './BlocklyComponent.css'; - import {useEffect, useRef} from 'react'; +import React from 'react'; +import './BlocklyComponent.css'; +import {useEffect, useRef} from 'react'; - import Blockly from 'blockly/core'; - import {javascriptGenerator} from 'blockly/javascript'; - import locale from 'blockly/msg/en'; - import 'blockly/blocks'; +import Blockly from 'blockly/core'; +import {javascriptGenerator} from 'blockly/javascript'; +import locale from 'blockly/msg/en'; +import 'blockly/blocks'; - Blockly.setLocale(locale); +Blockly.setLocale(locale); - function BlocklyComponent(props) { - const blocklyDiv = useRef(); - const toolbox = useRef(); - let primaryWorkspace = useRef(); +function BlocklyComponent(props) { + const blocklyDiv = useRef(); + const toolbox = useRef(); + let primaryWorkspace = useRef(); - const generateCode = () => { - var code = javascriptGenerator.workspaceToCode( - primaryWorkspace.current - ); - console.log(code); - } + const generateCode = () => { + var code = javascriptGenerator.workspaceToCode(primaryWorkspace.current); + console.log(code); + }; - useEffect(() => { - const { initialXml, children, ...rest } = props; - primaryWorkspace.current = Blockly.inject( - blocklyDiv.current, - { - toolbox: toolbox.current, - ...rest - }, - ); + useEffect(() => { + const {initialXml, children, ...rest} = props; + primaryWorkspace.current = Blockly.inject(blocklyDiv.current, { + toolbox: toolbox.current, + ...rest, + }); - if (initialXml) { - Blockly.Xml.domToWorkspace(Blockly.utils.xml.textToDom(initialXml), primaryWorkspace.current); - } - }, [primaryWorkspace, toolbox, blocklyDiv, props]); + if (initialXml) { + Blockly.Xml.domToWorkspace( + Blockly.utils.xml.textToDom(initialXml), + primaryWorkspace.current, + ); + } + }, [primaryWorkspace, toolbox, blocklyDiv, props]); - return ( + return ( - -
-
- {props.children} -
- ); + +
+
+ {props.children} +
+ + ); } export default BlocklyComponent; diff --git a/examples/blockly-react/src/Blockly/index.js b/examples/blockly-react/src/Blockly/index.js index 04c299a4a8..cef00f74fe 100644 --- a/examples/blockly-react/src/Blockly/index.js +++ b/examples/blockly-react/src/Blockly/index.js @@ -21,39 +21,39 @@ * @author samelh@google.com (Sam El-Husseini) */ - import React from 'react'; +import React from 'react'; import BlocklyComponent from './BlocklyComponent'; export default BlocklyComponent; const Block = (p) => { - const { children, ...props } = p; - props.is = "blockly"; - return React.createElement("block", props, children); + const {children, ...props} = p; + props.is = 'blockly'; + return React.createElement('block', props, children); }; const Category = (p) => { - const { children, ...props } = p; - props.is = "blockly"; - return React.createElement("category", props, children); + const {children, ...props} = p; + props.is = 'blockly'; + return React.createElement('category', props, children); }; const Value = (p) => { - const { children, ...props } = p; - props.is = "blockly"; - return React.createElement("value", props, children); + const {children, ...props} = p; + props.is = 'blockly'; + return React.createElement('value', props, children); }; const Field = (p) => { - const { children, ...props } = p; - props.is = "blockly"; - return React.createElement("field", props, children); + const {children, ...props} = p; + props.is = 'blockly'; + return React.createElement('field', props, children); }; const Shadow = (p) => { - const { children, ...props } = p; - props.is = "blockly"; - return React.createElement("shadow", props, children); + const {children, ...props} = p; + props.is = 'blockly'; + return React.createElement('shadow', props, children); }; -export { Block, Category, Value, Field, Shadow } +export {Block, Category, Value, Field, Shadow}; diff --git a/examples/blockly-react/src/blocks/customblocks.js b/examples/blockly-react/src/blocks/customblocks.js index 0258acaea2..f839d3e0c2 100644 --- a/examples/blockly-react/src/blocks/customblocks.js +++ b/examples/blockly-react/src/blocks/customblocks.js @@ -24,7 +24,6 @@ // More on defining blocks: // https://developers.google.com/blockly/guides/create-custom-blocks/define-blocks - import * as Blockly from 'blockly/core'; // Since we're using json to initialize the field, we'll need to import it. @@ -34,43 +33,43 @@ import '../fields/DateField'; import '@blockly/field-date'; const reactDateField = { - "type": "test_react_date_field", - "message0": "date field: %1", - "args0": [ - { - "type": "field_date", - "name": "DATE", - "date": "2020-02-20" - } - ], - "previousStatement": null, - "nextStatement": null, - }; + type: 'test_react_date_field', + message0: 'date field: %1', + args0: [ + { + type: 'field_date', + name: 'DATE', + date: '2020-02-20', + }, + ], + previousStatement: null, + nextStatement: null, +}; Blockly.Blocks['test_react_date_field'] = { - init: function() { + init: function () { this.jsonInit(reactDateField); this.setStyle('loop_blocks'); - } -} + }, +}; const testReactField = { - "type": "test_react_field", - "message0": "custom field %1", - "args0": [ + type: 'test_react_field', + message0: 'custom field %1', + args0: [ { - "type": "field_react_component", - "name": "FIELD", - "text": "Click me" + type: 'field_react_component', + name: 'FIELD', + text: 'Click me', }, ], - "previousStatement": null, - "nextStatement": null, + previousStatement: null, + nextStatement: null, }; Blockly.Blocks['test_react_field'] = { - init: function() { + init: function () { this.jsonInit(testReactField); this.setStyle('loop_blocks'); - } + }, }; diff --git a/examples/blockly-react/src/fields/BlocklyReactField.jsx b/examples/blockly-react/src/fields/BlocklyReactField.jsx index 41346f1d6c..54bcd31c39 100644 --- a/examples/blockly-react/src/fields/BlocklyReactField.jsx +++ b/examples/blockly-react/src/fields/BlocklyReactField.jsx @@ -28,10 +28,8 @@ import ReactDOM from 'react-dom'; import * as Blockly from 'blockly/core'; - class BlocklyReactField extends Blockly.Field { - - SERIALIZABLE = true + SERIALIZABLE = true; static fromJson(options) { // `this` might be a subclass of BlocklyReactField if that class doesn't @@ -41,15 +39,16 @@ class BlocklyReactField extends Blockly.Field { showEditor_() { this.div_ = Blockly.DropDownDiv.getContentDiv(); - ReactDOM.render(this.render(), - this.div_); + ReactDOM.render(this.render(), this.div_); var border = this.sourceBlock_.style.colourTertiary; border = border.colourBorder || border.colourLight; Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), border); Blockly.DropDownDiv.showPositionedByField( - this, this.dropdownDispose_.bind(this)); + this, + this.dropdownDispose_.bind(this), + ); } dropdownDispose_() { @@ -57,16 +56,13 @@ class BlocklyReactField extends Blockly.Field { } render() { - return + return ; } } class FieldRenderComponent extends React.Component { - render() { - return
- Hello from React! -
; + return
Hello from React!
; } } diff --git a/examples/blockly-react/src/fields/DateField.jsx b/examples/blockly-react/src/fields/DateField.jsx index 06f17de33c..f7079572f7 100644 --- a/examples/blockly-react/src/fields/DateField.jsx +++ b/examples/blockly-react/src/fields/DateField.jsx @@ -26,12 +26,10 @@ import * as Blockly from 'blockly/core'; import BlocklyReactField from './BlocklyReactField'; -import DatePicker from "react-datepicker"; -import "react-datepicker/dist/react-datepicker.css"; - +import DatePicker from 'react-datepicker'; +import 'react-datepicker/dist/react-datepicker.css'; class ReactDateField extends BlocklyReactField { - static fromJson(options) { // `this` might be a subclass of ReactDateField if that class doesn't // override the static fromJson method. @@ -41,21 +39,24 @@ class ReactDateField extends BlocklyReactField { onDateSelected_ = (date) => { this.setValue(new Date(date)); Blockly.DropDownDiv.hideIfOwner(this, true); - } + }; getText_() { return this.value_.toLocaleDateString(); - }; + } fromXml(fieldElement) { this.setValue(new Date(fieldElement.textContent)); } render() { - return + inline + /> + ); } } diff --git a/examples/blockly-react/src/generator/generator.js b/examples/blockly-react/src/generator/generator.js index 6d2a04675a..9f2666fd3d 100644 --- a/examples/blockly-react/src/generator/generator.js +++ b/examples/blockly-react/src/generator/generator.js @@ -27,9 +27,9 @@ import {javascriptGenerator} from 'blockly/javascript'; javascriptGenerator.forBlock['test_react_field'] = function (block) { - return 'console.log(\'custom block\');\n'; + return "console.log('custom block');\n"; }; javascriptGenerator.forBlock['test_react_date_field'] = function (block) { - return 'console.log(' + block.getField('DATE').getText() + ');\n'; + return 'console.log(' + block.getField('DATE').getText() + ');\n'; }; diff --git a/examples/blockly-react/src/index.css b/examples/blockly-react/src/index.css index 0879831893..eeab7d46cb 100644 --- a/examples/blockly-react/src/index.css +++ b/examples/blockly-react/src/index.css @@ -1,13 +1,14 @@ body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } -html, body { +html, +body { height: 100%; } @@ -16,6 +17,6 @@ html, body { } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } diff --git a/examples/blockly-react/src/serviceWorker.js b/examples/blockly-react/src/serviceWorker.js index f8c7e50c20..1e4983de5d 100644 --- a/examples/blockly-react/src/serviceWorker.js +++ b/examples/blockly-react/src/serviceWorker.js @@ -16,8 +16,8 @@ const isLocalhost = Boolean( window.location.hostname === '[::1]' || // 127.0.0.1/8 is considered localhost for IPv4. window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/, + ), ); export function register(config) { @@ -43,7 +43,7 @@ export function register(config) { navigator.serviceWorker.ready.then(() => { console.log( 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://bit.ly/CRA-PWA' + 'worker. To learn more, visit https://bit.ly/CRA-PWA', ); }); } else { @@ -57,7 +57,7 @@ export function register(config) { function registerValidSW(swUrl, config) { navigator.serviceWorker .register(swUrl) - .then(registration => { + .then((registration) => { registration.onupdatefound = () => { const installingWorker = registration.installing; if (installingWorker == null) { @@ -71,7 +71,7 @@ function registerValidSW(swUrl, config) { // content until all client tabs are closed. console.log( 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.', ); // Execute callback @@ -93,7 +93,7 @@ function registerValidSW(swUrl, config) { }; }; }) - .catch(error => { + .catch((error) => { console.error('Error during service worker registration:', error); }); } @@ -101,7 +101,7 @@ function registerValidSW(swUrl, config) { function checkValidServiceWorker(swUrl, config) { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl) - .then(response => { + .then((response) => { // Ensure service worker exists, and that we really are getting a JS file. const contentType = response.headers.get('content-type'); if ( @@ -109,7 +109,7 @@ function checkValidServiceWorker(swUrl, config) { (contentType != null && contentType.indexOf('javascript') === -1) ) { // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then(registration => { + navigator.serviceWorker.ready.then((registration) => { registration.unregister().then(() => { window.location.reload(); }); @@ -121,14 +121,14 @@ function checkValidServiceWorker(swUrl, config) { }) .catch(() => { console.log( - 'No internet connection found. App is running in offline mode.' + 'No internet connection found. App is running in offline mode.', ); }); } export function unregister() { if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(registration => { + navigator.serviceWorker.ready.then((registration) => { registration.unregister(); }); } diff --git a/examples/blockly-rtc/README.md b/examples/blockly-rtc/README.md index c4f49e3226..c603e597e0 100644 --- a/examples/blockly-rtc/README.md +++ b/examples/blockly-rtc/README.md @@ -1,27 +1,29 @@ # Blockly Realtime Collaboration Coding Sample [![Built on Blockly](https://tinyurl.com/built-on-blockly)](https://github.com/google/blockly) + This sample demonstrates how to create a realtime collaboration environment on top of the Blockly framework. ## Installation + From the blockly-rtc directory run: -```npm install``` +`npm install` ## Running + You can run the sample with either a websocket server (full-duplex communication) or a basic http server (half-duplex communication). The websocket server implementation includes a presence feature which detects when clients have disconnected from the session. To run the websocket implementation: -```npm run start-websocket``` +`npm run start-websocket` Open http://localhost:3000/websocket.html To run the http implementation: -```npm run start-http``` +`npm run start-http` Open http://localhost:3000/http.html - ## Design Overview ### Event Resolution Algorithm diff --git a/examples/blockly-rtc/package-lock.json b/examples/blockly-rtc/package-lock.json index 53d77e8420..ede6c07eb6 100644 --- a/examples/blockly-rtc/package-lock.json +++ b/examples/blockly-rtc/package-lock.json @@ -3031,9 +3031,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true, "funding": [ { @@ -12631,9 +12631,9 @@ } }, "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true }, "for-in": { diff --git a/examples/blockly-rtc/public/http.html b/examples/blockly-rtc/public/http.html index 12d6af4265..4a20d76555 100644 --- a/examples/blockly-rtc/public/http.html +++ b/examples/blockly-rtc/public/http.html @@ -1,30 +1,25 @@ - - + - - + Blockly - Realtime Collaboration Demo - - - -
-
- - + - + +
+ + diff --git a/examples/blockly-rtc/public/websocket.html b/examples/blockly-rtc/public/websocket.html index 8447a0b6e7..ad716d8bcf 100644 --- a/examples/blockly-rtc/public/websocket.html +++ b/examples/blockly-rtc/public/websocket.html @@ -1,30 +1,25 @@ - - + - - + Blockly - Realtime Collaboration Demo - - - -
-
- - + - + +
+ + diff --git a/examples/blockly-rtc/server/Database.js b/examples/blockly-rtc/server/Database.js index 1727fb7083..83b260dd89 100644 --- a/examples/blockly-rtc/server/Database.js +++ b/examples/blockly-rtc/server/Database.js @@ -31,9 +31,9 @@ class Database { this.db = db; this.snapshot = { serverId: 0, - xml: '' + xml: '', }; - }; + } /** * Query the database for entries since the given server id. @@ -43,21 +43,23 @@ class Database { * @public */ query(serverId) { - return new Promise ((resolve, reject) => { - this.db.all(`SELECT * from eventsdb WHERE serverId > ${serverId};`, - (err, entries) => { - if (err) { - console.error(err.message); - reject('Failed to query the database.'); - } else { - entries.forEach((entry) => { - entry.events = JSON.parse(entry.events); - }); - resolve(entries); - }; - }); + return new Promise((resolve, reject) => { + this.db.all( + `SELECT * from eventsdb WHERE serverId > ${serverId};`, + (err, entries) => { + if (err) { + console.error(err.message); + reject('Failed to query the database.'); + } else { + entries.forEach((entry) => { + entry.events = JSON.parse(entry.events); + }); + resolve(entries); + } + }, + ); }); - }; + } /** * Add entry to the database if the entry is a valid next addition. @@ -74,18 +76,21 @@ class Database { if (entry.entryNumber > lastEntryNumber) { try { const serverId = await this.runInsertQuery_(entry); - await this.updateLastEntryNumber_(entry.workspaceId, entry.entryNumber); + await this.updateLastEntryNumber_( + entry.workspaceId, + entry.entryNumber, + ); resolve(serverId); } catch { reject('Failed to write to the database'); - }; + } } else if (entry.entryNumber == lastEntryNumber) { resolve(null); } else { reject('Entry is not valid.'); - }; + } }); - }; + } /** * Run query to add an entry to the database. @@ -97,25 +102,30 @@ class Database { runInsertQuery_(entry) { return new Promise((resolve, reject) => { this.db.serialize(() => { - this.db.run(`INSERT INTO eventsdb + this.db.run( + `INSERT INTO eventsdb (events, workspaceId, entryNumber) VALUES(?,?,?)`, - [JSON.stringify(entry.events), entry.workspaceId, entry.entryNumber], - (err) => { - if (err) { - console.error(err.message); - reject('Failed to write to the database.'); - }; - }); - this.db.each(`SELECT last_insert_rowid() as serverId;`, (err, lastServerId) => { - if (err) { - console.error(err.message); - reject('Failed to retrieve serverId.'); - }; - resolve(lastServerId.serverId); - }); + [JSON.stringify(entry.events), entry.workspaceId, entry.entryNumber], + (err) => { + if (err) { + console.error(err.message); + reject('Failed to write to the database.'); + } + }, + ); + this.db.each( + `SELECT last_insert_rowid() as serverId;`, + (err, lastServerId) => { + if (err) { + console.error(err.message); + reject('Failed to retrieve serverId.'); + } + resolve(lastServerId.serverId); + }, + ); }); }); - }; + } /** * Update lastEntryNumber in the users table for a given user. @@ -127,18 +137,20 @@ class Database { */ updateLastEntryNumber_(workspaceId, entryNumber) { return new Promise((resolve, reject) => { - this.db.run(`UPDATE users SET lastEntryNumber = ? + this.db.run( + `UPDATE users SET lastEntryNumber = ? WHERE workspaceId = ?;`, - [entryNumber, workspaceId], - async (err) => { - if (err) { - console.error(err.message); - reject('Failed update users table.'); - }; - resolve(); - }); + [entryNumber, workspaceId], + async (err) => { + if (err) { + console.error(err.message); + reject('Failed update users table.'); + } + resolve(); + }, + ); }); - }; + } /** * Get the lastEntryNumber for a given user. @@ -150,36 +162,40 @@ class Database { getLastEntryNumber_(workspaceId) { return new Promise((resolve, reject) => { this.db.serialize(() => { - // Ensure user is in the database, otherwise add it. this.db.all( - `SELECT * from users + `SELECT * from users WHERE (EXISTS (SELECT 1 from users WHERE workspaceId == ?));`, - [workspaceId], - (err, entries) => { - if (err) { - console.error(err.message); - reject('Failed to get last entry number.'); - } else if (entries.length == 0) { - this.db.run(`INSERT INTO users(workspaceId, lastEntryNumber) - VALUES(?, -1)`, [workspaceId]); - }; - }); + [workspaceId], + (err, entries) => { + if (err) { + console.error(err.message); + reject('Failed to get last entry number.'); + } else if (entries.length == 0) { + this.db.run( + `INSERT INTO users(workspaceId, lastEntryNumber) + VALUES(?, -1)`, + [workspaceId], + ); + } + }, + ); this.db.each( - `SELECT lastEntryNumber from users WHERE workspaceId = ?;`, - [workspaceId], - (err, result) => { - if (err) { - console.error(err.message); - reject('Failed to get last entry number.'); - } else { - resolve(result.lastEntryNumber); - }; - }); + `SELECT lastEntryNumber from users WHERE workspaceId = ?;`, + [workspaceId], + (err, result) => { + if (err) { + console.error(err.message); + reject('Failed to get last entry number.'); + } else { + resolve(result.lastEntryNumber); + } + }, + ); }); }); - }; + } /** * Query the position for the given user. If no user is specified will @@ -190,12 +206,12 @@ class Database { */ getPositionUpdates(workspaceId) { return new Promise((resolve, reject) => { - const sql = workspaceId ? - `SELECT workspaceId, position from users + const sql = workspaceId + ? `SELECT workspaceId, position from users WHERE (EXISTS (SELECT 1 from users WHERE workspaceId == ${workspaceId})) - AND workspaceId = ${workspaceId};` : - `SELECT workspaceId, position from users;`; + AND workspaceId = ${workspaceId};` + : `SELECT workspaceId, position from users;`; this.db.all(sql, (err, positionUpdates) => { if (err) { console.error(err.message); @@ -205,10 +221,10 @@ class Database { positionUpdate.position = JSON.parse(positionUpdate.position); }); resolve(positionUpdates); - }; + } }); }); - }; + } /** * Update the position in the users table for a given user. @@ -220,24 +236,25 @@ class Database { updatePosition(positionUpdate) { return new Promise((resolve, reject) => { this.db.run( - `INSERT INTO users(workspaceId, lastEntryNumber, position) + `INSERT INTO users(workspaceId, lastEntryNumber, position) VALUES(?, -1, ?) ON CONFLICT(workspaceId) DO UPDATE SET position = ?`, - [ - positionUpdate.workspaceId, - JSON.stringify(positionUpdate.position), - JSON.stringify(positionUpdate.position) - ], - (err) => { - if (err) { - console.error(err.message); - reject(); - }; - resolve(); - }); + [ + positionUpdate.workspaceId, + JSON.stringify(positionUpdate.position), + JSON.stringify(positionUpdate.position), + ], + (err) => { + if (err) { + console.error(err.message); + reject(); + } + resolve(); + }, + ); }); - }; + } /** * Delete a user from the users table. @@ -249,16 +266,17 @@ class Database { deleteUser(workspaceId) { return new Promise((resolve, reject) => { this.db.run( - `DELETE FROM users WHERE workspaceId = '${workspaceId}';`, - (err) => { - if (err) { - console.error(err.message); - reject(); - }; - resolve(); - }); + `DELETE FROM users WHERE workspaceId = '${workspaceId}';`, + (err) => { + if (err) { + console.error(err.message); + reject(); + } + resolve(); + }, + ); }); - }; + } /** * Retrieve the latest snapshot of the workspace. @@ -268,7 +286,7 @@ class Database { async getSnapshot() { await this.updateSnapshot_(); return this.snapshot; - }; + } /** * Update the snapshot of the workspace. @@ -282,13 +300,13 @@ class Database { if (newEntries.length == 0) { resolve(); return; - }; + } // Load last stored snapshot of the workspace. const workspace = new Blocky.Workspace(); if (this.snapshot.xml) { const xml = Blocky.Xml.textToDom(this.snapshot.xml); Blocky.Xml.domToWorkspace(xml, workspace); - }; + } // Play events since the last time the snapshot was generated. newEntries.forEach((entry) => { entry.events.forEach((event) => { @@ -300,10 +318,10 @@ class Database { const newSnapshotXml = Blocky.Xml.workspaceToDom(workspace, false); const newSnapshotText = Blocky.Xml.domToText(newSnapshotXml); this.snapshot.xml = newSnapshotText; - this.snapshot.serverId = newEntries[newEntries.length -1].serverId; + this.snapshot.serverId = newEntries[newEntries.length - 1].serverId; resolve(); }); - }; -}; + } +} module.exports = new Database(); diff --git a/examples/blockly-rtc/server/db.js b/examples/blockly-rtc/server/db.js index 66558d807f..fb030705a7 100644 --- a/examples/blockly-rtc/server/db.js +++ b/examples/blockly-rtc/server/db.js @@ -25,25 +25,25 @@ const sqlite3 = require('@vscode/sqlite3'); const db = new sqlite3.Database('./eventsdb.sqlite', (err) => { if (err) { return console.error(err.message); - }; + } console.log('successful connection'); const eventsDbSql = `CREATE TABLE IF NOT EXISTS eventsdb( serverId INTEGER PRIMARY KEY, workspaceId TEXT, entryNumber INTEGER, events BLOB);`; - db.run(eventsDbSql, function(err) { + db.run(eventsDbSql, function (err) { if (err) { return console.error(err.message); - }; + } }); const userTableSql = `CREATE TABLE IF NOT EXISTS users( workspaceId TEXT UNIQUE, lastEntryNumber INTEGER, - position TEXT);` - db.run(userTableSql, function(err) { + position TEXT);`; + db.run(userTableSql, function (err) { if (err) { return console.error(err.message); - }; + } }); }); -module.exports = db; \ No newline at end of file +module.exports = db; diff --git a/examples/blockly-rtc/server/http/events_handlers.js b/examples/blockly-rtc/server/http/events_handlers.js index 5defc04315..4ec33b9b87 100644 --- a/examples/blockly-rtc/server/http/events_handlers.js +++ b/examples/blockly-rtc/server/http/events_handlers.js @@ -36,13 +36,13 @@ async function queryEventsHandler(res, serverId) { const entries = await database.query(serverId); res.setHeader('Content-Type', 'application/json'); res.statusCode = 200; - res.write(JSON.stringify({ entries })); + res.write(JSON.stringify({entries})); res.end(); } catch { res.statusCode = 401; res.end(); - }; -}; + } +} /** * Handler for an events POST request. Add an entry to the database. @@ -53,19 +53,19 @@ async function queryEventsHandler(res, serverId) { async function addEventsHandler(req, res) { try { const data = []; - req.on('data', chunk => { + req.on('data', (chunk) => { data.push(chunk); }); req.on('end', async () => { - await database.addToServer(JSON.parse(data).entry) + await database.addToServer(JSON.parse(data).entry); res.statusCode = 200; res.end(); }); } catch { res.statusCode = 401; res.end(); - }; -}; + } +} /** * Handler for a snapshot GET request. Get the latest snapshot of the @@ -78,13 +78,13 @@ async function getSnapshotHandler(res) { const snapshot = await database.getSnapshot(); res.setHeader('Content-Type', 'application/json'); res.statusCode = 200; - res.write(JSON.stringify({ snapshot })); + res.write(JSON.stringify({snapshot})); res.end(); } catch { res.statusCode = 401; res.end(); - }; -}; + } +} module.exports.queryEventsHandler = queryEventsHandler; module.exports.addEventsHandler = addEventsHandler; diff --git a/examples/blockly-rtc/server/http/users_handlers.js b/examples/blockly-rtc/server/http/users_handlers.js index 030e7bf6e1..6c3cd9a596 100644 --- a/examples/blockly-rtc/server/http/users_handlers.js +++ b/examples/blockly-rtc/server/http/users_handlers.js @@ -24,16 +24,16 @@ const database = require('../Database'); - /** - * Handler for a users PUT request. Update a user's position in the users table. - * @param {!Object} req The HTTP request object. - * @param {!Object} res The HTTP response object. - * @private - */ +/** + * Handler for a users PUT request. Update a user's position in the users table. + * @param {!Object} req The HTTP request object. + * @param {!Object} res The HTTP response object. + * @private + */ async function updatePositionHandler(req, res) { try { const data = []; - req.on('data', chunk => { + req.on('data', (chunk) => { data.push(chunk); }); req.on('end', async () => { @@ -45,8 +45,8 @@ async function updatePositionHandler(req, res) { } catch { res.statusCode = 401; res.end(); - }; -}; + } +} /** * Handler for a getPositionUpdates message. Query the database for a @@ -60,13 +60,13 @@ async function getPositionUpdatesHandler(res, workspaceId) { const positionUpdates = await database.getPositionUpdates(workspaceId); res.setHeader('Content-Type', 'application/json'); res.statusCode = 200; - res.write(JSON.stringify({ positionUpdates })); + res.write(JSON.stringify({positionUpdates})); res.end(); } catch { res.statusCode = 401; res.end(); - }; -}; + } +} module.exports.updatePositionHandler = updatePositionHandler; module.exports.getPositionUpdatesHandler = getPositionUpdatesHandler; diff --git a/examples/blockly-rtc/server/http_server.js b/examples/blockly-rtc/server/http_server.js index 292ba55de5..c8587ccfd0 100644 --- a/examples/blockly-rtc/server/http_server.js +++ b/examples/blockly-rtc/server/http_server.js @@ -28,22 +28,39 @@ const UsersHandlers = require('./http/users_handlers'); const PORT = 3001; -http.createServer(async (req, res) => { - const parsedUrl = url.parse(req.url, true); - if (req.method === 'GET' && parsedUrl.pathname === '/api/events/query') { - await EventsHandlers.queryEventsHandler(res, parsedUrl.query.serverId); - } else if (req.method === 'POST' && parsedUrl.pathname === '/api/events/add') { - await EventsHandlers.addEventsHandler(req, res); - } else if (req.method === 'GET' && parsedUrl.pathname === '/api/snapshot/query') { - await EventsHandlers.getSnapshotHandler(res); - } else if (req.method === 'GET' && parsedUrl.pathname === '/api/users/position/query') { - await UsersHandlers.getPositionUpdatesHandler(res, parsedUrl.query.workspaceId); - } else if (req.method === 'PUT' && parsedUrl.pathname === '/api/users/position/update') { - await UsersHandlers.updatePositionHandler(req, res); - } else { - res.statusCode = 404; - res.end(); - }; -}).listen(PORT, () => { +http + .createServer(async (req, res) => { + const parsedUrl = url.parse(req.url, true); + if (req.method === 'GET' && parsedUrl.pathname === '/api/events/query') { + await EventsHandlers.queryEventsHandler(res, parsedUrl.query.serverId); + } else if ( + req.method === 'POST' && + parsedUrl.pathname === '/api/events/add' + ) { + await EventsHandlers.addEventsHandler(req, res); + } else if ( + req.method === 'GET' && + parsedUrl.pathname === '/api/snapshot/query' + ) { + await EventsHandlers.getSnapshotHandler(res); + } else if ( + req.method === 'GET' && + parsedUrl.pathname === '/api/users/position/query' + ) { + await UsersHandlers.getPositionUpdatesHandler( + res, + parsedUrl.query.workspaceId, + ); + } else if ( + req.method === 'PUT' && + parsedUrl.pathname === '/api/users/position/update' + ) { + await UsersHandlers.updatePositionHandler(req, res); + } else { + res.statusCode = 404; + res.end(); + } + }) + .listen(PORT, () => { console.log('server start at port 3001'); -}); + }); diff --git a/examples/blockly-rtc/server/websocket/events_handlers.js b/examples/blockly-rtc/server/websocket/events_handlers.js index 474950a996..ee9c6d3755 100644 --- a/examples/blockly-rtc/server/websocket/events_handlers.js +++ b/examples/blockly-rtc/server/websocket/events_handlers.js @@ -35,7 +35,7 @@ const database = require('../Database'); async function getEventsHandler(serverId, callback) { const entries = await database.query(serverId); callback(entries); -}; +} /** * Handler for an addEvents message. Add an entry to the database. @@ -47,7 +47,7 @@ async function getEventsHandler(serverId, callback) { async function addEventsHandler(entry, callback) { const serverId = await database.addToServer(entry); callback(serverId); -}; +} /** * Handler for a getSnapshot message. Get the latest snapshot of the workspace. @@ -58,7 +58,7 @@ async function addEventsHandler(entry, callback) { async function getSnapshotHandler(callback) { const snapshot = await database.getSnapshot(); callback(snapshot); -}; +} module.exports.getEventsHandler = getEventsHandler; module.exports.addEventsHandler = addEventsHandler; diff --git a/examples/blockly-rtc/server/websocket/users_handlers.js b/examples/blockly-rtc/server/websocket/users_handlers.js index 313ec061c0..17d9cc368e 100644 --- a/examples/blockly-rtc/server/websocket/users_handlers.js +++ b/examples/blockly-rtc/server/websocket/users_handlers.js @@ -39,7 +39,7 @@ async function updatePositionHandler(user, positionUpdate, callback) { await database.updatePosition(positionUpdate); callback(); user.broadcast.emit('broadcastPosition', [positionUpdate]); -}; +} /** * Handler for a getPositionUpdates message. Query the database for a @@ -52,7 +52,7 @@ async function updatePositionHandler(user, positionUpdate, callback) { async function getPositionUpdatesHandler(workspaceId, callback) { const positionUpdates = await database.getPositionUpdates(workspaceId); callback(positionUpdates); -}; +} /** * Handler for a connectUser message. Attach the workspaceId to the user and @@ -70,11 +70,11 @@ async function connectUserHandler(user, workspaceId, callback) { position: { type: null, blockId: null, - fieldName: null + fieldName: null, }, }; await updatePositionHandler(user, positionUpdate, callback); -}; +} /** * Handler for a disconnect. Delete the user from the users table. @@ -86,7 +86,7 @@ async function connectUserHandler(user, workspaceId, callback) { async function disconnectUserHandler(workspaceId, callback) { await database.deleteUser(workspaceId); callback(); -}; +} module.exports.updatePositionHandler = updatePositionHandler; module.exports.getPositionUpdatesHandler = getPositionUpdatesHandler; diff --git a/examples/blockly-rtc/server/websocket_server.js b/examples/blockly-rtc/server/websocket_server.js index 0dc56bc007..58b84bf08b 100644 --- a/examples/blockly-rtc/server/websocket_server.js +++ b/examples/blockly-rtc/server/websocket_server.js @@ -29,12 +29,12 @@ const UsersHandlers = require('./websocket/users_handlers'); const WS_PORT = 3001; -const server = http.createServer(function(request, response) { +const server = http.createServer(function (request, response) { response.writeHead(404); response.end(); }); -server.listen(WS_PORT, function() { +server.listen(WS_PORT, function () { console.log('server start at port 3001'); }); @@ -83,4 +83,4 @@ async function onConnect_(user) { user.on('getSnapshot', async (callback) => { await EventsHandlers.getSnapshotHandler(callback); }); -}; +} diff --git a/examples/blockly-rtc/src/Position.js b/examples/blockly-rtc/src/Position.js index 2d1ec6d82d..169a8f5688 100644 --- a/examples/blockly-rtc/src/Position.js +++ b/examples/blockly-rtc/src/Position.js @@ -27,7 +27,7 @@ export default class Position { this.type = type; this.blockId = blockId; this.fieldName = fieldName; - }; + } /** * Create a Position from an event. Currently supports creating Positions for @@ -39,15 +39,19 @@ export default class Position { static fromEvent(event) { if (event.type === Blockly.Events.SELECTED) { return this.fromSelectedUiEvent_( - /** @type {!Blockly.Events.Selected} */ (event)); - } else if (event.type === Blockly.Events.CHANGE && - event.element === 'field') { + /** @type {!Blockly.Events.Selected} */ (event), + ); + } else if ( + event.type === Blockly.Events.CHANGE && + event.element === 'field' + ) { return this.fromFieldChangeEvent_( - /** @type {!Blockly.Events.Change} */ (event)); + /** @type {!Blockly.Events.Change} */ (event), + ); } else { throw Error('Cannot create position from this event.'); } - }; + } /** * Create a Position from a Blockly UI event. @@ -62,7 +66,7 @@ export default class Position { const blockId = event.newElementId; const fieldName = null; return new Position(type, blockId, fieldName); - }; + } /** * Create a Position from a Blockly Change event. @@ -75,7 +79,7 @@ export default class Position { const blockId = event.blockId; const fieldName = event.name; return new Position(type, blockId, fieldName); - }; + } /** * Decode the JSON into a Position. @@ -85,7 +89,7 @@ export default class Position { */ static fromJson(json) { return new Position(json.type, json.blockId, json.fieldName); - }; + } /** * Check if the combination of Position properties describe a viable position. @@ -99,8 +103,8 @@ export default class Position { return true; } else { return false; - }; - }; + } + } /** * Create a Marker at the Position. @@ -113,7 +117,7 @@ export default class Position { const node = this.createNode(workspace); marker.setCurNode(node); return marker; - }; + } /** * Create an ASTNode pointing to the Position. @@ -125,13 +129,13 @@ export default class Position { createNode(workspace) { if (!this.hasValidPosition()) { return null; - }; + } if (this.type == 'BLOCK') { return this.createBlockNode_(workspace); } else if (this.type == 'FIELD') { return this.createFieldNode_(workspace); - }; - }; + } + } /** * Create an ASTNode pointing to a block. @@ -142,7 +146,7 @@ export default class Position { createBlockNode_(workspace) { const block = workspace.getBlockById(this.blockId); return Blockly.ASTNode.createBlockNode(block); - }; + } /** * Create an ASTNode pointing to a field. @@ -154,5 +158,5 @@ export default class Position { const block = workspace.getBlockById(this.blockId); const field = block.getField(this.fieldName); return Blockly.ASTNode.createFieldNode(field); - }; -}; + } +} diff --git a/examples/blockly-rtc/src/UserDataManager.js b/examples/blockly-rtc/src/UserDataManager.js index c5df722763..1630ec70d0 100644 --- a/examples/blockly-rtc/src/UserDataManager.js +++ b/examples/blockly-rtc/src/UserDataManager.js @@ -24,16 +24,26 @@ import * as Blockly from 'blockly'; import Position from './Position'; export default class UserDataManager { - constructor(workspaceId, sendPositionUpdate, getPositionUpdates, - getBroadcastPositionUpdates) { + constructor( + workspaceId, + sendPositionUpdate, + getPositionUpdates, + getBroadcastPositionUpdates, + ) { this.workspaceId = workspaceId; this.colours = [ - '#fcba03', '#03fc20', '#03f0fc', '#035efc', '#5603fc', '#fc03d2']; + '#fcba03', + '#03fc20', + '#03f0fc', + '#035efc', + '#5603fc', + '#fc03d2', + ]; this.sendPositionUpdate = sendPositionUpdate; this.getPositionUpdates = getPositionUpdates; this.getBroadcastPositionUpdates = getBroadcastPositionUpdates; this.getUserDisconnects = null; - }; + } /** * Initialize the workspace by creating and registering markers for all active @@ -49,11 +59,11 @@ export default class UserDataManager { this.getBroadcastPositionUpdates(this.updateMarkerPositions_.bind(this)); } else { this.pollServer_(); - }; + } if (this.getUserDisconnects) { this.getUserDisconnects(this.disposeMarker_.bind(this)); - }; - }; + } + } /** * Set handlers that enable the detection of user presence on the workspace @@ -67,7 +77,7 @@ export default class UserDataManager { async setPresenceHandlers(connectUserHandler, getUserDisconnectsHandler) { this.getUserDisconnects = getUserDisconnectsHandler; await connectUserHandler(this.workspaceId); - }; + } /** * Create a PositionUpdate from a Blockly event and send it to the server. @@ -79,9 +89,9 @@ export default class UserDataManager { const position = Position.fromEvent(event); await this.sendPositionUpdate({ workspaceId: this.workspaceId, - position: position + position: position, }); - }; + } /** * Periodically query the database for PositionUpdates. @@ -92,8 +102,8 @@ export default class UserDataManager { await this.updateMarkerPositions_(positionUpdates); setTimeout(() => { this.pollServer_(); - }, 5000) - }; + }, 5000); + } /** * Get the workspace that corresponds to workspaceId. @@ -102,7 +112,7 @@ export default class UserDataManager { */ getWorkspace_() { return Blockly.Workspace.getById(this.workspaceId); - }; + } /** * Get the MarkerManager for the workspace. @@ -111,9 +121,10 @@ export default class UserDataManager { * @private */ getMarkerManager_() { - return this.getWorkspace_() ? - this.getWorkspace_().getMarkerManager(): null; - }; + return this.getWorkspace_() + ? this.getWorkspace_().getMarkerManager() + : null; + } /** * Get a color to assign to a new user marker. @@ -124,7 +135,7 @@ export default class UserDataManager { const colour = this.colours.shift(); this.colours.push(colour); return colour; - }; + } /** * Create a Marker with a unique color and register it. @@ -138,14 +149,14 @@ export default class UserDataManager { createMarker_(positionUpdate) { if (!this.getMarkerManager_()) { throw Error('Cannot create a Marker without Blockly MarkerManager.'); - }; + } const position = positionUpdate.position; const marker = position.toMarker(this.getWorkspace_()); marker.colour = this.getColour_(); - this.getMarkerManager_().registerMarker(positionUpdate.workspaceId, marker) + this.getMarkerManager_().registerMarker(positionUpdate.workspaceId, marker); marker.setCurNode(position.createNode(this.getWorkspace_())); return marker; - }; + } /** * Unregister the Marker from Blockly MarkerManager and dispose the marker. @@ -157,11 +168,11 @@ export default class UserDataManager { disposeMarker_(workspaceId) { if (!this.getMarkerManager_()) { throw Error('Cannot dispose of a Marker without Blockly MarkerManager.'); - }; + } try { this.getMarkerManager_().unregisterMarker(workspaceId); - } catch {}; - }; + } catch {} + } /** * Get the Marker that corresponds to the given user. @@ -171,9 +182,10 @@ export default class UserDataManager { * @private */ getMarker(workspaceId) { - return this.getMarkerManager_() ? - this.getMarkerManager_().getMarker(workspaceId) : null; - }; + return this.getMarkerManager_() + ? this.getMarkerManager_().getMarker(workspaceId) + : null; + } /** * Updates curNode on a Marker based on MarkerPosition. @@ -183,7 +195,8 @@ export default class UserDataManager { */ async updateMarkerPositions_(positionUpdates) { const filteredPositionUpdates = positionUpdates.filter( - positionUpdate => positionUpdate.workspaceId != this.workspaceId); + (positionUpdate) => positionUpdate.workspaceId != this.workspaceId, + ); filteredPositionUpdates.forEach((positionUpdate) => { const position = positionUpdate.position; const node = position.createNode(this.getWorkspace_()); @@ -191,7 +204,7 @@ export default class UserDataManager { this.getMarker(positionUpdate.workspaceId).setCurNode(node); } else { this.createMarker_(positionUpdate).setCurNode(node); - }; + } }); - }; -}; + } +} diff --git a/examples/blockly-rtc/src/WorkspaceClient.js b/examples/blockly-rtc/src/WorkspaceClient.js index 4fa5a024bb..f08b18a944 100644 --- a/examples/blockly-rtc/src/WorkspaceClient.js +++ b/examples/blockly-rtc/src/WorkspaceClient.js @@ -30,7 +30,13 @@ import EventEmitter from 'events'; * client corresponds to. */ export default class WorkspaceClient { - constructor(workspaceId, getSnapshotHandler, getEventsHandler, addEventsHandler, broadcastEventsHandler) { + constructor( + workspaceId, + getSnapshotHandler, + getEventsHandler, + addEventsHandler, + broadcastEventsHandler, + ) { this.workspaceId = workspaceId; this.lastSync = 0; this.inProgress = []; @@ -45,8 +51,7 @@ export default class WorkspaceClient { this.addEventsHandler = addEventsHandler; this.broadcastEventsHandler = broadcastEventsHandler; this.listener = new EventEmitter(); - }; - + } /** * Initiate the workspace by loading the current workspace and activating the @@ -69,8 +74,8 @@ export default class WorkspaceClient { this.broadcastEventsHandler(this.addServerEvents_.bind(this)); } else { this.pollServer_(); - }; - }; + } + } /** * Add an event to activeChanges. @@ -79,7 +84,7 @@ export default class WorkspaceClient { */ addEvent(event) { this.activeChanges.push(event); - }; + } /** * Add the events in activeChanges to notSent. Initiates process for sending @@ -90,7 +95,7 @@ export default class WorkspaceClient { this.notSent = this.notSent.concat(this.activeChanges); this.activeChanges = []; this.updateServer_(); - }; + } /** * Send local changes to the server. Continuously runs until all local changes @@ -100,13 +105,13 @@ export default class WorkspaceClient { async updateServer_() { if (this.writeInProgress || this.notSent.length == 0) { return; - }; + } this.writeInProgress = true; while (this.notSent.length > 0) { await this.writeToDatabase_(); - }; + } this.writeInProgress = false; - }; + } /** * Trigger an API call to write events to the database. @@ -121,9 +126,8 @@ export default class WorkspaceClient { } catch { this.endWrite_(false); throw Error('Failed to write to database.'); - }; - }; - + } + } /** * Change status of WorkspaceClient in preparation for the network call. @@ -140,7 +144,7 @@ export default class WorkspaceClient { }); this.counter += 1; this.notSent = []; - }; + } /** * Change status of WorkspaceClient once network call completes. @@ -155,9 +159,9 @@ export default class WorkspaceClient { this.notSent = this.inProgress[0].events.concat(this.notSent); this.inProgress = []; this.counter -= 1; - }; + } this.writeInProgress = false; - }; + } /** * Periodically query the database for new server events and add them to @@ -167,8 +171,10 @@ export default class WorkspaceClient { async pollServer_() { const entries = await this.queryDatabase_(); await this.addServerEvents_(entries); - setTimeout(() => {this.pollServer_()}, 5000); - }; + setTimeout(() => { + this.pollServer_(); + }, 5000); + } /** * Trigger an API call to query events from the database. @@ -180,8 +186,8 @@ export default class WorkspaceClient { return await this.getEventsHandler(this.lastSync); } catch { return []; - }; - }; + } + } /** * Add newServerEvents to the end of this.serverEvents and initiate process of @@ -196,14 +202,14 @@ export default class WorkspaceClient { async addServerEvents_(newServerEvents) { if (newServerEvents.length == 0) { return; - }; + } if (newServerEvents[0].serverId != this.lastSync + 1) { newServerEvents = await this.queryDatabase_(); - }; + } this.lastSync = newServerEvents[newServerEvents.length - 1].serverId; this.serverEvents.push.apply(this.serverEvents, newServerEvents); this.updateWorkspace_(); - }; + } /** * Send server events to the local workspace. Continuously runs until all @@ -213,7 +219,7 @@ export default class WorkspaceClient { async updateWorkspace_() { if (this.updateInProgress || this.serverEvents == 0) { return; - }; + } this.updateInProgress = true; while (this.serverEvents.length > 0) { const newServerEvents = this.serverEvents; @@ -221,8 +227,8 @@ export default class WorkspaceClient { const eventQueue = await this.processQueryResults_(newServerEvents); this.updateInProgress = false; this.listener.emit('runEvents', eventQueue); - }; - }; + } + } /** * Compare the order of events in the entries retrieved from the database to @@ -238,7 +244,7 @@ export default class WorkspaceClient { if (entries.length == 0) { return eventQueue; - }; + } this.lastSync = entries[entries.length - 1].serverId; @@ -246,55 +252,76 @@ export default class WorkspaceClient { if (this.notSent.length == 0 && this.inProgress.length == 0) { entries.forEach((entry) => { eventQueue.push.apply( - eventQueue, this.createWorkspaceActions_(entry.events, true)); + eventQueue, + this.createWorkspaceActions_(entry.events, true), + ); }); return eventQueue; - }; + } // Common root, remove common events from server events. - if (this.inProgress.length > 0 - && entries[0].workspaceId == this.workspaceId - && entries[0].entryNumber == this.inProgress[0].entryNumber) { + if ( + this.inProgress.length > 0 && + entries[0].workspaceId == this.workspaceId && + entries[0].entryNumber == this.inProgress[0].entryNumber + ) { entries.shift(); this.inProgress = []; - }; + } if (entries.length > 0) { // Undo local events. eventQueue.push.apply( - eventQueue, - this.createWorkspaceActions_(this.notSent.slice().reverse(), false)); + eventQueue, + this.createWorkspaceActions_(this.notSent.slice().reverse(), false), + ); if (this.inProgress.length > 0) { - this.inProgress.slice().reverse().forEach((entry) => { - eventQueue.push.apply(eventQueue, this.createWorkspaceActions_( - entry.events.slice().reverse(), false)); - }); - }; + this.inProgress + .slice() + .reverse() + .forEach((entry) => { + eventQueue.push.apply( + eventQueue, + this.createWorkspaceActions_( + entry.events.slice().reverse(), + false, + ), + ); + }); + } // Apply server events. entries.forEach((entry) => { - if (this.inProgress.length > 0 - && entry.workspaceId == this.inProgress[0].workspaceId - && entry.entryNumber == this.inProgress[0].entryNumber) { + if ( + this.inProgress.length > 0 && + entry.workspaceId == this.inProgress[0].workspaceId && + entry.entryNumber == this.inProgress[0].entryNumber + ) { eventQueue.push.apply( - eventQueue, - this.createWorkspaceActions_(this.inProgress[0].events, true)); + eventQueue, + this.createWorkspaceActions_(this.inProgress[0].events, true), + ); this.inProgress.shift(); } else { eventQueue.push.apply( - eventQueue, this.createWorkspaceActions_(entry.events, true)); - }; + eventQueue, + this.createWorkspaceActions_(entry.events, true), + ); + } }); // Reapply remaining local changes. if (this.inProgress.length > 0) { eventQueue.push.apply( - eventQueue, - this.createWorkspaceActions_(this.inProgress[0].events, true)); - }; + eventQueue, + this.createWorkspaceActions_(this.inProgress[0].events, true), + ); + } eventQueue.push.apply( - eventQueue, this.createWorkspaceActions_(this.notSent, true)); - }; + eventQueue, + this.createWorkspaceActions_(this.notSent, true), + ); + } return eventQueue; - }; + } /** * Create WorkspaceActions from a list of events. @@ -309,9 +336,9 @@ export default class WorkspaceClient { events.forEach((event) => { eventQueue.push({ event: event, - forward: forward + forward: forward, }); }); return eventQueue; - }; -}; + } +} diff --git a/examples/blockly-rtc/src/http/index.js b/examples/blockly-rtc/src/http/index.js index b2da4d482b..bef5153a06 100644 --- a/examples/blockly-rtc/src/http/index.js +++ b/examples/blockly-rtc/src/http/index.js @@ -88,35 +88,43 @@ const toolbox = { fields: { VAR: { name: 'text', - } + }, }, }, }, }, - } - ] -} + }, + ], +}; document.addEventListener('DOMContentLoaded', async () => { - const workspace = Blockly.inject('blocklyDiv', - { - toolbox: toolbox, - media: 'media/', - }); + const workspace = Blockly.inject('blocklyDiv', { + toolbox: toolbox, + media: 'media/', + }); const workspaceClient = new WorkspaceClient( - workspace.id, getSnapshot, getEvents, writeEvents); + workspace.id, + getSnapshot, + getEvents, + writeEvents, + ); workspaceClient.listener.on('runEvents', (eventQueue) => { runEvents_(eventQueue); }); await workspaceClient.start(); - const userDataManager = new UserDataManager(workspace.id, sendPositionUpdate, - getPositionUpdates); + const userDataManager = new UserDataManager( + workspace.id, + sendPositionUpdate, + getPositionUpdates, + ); await userDataManager.start(); workspace.addChangeListener((event) => { - if (event.type === Blockly.Events.SELECTED || - (event.type === Blockly.Events.CHANGE && event.element === 'field')) { + if ( + event.type === Blockly.Events.SELECTED || + (event.type === Blockly.Events.CHANGE && event.element === 'field') + ) { userDataManager.handleEvent(event); } if (event.isUiEvent) { @@ -141,5 +149,5 @@ document.addEventListener('DOMContentLoaded', async () => { workspaceAction.event.run(workspaceAction.forward); Blockly.Events.enable(); }); - }; + } }); diff --git a/examples/blockly-rtc/src/http/user_data_handlers.js b/examples/blockly-rtc/src/http/user_data_handlers.js index 825e676354..210f3be7ad 100644 --- a/examples/blockly-rtc/src/http/user_data_handlers.js +++ b/examples/blockly-rtc/src/http/user_data_handlers.js @@ -31,8 +31,9 @@ import Position from '../Position'; * @public */ export async function getPositionUpdates(workspaceId) { - const response = workspaceId ? await fetch('/api/users/position/query?workspaceId=' + workspaceId) : - await fetch('/api/users/position/query?'); + const response = workspaceId + ? await fetch('/api/users/position/query?workspaceId=' + workspaceId) + : await fetch('/api/users/position/query?'); const responseJson = await response.json(); if (response.status === 200) { const positionUpdates = responseJson.positionUpdates; @@ -42,8 +43,8 @@ export async function getPositionUpdates(workspaceId) { return positionUpdates; } else { throw 'Failed to get PositionUpdates.'; - }; -}; + } +} /** * Update the position of a user in the database. @@ -55,11 +56,11 @@ export async function getPositionUpdates(workspaceId) { export async function sendPositionUpdate(positionUpdate) { const response = await fetch('/api/users/position/update', { method: 'PUT', - body: JSON.stringify({ positionUpdate }) + body: JSON.stringify({positionUpdate}), }); if (response.status === 200) { return; } else { throw 'Failed to update position.'; - }; -}; + } +} diff --git a/examples/blockly-rtc/src/http/workspace_client_handlers.js b/examples/blockly-rtc/src/http/workspace_client_handlers.js index 651d8e7c60..cdd21d1765 100644 --- a/examples/blockly-rtc/src/http/workspace_client_handlers.js +++ b/examples/blockly-rtc/src/http/workspace_client_handlers.js @@ -37,8 +37,8 @@ export async function getSnapshot() { return snapshot; } else { throw 'Failed to get workspace snapshot.'; - }; -}; + } +} /** * Query the database for entries since the given server id. @@ -60,8 +60,8 @@ export async function getEvents(serverId) { return entries; } else { throw 'Failed to query database.'; - }; -}; + } +} /** * Add an entry to database. @@ -74,15 +74,15 @@ export async function writeEvents(entry) { const entryJson = { workspaceId: entry.workspaceId, entryNumber: entry.entryNumber, - events: entry.events.map((event) => event.toJson()) + events: entry.events.map((event) => event.toJson()), }; const response = await fetch('/api/events/add', { method: 'POST', - body: JSON.stringify({entry: entryJson}) + body: JSON.stringify({entry: entryJson}), }); if (response.status === 200) { return; } else { throw 'Failed to write to database.'; - }; -}; + } +} diff --git a/examples/blockly-rtc/src/websocket/index.js b/examples/blockly-rtc/src/websocket/index.js index 7ab3aeddac..fd1b936580 100644 --- a/examples/blockly-rtc/src/websocket/index.js +++ b/examples/blockly-rtc/src/websocket/index.js @@ -22,9 +22,19 @@ */ import * as Blockly from 'blockly'; -import {getSnapshot, getEvents, writeEvents, getBroadcast} from './workspace_client_handlers'; -import {getPositionUpdates, sendPositionUpdate, getBroadcastPositionUpdates, - connectUser, getUserDisconnects} from './user_data_handlers'; +import { + getSnapshot, + getEvents, + writeEvents, + getBroadcast, +} from './workspace_client_handlers'; +import { + getPositionUpdates, + sendPositionUpdate, + getBroadcastPositionUpdates, + connectUser, + getUserDisconnects, +} from './user_data_handlers'; import UserDataManager from '../UserDataManager'; import WorkspaceClient from '../WorkspaceClient'; @@ -88,36 +98,46 @@ const toolbox = { fields: { VAR: { name: 'text', - } + }, }, }, }, }, - } - ] -} + }, + ], +}; document.addEventListener('DOMContentLoaded', async () => { - const workspace = Blockly.inject('blocklyDiv', - { - toolbox: toolbox, - media: 'media/', - }); + const workspace = Blockly.inject('blocklyDiv', { + toolbox: toolbox, + media: 'media/', + }); const workspaceClient = new WorkspaceClient( - workspace.id, getSnapshot, getEvents, writeEvents, getBroadcast); + workspace.id, + getSnapshot, + getEvents, + writeEvents, + getBroadcast, + ); workspaceClient.listener.on('runEvents', (eventQueue) => { runEvents_(eventQueue); }); await workspaceClient.start(); - const userDataManager = new UserDataManager(workspace.id, sendPositionUpdate, - getPositionUpdates, getBroadcastPositionUpdates); + const userDataManager = new UserDataManager( + workspace.id, + sendPositionUpdate, + getPositionUpdates, + getBroadcastPositionUpdates, + ); await userDataManager.setPresenceHandlers(connectUser, getUserDisconnects); await userDataManager.start(); workspace.addChangeListener((event) => { - if (event.type === Blockly.Events.SELECTED || - (event.type === Blockly.Events.CHANGE && event.element === 'field')) { + if ( + event.type === Blockly.Events.SELECTED || + (event.type === Blockly.Events.CHANGE && event.element === 'field') + ) { userDataManager.handleEvent(event); } if (event.isUiEvent) { @@ -142,5 +162,5 @@ document.addEventListener('DOMContentLoaded', async () => { workspaceAction.event.run(workspaceAction.forward); Blockly.Events.enable(); }); - }; + } }); diff --git a/examples/blockly-rtc/src/websocket/user_data_handlers.js b/examples/blockly-rtc/src/websocket/user_data_handlers.js index bef09297b2..7427f9df33 100644 --- a/examples/blockly-rtc/src/websocket/user_data_handlers.js +++ b/examples/blockly-rtc/src/websocket/user_data_handlers.js @@ -1,4 +1,3 @@ - /** * @license * @@ -44,7 +43,7 @@ export async function getPositionUpdates(workspaceId) { resolve(positionUpdates); }); }); -}; +} /** * Update the position of a user in the database. @@ -59,7 +58,7 @@ export async function sendPositionUpdate(positionUpdate) { resolve(); }); }); -}; +} /** * Listen for PositionUpdates broadcast by the server. @@ -68,13 +67,13 @@ export async function sendPositionUpdate(positionUpdate) { * @public */ export async function getBroadcastPositionUpdates(callback) { - socket.on('broadcastPosition', async (positionUpdates)=> { + socket.on('broadcastPosition', async (positionUpdates) => { positionUpdates.forEach((positionUpdate) => { positionUpdate.position = Position.fromJson(positionUpdate.position); }); await callback(positionUpdates); }); -}; +} /** * Enable tracking of the user by sending the workspaceId to the server. @@ -83,11 +82,11 @@ export async function getBroadcastPositionUpdates(callback) { */ export async function connectUser(workspaceId) { return new Promise((resolve, reject) => { - socket.emit('connectUser', workspaceId, ()=> { + socket.emit('connectUser', workspaceId, () => { resolve(); }); }); -}; +} /** * Listen for user disconnects broadcast by the server. @@ -96,7 +95,7 @@ export async function connectUser(workspaceId) { * @public */ export function getUserDisconnects(callback) { - socket.on('disconnectUser', async (workspaceId)=> { + socket.on('disconnectUser', async (workspaceId) => { await callback(workspaceId); }); -}; +} diff --git a/examples/blockly-rtc/src/websocket/workspace_client_handlers.js b/examples/blockly-rtc/src/websocket/workspace_client_handlers.js index 5f3aba0b60..fa62525cca 100644 --- a/examples/blockly-rtc/src/websocket/workspace_client_handlers.js +++ b/examples/blockly-rtc/src/websocket/workspace_client_handlers.js @@ -40,7 +40,7 @@ export async function getSnapshot() { resolve(snapshot); }); }); -}; +} /** * Query the database for entries since the given server id. @@ -60,7 +60,7 @@ export async function getEvents(serverId) { resolve(entries); }); }); -}; +} /** * Add an entry to the database. @@ -72,14 +72,14 @@ export async function writeEvents(entry) { const entryJson = { workspaceId: entry.workspaceId, entryNumber: entry.entryNumber, - events: entry.events.map((event) => event.toJson()) + events: entry.events.map((event) => event.toJson()), }; return new Promise((resolve, reject) => { socket.emit('addEvents', entryJson, () => { resolve(); }); }); -}; +} /** * Listen for events broadcast by the server. @@ -89,7 +89,7 @@ export async function writeEvents(entry) { * @public */ export function getBroadcast(callback) { - socket.on('broadcastEvents', (entries)=> { + socket.on('broadcastEvents', (entries) => { entries.forEach((entry) => { entry.events = entry.events.map((entry) => { return Blockly.Events.fromJson(entry, Blockly.getMainWorkspace()); @@ -97,4 +97,4 @@ export function getBroadcast(callback) { }); callback(entries); }); -}; +} diff --git a/examples/blockly-rtc/test/database_test.js b/examples/blockly-rtc/test/database_test.js index 47e6884170..e7afbd45ad 100644 --- a/examples/blockly-rtc/test/database_test.js +++ b/examples/blockly-rtc/test/database_test.js @@ -28,65 +28,77 @@ const database = require('../server/Database'); suite('Database', () => { teardown(() => { sinon.restore(); - }) + }); suite('getSnapshot()', () => { setup(() => { - this.xmlText0 = ''; - this.xmlText1 = '' + - '' + - ''; - this.xmlText2 = '' + - '' + - '' + - '' + - 'EQ' + - '' + this.xmlText0 = + ''; + this.xmlText1 = + '' + + '' + + ''; + this.xmlText2 = + '' + + '' + + '' + + '' + + 'EQ' + + ''; this.entry1 = { serverId: 1, - events: [{ - type: "create", - group: "zH!7f,gfyd$ni%`Wq`Y|", - blockId: "^EzM:}wIx;MjBTcxQ@oB", - xml: '', - ids: ["^EzM:}wIx;MjBTcxQ@oB"] - }, { - type: "move", - group: "zH!7f,gfyd$ni%`Wq`Y|", - blockId: "^EzM:}wIx;MjBTcxQ@oB", - newCoordinate: "228,58" - }, { - type: "move", - group: "zH!7f,gfyd$ni%`Wq`Y|", - blockId: "^EzM:}wIx;MjBTcxQ@oB", - newCoordinate: "238,63" - }] + ids: ['^EzM:}wIx;MjBTcxQ@oB'], + }, + { + type: 'move', + group: 'zH!7f,gfyd$ni%`Wq`Y|', + blockId: '^EzM:}wIx;MjBTcxQ@oB', + newCoordinate: '228,58', + }, + { + type: 'move', + group: 'zH!7f,gfyd$ni%`Wq`Y|', + blockId: '^EzM:}wIx;MjBTcxQ@oB', + newCoordinate: '238,63', + }, + ], }; this.entry2 = { serverId: 2, - events: [{ - type: "create", - group: "|r115vF03q}F@7l]*PcB", - blockId: "oNVDtK2cF?jWDM+.gCR3", - xml: '' + 'EQ', - ids: ["oNVDtK2cF?jWDM+.gCR3"] - }, { - type: "move", - group: "|r115vF03q}F@7l]*PcB", - blockId: "oNVDtK2cF?jWDM+.gCR3", - newParentId: "^EzM:}wIx;MjBTcxQ@oB", - newInputName: "IF0" - }] + ids: ['oNVDtK2cF?jWDM+.gCR3'], + }, + { + type: 'move', + group: '|r115vF03q}F@7l]*PcB', + blockId: 'oNVDtK2cF?jWDM+.gCR3', + newParentId: '^EzM:}wIx;MjBTcxQ@oB', + newInputName: 'IF0', + }, + ], }; }); test('No previous snapshot, no new events', async () => { database.snapshot = { xml: this.xmlText0, - serverId: 0 + serverId: 0, }; sinon.stub(database, 'query').resolves([]); const newSnapshot = await database.getSnapshot(); @@ -98,7 +110,7 @@ suite('Database', () => { test('No previous snapshot, new events', async () => { database.snapshot = { xml: this.xmlText0, - serverId: 0 + serverId: 0, }; sinon.stub(database, 'query').resolves([this.entry1, this.entry2]); const newSnapshot = await database.getSnapshot(); @@ -110,7 +122,7 @@ suite('Database', () => { test('Snapshot stored, no new events.', async () => { database.snapshot = { xml: this.xmlText1, - serverId: 1 + serverId: 1, }; sinon.stub(database, 'query').resolves([]); const newSnapshot = await database.getSnapshot(); @@ -122,7 +134,7 @@ suite('Database', () => { test('Snapshot stored, new events.', async () => { database.snapshot = { xml: this.xmlText1, - serverId: 1 + serverId: 1, }; sinon.stub(database, 'query').resolves([this.entry2]); const newSnapshot = await database.getSnapshot(); @@ -147,9 +159,9 @@ suite('Database', () => { database.getLastEntryNumber_.resolves(-1); database.runInsertQuery_.resolves(2); const entry = { - workspaceId: 'newUser', - entryNumber: '1', - events: [JSON.stringify({mockEvent:'event'})], + workspaceId: 'newUser', + entryNumber: '1', + events: [JSON.stringify({mockEvent: 'event'})], }; const serverId = await database.addToServer(entry); assert.equal(2, serverId); @@ -160,9 +172,9 @@ suite('Database', () => { database.getLastEntryNumber_.resolves(2); database.runInsertQuery_.resolves(2); const entry = { - workspaceId: 'mockUser', - entryNumber: '4', - events: [JSON.stringify({mockEvent:'event'})], + workspaceId: 'mockUser', + entryNumber: '4', + events: [JSON.stringify({mockEvent: 'event'})], }; const serverId = await database.addToServer(entry); assert.equal(2, serverId); @@ -175,7 +187,7 @@ suite('Database', () => { const entry = { workspaceId: 'mockUser', entryNumber: '3', - events: [JSON.stringify({mockEvent:'event'})], + events: [JSON.stringify({mockEvent: 'event'})], }; assert.rejects(database.addToServer(entry)); }); @@ -186,7 +198,7 @@ suite('Database', () => { const entry = { workspaceId: 'mockUser', entryNumber: '2', - events: [JSON.stringify({mockEvent:'event'})], + events: [JSON.stringify({mockEvent: 'event'})], }; const serverId = await database.addToServer(entry); assert.equal(null, serverId); @@ -199,7 +211,7 @@ suite('Database', () => { const entry = { workspaceId: 'mockUser', entryNumber: '1', - events: [JSON.stringify({mockEvent:'event'})], + events: [JSON.stringify({mockEvent: 'event'})], }; assert.rejects(database.addToServer(entry)); assert(database.runInsertQuery_.notCalled); diff --git a/examples/blockly-rtc/test/position_test.js b/examples/blockly-rtc/test/position_test.js index 7dadaac7f2..ed367c7ec3 100644 --- a/examples/blockly-rtc/test/position_test.js +++ b/examples/blockly-rtc/test/position_test.js @@ -27,18 +27,22 @@ const sinon = require('sinon'); const Position = require('../src/Position').default; suite('Position', () => { - suite('fromEvent()', () => { setup(() => { - Blockly.defineBlocksWithJsonArray([{ - 'type': 'test_block', - 'message0': 'test block' - }]); + Blockly.defineBlocksWithJsonArray([ + { + type: 'test_block', + message0: 'test block', + }, + ]); this.FAKE_WORKSPACE_ID = 'mockWorkspaceId'; - this.FAKE_BLOCK_ID = 'mockBlockId' - sinon.stub(Blockly.utils, 'genUid') - .onFirstCall().returns(this.FAKE_WORKSPACE_ID) - .onSecondCall().returns(this.FAKE_BLOCK_ID); + this.FAKE_BLOCK_ID = 'mockBlockId'; + sinon + .stub(Blockly.utils, 'genUid') + .onFirstCall() + .returns(this.FAKE_WORKSPACE_ID) + .onSecondCall() + .returns(this.FAKE_BLOCK_ID); this.workspace = new Blockly.Workspace(); this.block = new Blockly.Block(this.workspace, 'test_block'); this.field = new Blockly.Field('hello'); @@ -54,7 +58,11 @@ suite('Position', () => { test('From SELECT UI event on a block.', async () => { const event = new Blockly.Events.Ui( - this.block, 'selected', 'old', this.FAKE_BLOCK_ID); + this.block, + 'selected', + 'old', + this.FAKE_BLOCK_ID, + ); const position = Position.fromEvent(event); const expectedPosition = new Position('BLOCK', this.FAKE_BLOCK_ID, null); assert.deepEqual(position, expectedPosition); @@ -62,20 +70,33 @@ suite('Position', () => { test('From CHANGE event on a field.', async () => { const event = new Blockly.Events.Change( - this.block, 'field', 'message0', 'hello', 'goodbye'); + this.block, + 'field', + 'message0', + 'hello', + 'goodbye', + ); const position = Position.fromEvent(event); const expectedPosition = new Position( - 'FIELD', this.FAKE_BLOCK_ID, 'message0'); + 'FIELD', + this.FAKE_BLOCK_ID, + 'message0', + ); assert.deepEqual(position, expectedPosition); }); test('From other not supported event, throw error.', async () => { sinon.spy(Position, 'fromEvent'); const event = new Blockly.Events.Change( - this.block, 'comment', 'message0', 'hello', 'goodbye'); + this.block, + 'comment', + 'message0', + 'hello', + 'goodbye', + ); try { Position.fromEvent(event); - } catch {}; + } catch {} assert(Position.fromEvent.threw); }); }); @@ -85,11 +106,10 @@ suite('Position', () => { const json = { type: 'type', blockId: 'blockId', - fieldName: 'fieldName' + fieldName: 'fieldName', }; const position = Position.fromJson(json); - const expectedPosition = new Position( - 'type', 'blockId', 'fieldName'); + const expectedPosition = new Position('type', 'blockId', 'fieldName'); assert.deepEqual(position, expectedPosition); }); }); diff --git a/examples/blockly-rtc/test/user_data_manager_test.js b/examples/blockly-rtc/test/user_data_manager_test.js index ed169f6433..a5b98b6303 100644 --- a/examples/blockly-rtc/test/user_data_manager_test.js +++ b/examples/blockly-rtc/test/user_data_manager_test.js @@ -31,17 +31,25 @@ const Position = require('../src/Position').default; suite('UserDataManager', () => { setup(() => { this.userDataManager = new UserDataManager( - 'mockWorkspaceId', handlers.sendPositionUpdate, - handlers.getPositionUpdates, handlers.getBroadcastPositionUpdates); - Blockly.defineBlocksWithJsonArray([{ - 'type': 'test_block', - 'message0': 'test block' - }]); + 'mockWorkspaceId', + handlers.sendPositionUpdate, + handlers.getPositionUpdates, + handlers.getBroadcastPositionUpdates, + ); + Blockly.defineBlocksWithJsonArray([ + { + type: 'test_block', + message0: 'test block', + }, + ]); this.FAKE_WORKSPACE_ID = 'mockWorkspaceId'; this.FAKE_BLOCK_ID = 'blockId'; - sinon.stub(Blockly.utils, "genUid") - .onFirstCall().returns(this.FAKE_WORKSPACE_ID) - .onSecondCall().returns(this.FAKE_BLOCK_ID); + sinon + .stub(Blockly.utils, 'genUid') + .onFirstCall() + .returns(this.FAKE_WORKSPACE_ID) + .onSecondCall() + .returns(this.FAKE_BLOCK_ID); this.workspace = new Blockly.WorkspaceSvg({}); this.block = new Blockly.Block(this.workspace, 'test_block'); this.position = new Position('BLOCK', 'blockId', null); @@ -51,8 +59,9 @@ suite('UserDataManager', () => { this.BlocklyMarkerManager.registerMarker.callsFake((markerId, marker) => { this.BlocklyMarkerManager.markers_[markerId] = marker; }); - sinon.stub(this.workspace, 'getMarkerManager') - .returns(this.BlocklyMarkerManager); + sinon + .stub(this.workspace, 'getMarkerManager') + .returns(this.BlocklyMarkerManager); }); teardown(() => { @@ -67,7 +76,7 @@ suite('UserDataManager', () => { const positionUpdate1 = {workspaceId: 'mockId1', position: this.position}; try { this.userDataManager.createMarker_(positionUpdate1); - } catch {}; + } catch {} assert(this.userDataManager.createMarker_.threw()); }); @@ -88,7 +97,7 @@ suite('UserDataManager', () => { sinon.spy(this.userDataManager, 'disposeMarker_'); try { this.userDataManager.disposeMarker_(); - } catch {}; + } catch {} assert(this.userDataManager.disposeMarker_.threw()); }); @@ -103,14 +112,16 @@ suite('UserDataManager', () => { const marker = new Blockly.Marker(); this.BlocklyMarkerManager.markers_['mockId'] = marker; this.userDataManager.disposeMarker_('mockId'); - assert(this.BlocklyMarkerManager.unregisterMarker.calledOnceWith('mockId')); + assert( + this.BlocklyMarkerManager.unregisterMarker.calledOnceWith('mockId'), + ); }); }); suite('updateMarkerPositions', () => { setup(() => { this.BlocklyMarkerManager.markers_ = { - 'mockId': new Blockly.Marker() + mockId: new Blockly.Marker(), }; }); diff --git a/examples/blockly-rtc/test/workspace_client_test.js b/examples/blockly-rtc/test/workspace_client_test.js index 306d0d7235..24ccad8555 100644 --- a/examples/blockly-rtc/test/workspace_client_test.js +++ b/examples/blockly-rtc/test/workspace_client_test.js @@ -29,37 +29,45 @@ const WorkspaceClient = require('../src/WorkspaceClient').default; suite('WorkspaceClient', () => { setup(() => { this.workspaceClient = new WorkspaceClient( - 'mockClient', handler.getEvents, handler.writeEvents, - handler.getBroadcast); + 'mockClient', + handler.getEvents, + handler.writeEvents, + handler.getBroadcast, + ); sinon.stub(Blockly.Events, 'filter').callsFake((events) => { return events; }); }); - teardown(() => { + teardown(() => { sinon.restore(); }); suite('writeToDatabase_()', () => { test('Write succeeds, events move from notSent to inProgress.', async () => { sinon.stub(this.workspaceClient, 'addEventsHandler').resolves(); - this.workspaceClient.notSent = [1,2,3]; + this.workspaceClient.notSent = [1, 2, 3]; await this.workspaceClient.writeToDatabase_(); assert.deepStrictEqual([], this.workspaceClient.notSent); - assert.deepStrictEqual([{ - workspaceId: 'mockClient', - entryNumber: 0, - events: [1,2,3] - }], this.workspaceClient.inProgress); + assert.deepStrictEqual( + [ + { + workspaceId: 'mockClient', + entryNumber: 0, + events: [1, 2, 3], + }, + ], + this.workspaceClient.inProgress, + ); assert.strictEqual(1, this.workspaceClient.counter); assert(Blockly.Events.filter.called); }); test('Write fails, error is thrown and events stay in notSent.', async () => { sinon.stub(this.workspaceClient, 'addEventsHandler').rejects(); - this.workspaceClient.notSent = [1,2,3]; + this.workspaceClient.notSent = [1, 2, 3]; await assert.rejects(this.workspaceClient.writeToDatabase_()); - assert.deepStrictEqual([1,2,3], this.workspaceClient.notSent); + assert.deepStrictEqual([1, 2, 3], this.workspaceClient.notSent); assert.deepStrictEqual([], this.workspaceClient.inProgress); assert.strictEqual(0, this.workspaceClient.counter); assert(Blockly.Events.filter.called); @@ -67,29 +75,31 @@ suite('WorkspaceClient', () => { }); suite('addEvents()', () => { - test('Events added to activeChanges with the correct order and entryNumber.', - async () => { + test('Events added to activeChanges with the correct order and entryNumber.', async () => { this.workspaceClient.addEvent({event: 'mockEvent0'}); this.workspaceClient.addEvent({event: 'mockEvent1'}); - assert.deepStrictEqual([ - {event:'mockEvent0'}, - {event:'mockEvent1'} - ], this.workspaceClient.activeChanges); + assert.deepStrictEqual( + [{event: 'mockEvent0'}, {event: 'mockEvent1'}], + this.workspaceClient.activeChanges, + ); }); }); suite('flushEvents()', () => { test('Events in activeChanges are moved to end of notSent.', async () => { - const updateServerStub = new sinon.stub(this.workspaceClient, 'updateServer_'); + const updateServerStub = new sinon.stub( + this.workspaceClient, + 'updateServer_', + ); this.workspaceClient.counter = 2; this.workspaceClient.notSent = [ {event: 'mockEvent0'}, - {event: 'mockEvent1'} + {event: 'mockEvent1'}, ]; this.workspaceClient.activeChanges = [ {event: 'mockActiveChange2'}, - {event: 'mockActiveChange3'} + {event: 'mockActiveChange3'}, ]; this.workspaceClient.flushEvents(); assert.equal(true, updateServerStub.calledOnce); @@ -98,8 +108,10 @@ suite('WorkspaceClient', () => { {event: 'mockEvent0'}, {event: 'mockEvent1'}, {event: 'mockActiveChange2'}, - {event: 'mockActiveChange3'} - ], this.workspaceClient.notSent); + {event: 'mockActiveChange3'}, + ], + this.workspaceClient.notSent, + ); assert.deepStrictEqual([], this.workspaceClient.activeChanges); }); }); @@ -114,7 +126,7 @@ suite('WorkspaceClient', () => { }); test('Write in progress, returns.', async () => { - const writeStub = sinon.stub(this.workspaceClient, 'writeToDatabase_') + const writeStub = sinon.stub(this.workspaceClient, 'writeToDatabase_'); this.workspaceClient.notSent = ['event']; this.workspaceClient.writeInProgress = true; @@ -135,164 +147,190 @@ suite('WorkspaceClient', () => { suite('processQueryResults_()', () => { setup(() => { - this.workspaceClient.inProgress = [{ - events: [{mockEvent: 'mockLocalEvent0'}], - workspaceId: 'mockClient', - entryNumber: 0 - }]; - }) + this.workspaceClient.inProgress = [ + { + events: [{mockEvent: 'mockLocalEvent0'}], + workspaceId: 'mockClient', + entryNumber: 0, + }, + ]; + }); test('Entries is empty.', () => { this.workspaceClient.notSent = [ {mockEvent: 'mockLocalEvent1'}, - {mockEvent: 'mockLocalEvent2'} + {mockEvent: 'mockLocalEvent2'}, ]; const eventQueue = this.workspaceClient.processQueryResults_([]); assert.deepStrictEqual([], eventQueue); assert.equal(0, this.workspaceClient.lastSync); - assert.deepStrictEqual([{ - events: [{mockEvent: 'mockLocalEvent0'}], - workspaceId: 'mockClient', - entryNumber: 0 - }], this.workspaceClient.inProgress); - assert.deepStrictEqual([ - {mockEvent: 'mockLocalEvent1'}, - {mockEvent: 'mockLocalEvent2'} - ], this.workspaceClient.notSent); + assert.deepStrictEqual( + [ + { + events: [{mockEvent: 'mockLocalEvent0'}], + workspaceId: 'mockClient', + entryNumber: 0, + }, + ], + this.workspaceClient.inProgress, + ); + assert.deepStrictEqual( + [{mockEvent: 'mockLocalEvent1'}, {mockEvent: 'mockLocalEvent2'}], + this.workspaceClient.notSent, + ); }); test('Entries contain all local events.', () => { this.workspaceClient.notSent = [ {mockEvent: 'mockLocalEvent1'}, - {mockEvent: 'mockLocalEvent2'} + {mockEvent: 'mockLocalEvent2'}, ]; - const eventQueue = this.workspaceClient.processQueryResults_([{ - events: ['mockLocalEvent0'], - workspaceId: 'mockClient', - entryNumber: 0, - serverId: 1 - }]); + const eventQueue = this.workspaceClient.processQueryResults_([ + { + events: ['mockLocalEvent0'], + workspaceId: 'mockClient', + entryNumber: 0, + serverId: 1, + }, + ]); assert.deepStrictEqual([], eventQueue); assert.equal(1, this.workspaceClient.lastSync); assert.deepStrictEqual([], this.workspaceClient.inProgress); - assert.deepStrictEqual([ - {mockEvent: 'mockLocalEvent1'}, - {mockEvent: 'mockLocalEvent2'} - ], this.workspaceClient.notSent); + assert.deepStrictEqual( + [{mockEvent: 'mockLocalEvent1'}, {mockEvent: 'mockLocalEvent2'}], + this.workspaceClient.notSent, + ); }); test('Entries contain no local changes.', () => { this.workspaceClient.notSent = [ {mockEvent: 'mockLocalEvent1'}, - {mockEvent: 'mockLocalEvent2'} + {mockEvent: 'mockLocalEvent2'}, ]; - const eventQueue = this.workspaceClient.processQueryResults_([{ - events: [{mockEvent:'mockExternalEvent0'}], - workspaceId: 'otherClient', - entryNumber: 0, - serverId: 1 - }]); - assert.deepStrictEqual([ - {event: {mockEvent: 'mockLocalEvent2'}, forward: false}, - {event: {mockEvent: 'mockLocalEvent1'}, forward: false}, - {event: {mockEvent: 'mockLocalEvent0'}, forward: false}, - {event: {mockEvent: 'mockExternalEvent0'}, forward: true}, - {event: {mockEvent: 'mockLocalEvent0'}, forward: true}, - {event: {mockEvent: 'mockLocalEvent1'}, forward: true}, - {event: {mockEvent: 'mockLocalEvent2'}, forward: true} - ], eventQueue); + const eventQueue = this.workspaceClient.processQueryResults_([ + { + events: [{mockEvent: 'mockExternalEvent0'}], + workspaceId: 'otherClient', + entryNumber: 0, + serverId: 1, + }, + ]); + assert.deepStrictEqual( + [ + {event: {mockEvent: 'mockLocalEvent2'}, forward: false}, + {event: {mockEvent: 'mockLocalEvent1'}, forward: false}, + {event: {mockEvent: 'mockLocalEvent0'}, forward: false}, + {event: {mockEvent: 'mockExternalEvent0'}, forward: true}, + {event: {mockEvent: 'mockLocalEvent0'}, forward: true}, + {event: {mockEvent: 'mockLocalEvent1'}, forward: true}, + {event: {mockEvent: 'mockLocalEvent2'}, forward: true}, + ], + eventQueue, + ); assert.equal(1, this.workspaceClient.lastSync); - assert.deepStrictEqual([ - {events: [{mockEvent: 'mockLocalEvent0'}], - workspaceId: 'mockClient', - entryNumber: 0 - }], this.workspaceClient.inProgress); - assert.deepStrictEqual([ - {mockEvent: 'mockLocalEvent1'}, - {mockEvent: 'mockLocalEvent2'} - ], this.workspaceClient.notSent); + assert.deepStrictEqual( + [ + { + events: [{mockEvent: 'mockLocalEvent0'}], + workspaceId: 'mockClient', + entryNumber: 0, + }, + ], + this.workspaceClient.inProgress, + ); + assert.deepStrictEqual( + [{mockEvent: 'mockLocalEvent1'}, {mockEvent: 'mockLocalEvent2'}], + this.workspaceClient.notSent, + ); }); test('Entries contain local changes followed by external changes.', () => { this.workspaceClient.notSent = [ - {mockEvent:'mockLocalEvent1'}, - {mockEvent:'mockLocalEvent2'} + {mockEvent: 'mockLocalEvent1'}, + {mockEvent: 'mockLocalEvent2'}, ]; const eventQueue = this.workspaceClient.processQueryResults_([ { - events: [{mockEvent:'mockLocalEvent0'}], + events: [{mockEvent: 'mockLocalEvent0'}], workspaceId: 'mockClient', entryNumber: 0, - serverId: 1 + serverId: 1, }, { - events: [{mockEvent:'mockExternalEvent0'}], + events: [{mockEvent: 'mockExternalEvent0'}], workspaceId: 'otherClient', entryNumber: 0, - serverId: 2 - } + serverId: 2, + }, ]); - assert.deepStrictEqual([ - {event: {mockEvent: 'mockLocalEvent2'}, forward: false}, - {event: {mockEvent: 'mockLocalEvent1'}, forward: false}, - {event: {mockEvent: 'mockExternalEvent0'}, forward: true}, - {event: {mockEvent: 'mockLocalEvent1'}, forward: true}, - {event: {mockEvent: 'mockLocalEvent2'}, forward: true} - ], eventQueue); + assert.deepStrictEqual( + [ + {event: {mockEvent: 'mockLocalEvent2'}, forward: false}, + {event: {mockEvent: 'mockLocalEvent1'}, forward: false}, + {event: {mockEvent: 'mockExternalEvent0'}, forward: true}, + {event: {mockEvent: 'mockLocalEvent1'}, forward: true}, + {event: {mockEvent: 'mockLocalEvent2'}, forward: true}, + ], + eventQueue, + ); assert.equal(2, this.workspaceClient.lastSync); assert.deepStrictEqual([], this.workspaceClient.inProgress); - assert.deepStrictEqual([ - {mockEvent: 'mockLocalEvent1'}, - {mockEvent: 'mockLocalEvent2'} - ], this.workspaceClient.notSent); + assert.deepStrictEqual( + [{mockEvent: 'mockLocalEvent1'}, {mockEvent: 'mockLocalEvent2'}], + this.workspaceClient.notSent, + ); }); test('Entries contain local changes sandwiched by external changes.', () => { this.workspaceClient.notSent = [ {mockEvent: 'mockLocalEvent1'}, - {mockEvent: 'mockLocalEvent2'} + {mockEvent: 'mockLocalEvent2'}, ]; const eventQueue = this.workspaceClient.processQueryResults_([ { - events: [{mockEvent:'mockExternalEvent0'}], + events: [{mockEvent: 'mockExternalEvent0'}], workspaceId: 'otherClient', entryNumber: 0, - serverId: 1 + serverId: 1, }, { - events: [{mockEvent:'mockLocalEvent0'}], + events: [{mockEvent: 'mockLocalEvent0'}], workspaceId: 'mockClient', entryNumber: 0, - serverId: 2}, + serverId: 2, + }, { - events: [{mockEvent:'mockExternalEvent1'}], + events: [{mockEvent: 'mockExternalEvent1'}], workspaceId: 'otherClient', entryNumber: 1, - serverId: 3 - } + serverId: 3, + }, ]); - assert.deepStrictEqual([ - {event: {mockEvent: 'mockLocalEvent2'}, forward: false}, - {event: {mockEvent: 'mockLocalEvent1'}, forward: false}, - {event: {mockEvent: 'mockLocalEvent0'}, forward: false}, - {event: {mockEvent: 'mockExternalEvent0'}, forward: true}, - {event: {mockEvent: 'mockLocalEvent0'}, forward: true}, - {event: {mockEvent: 'mockExternalEvent1'}, forward: true}, - {event: {mockEvent: 'mockLocalEvent1'}, forward: true}, - {event: {mockEvent: 'mockLocalEvent2'}, forward: true} - ], eventQueue); + assert.deepStrictEqual( + [ + {event: {mockEvent: 'mockLocalEvent2'}, forward: false}, + {event: {mockEvent: 'mockLocalEvent1'}, forward: false}, + {event: {mockEvent: 'mockLocalEvent0'}, forward: false}, + {event: {mockEvent: 'mockExternalEvent0'}, forward: true}, + {event: {mockEvent: 'mockLocalEvent0'}, forward: true}, + {event: {mockEvent: 'mockExternalEvent1'}, forward: true}, + {event: {mockEvent: 'mockLocalEvent1'}, forward: true}, + {event: {mockEvent: 'mockLocalEvent2'}, forward: true}, + ], + eventQueue, + ); assert.equal(3, this.workspaceClient.lastSync); assert.deepStrictEqual([], this.workspaceClient.inProgress); - assert.deepStrictEqual([ - {mockEvent: 'mockLocalEvent1'}, - {mockEvent: 'mockLocalEvent2'} - ], this.workspaceClient.notSent); + assert.deepStrictEqual( + [{mockEvent: 'mockLocalEvent1'}, {mockEvent: 'mockLocalEvent2'}], + this.workspaceClient.notSent, + ); }); }); @@ -303,16 +341,19 @@ suite('WorkspaceClient', () => { this.workspaceClient.lastSync = 2; this.workspaceClient.serverEvents = [ {mockEvent: 'mockEvent', serverId: 1}, - {mockEvent: 'mockEvent', serverId: 2} + {mockEvent: 'mockEvent', serverId: 2}, ]; newServerEvents = [{mockEvent: 'mockEvent', serverId: 3}]; await this.workspaceClient.addServerEvents_(newServerEvents); - assert.deepStrictEqual([ - {mockEvent: 'mockEvent', serverId: 1}, - {mockEvent: 'mockEvent', serverId: 2}, - {mockEvent: 'mockEvent', serverId: 3} - ], this.workspaceClient.serverEvents); + assert.deepStrictEqual( + [ + {mockEvent: 'mockEvent', serverId: 1}, + {mockEvent: 'mockEvent', serverId: 2}, + {mockEvent: 'mockEvent', serverId: 3}, + ], + this.workspaceClient.serverEvents, + ); assert.equal(true, queryStub.notCalled); }); @@ -323,16 +364,19 @@ suite('WorkspaceClient', () => { this.workspaceClient.lastSync = 2; this.workspaceClient.serverEvents = [ {mockEvent: 'mockEvent', serverId: 1}, - {mockEvent: 'mockEvent', serverId: 2} + {mockEvent: 'mockEvent', serverId: 2}, ]; newServerEvents = [{mockEvent: 'mockEvent', serverId: 4}]; await this.workspaceClient.addServerEvents_(newServerEvents); - assert.deepStrictEqual([ - {mockEvent: 'mockEvent', serverId: 1}, - {mockEvent: 'mockEvent', serverId: 2}, - {mockEvent: 'mockEvent', serverId: 3} - ], this.workspaceClient.serverEvents); + assert.deepStrictEqual( + [ + {mockEvent: 'mockEvent', serverId: 1}, + {mockEvent: 'mockEvent', serverId: 2}, + {mockEvent: 'mockEvent', serverId: 3}, + ], + this.workspaceClient.serverEvents, + ); assert.equal(true, queryStub.calledOnce); }); }); @@ -345,8 +389,10 @@ suite('WorkspaceClient', () => { }); test('Query succeeds.', async () => { - const getEventsStub = sinon.stub(handler, 'getEvents') - sinon.stub(this.workspaceClient, 'getEventsHandler').resolves(['resolved']); + const getEventsStub = sinon.stub(handler, 'getEvents'); + sinon + .stub(this.workspaceClient, 'getEventsHandler') + .resolves(['resolved']); const entries = await this.workspaceClient.queryDatabase_(); assert.deepStrictEqual(['resolved'], entries); }); @@ -355,7 +401,9 @@ suite('WorkspaceClient', () => { suite('updateWorkspace_()', () => { test('New server events, no update in progress.', async () => { const processQueryStub = sinon.stub( - this.workspaceClient, 'processQueryResults_'); + this.workspaceClient, + 'processQueryResults_', + ); processQueryStub.returns([]); this.workspaceClient.serverEvents = ['event']; @@ -366,7 +414,9 @@ suite('WorkspaceClient', () => { test('Update in progress, returns.', async () => { const processQueryStub = sinon.stub( - this.workspaceClient, 'processQueryResults_'); + this.workspaceClient, + 'processQueryResults_', + ); this.workspaceClient.serverEvents = ['event']; this.workspaceClient.updateInProgress = true; @@ -377,7 +427,9 @@ suite('WorkspaceClient', () => { test('No more server events, returns.', async () => { const processQueryStub = sinon.stub( - this.workspaceClient, 'processQueryResults_'); + this.workspaceClient, + 'processQueryResults_', + ); this.workspaceClient.serverEvents = []; await this.workspaceClient.updateWorkspace_(); diff --git a/examples/blockly-rtc/webpack.config.js b/examples/blockly-rtc/webpack.config.js index d05cf0e2ab..e4f15e2a46 100644 --- a/examples/blockly-rtc/webpack.config.js +++ b/examples/blockly-rtc/webpack.config.js @@ -26,41 +26,41 @@ const webpack = require('webpack'); const CopyPlugin = require('copy-webpack-plugin'); module.exports = { - target: 'web', - mode: 'development', - entry: { - http: './src/http/index.js', - websocket: './src/websocket/index.js' + target: 'web', + mode: 'development', + entry: { + http: './src/http/index.js', + websocket: './src/websocket/index.js', + }, + output: { + path: path.resolve(__dirname, 'build'), + filename: '[name].js', + clean: true, + }, + plugins: [ + new webpack.optimize.ModuleConcatenationPlugin(), + new CopyPlugin([ + { + from: path.resolve(__dirname, 'public'), + to: path.resolve(__dirname, 'build'), + }, + ]), + // Copy over media resources from the Blockly package + new CopyPlugin([ + { + from: path.resolve(__dirname, './node_modules/blockly/media'), + to: path.resolve(__dirname, 'build/media'), + }, + ]), + ], + devServer: { + port: 3000, + proxy: { + '/api': 'http://localhost:3001', + '/socket.io': { + target: 'ws://localhost:3001', + ws: true, + }, }, - output: { - path: path.resolve(__dirname, 'build'), - filename: '[name].js', - clean: true, - }, - plugins: [ - new webpack.optimize.ModuleConcatenationPlugin(), - new CopyPlugin([ - { - from: path.resolve(__dirname, 'public'), - to: path.resolve(__dirname, 'build') - } - ]), - // Copy over media resources from the Blockly package - new CopyPlugin([ - { - from: path.resolve(__dirname, './node_modules/blockly/media'), - to: path.resolve(__dirname, 'build/media') - } - ]) - ], - devServer: { - port: 3000, - proxy: { - '/api': 'http://localhost:3001', - '/socket.io': { - target: 'ws://localhost:3001', - ws: true - } - } - } + }, }; diff --git a/examples/blockly-svelte/README.md b/examples/blockly-svelte/README.md index 108fb051f4..16f6ea1003 100644 --- a/examples/blockly-svelte/README.md +++ b/examples/blockly-svelte/README.md @@ -15,10 +15,11 @@ npm install ### Running start [Rollup](https://rollupjs.org) by: + ```bash npm run start ``` ### Browse -Navigate to [http://localhost:3000/](http://localhost:3000/) +Navigate to [http://localhost:3000/](http://localhost:3000/) diff --git a/examples/blockly-svelte/public/global.css b/examples/blockly-svelte/public/global.css index deaa4cfcc3..2807b357f6 100644 --- a/examples/blockly-svelte/public/global.css +++ b/examples/blockly-svelte/public/global.css @@ -1,62 +1,67 @@ -html, body { - position: relative; - width: 100%; - height: 100%; +html, +body { + position: relative; + width: 100%; + height: 100%; } body { - color: #333; - margin: 0; - padding: 8px; - box-sizing: border-box; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; + color: #333; + margin: 0; + padding: 8px; + box-sizing: border-box; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; } a { - color: rgb(0,100,200); - text-decoration: none; + color: rgb(0, 100, 200); + text-decoration: none; } a:hover { - text-decoration: underline; + text-decoration: underline; } a:visited { - color: rgb(0,80,160); + color: rgb(0, 80, 160); } label { - display: block; + display: block; } -input, button, select, textarea { - font-family: inherit; - font-size: inherit; - padding: 0.4em; - margin: 0 0 0.5em 0; - box-sizing: border-box; - border: 1px solid #ccc; - border-radius: 2px; +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + padding: 0.4em; + margin: 0 0 0.5em 0; + box-sizing: border-box; + border: 1px solid #ccc; + border-radius: 2px; } input:disabled { - color: #ccc; + color: #ccc; } -input[type="range"] { - height: 0; +input[type='range'] { + height: 0; } button { - color: #333; - background-color: #f4f4f4; - outline: none; + color: #333; + background-color: #f4f4f4; + outline: none; } button:active { - background-color: #ddd; + background-color: #ddd; } button:focus { - border-color: #666; + border-color: #666; } diff --git a/examples/blockly-svelte/public/index.html b/examples/blockly-svelte/public/index.html index de7354234c..e1e4730a53 100644 --- a/examples/blockly-svelte/public/index.html +++ b/examples/blockly-svelte/public/index.html @@ -1,18 +1,17 @@ - - - + + + - Svelte app + Svelte app - - - + + + - - + + - - + diff --git a/examples/blockly-svelte/rollup.config.js b/examples/blockly-svelte/rollup.config.js index d6eb97bd34..2666c43866 100644 --- a/examples/blockly-svelte/rollup.config.js +++ b/examples/blockly-svelte/rollup.config.js @@ -26,7 +26,7 @@ import svelte from 'rollup-plugin-svelte'; import resolve from 'rollup-plugin-node-resolve'; import commonjs from 'rollup-plugin-commonjs'; import livereload from 'rollup-plugin-livereload'; -import { terser } from 'rollup-plugin-terser'; +import {terser} from 'rollup-plugin-terser'; const production = !process.env.ROLLUP_WATCH; @@ -36,7 +36,7 @@ export default { sourcemap: true, format: 'iife', name: 'app', - file: 'public/bundle.js' + file: 'public/bundle.js', }, plugins: [ svelte({ @@ -44,9 +44,9 @@ export default { dev: !production, // we'll extract any component CSS out into // a separate file — better for performance - css: css => { + css: (css) => { css.write('bundle.css'); - } + }, }), // If you have external dependencies installed from @@ -56,7 +56,8 @@ export default { // https://github.com/rollup/rollup-plugin-commonjs resolve({ browser: true, - dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/') + dedupe: (importee) => + importee === 'svelte' || importee.startsWith('svelte/'), }), commonjs(), @@ -66,9 +67,9 @@ export default { // If we're building for production (npm run build // instead of npm run dev), minify - production && terser() + production && terser(), ], watch: { - clearScreen: false - } + clearScreen: false, + }, }; diff --git a/examples/blockly-svelte/src/main.js b/examples/blockly-svelte/src/main.js index 3be4eb417d..e0d7434542 100644 --- a/examples/blockly-svelte/src/main.js +++ b/examples/blockly-svelte/src/main.js @@ -24,7 +24,7 @@ import App from './App.svelte'; const app = new App({ - target: document.body + target: document.body, }); export default app; diff --git a/examples/blockly-vue3/.eslintrc.cjs b/examples/blockly-vue3/.eslintrc.cjs index dcd4c7cc85..23a6928bdf 100644 --- a/examples/blockly-vue3/.eslintrc.cjs +++ b/examples/blockly-vue3/.eslintrc.cjs @@ -1,11 +1,11 @@ /* eslint-env node */ -require("@rushstack/eslint-patch/modern-module-resolution"); +require('@rushstack/eslint-patch/modern-module-resolution'); module.exports = { root: true, extends: [ - "plugin:vue/vue3-essential", - "eslint:recommended", - "@vue/eslint-config-prettier", + 'plugin:vue/vue3-essential', + 'eslint:recommended', + '@vue/eslint-config-prettier', ], }; diff --git a/examples/blockly-vue3/README.md b/examples/blockly-vue3/README.md index 1df0876780..0b8c7e6ce6 100644 --- a/examples/blockly-vue3/README.md +++ b/examples/blockly-vue3/README.md @@ -35,4 +35,5 @@ npm run lint ``` ### External resources -[Vue logo](https://github.com/vuejs/art) (logo.png) included during project creation `npm init vue@latest`. \ No newline at end of file + +[Vue logo](https://github.com/vuejs/art) (logo.png) included during project creation `npm init vue@latest`. diff --git a/examples/blockly-vue3/index.html b/examples/blockly-vue3/index.html index fda9aadabf..effc0fc66e 100644 --- a/examples/blockly-vue3/index.html +++ b/examples/blockly-vue3/index.html @@ -1,10 +1,8 @@ - - - - + + - + Vite App @@ -12,11 +10,12 @@
- - + diff --git a/examples/blockly-vue3/package-lock.json b/examples/blockly-vue3/package-lock.json index f3f2bd7779..2f838c0e8b 100644 --- a/examples/blockly-vue3/package-lock.json +++ b/examples/blockly-vue3/package-lock.json @@ -18,7 +18,7 @@ "eslint": "^8.5.0", "eslint-plugin-vue": "^9.0.0", "prettier": "^2.5.1", - "vite": "^2.9.16", + "vite": "^2.9.17", "vite-plugin-static-copy": "^0.6.0" } }, @@ -1952,9 +1952,9 @@ "license": "MIT" }, "node_modules/vite": { - "version": "2.9.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.16.tgz", - "integrity": "sha512-X+6q8KPyeuBvTQV8AVSnKDvXoBMnTx8zxh54sOwmmuOdxkjMmEJXH2UEchA+vTMps1xw9vL64uwJOWryULg7nA==", + "version": "2.9.17", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.17.tgz", + "integrity": "sha512-XxcRzra6d7xrKXH66jZUgb+srThoPu+TLJc06GifUyKq9JmjHkc1Numc8ra0h56rju2jfVWw3B3fs5l3OFMvUw==", "dev": true, "dependencies": { "esbuild": "^0.14.27", @@ -3394,9 +3394,9 @@ "dev": true }, "vite": { - "version": "2.9.16", - "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.16.tgz", - "integrity": "sha512-X+6q8KPyeuBvTQV8AVSnKDvXoBMnTx8zxh54sOwmmuOdxkjMmEJXH2UEchA+vTMps1xw9vL64uwJOWryULg7nA==", + "version": "2.9.17", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.9.17.tgz", + "integrity": "sha512-XxcRzra6d7xrKXH66jZUgb+srThoPu+TLJc06GifUyKq9JmjHkc1Numc8ra0h56rju2jfVWw3B3fs5l3OFMvUw==", "dev": true, "requires": { "esbuild": "^0.14.27", diff --git a/examples/blockly-vue3/package.json b/examples/blockly-vue3/package.json index 1e85b384d4..ef523cfc8f 100644 --- a/examples/blockly-vue3/package.json +++ b/examples/blockly-vue3/package.json @@ -18,7 +18,7 @@ "eslint": "^8.5.0", "eslint-plugin-vue": "^9.0.0", "prettier": "^2.5.1", - "vite": "^2.9.16", + "vite": "^2.9.17", "vite-plugin-static-copy": "^0.6.0" } } diff --git a/examples/blockly-vue3/src/App.vue b/examples/blockly-vue3/src/App.vue index 70a1c3d4c7..64e9db1d39 100644 --- a/examples/blockly-vue3/src/App.vue +++ b/examples/blockly-vue3/src/App.vue @@ -10,20 +10,20 @@ * @author dcoodien@google.com (Dylan Coodien) */ -import { ref } from "vue"; -import BlocklyComponent from "./components/BlocklyComponent.vue"; -import "./blocks/stocks"; +import {ref} from 'vue'; +import BlocklyComponent from './components/BlocklyComponent.vue'; +import './blocks/stocks'; -import { javascriptGenerator } from "blockly/javascript"; +import {javascriptGenerator} from 'blockly/javascript'; const foo = ref(); const code = ref(); const options = { - media: "media/", + media: 'media/', grid: { spacing: 25, length: 3, - colour: "#ccc", + colour: '#ccc', snap: true, }, toolbox: ` @@ -66,7 +66,8 @@ const options = { `, }; -const showCode = () => (code.value = javascriptGenerator.workspaceToCode(foo.value.workspace)); +const showCode = () => + (code.value = javascriptGenerator.workspaceToCode(foo.value.workspace)); - - - -

Context Menu Codelab

-
- + #blocklyDiv { + float: bottom; + height: 90%; + width: 100%; + } + + + +

Context Menu Codelab

+
+ diff --git a/examples/context-menu-codelab/complete-code/index.js b/examples/context-menu-codelab/complete-code/index.js index fc340bc849..5c13604ce6 100644 --- a/examples/context-menu-codelab/complete-code/index.js +++ b/examples/context-menu-codelab/complete-code/index.js @@ -9,10 +9,9 @@ function start() { registerDisplayOption(); Blockly.ContextMenuRegistry.registry.unregister('workspaceDelete'); // Create main workspace. - workspace = Blockly.inject('blocklyDiv', - { - toolbox: toolboxSimple, - }); + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxSimple, + }); } function registerFirstContextMenuOptions() { @@ -20,15 +19,14 @@ function registerFirstContextMenuOptions() { const workspaceItem = { displayText: 'Hello World', // Precondition: Enable for the first 30 seconds of every minute; disable for the next 30 seconds. - preconditionFn: function(scope) { + preconditionFn: function (scope) { const now = new Date(Date.now()); if (now.getSeconds() < 30) { return 'enabled'; } return 'disabled'; }, - callback: function(scope) { - }, + callback: function (scope) {}, scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE, id: 'hello_world', weight: 100, @@ -37,7 +35,7 @@ function registerFirstContextMenuOptions() { Blockly.ContextMenuRegistry.registry.register(workspaceItem); // Duplicate the workspace item (using the spread operator). - const blockItem = {...workspaceItem} + const blockItem = {...workspaceItem}; // Use block scope and update the id to a nonconflicting value. blockItem.scopeType = Blockly.ContextMenuRegistry.ScopeType.BLOCK; blockItem.id = 'hello_world_block'; @@ -48,20 +46,23 @@ function registerHelpOption() { const helpItem = { displayText: 'Help! There are no blocks', // Use the workspace scope in the precondition function to check for blocks on the workspace. - preconditionFn: function(scope) { + preconditionFn: function (scope) { if (!scope.workspace.getTopBlocks().length) { return 'enabled'; } return 'hidden'; }, // Use the workspace scope in the callback function to add a block to the workspace. - callback: function(scope) { - Blockly.serialization.blocks.append({ - 'type': 'text', - 'fields': { - 'TEXT': 'Now there is a block' - } - }, scope.workspace); + callback: function (scope) { + Blockly.serialization.blocks.append( + { + type: 'text', + fields: { + TEXT: 'Now there is a block', + }, + }, + scope.workspace, + ); }, scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE, id: 'help_no_blocks', @@ -75,14 +76,13 @@ function registerOutputOption() { displayText: 'I have an output connection', // Use the block scope in the precondition function to hide the option on blocks with no // output connection. - preconditionFn: function(scope) { + preconditionFn: function (scope) { if (scope.block.outputConnection) { return 'enabled'; } return 'hidden'; }, - callback: function (scope) { - }, + callback: function (scope) {}, scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK, id: 'block_has_output', // Use a larger weight to push the option lower on the context menu. @@ -94,7 +94,7 @@ function registerOutputOption() { function registerDisplayOption() { const displayOption = { // Use the block scope to set display text dynamically based on the type of the block. - displayText: function(scope) { + displayText: function (scope) { if (scope.block.type.startsWith('text')) { return 'Text block'; } else if (scope.block.type.startsWith('controls')) { @@ -106,8 +106,7 @@ function registerDisplayOption() { preconditionFn: function (scope) { return 'enabled'; }, - callback: function (scope) { - }, + callback: function (scope) {}, scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK, id: 'display_text_example', weight: 100, diff --git a/examples/context-menu-codelab/starter-code/index.html b/examples/context-menu-codelab/starter-code/index.html index 2cb1786a1f..c0821a8ec2 100644 --- a/examples/context-menu-codelab/starter-code/index.html +++ b/examples/context-menu-codelab/starter-code/index.html @@ -1,42 +1,40 @@ - + + + + Context Menu Codelab + + + - - - Context Menu Codelab - - - + - - - -

Context Menu Codelab

-
- + #blocklyDiv { + float: bottom; + height: 90%; + width: 100%; + } + + + +

Context Menu Codelab

+
+ diff --git a/examples/context-menu-codelab/starter-code/index.js b/examples/context-menu-codelab/starter-code/index.js index 9f9f06a220..e712891f4b 100644 --- a/examples/context-menu-codelab/starter-code/index.js +++ b/examples/context-menu-codelab/starter-code/index.js @@ -4,8 +4,7 @@ let workspace = null; function start() { // Create main workspace. - workspace = Blockly.inject('blocklyDiv', - { - toolbox: toolboxSimple, - }); + workspace = Blockly.inject('blocklyDiv', { + toolbox: toolboxSimple, + }); } diff --git a/examples/custom-dialogs-demo/custom-dialog.js b/examples/custom-dialogs-demo/custom-dialog.js index cf4f2c3760..311eb7f1a7 100644 --- a/examples/custom-dialogs-demo/custom-dialog.js +++ b/examples/custom-dialogs-demo/custom-dialog.js @@ -13,39 +13,39 @@ CustomDialog = {}; /** Override Blockly.dialog.setAlert() with custom implementation. */ -Blockly.dialog.setAlert(function(message, callback) { +Blockly.dialog.setAlert(function (message, callback) { console.log('Alert: ' + message); CustomDialog.show('Alert', message, { - onCancel: callback + onCancel: callback, }); }); /** Override Blockly.dialog.setConfirm() with custom implementation. */ -Blockly.dialog.setConfirm(function(message, callback) { +Blockly.dialog.setConfirm(function (message, callback) { console.log('Confirm: ' + message); CustomDialog.show('Confirm', message, { showOkay: true, - onOkay: function() { + onOkay: function () { callback(true); }, showCancel: true, - onCancel: function() { + onCancel: function () { callback(false); - } + }, }); }); /** Override Blockly.dialog.setPrompt() with custom implementation. */ -Blockly.dialog.setPrompt(function(message, defaultValue, callback) { +Blockly.dialog.setPrompt(function (message, defaultValue, callback) { console.log('Prompt: ' + message); CustomDialog.show('Prompt', message, { showInput: true, showOkay: true, - onOkay: function() { + onOkay: function () { callback(CustomDialog.inputField.value); }, showCancel: true, - onCancel: function() { + onCancel: function () { callback(null); }, }); @@ -53,7 +53,7 @@ Blockly.dialog.setPrompt(function(message, defaultValue, callback) { }); /** Hides any currently visible dialog. */ -CustomDialog.hide = function() { +CustomDialog.hide = function () { if (CustomDialog.backdropDiv_) { CustomDialog.backdropDiv_.style.display = 'none'; CustomDialog.dialogDiv_.style.display = 'none'; @@ -69,7 +69,7 @@ CustomDialog.hide = function() { * - onOkay: Callback to handle the okay button. * - onCancel: Callback to handle the cancel button and backdrop clicks. */ -CustomDialog.show = function(title, message, options) { +CustomDialog.show = function (title, message, options) { let backdropDiv = CustomDialog.backdropDiv_; let dialogDiv = CustomDialog.dialogDiv_; if (!dialogDiv) { @@ -77,22 +77,22 @@ CustomDialog.show = function(title, message, options) { backdropDiv = document.createElement('div'); backdropDiv.id = 'customDialogBackdrop'; backdropDiv.style.cssText = - 'position: absolute;' + - 'top: 0; left: 0; right: 0; bottom: 0;' + - 'background-color: rgba(0, 0, 0, 0.7);' + - 'z-index: 100;'; + 'position: absolute;' + + 'top: 0; left: 0; right: 0; bottom: 0;' + + 'background-color: rgba(0, 0, 0, 0.7);' + + 'z-index: 100;'; document.body.appendChild(backdropDiv); dialogDiv = document.createElement('div'); dialogDiv.id = 'customDialog'; dialogDiv.style.cssText = - 'background-color: #fff;' + - 'width: 400px;' + - 'margin: 20px auto 0;' + - 'padding: 10px;'; + 'background-color: #fff;' + + 'width: 400px;' + + 'margin: 20px auto 0;' + + 'padding: 10px;'; backdropDiv.appendChild(dialogDiv); - dialogDiv.onclick = function(event) { + dialogDiv.onclick = function (event) { event.stopPropagation(); }; @@ -103,24 +103,28 @@ CustomDialog.show = function(title, message, options) { dialogDiv.style.display = 'block'; dialogDiv.innerHTML = - '
' + - '

' + - (options.showInput ? '
' : '') + - '
' + - (options.showCancel ? '': '') + - (options.showOkay ? '': '') + - '
'; - dialogDiv.getElementsByClassName('customDialogTitle')[0] - .appendChild(document.createTextNode(title)); - dialogDiv.getElementsByClassName('customDialogMessage')[0] - .appendChild(document.createTextNode(message)); + '
' + + '

' + + (options.showInput ? '
' : '') + + '
' + + (options.showCancel + ? '' + : '') + + (options.showOkay ? '' : '') + + '
'; + dialogDiv + .getElementsByClassName('customDialogTitle')[0] + .appendChild(document.createTextNode(title)); + dialogDiv + .getElementsByClassName('customDialogMessage')[0] + .appendChild(document.createTextNode(message)); - const onOkay = function(event) { + const onOkay = function (event) { CustomDialog.hide(); options.onOkay && options.onOkay(); event && event.stopPropagation(); }; - const onCancel = function(event) { + const onCancel = function (event) { CustomDialog.hide(); options.onCancel && options.onCancel(); event && event.stopPropagation(); @@ -131,12 +135,12 @@ CustomDialog.show = function(title, message, options) { if (dialogInput) { dialogInput.focus(); - dialogInput.onkeyup = function(event) { + dialogInput.onkeyup = function (event) { if (event.key === 'Enter') { // Process as OK when user hits enter. onOkay(); return false; - } else if (event.key === 'Escape') { + } else if (event.key === 'Escape') { // Process as cancel when user hits esc. onCancel(); return false; @@ -148,12 +152,14 @@ CustomDialog.show = function(title, message, options) { } if (options.showOkay) { - document.getElementById('customDialogOkay') - .addEventListener('click', onOkay); + document + .getElementById('customDialogOkay') + .addEventListener('click', onOkay); } if (options.showCancel) { - document.getElementById('customDialogCancel') - .addEventListener('click', onCancel); + document + .getElementById('customDialogCancel') + .addEventListener('click', onCancel); } backdropDiv.onclick = onCancel; diff --git a/examples/custom-dialogs-demo/index.html b/examples/custom-dialogs-demo/index.html index 676f586843..9c570e653f 100644 --- a/examples/custom-dialogs-demo/index.html +++ b/examples/custom-dialogs-demo/index.html @@ -1,4 +1,4 @@ - + @@ -25,39 +25,39 @@ or deleting multiple blocks on the workspace.

-
+
diff --git a/examples/custom-generator-codelab/src/blocks/json.js b/examples/custom-generator-codelab/src/blocks/json.js index 53a23198f0..f5def025db 100644 --- a/examples/custom-generator-codelab/src/blocks/json.js +++ b/examples/custom-generator-codelab/src/blocks/json.js @@ -11,41 +11,43 @@ import * as Blockly from 'blockly'; -export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray([{ - 'type': 'object', - 'message0': '{ %1 %2 }', - 'args0': [ - { - 'type': 'input_dummy', - }, - { - 'type': 'input_statement', - 'name': 'MEMBERS', - }, - ], - 'output': null, - 'colour': 230, -}, -{ - 'type': 'member', - 'message0': '%1 %2 %3', - 'args0': [ - { - 'type': 'field_input', - 'name': 'MEMBER_NAME', - 'text': '', - }, - { - 'type': 'field_label', - 'name': 'COLON', - 'text': ':', - }, - { - 'type': 'input_value', - 'name': 'MEMBER_VALUE', - }, - ], - 'previousStatement': null, - 'nextStatement': null, - 'colour': 230, -}]); +export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray([ + { + type: 'object', + message0: '{ %1 %2 }', + args0: [ + { + type: 'input_dummy', + }, + { + type: 'input_statement', + name: 'MEMBERS', + }, + ], + output: null, + colour: 230, + }, + { + type: 'member', + message0: '%1 %2 %3', + args0: [ + { + type: 'field_input', + name: 'MEMBER_NAME', + text: '', + }, + { + type: 'field_label', + name: 'COLON', + text: ':', + }, + { + type: 'input_value', + name: 'MEMBER_VALUE', + }, + ], + previousStatement: null, + nextStatement: null, + colour: 230, + }, +]); diff --git a/examples/custom-generator-codelab/src/generators/json.js b/examples/custom-generator-codelab/src/generators/json.js index 07151a4582..383e2c93fb 100644 --- a/examples/custom-generator-codelab/src/generators/json.js +++ b/examples/custom-generator-codelab/src/generators/json.js @@ -17,62 +17,60 @@ const Order = { ATOMIC: 0, }; -jsonGenerator.scrub_ = function(block, code, thisOnly) { - const nextBlock = - block.nextConnection && block.nextConnection.targetBlock(); +jsonGenerator.scrub_ = function (block, code, thisOnly) { + const nextBlock = block.nextConnection && block.nextConnection.targetBlock(); if (nextBlock && !thisOnly) { return code + ',\n' + jsonGenerator.blockToCode(nextBlock); } return code; }; -jsonGenerator.forBlock['logic_null'] = function(block) { +jsonGenerator.forBlock['logic_null'] = function (block) { return ['null', Order.ATOMIC]; }; -jsonGenerator.forBlock['text'] = function(block) { +jsonGenerator.forBlock['text'] = function (block) { const textValue = block.getFieldValue('TEXT'); const code = `"${textValue}"`; return [code, Order.ATOMIC]; }; -jsonGenerator.forBlock['math_number'] = function(block) { +jsonGenerator.forBlock['math_number'] = function (block) { const code = String(block.getFieldValue('NUM')); return [code, Order.ATOMIC]; }; -jsonGenerator.forBlock['logic_boolean'] = function(block) { - const code = (block.getFieldValue('BOOL') == 'TRUE') ? 'true' : 'false'; +jsonGenerator.forBlock['logic_boolean'] = function (block) { + const code = block.getFieldValue('BOOL') == 'TRUE' ? 'true' : 'false'; return [code, Order.ATOMIC]; }; -jsonGenerator.forBlock['member'] = function(block, generator) { +jsonGenerator.forBlock['member'] = function (block, generator) { const name = block.getFieldValue('MEMBER_NAME'); - const value = generator.valueToCode( - block, 'MEMBER_VALUE', Order.ATOMIC); + const value = generator.valueToCode(block, 'MEMBER_VALUE', Order.ATOMIC); const code = `"${name}": ${value}`; return code; }; -jsonGenerator.forBlock['lists_create_with'] = function(block, generator) { +jsonGenerator.forBlock['lists_create_with'] = function (block, generator) { const values = []; for (let i = 0; i < block.itemCount_; i++) { - const valueCode = generator.valueToCode(block, 'ADD' + i, - Order.ATOMIC); + const valueCode = generator.valueToCode(block, 'ADD' + i, Order.ATOMIC); if (valueCode) { values.push(valueCode); } } const valueString = values.join(',\n'); - const indentedValueString = - generator.prefixLines(valueString, generator.INDENT); + const indentedValueString = generator.prefixLines( + valueString, + generator.INDENT, + ); const codeString = '[\n' + indentedValueString + '\n]'; return [codeString, Order.ATOMIC]; }; -jsonGenerator.forBlock['object'] = function(block, generator) { - const statementMembers = - generator.statementToCode(block, 'MEMBERS'); +jsonGenerator.forBlock['object'] = function (block, generator) { + const statementMembers = generator.statementToCode(block, 'MEMBERS'); const code = '{\n' + statementMembers + '\n}'; return [code, Order.ATOMIC]; }; diff --git a/examples/custom-generator-codelab/src/index.css b/examples/custom-generator-codelab/src/index.css index 4a05dbfd9f..f282700701 100644 --- a/examples/custom-generator-codelab/src/index.css +++ b/examples/custom-generator-codelab/src/index.css @@ -1,39 +1,40 @@ body { - margin: 0; - max-width: 100vw; + margin: 0; + max-width: 100vw; } -pre, code { - overflow: auto; +pre, +code { + overflow: auto; } #pageContainer { - display: flex; - width: 100%; - max-width: 100vw; - height: 100vh; + display: flex; + width: 100%; + max-width: 100vw; + height: 100vh; } #blocklyDiv { - flex-basis: 100%; - height: 100%; - min-width: 600px; + flex-basis: 100%; + height: 100%; + min-width: 600px; } #outputPane { - display: flex; - flex-direction: column; - width: 400px; - flex: 0 0 400px; - overflow: auto; - margin: 1rem; + display: flex; + flex-direction: column; + width: 400px; + flex: 0 0 400px; + overflow: auto; + margin: 1rem; } #generatedCode { - height: 50%; - background-color: rgb(247, 240, 228); + height: 50%; + background-color: rgb(247, 240, 228); } #output { - height: 50%; -} \ No newline at end of file + height: 50%; +} diff --git a/examples/custom-generator-codelab/src/index.html b/examples/custom-generator-codelab/src/index.html index 2f81d3c111..36d8eeacd9 100644 --- a/examples/custom-generator-codelab/src/index.html +++ b/examples/custom-generator-codelab/src/index.html @@ -1,10 +1,10 @@ - - - - - Blockly Sample App - - + + + + + Blockly Sample App + +
@@ -12,5 +12,5 @@
- - + + diff --git a/examples/custom-generator-codelab/src/index.js b/examples/custom-generator-codelab/src/index.js index 7d45f63b29..175127a432 100644 --- a/examples/custom-generator-codelab/src/index.js +++ b/examples/custom-generator-codelab/src/index.js @@ -38,14 +38,16 @@ ws.addChangeListener((e) => { save(ws); }); - // Whenever the workspace changes meaningfully, run the code again. ws.addChangeListener((e) => { // Don't run the code when the workspace finishes loading; we're // already running it once when the application starts. // Don't run the code during drags; we might have invalid state. - if (e.isUiEvent || e.type == Blockly.Events.FINISHED_LOADING || - ws.isDragging()) { + if ( + e.isUiEvent || + e.type == Blockly.Events.FINISHED_LOADING || + ws.isDragging() + ) { return; } runCode(); diff --git a/examples/custom-generator-codelab/src/serialization.js b/examples/custom-generator-codelab/src/serialization.js index b31c22b9fd..2ffda8b460 100644 --- a/examples/custom-generator-codelab/src/serialization.js +++ b/examples/custom-generator-codelab/src/serialization.js @@ -13,7 +13,7 @@ const storageKey = 'jsonGeneratorWorkspace'; * Saves the state of the workspace to browser's local storage. * @param {Blockly.Workspace} workspace Blockly workspace to save. */ -export const save = function(workspace) { +export const save = function (workspace) { const data = Blockly.serialization.workspaces.save(workspace); window.localStorage?.setItem(storageKey, JSON.stringify(data)); }; @@ -22,7 +22,7 @@ export const save = function(workspace) { * Loads saved state from local storage into the given workspace. * @param {Blockly.Workspace} workspace Blockly workspace to load into. */ -export const load = function(workspace) { +export const load = function (workspace) { const data = window.localStorage?.getItem(storageKey); if (!data) return; diff --git a/examples/custom-generator-codelab/src/toolbox.js b/examples/custom-generator-codelab/src/toolbox.js index 65fe7c8898..45e5b237d1 100644 --- a/examples/custom-generator-codelab/src/toolbox.js +++ b/examples/custom-generator-codelab/src/toolbox.js @@ -5,35 +5,35 @@ */ export const toolbox = { - 'kind': 'flyoutToolbox', - 'contents': [ + kind: 'flyoutToolbox', + contents: [ { - 'kind': 'block', - 'type': 'object', + kind: 'block', + type: 'object', }, { - 'kind': 'block', - 'type': 'member', + kind: 'block', + type: 'member', }, { - 'kind': 'block', - 'type': 'math_number', + kind: 'block', + type: 'math_number', }, { - 'kind': 'block', - 'type': 'text', + kind: 'block', + type: 'text', }, { - 'kind': 'block', - 'type': 'logic_boolean', + kind: 'block', + type: 'logic_boolean', }, { - 'kind': 'block', - 'type': 'logic_null', + kind: 'block', + type: 'logic_null', }, { - 'kind': 'block', - 'type': 'lists_create_with', + kind: 'block', + type: 'lists_create_with', }, ], }; diff --git a/examples/custom-renderer-codelab/src/blocks/text.js b/examples/custom-renderer-codelab/src/blocks/text.js index 30159e8df3..83408ea00a 100644 --- a/examples/custom-renderer-codelab/src/blocks/text.js +++ b/examples/custom-renderer-codelab/src/blocks/text.js @@ -11,29 +11,30 @@ import * as Blockly from 'blockly/core'; // This is just an example and you should replace this with your // own custom blocks. const addText = { - 'type': 'add_text', - 'message0': 'Add text %1 with color %2', - 'args0': [ + type: 'add_text', + message0: 'Add text %1 with color %2', + args0: [ { - 'type': 'input_value', - 'name': 'TEXT', - 'check': 'String', + type: 'input_value', + name: 'TEXT', + check: 'String', }, { - 'type': 'input_value', - 'name': 'COLOR', - 'check': 'Colour', + type: 'input_value', + name: 'COLOR', + check: 'Colour', }, ], - 'previousStatement': null, - 'nextStatement': null, - 'colour': 160, - 'tooltip': '', - 'helpUrl': '', + previousStatement: null, + nextStatement: null, + colour: 160, + tooltip: '', + helpUrl: '', }; // Create the block definitions for the JSON-only blocks. // This does not register their definitions with Blockly. // This file has no side effects! -export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray( - [addText]); +export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray([ + addText, +]); diff --git a/examples/custom-renderer-codelab/src/generators/javascript.js b/examples/custom-renderer-codelab/src/generators/javascript.js index f2af8c19ac..1ee6bc2364 100644 --- a/examples/custom-renderer-codelab/src/generators/javascript.js +++ b/examples/custom-renderer-codelab/src/generators/javascript.js @@ -11,14 +11,14 @@ import {Order} from 'blockly/javascript'; // This file has no side effects! export const forBlock = Object.create(null); -forBlock['add_text'] = function(block, generator) { - const text = generator.valueToCode(block, 'TEXT', Order.NONE) || '\'\''; +forBlock['add_text'] = function (block, generator) { + const text = generator.valueToCode(block, 'TEXT', Order.NONE) || "''"; const color = - generator.valueToCode(block, 'COLOR', Order.ATOMIC) || '\'#ffffff\''; + generator.valueToCode(block, 'COLOR', Order.ATOMIC) || "'#ffffff'"; const addText = generator.provideFunction_( - 'addText', - `function ${generator.FUNCTION_NAME_PLACEHOLDER_}(text, color) { + 'addText', + `function ${generator.FUNCTION_NAME_PLACEHOLDER_}(text, color) { // Add text to the output area. const outputDiv = document.getElementById('output'); @@ -26,7 +26,7 @@ forBlock['add_text'] = function(block, generator) { textEl.innerText = text; textEl.style.color = color; outputDiv.appendChild(textEl); -}` +}`, ); // Generate the function call for this block. const code = `${addText}(${text}, ${color});\n`; diff --git a/examples/custom-renderer-codelab/src/index.css b/examples/custom-renderer-codelab/src/index.css index 4a05dbfd9f..f282700701 100644 --- a/examples/custom-renderer-codelab/src/index.css +++ b/examples/custom-renderer-codelab/src/index.css @@ -1,39 +1,40 @@ body { - margin: 0; - max-width: 100vw; + margin: 0; + max-width: 100vw; } -pre, code { - overflow: auto; +pre, +code { + overflow: auto; } #pageContainer { - display: flex; - width: 100%; - max-width: 100vw; - height: 100vh; + display: flex; + width: 100%; + max-width: 100vw; + height: 100vh; } #blocklyDiv { - flex-basis: 100%; - height: 100%; - min-width: 600px; + flex-basis: 100%; + height: 100%; + min-width: 600px; } #outputPane { - display: flex; - flex-direction: column; - width: 400px; - flex: 0 0 400px; - overflow: auto; - margin: 1rem; + display: flex; + flex-direction: column; + width: 400px; + flex: 0 0 400px; + overflow: auto; + margin: 1rem; } #generatedCode { - height: 50%; - background-color: rgb(247, 240, 228); + height: 50%; + background-color: rgb(247, 240, 228); } #output { - height: 50%; -} \ No newline at end of file + height: 50%; +} diff --git a/examples/custom-renderer-codelab/src/index.html b/examples/custom-renderer-codelab/src/index.html index 2f81d3c111..36d8eeacd9 100644 --- a/examples/custom-renderer-codelab/src/index.html +++ b/examples/custom-renderer-codelab/src/index.html @@ -1,10 +1,10 @@ - - - - - Blockly Sample App - - + + + + + Blockly Sample App + +
@@ -12,5 +12,5 @@
- - + + diff --git a/examples/custom-renderer-codelab/src/index.js b/examples/custom-renderer-codelab/src/index.js index a88e98d52a..c35ac7febe 100644 --- a/examples/custom-renderer-codelab/src/index.js +++ b/examples/custom-renderer-codelab/src/index.js @@ -50,14 +50,16 @@ ws.addChangeListener((e) => { save(ws); }); - // Whenever the workspace changes meaningfully, run the code again. ws.addChangeListener((e) => { // Don't run the code when the workspace finishes loading; we're // already running it once when the application starts. // Don't run the code during drags; we might have invalid state. - if (e.isUiEvent || e.type == Blockly.Events.FINISHED_LOADING || - ws.isDragging()) { + if ( + e.isUiEvent || + e.type == Blockly.Events.FINISHED_LOADING || + ws.isDragging() + ) { return; } runCode(); diff --git a/examples/custom-renderer-codelab/src/renderers/custom.js b/examples/custom-renderer-codelab/src/renderers/custom.js index 196b15ec9e..f6fcc9a629 100644 --- a/examples/custom-renderer-codelab/src/renderers/custom.js +++ b/examples/custom-renderer-codelab/src/renderers/custom.js @@ -94,12 +94,11 @@ class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider { * @returns SVGPath line for use with previous and next connections. */ function makeMainPath(dir) { - return Blockly.utils.svgPaths.line( - [ - Blockly.utils.svgPaths.point(0, height), - Blockly.utils.svgPaths.point(dir * width, 0), - Blockly.utils.svgPaths.point(0, -height), - ]); + return Blockly.utils.svgPaths.line([ + Blockly.utils.svgPaths.point(0, height), + Blockly.utils.svgPaths.point(dir * width, 0), + Blockly.utils.svgPaths.point(0, -height), + ]); } const pathLeft = makeMainPath(1); const pathRight = makeMainPath(-1); @@ -126,12 +125,11 @@ class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider { * @returns SVGPath line for use with input and output connections. */ function makeMainPath(dir) { - return Blockly.utils.svgPaths.line( - [ - Blockly.utils.svgPaths.point(-width, 0), - Blockly.utils.svgPaths.point(0, dir * height), - Blockly.utils.svgPaths.point(width, 0), - ]); + return Blockly.utils.svgPaths.line([ + Blockly.utils.svgPaths.point(-width, 0), + Blockly.utils.svgPaths.point(0, dir * height), + Blockly.utils.svgPaths.point(width, 0), + ]); } const pathUp = makeMainPath(-1); const pathDown = makeMainPath(1); diff --git a/examples/custom-renderer-codelab/src/serialization.js b/examples/custom-renderer-codelab/src/serialization.js index 0cf9a6377f..685eaf2fd7 100644 --- a/examples/custom-renderer-codelab/src/serialization.js +++ b/examples/custom-renderer-codelab/src/serialization.js @@ -12,7 +12,7 @@ const storageKey = 'mainWorkspace'; * Saves the state of the workspace to browser's local storage. * @param {Blockly.Workspace} workspace Blockly workspace to save. */ -export const save = function(workspace) { +export const save = function (workspace) { const data = Blockly.serialization.workspaces.save(workspace); window.localStorage?.setItem(storageKey, JSON.stringify(data)); }; @@ -21,7 +21,7 @@ export const save = function(workspace) { * Loads saved state from local storage into the given workspace. * @param {Blockly.Workspace} workspace Blockly workspace to load into. */ -export const load = function(workspace) { +export const load = function (workspace) { const data = window.localStorage?.getItem(storageKey); if (!data) return; diff --git a/examples/custom-renderer-codelab/src/toolbox.js b/examples/custom-renderer-codelab/src/toolbox.js index 4162ee4b55..0da9795cbb 100644 --- a/examples/custom-renderer-codelab/src/toolbox.js +++ b/examples/custom-renderer-codelab/src/toolbox.js @@ -13,305 +13,305 @@ listed here. */ export const toolbox = { - 'kind': 'categoryToolbox', - 'contents': [ + kind: 'categoryToolbox', + contents: [ { - 'kind': 'category', - 'name': 'Logic', - 'categorystyle': 'logic_category', - 'contents': [ + kind: 'category', + name: 'Logic', + categorystyle: 'logic_category', + contents: [ { - 'kind': 'block', - 'type': 'controls_if', + kind: 'block', + type: 'controls_if', }, { - 'kind': 'block', - 'type': 'logic_compare', + kind: 'block', + type: 'logic_compare', }, { - 'kind': 'block', - 'type': 'logic_operation', + kind: 'block', + type: 'logic_operation', }, { - 'kind': 'block', - 'type': 'logic_negate', + kind: 'block', + type: 'logic_negate', }, { - 'kind': 'block', - 'type': 'logic_boolean', + kind: 'block', + type: 'logic_boolean', }, { - 'kind': 'block', - 'type': 'logic_null', + kind: 'block', + type: 'logic_null', }, { - 'kind': 'block', - 'type': 'logic_ternary', + kind: 'block', + type: 'logic_ternary', }, ], }, { - 'kind': 'category', - 'name': 'Loops', - 'categorystyle': 'loop_category', - 'contents': [ + kind: 'category', + name: 'Loops', + categorystyle: 'loop_category', + contents: [ { - 'kind': 'block', - 'type': 'controls_repeat_ext', - 'inputs': { - 'TIMES': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 10, + kind: 'block', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, }, }, }, }, }, { - 'kind': 'block', - 'type': 'controls_whileUntil', + kind: 'block', + type: 'controls_whileUntil', }, { - 'kind': 'block', - 'type': 'controls_for', - 'inputs': { - 'FROM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + kind: 'block', + type: 'controls_for', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'TO': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 10, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, }, }, }, - 'BY': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + BY: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, }, }, { - 'kind': 'block', - 'type': 'controls_forEach', + kind: 'block', + type: 'controls_forEach', }, { - 'kind': 'block', - 'type': 'controls_flow_statements', + kind: 'block', + type: 'controls_flow_statements', }, ], }, { - 'kind': 'category', - 'name': 'Math', - 'categorystyle': 'math_category', - 'contents': [ + kind: 'category', + name: 'Math', + categorystyle: 'math_category', + contents: [ { - 'kind': 'block', - 'type': 'math_number', - 'fields': { - 'NUM': 123, + kind: 'block', + type: 'math_number', + fields: { + NUM: 123, }, }, { - 'kind': 'block', - 'type': 'math_arithmetic', - 'inputs': { - 'A': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + kind: 'block', + type: 'math_arithmetic', + inputs: { + A: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'B': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + B: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_single', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 9, + kind: 'block', + type: 'math_single', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 9, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_trig', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 45, + kind: 'block', + type: 'math_trig', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 45, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_constant', + kind: 'block', + type: 'math_constant', }, { - 'kind': 'block', - 'type': 'math_number_property', - 'inputs': { - 'NUMBER_TO_CHECK': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 0, + kind: 'block', + type: 'math_number_property', + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_round', - 'fields': { - 'OP': 'ROUND', + kind: 'block', + type: 'math_round', + fields: { + OP: 'ROUND', }, - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 3.1, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 3.1, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_on_list', - 'fields': { - 'OP': 'SUM', + kind: 'block', + type: 'math_on_list', + fields: { + OP: 'SUM', }, }, { - 'kind': 'block', - 'type': 'math_modulo', - 'inputs': { - 'DIVIDEND': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 64, + kind: 'block', + type: 'math_modulo', + inputs: { + DIVIDEND: { + shadow: { + type: 'math_number', + fields: { + NUM: 64, }, }, }, - 'DIVISOR': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 10, + DIVISOR: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_constrain', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 50, + kind: 'block', + type: 'math_constrain', + inputs: { + VALUE: { + shadow: { + type: 'math_number', + fields: { + NUM: 50, }, }, }, - 'LOW': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + LOW: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'HIGH': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 100, + HIGH: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_random_int', - 'inputs': { - 'FROM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + kind: 'block', + type: 'math_random_int', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'TO': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 100, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_random_float', + kind: 'block', + type: 'math_random_float', }, { - 'kind': 'block', - 'type': 'math_atan2', - 'inputs': { - 'X': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + kind: 'block', + type: 'math_atan2', + inputs: { + X: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'Y': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + Y: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, @@ -320,198 +320,198 @@ export const toolbox = { ], }, { - 'kind': 'category', - 'name': 'Text', - 'categorystyle': 'text_category', - 'contents': [ + kind: 'category', + name: 'Text', + categorystyle: 'text_category', + contents: [ { - 'kind': 'block', - 'type': 'text', + kind: 'block', + type: 'text', }, { - 'kind': 'block', - 'type': 'text_multiline', + kind: 'block', + type: 'text_multiline', }, { - 'kind': 'block', - 'type': 'text_join', + kind: 'block', + type: 'text_join', }, { - 'kind': 'block', - 'type': 'text_append', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': '', + kind: 'block', + type: 'text_append', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_length', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + kind: 'block', + type: 'text_length', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_isEmpty', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': '', + kind: 'block', + type: 'text_isEmpty', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: '', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_indexOf', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'text_indexOf', + inputs: { + VALUE: { + block: { + type: 'variables_get', }, }, - 'FIND': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + FIND: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_charAt', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'text_charAt', + inputs: { + VALUE: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'text_getSubstring', - 'inputs': { - 'STRING': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'text_getSubstring', + inputs: { + STRING: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'text_changeCase', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + kind: 'block', + type: 'text_changeCase', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_trim', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + kind: 'block', + type: 'text_trim', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_count', - 'inputs': { - 'SUB': { - 'shadow': { - 'type': 'text', + kind: 'block', + type: 'text_count', + inputs: { + SUB: { + shadow: { + type: 'text', }, }, - 'TEXT': { - 'shadow': { - 'type': 'text', + TEXT: { + shadow: { + type: 'text', }, }, }, }, { - 'kind': 'block', - 'type': 'text_replace', - 'inputs': { - 'FROM': { - 'shadow': { - 'type': 'text', + kind: 'block', + type: 'text_replace', + inputs: { + FROM: { + shadow: { + type: 'text', }, }, - 'TO': { - 'shadow': { - 'type': 'text', + TO: { + shadow: { + type: 'text', }, }, - 'TEXT': { - 'shadow': { - 'type': 'text', + TEXT: { + shadow: { + type: 'text', }, }, }, }, { - 'kind': 'block', - 'type': 'text_reverse', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', + kind: 'block', + type: 'text_reverse', + inputs: { + TEXT: { + shadow: { + type: 'text', }, }, }, }, { - 'kind': 'block', - 'type': 'add_text', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + kind: 'block', + type: 'add_text', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, - 'COLOR': { - 'shadow': { - 'type': 'colour_picker', - 'fields': { - 'COLOUR': '#aa00cc', + COLOR: { + shadow: { + type: 'colour_picker', + fields: { + COLOUR: '#aa00cc', }, }, }, @@ -520,176 +520,176 @@ export const toolbox = { ], }, { - 'kind': 'category', - 'name': 'Lists', - 'categorystyle': 'list_category', - 'contents': [ + kind: 'category', + name: 'Lists', + categorystyle: 'list_category', + contents: [ { - 'kind': 'block', - 'type': 'lists_create_with', + kind: 'block', + type: 'lists_create_with', }, { - 'kind': 'block', - 'type': 'lists_create_with', + kind: 'block', + type: 'lists_create_with', }, { - 'kind': 'block', - 'type': 'lists_repeat', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 5, + kind: 'block', + type: 'lists_repeat', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, }, }, }, }, }, { - 'kind': 'block', - 'type': 'lists_length', + kind: 'block', + type: 'lists_length', }, { - 'kind': 'block', - 'type': 'lists_isEmpty', + kind: 'block', + type: 'lists_isEmpty', }, { - 'kind': 'block', - 'type': 'lists_indexOf', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'lists_indexOf', + inputs: { + VALUE: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'lists_getIndex', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'lists_getIndex', + inputs: { + VALUE: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'lists_setIndex', - 'inputs': { - 'LIST': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'lists_setIndex', + inputs: { + LIST: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'lists_getSublist', - 'inputs': { - 'LIST': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'lists_getSublist', + inputs: { + LIST: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'lists_split', - 'inputs': { - 'DELIM': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': ',', + kind: 'block', + type: 'lists_split', + inputs: { + DELIM: { + shadow: { + type: 'text', + fields: { + TEXT: ',', }, }, }, }, }, { - 'kind': 'block', - 'type': 'lists_sort', + kind: 'block', + type: 'lists_sort', }, { - 'kind': 'block', - 'type': 'lists_reverse', + kind: 'block', + type: 'lists_reverse', }, ], }, { - 'kind': 'category', - 'name': 'Color', - 'categorystyle': 'colour_category', - 'contents': [ + kind: 'category', + name: 'Color', + categorystyle: 'colour_category', + contents: [ { - 'kind': 'block', - 'type': 'colour_picker', + kind: 'block', + type: 'colour_picker', }, { - 'kind': 'block', - 'type': 'colour_random', + kind: 'block', + type: 'colour_random', }, { - 'kind': 'block', - 'type': 'colour_rgb', - 'inputs': { - 'RED': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 100, + kind: 'block', + type: 'colour_rgb', + inputs: { + RED: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, }, }, }, - 'GREEN': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 50, + GREEN: { + shadow: { + type: 'math_number', + fields: { + NUM: 50, }, }, }, - 'BLUE': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 0, + BLUE: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, }, }, }, }, }, { - 'kind': 'block', - 'type': 'colour_blend', - 'inputs': { - 'COLOUR1': { - 'shadow': { - 'type': 'colour_picker', - 'fields': { - 'COLOUR': '#ff0000', + kind: 'block', + type: 'colour_blend', + inputs: { + COLOUR1: { + shadow: { + type: 'colour_picker', + fields: { + COLOUR: '#ff0000', }, }, }, - 'COLOUR2': { - 'shadow': { - 'type': 'colour_picker', - 'fields': { - 'COLOUR': '#3333ff', + COLOUR2: { + shadow: { + type: 'colour_picker', + fields: { + COLOUR: '#3333ff', }, }, }, - 'RATIO': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 0.5, + RATIO: { + shadow: { + type: 'math_number', + fields: { + NUM: 0.5, }, }, }, @@ -698,19 +698,19 @@ export const toolbox = { ], }, { - 'kind': 'sep', + kind: 'sep', }, { - 'kind': 'category', - 'name': 'Variables', - 'categorystyle': 'variable_category', - 'custom': 'VARIABLE', + kind: 'category', + name: 'Variables', + categorystyle: 'variable_category', + custom: 'VARIABLE', }, { - 'kind': 'category', - 'name': 'Functions', - 'categorystyle': 'procedure_category', - 'custom': 'PROCEDURE', + kind: 'category', + name: 'Functions', + categorystyle: 'procedure_category', + custom: 'PROCEDURE', }, ], }; diff --git a/examples/custom-toolbox-codelab/complete-code/custom_category_es6.js b/examples/custom-toolbox-codelab/complete-code/custom_category_es6.js index 486823bf48..12b70e8e53 100644 --- a/examples/custom-toolbox-codelab/complete-code/custom_category_es6.js +++ b/examples/custom-toolbox-codelab/complete-code/custom_category_es6.js @@ -23,7 +23,7 @@ class CustomCategory extends Blockly.ToolboxCategory { * This is called on category creation and whenever the theme changes. * @override */ - addColourBorder_(colour){ + addColourBorder_(colour) { this.rowDiv_.style.backgroundColor = colour; } @@ -33,7 +33,7 @@ class CustomCategory extends Blockly.ToolboxCategory { * false otherwise. * @override */ - setSelected(isSelected){ + setSelected(isSelected) { // We do not store the label span on the category, so use getElementsByClassName. const labelDom = this.rowDiv_.getElementsByClassName('blocklyTreeLabel')[0]; if (isSelected) { @@ -50,8 +50,11 @@ class CustomCategory extends Blockly.ToolboxCategory { this.iconDom_.style.color = 'white'; } // This is used for accessibility purposes. - Blockly.utils.aria.setState(/** @type {!Element} */ (this.htmlDiv_), - Blockly.utils.aria.State.SELECTED, isSelected); + Blockly.utils.aria.setState( + /** @type {!Element} */ (this.htmlDiv_), + Blockly.utils.aria.State.SELECTED, + isSelected, + ); } /** @@ -70,6 +73,8 @@ class CustomCategory extends Blockly.ToolboxCategory { } Blockly.registry.register( - Blockly.registry.Type.TOOLBOX_ITEM, - Blockly.ToolboxCategory.registrationName, - CustomCategory, true); + Blockly.registry.Type.TOOLBOX_ITEM, + Blockly.ToolboxCategory.registrationName, + CustomCategory, + true, +); diff --git a/examples/custom-toolbox-codelab/complete-code/index.html b/examples/custom-toolbox-codelab/complete-code/index.html index 515c97debb..3635b1fb28 100644 --- a/examples/custom-toolbox-codelab/complete-code/index.html +++ b/examples/custom-toolbox-codelab/complete-code/index.html @@ -1,387 +1,398 @@ - + + + + Toolbox Customization Codelab + + + + + + - - - Toolbox Customization Codelab - - - - - - + + - #blocklyDiv { - float: bottom; - height: 90%; - width: 100%; - } - - + +

Toolbox Customization Codelab

+
- -

Toolbox Customization Codelab

-
- - - - + + + - - diff --git a/examples/custom-toolbox-codelab/complete-code/index.js b/examples/custom-toolbox-codelab/complete-code/index.js index eed083c910..adddf0322c 100644 --- a/examples/custom-toolbox-codelab/complete-code/index.js +++ b/examples/custom-toolbox-codelab/complete-code/index.js @@ -4,8 +4,7 @@ let workspace = null; function start() { // Create main workspace. - workspace = Blockly.inject('blocklyDiv', - { - toolbox: document.getElementById('toolbox-categories'), - }); + workspace = Blockly.inject('blocklyDiv', { + toolbox: document.getElementById('toolbox-categories'), + }); } diff --git a/examples/custom-toolbox-codelab/complete-code/toolbox_label_es6.js b/examples/custom-toolbox-codelab/complete-code/toolbox_label_es6.js index 78e1f28ee6..401ffa42aa 100644 --- a/examples/custom-toolbox-codelab/complete-code/toolbox_label_es6.js +++ b/examples/custom-toolbox-codelab/complete-code/toolbox_label_es6.js @@ -57,6 +57,7 @@ class ToolboxLabel extends Blockly.ToolboxItem { } Blockly.registry.register( - Blockly.registry.Type.TOOLBOX_ITEM, - 'toolboxlabel', - ToolboxLabel); + Blockly.registry.Type.TOOLBOX_ITEM, + 'toolboxlabel', + ToolboxLabel, +); diff --git a/examples/custom-toolbox-codelab/starter-code/index.html b/examples/custom-toolbox-codelab/starter-code/index.html index 12f5eb06d4..ae5262dee4 100644 --- a/examples/custom-toolbox-codelab/starter-code/index.html +++ b/examples/custom-toolbox-codelab/starter-code/index.html @@ -1,384 +1,388 @@ - + + + + Toolbox Customization Codelab + + - - - Toolbox Customization Codelab - - + + - #blocklyDiv { - float: bottom; - height: 90%; - width: 100%; - } - - - - -

Toolbox Customization Codelab

-
- - - - - + +

Toolbox Customization Codelab

+
+ + + - - diff --git a/examples/custom-toolbox-codelab/starter-code/index.js b/examples/custom-toolbox-codelab/starter-code/index.js index 9683663bcf..adddf0322c 100644 --- a/examples/custom-toolbox-codelab/starter-code/index.js +++ b/examples/custom-toolbox-codelab/starter-code/index.js @@ -4,8 +4,7 @@ let workspace = null; function start() { // Create main workspace. - workspace = Blockly.inject('blocklyDiv', - { - toolbox: document.getElementById('toolbox-categories'), - }); + workspace = Blockly.inject('blocklyDiv', { + toolbox: document.getElementById('toolbox-categories'), + }); } diff --git a/examples/custom-tooltips-demo/README.md b/examples/custom-tooltips-demo/README.md index be269653b8..f2c6925e5e 100644 --- a/examples/custom-tooltips-demo/README.md +++ b/examples/custom-tooltips-demo/README.md @@ -7,4 +7,5 @@ This is a demo of the custom tooltip API. This isn't a plugin that can be instal Create a function that takes two parameters. The first is the div element to render the tooltip DOM into. The second is the element being moused over. You can get the tooltip string for the element by calling `Blockly.Tooltip.getTooltipOfObject(element)`. Do any custom logic you like to render the tooltip into the given div. Register your function with Blockly by calling `Blockly.Tooltip.setCustomTooltip(yourFunction)`. Your function will be called instead of the default rendering logic whenever a tooltip should be shown. ## License + Apache 2.0 diff --git a/examples/custom-tooltips-demo/index.html b/examples/custom-tooltips-demo/index.html index 918454f37e..021ca334a2 100644 --- a/examples/custom-tooltips-demo/index.html +++ b/examples/custom-tooltips-demo/index.html @@ -1,23 +1,22 @@ - + + + + Blockly Custom Tooltip Example + + + + + + + - - - Blockly Custom Tooltip Example - - - - - - - - - -
- - + +
+ diff --git a/examples/custom-tooltips-demo/index.js b/examples/custom-tooltips-demo/index.js index 9eabacd540..002383c099 100644 --- a/examples/custom-tooltips-demo/index.js +++ b/examples/custom-tooltips-demo/index.js @@ -8,7 +8,6 @@ * @fileoverview Test page for example plugin showing custom tooltip rendering. */ - /** * Create and register the custom tooltip rendering function. * This could be extracted into a plugin if desired. @@ -18,7 +17,7 @@ function initTooltips() { // a tooltip is shown in Blockly. The first argument is the div to render // the content into. The second argument is the element to show the tooltip // for. - const customTooltip = function(div, element) { + const customTooltip = function (div, element) { if (element instanceof Blockly.BlockSvg) { // You can access the block being moused over. // Here we get the color of the block to set the background color. @@ -58,9 +57,9 @@ function createWorkspace(blocklyDiv, options) { return workspace; } -document.addEventListener('DOMContentLoaded', function() { +document.addEventListener('DOMContentLoaded', function () { Blockly.Blocks['custom_tooltip_1'] = { - init: function() { + init: function () { this.appendDummyInput().appendField('This is a test block.'); this.setColour(150); this.setTooltip('This is a regular tooltip.'); @@ -68,7 +67,7 @@ document.addEventListener('DOMContentLoaded', function() { }, }; Blockly.Blocks['custom_tooltip_2'] = { - init: function() { + init: function () { this.appendDummyInput().appendField('Mouse over me.'); this.setColour(150); this.setTooltip('Tip: This tooltip has an image.'); @@ -79,10 +78,10 @@ document.addEventListener('DOMContentLoaded', function() { }; const defaultOptions = { toolbox: { - 'kind': 'flyoutToolbox', - 'contents': [ - {'kind': 'block', 'type': 'custom_tooltip_1'}, - {'kind': 'block', 'type': 'custom_tooltip_2'}, + kind: 'flyoutToolbox', + contents: [ + {kind: 'block', type: 'custom_tooltip_1'}, + {kind: 'block', type: 'custom_tooltip_2'}, ], }, }; @@ -90,5 +89,8 @@ document.addEventListener('DOMContentLoaded', function() { // createPlayground is from @blockly/dev-tools. // eslint-disable-next-line no-undef createPlayground( - document.getElementById('root'), createWorkspace, defaultOptions); + document.getElementById('root'), + createWorkspace, + defaultOptions, + ); }); diff --git a/examples/devsite-demo/index.html b/examples/devsite-demo/index.html index b9eb633bea..e95284a67f 100644 --- a/examples/devsite-demo/index.html +++ b/examples/devsite-demo/index.html @@ -1,12 +1,11 @@ - Blockly Demo - - - - + + + + @@ -33,11 +32,16 @@ -
+

       
- +
diff --git a/examples/devsite-demo/msgs.js b/examples/devsite-demo/msgs.js index eadb904ab3..79a3428256 100644 --- a/examples/devsite-demo/msgs.js +++ b/examples/devsite-demo/msgs.js @@ -13,18 +13,18 @@ * Lookup for names of languages. Keys should be in ISO 639 format. */ const LANGUAGE_NAME = { -// 'ace': 'بهسا اچيه', // RTL -// 'af': 'Afrikaans', + // 'ace': 'بهسا اچيه', // RTL + // 'af': 'Afrikaans', 'am': 'አማርኛ', - 'ar': 'العربية', // RTL -// 'az': 'Azərbaycanca', + 'ar': 'العربية', // RTL + // 'az': 'Azərbaycanca', 'be': 'беларускі', 'be-tarask': 'Taraškievica', 'bg': 'български език', 'bn': 'বাংলা', 'br': 'Brezhoneg', 'ca': 'Català', -// 'cdo': '閩東語', + // 'cdo': '閩東語', 'cs': 'Česky', 'da': 'Dansk', 'de': 'Deutsch', @@ -33,18 +33,18 @@ const LANGUAGE_NAME = { 'eo': 'Esperanto', 'es': 'Español', 'eu': 'Euskara', - 'fa': 'فارسی', // RTL + 'fa': 'فارسی', // RTL 'fi': 'Suomi', 'fo': 'Føroyskt', 'fr': 'Français', -// 'frr': 'Frasch', + // 'frr': 'Frasch', 'gl': 'Galego', 'ha': 'Hausa', -// 'hak': '客家話', - 'he': 'עברית', // RTL + // 'hak': '客家話', + 'he': 'עברית', // RTL 'hi': 'हिन्दी', 'hr': 'Hrvatski', -// 'hrx': 'Hunsrik', + // 'hrx': 'Hunsrik', 'hu': 'Magyar', 'hy': 'հայերէն', 'ia': 'Interlingua', @@ -53,1025 +53,1023 @@ const LANGUAGE_NAME = { 'is': 'Íslenska', 'it': 'Italiano', 'ja': '日本語', -// 'ka': 'ქართული', + // 'ka': 'ქართული', 'kab': 'Taqbaylit', -// 'km': 'ភាសាខ្មែរ', + // 'km': 'ភាសាខ្មែរ', 'kn': 'ಕನ್ನಡ', 'ko': '한국어', -// 'ksh': 'Ripoarėsch', -// 'ky': 'Кыргызча', -// 'la': 'Latine', -// 'lb': 'Lëtzebuergesch', + // 'ksh': 'Ripoarėsch', + // 'ky': 'Кыргызча', + // 'la': 'Latine', + // 'lb': 'Lëtzebuergesch', 'lt': 'Lietuvių', 'lv': 'Latviešu', -// 'mg': 'Malagasy', -// 'ml': 'മലയാളം', -// 'mk': 'Македонски', -// 'mr': 'मराठी', + // 'mg': 'Malagasy', + // 'ml': 'മലയാളം', + // 'mk': 'Македонски', + // 'mr': 'मराठी', 'ms': 'Bahasa Melayu', 'my': 'မြန်မာစာ', -// 'mzn': 'مازِرونی', // RTL + // 'mzn': 'مازِرونی', // RTL 'nb': 'Norsk (bokmål)', 'nl': 'Nederlands, Vlaams', -// 'oc': 'Lenga d\'òc', -// 'pa': 'पंजाबी', + // 'oc': 'Lenga d\'òc', + // 'pa': 'पंजाबी', 'pl': 'Polski', 'pms': 'Piemontèis', -// 'ps': 'پښتو', // RTL + // 'ps': 'پښتو', // RTL 'pt': 'Português', 'pt-br': 'Português Brasileiro', 'ro': 'Română', 'ru': 'Русский', 'sc': 'Sardu', -// 'sco': 'Scots', -// 'si': 'සිංහල', + // 'sco': 'Scots', + // 'si': 'සිංහල', 'sk': 'Slovenčina', 'sl': 'Slovenščina', -// 'smn': 'Anarâškielâ', + // 'smn': 'Anarâškielâ', 'sq': 'Shqip', 'sr': 'Српски', 'sr-latn': 'Srpski', 'sv': 'Svenska', -// 'sw': 'Kishwahili', -// 'ta': 'தமிழ்', + // 'sw': 'Kishwahili', + // 'ta': 'தமிழ்', 'th': 'ภาษาไทย', 'ti': 'ትግርኛ', -// 'tl': 'Tagalog', + // 'tl': 'Tagalog', 'tr': 'Türkçe', 'uk': 'Українська', - 'ur': 'اُردُو‬', // RTL + 'ur': 'اُردُو‬', // RTL 'vi': 'Tiếng Việt', 'yo': 'Èdè Yorùbá', 'zh-hans': '简体中文', 'zh-hant': '正體中文', }; - /** * List of RTL languages. */ const LANGUAGE_RTL = [/* 'ace',*/ 'ar', 'fa', 'he', /* 'mzn', 'ps',*/ 'ur']; - /** * Category names in every language. */ const msgs = { - "ab": { - "Logic": "Алогика", - "Loops": "Ациклқәа", - "Math": "Аматематика", - "Text": "Атеқст", - "Lists": "Ахьӡынҵақәа", - "Colour": "Аԥштәы", - "Variables": "Аҽеиҭакқәа", - "Procedures": "Афункциақәа" - }, - "ace": { - "Logic": "Logis", - "Loops": "Kuwien", - "Math": "Matematik", - "Text": "Haraih", - "Lists": "Dapeuta", - "Colour": "Wareuna", - "Variables": "Meumacam", - "Procedures": "Prosedur" - }, - "am": { - "Logic": "የሁኔታዊ መገንቢያ ብሎኮች", - "Loops": "የዙሮች መገንቢያ ብሎኮች", - "Math": "የሂሳብ መገንቢያ ብሎኮች", - "Text": "የጽሕፈት መገንቢያ ብሎኮች", - "Lists": "የዝርዝር መገንቢያ ብሎኮች", - "Colour": "የቀለም መገንቢያ ብሎኮች", - "Variables": "የተላውጠ ቃላት መገንቢያ ብሎኮች", - "Procedures": "የመላዎች መገንቢያ ብሎኮች" - }, - "ar": { - "Logic": "منطق", - "Loops": "الحلقات", - "Math": "رياضيات", - "Text": "نص", - "Lists": "قوائم", - "Colour": "لون", - "Variables": "متغيرات", - "Procedures": "إجراءات" - }, - "ast": { - "Logic": "Lóxica", - "Loops": "Bucles", - "Math": "Matemátiques", - "Text": "Testu", - "Lists": "Llistes", - "Colour": "Color", - "Variables": "Variables", - "Procedures": "Funciones" - }, - "az": { - "Logic": "Məntiq", - "Loops": "Dövrə", - "Math": "Riyazi", - "Text": "Mətn", - "Lists": "Siyahılar", - "Colour": "Rəng", - "Variables": "Dəyişənlər", - "Procedures": "Funksiyalar" - }, - "ba": { - "Logic": " Танылыу", - "Loops": " Циклдар", - "Math": "Математика", - "Text": "Текст", - "Lists": "Исемлектәр", - "Colour": "Төҫ", - "Variables": " Үҙгәреүсән дәүмәлдәр", - "Procedures": " Функциялар" - }, - "be-tarask": { - "Logic": "Лёгіка", - "Loops": "Петлі", - "Math": "Матэматычныя формулы", - "Text": "Тэкст", - "Lists": "Сьпісы", - "Colour": "Колер", - "Variables": "Зьменныя", - "Procedures": "Функцыі" - }, - "be": { - "Logic": "Логіка", - "Loops": "Цыклы", - "Math": "Матэматыка", - "Text": "Тэкст", - "Lists": "Спісы", - "Colour": "Колер", - "Variables": "Пераменныя", - "Procedures": "Функцыі" - }, - "bg": { - "Logic": "Логика", - "Loops": "Цикли", - "Math": "Математика", - "Text": "Текст", - "Lists": "Списъци", - "Colour": "Цвят", - "Variables": "Променливи", - "Procedures": "Функции" - }, - "bn": { - "Logic": "যুক্তি", - "Loops": "লুপসমূহ", - "Math": "গণিত", - "Text": "লেখা", - "Lists": "তালিকাসমূহ", - "Colour": "রং", - "Variables": "চলকগুলো", - "Procedures": "ক্রিয়া" - }, - "br": { - "Logic": "Poell", - "Loops": "Rodelloù", - "Math": "Matematik", - "Text": "Testenn", - "Lists": "Rolloù", - "Colour": "Liv", - "Variables": "Argemmennoù", - "Procedures": "Arc'hwelioù" - }, - "ca": { - "Logic": "Lògica", - "Loops": "Bucles", - "Math": "Matemàtiques", - "Text": "Text", - "Lists": "Llistes", - "Colour": "Color", - "Variables": "Variables", - "Procedures": "Procediments" - }, - "cs": { - "Logic": "Logika", - "Loops": "Smyčky", - "Math": "Matika", - "Text": "Text", - "Lists": "Seznamy", - "Colour": "Barva", - "Variables": "Proměnné", - "Procedures": "Procedury" - }, - "da": { - "Logic": "Logik", - "Loops": "Løkker", - "Math": "Matematik", - "Text": "Tekst", - "Lists": "Lister", - "Colour": "Farve", - "Variables": "Variabler", - "Procedures": "Funktioner" - }, - "de": { - "Logic": "Logik", - "Loops": "Schleifen", - "Math": "Mathematik", - "Text": "Text", - "Lists": "Listen", - "Colour": "Farbe", - "Variables": "Variablen", - "Procedures": "Funktionen" - }, - "diq": { - "Logic": "Mentıq", - "Loops": "Dingeki", - "Math": "Matematik", - "Text": "Metın", - "Lists": "Listeyi", - "Colour": "Reng", - "Variables": "Vırneyeni", - "Procedures": "Fonksiyoni" - }, - "el": { - "Logic": "Λογική", - "Loops": "Επαναλήψεις", - "Math": "Μαθηματικά", - "Text": "Κείμενο", - "Lists": "Λίστες", - "Colour": "Χρώμα", - "Variables": "Μεταβλητές", - "Procedures": "Συναρτήσεις" - }, - "en": { - "Logic": "Logic", - "Loops": "Loops", - "Math": "Math", - "Text": "Text", - "Lists": "Lists", - "Colour": "Colour", - "Variables": "Variables", - "Procedures": "Functions" - }, - "eo": { - "Logic": "Logika", - "Loops": "Cikloj", - "Math": "Matematika", - "Text": "Teksto", - "Lists": "Listoj", - "Colour": "Koloro", - "Variables": "Variabloj", - "Procedures": "Funkcioj" - }, - "es": { - "Logic": "Lógica", - "Loops": "Bucles", - "Math": "Matemáticas", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Color", - "Variables": "Variables", - "Procedures": "Funciones" - }, - "et": { - "Logic": "Loogika", - "Loops": "Silmad", - "Math": "Matemaatika", - "Text": "Tekst", - "Lists": "Loendid", - "Colour": "Värv", - "Variables": "Muutujad", - "Procedures": "Funktsioonid" - }, - "eu": { - "Logic": "Logika", - "Loops": "Begiztak", - "Math": "Matematika", - "Text": "Testua", - "Lists": "Zerrendak", - "Colour": "Kolorea", - "Variables": "Aldagaiak", - "Procedures": "Prozedurak" - }, - "fa": { - "Logic": "منطق", - "Loops": "حلقه‌ها", - "Math": "ریاضی", - "Text": "متن", - "Lists": "فهرست‌ها", - "Colour": "رنگ", - "Variables": "متغییرها", - "Procedures": "توابع" - }, - "fi": { - "Logic": "Logiikka", - "Loops": "Silmukat", - "Math": "Matematiikka", - "Text": "Teksti", - "Lists": "Listat", - "Colour": "Väri", - "Variables": "Muuttujat", - "Procedures": "Funktiot" - }, - "fo": { - "Logic": "Logikkur", - "Loops": "Lykkjur", - "Math": "Støddfrøði", - "Text": "Tekstur", - "Lists": "Listar", - "Colour": "Litur", - "Variables": "Variablar", - "Procedures": "Funktiónir" - }, - "fr": { - "Logic": "Logique", - "Loops": "Boucles", - "Math": "Mathématiques", - "Text": "Texte", - "Lists": "Listes", - "Colour": "Couleur", - "Variables": "Variables", - "Procedures": "Fonctions" - }, - "gl": { - "Logic": "Lóxica", - "Loops": "Bucles", - "Math": "Matemáticas", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Cor", - "Variables": "Variables", - "Procedures": "Funcións" - }, - "gn": { - "Logic": "Kuaarape", - "Loops": "Tapykuegua", - "Math": "Papapykuaa", - "Text": "Jehaipy", - "Lists": "Tysýi", - "Colour": "Sa'y", - "Variables": "Ñemoambuéva", - "Procedures": "Aporeko" - }, - "ha": { - "Logic": "Dabara", - "Loops": "Tsallake-tsallake", - "Math": "Lissafi", - "Text": "Rubutu", - "Lists": "Jeri", - "Colour": "Launi", - "Variables": "Siffofi", - "Procedures": "Aikace-aikace" - }, - "hak": { - "Math": "Sṳ-ho̍k kûng-sṳt", - "Text": "文字", - "Lists": "列表", - "Colour": "顏色", - "Variables": "變量", - "Procedures": "函數" - }, - "he": { - "Logic": "לוגיקה", - "Loops": "לולאות", - "Math": "מתמטיקה", - "Text": "טקסט", - "Lists": "רשימות", - "Colour": "צבע", - "Variables": "משתנים", - "Procedures": "פונקציות" - }, - "hi": { - "Logic": "तर्क", - "Loops": "लूप", - "Math": "गणित", - "Text": "टेक्स्ट", - "Lists": "सूचियाँ", - "Colour": "रंग", - "Variables": "चर", - "Procedures": "प्रोसीजर" - }, - "hr": { - "Logic": "Logika", - "Loops": "Petlje", - "Math": "Matematika", - "Text": "Tekst", - "Lists": "Liste", - "Colour": "Boja", - "Variables": "Varijable", - "Procedures": "Funkcije" - }, - "hrx": { - "Logic": "Logik", - "Loops": "Schleife", - "Math": "Mathematik", - "Text": "Text", - "Lists": "Liste", - "Colour": "Farreb", - "Variables": "Variable", - "Procedures": "Funktione" - }, - "hu": { - "Logic": "Logika", - "Loops": "Ciklusok", - "Math": "Matek", - "Text": "Szövegkezelés", - "Lists": "Listakezelés", - "Colour": "Színek", - "Variables": "Változók", - "Procedures": "Eljárások" - }, - "hy": { - "Logic": "Տրամաբանական", - "Loops": "Կրկնող հանգույցներ", - "Math": "Մաթեմատիկա", - "Text": "Տեքստ", - "Lists": "Ցանկեր", - "Colour": "Գույն", - "Variables": "Փոփոխականներ", - "Procedures": "Գործառույթներ" - }, - "ia": { - "Logic": "Logica", - "Loops": "Buclas", - "Math": "Mathematica", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Color", - "Variables": "Variabiles", - "Procedures": "Functiones" - }, - "id": { - "Logic": "Logika", - "Loops": "Perulangan", - "Math": "Matematika", - "Text": "Teks", - "Lists": "Daftar", - "Colour": "Warna", - "Variables": "Variabel", - "Procedures": "Fungsi" - }, - "ig": { - "Logic": "Lọgịk", - "Loops": "Meghachi", - "Math": "Mgbakọ na mwepụ", - "Text": "Ederede", - "Lists": "Ndepụta", - "Colour": "Agba", - "Variables": "Agbanwe", - "Procedures": "Ọrụ" - }, - "inh": { - "Logic": "Логика", - "Loops": "Циклаш", - "Math": "Математика", - "Text": "Текст", - "Lists": "Спискаш", - "Colour": "Бoс", - "Variables": "Хувцалушъяраш", - "Procedures": "Функцеш" - }, - "is": { - "Logic": "Rökvísi", - "Loops": "Lykkjur", - "Math": "Reikningur", - "Text": "Texti", - "Lists": "Listar", - "Colour": "Litir", - "Variables": "Breytur", - "Procedures": "Föll" - }, - "it": { - "Logic": "Logica", - "Loops": "Cicli", - "Math": "Matematica", - "Text": "Testo", - "Lists": "Elenchi", - "Colour": "Colore", - "Variables": "Variabili", - "Procedures": "Funzioni" - }, - "ja": { - "Logic": "論理", - "Loops": "繰り返し", - "Math": "数学", - "Text": "テキスト", - "Lists": "リスト", - "Colour": "色", - "Variables": "変数", - "Procedures": "関数" - }, - "kab": { - "Logic": "Tameẓla", - "Loops": "Tiyerrisin", - "Math": "Tusnakt", - "Text": "Aḍris", - "Lists": "Tibdarin", - "Colour": "Ini", - "Variables": "Imuttiyen", - "Procedures": "Tiwuriwin" - }, - "kbd-cyrl": { - "Math": "Математикэ", - "Text": "Тхыгъэ", - "Lists": "КъебжэкI", - "Colour": "Плъыфэ" - }, - "kn": { - "Logic": "ತರ್ಕ", - "Loops": "ಸುತ್ತುಗಳು", - "Math": "ಗಣಿತ", - "Text": "ಪಠ್ಯ", - "Lists": "ಪಟ್ಟಿಗಳು", - "Colour": "ಬಣ್ಣ", - "Variables": "ಚರಾಂಶಗಳು", - "Procedures": "ಕಾರ್ಯಘಟಕಗಳು" - }, - "ko": { - "Logic": "논리", - "Loops": "반복", - "Math": "수학", - "Text": "문자열", - "Lists": "목록", - "Colour": "색", - "Variables": "변수", - "Procedures": "함수" - }, - "ku-latn": { - "Text": "Nivîs", - "Lists": "Lîste", - "Colour": "Reng" - }, - "lb": { - "Logic": "Logik", - "Loops": "Schleefen", - "Math": "Mathematik", - "Text": "Text", - "Lists": "Lëschten", - "Colour": "Faarf", - "Variables": "Variabelen", - "Procedures": "Funktiounen" - }, - "lki": { - "Logic": "منطق", - "Loops": "حلقه‌ها", - "Math": "ریاضی", - "Text": "متن", - "Lists": "لیستةل", - "Colour": "رةنگ", - "Variables": "متغییرها", - "Procedures": "توابع" - }, - "lrc": { - "Logic": "عٱقلمٱنی", - "Loops": "هٱلقٱیا", - "Math": "هساو کتاو", - "Text": "مٱتن", - "Lists": "نومگٱیا", - "Colour": "رٱنڳ", - "Variables": "آلشتؽا", - "Procedures": "رویٱیا" - }, - "lt": { - "Logic": "Logika", - "Loops": "Kartojimas", - "Math": "Matematika", - "Text": "Tekstas", - "Lists": "Sąrašai", - "Colour": "Spalva", - "Variables": "Kintamieji", - "Procedures": "Funkcijos" - }, - "lv": { - "Logic": "Loģika", - "Loops": "Cikli", - "Math": "Matemātika", - "Text": "Teksts", - "Lists": "Saraksti", - "Colour": "Krāsa", - "Variables": "Mainīgie", - "Procedures": "Funkcijas" - }, - "mg": { - "Logic": "Lôjika", - "Loops": "Tondro mifolaka", - "Math": "Matematika", - "Text": "Soratra", - "Lists": "Lisitra", - "Colour": "Loko", - "Variables": "Ova", - "Procedures": "Paika" - }, - "mk": { - "Logic": "Логика", - "Loops": "Јамки", - "Math": "Математика", - "Text": "Текст", - "Lists": "Списоци", - "Colour": "Боја", - "Variables": "Променливи", - "Procedures": "Функции" - }, - "mr": { - "Loops": "वेटोळ्या(लूप्स)", - "Text": "मजकूर", - "Colour": "रंग", - "Variables": "अस्थिरके" - }, - "ms": { - "Logic": "Logik", - "Loops": "Gelung", - "Math": "Matematik", - "Text": "Teks", - "Lists": "Senarai", - "Colour": "Warna", - "Variables": "Pemboleh ubah", - "Procedures": "Fungsi" - }, - "my": { - "Logic": "ယုတ္တိ", - "Loops": "ကွင်း", - "Math": "သင်္ချာ", - "Text": "စာသား", - "Lists": "စာရင်းများ", - "Colour": "အရောင်", - "Variables": "အမျိုးမျိုးပြောင်းလဲနိုင်သော", - "Procedures": "လုပ်ဆောင်ချက်များ" - }, - "nb": { - "Logic": "Logikk", - "Loops": "Løkker", - "Math": "Matte", - "Text": "Tekst", - "Lists": "Lister", - "Colour": "Farge", - "Variables": "Variabler", - "Procedures": "Funksjoner" - }, - "ne": { - "Logic": "लजिक", - "Loops": "लुपहरू", - "Math": "गणित", - "Text": "पाठ", - "Lists": "सूची", - "Colour": "रंग", - "Variables": "चल राशी(variables)", - "Procedures": "अनुक्रियाहरु" - }, - "nl": { - "Logic": "Logica", - "Loops": "Lussen", - "Math": "Formules", - "Text": "Tekst", - "Lists": "Lijsten", - "Colour": "Kleur", - "Variables": "Variabelen", - "Procedures": "Functies" - }, - "oc": { - "Logic": "Logic", - "Loops": "Boclas", - "Math": "Math", - "Text": "Tèxte", - "Lists": "Listas", - "Colour": "Color", - "Variables": "Variablas", - "Procedures": "Foncions" - }, - "olo": { - "Logic": "Lougiekku", - "Loops": "Čiepit", - "Math": "Matemuatiekku", - "Text": "Tekstu", - "Lists": "Listat", - "Colour": "Väri", - "Variables": "Variantat" - }, - "pa": { - "Math": "ਹਿਸਾਬ", - "Text": "ਲਿਖਤ", - "Lists": "ਸੂਚੀਆਂ", - "Colour": "ਰੰਗ", - "Variables": "ਬਦਲਣਹਾਰ" - }, - "pl": { - "Logic": "Logika", - "Loops": "Pętle", - "Math": "Matematyka", - "Text": "Tekst", - "Lists": "Listy", - "Colour": "Kolor", - "Variables": "Zmienne", - "Procedures": "Funkcje" - }, - "pms": { - "Logic": "Lògica", - "Loops": "Liasse", - "Math": "Matemàtica", - "Text": "Test", - "Lists": "Liste", - "Colour": "Color", - "Variables": "Variàbij", - "Procedures": "Fonsion" - }, - "ps": { - "Logic": "منطق", - "Math": "شمېرپوهنه", - "Text": "متن", - "Lists": "لړليکونه", - "Colour": "رنگ" - }, - "pt-br": { - "Logic": "Lógica", - "Loops": "Laços", - "Math": "Matemática", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Cor", - "Variables": "Variáveis", - "Procedures": "Funções" - }, - "pt": { - "Logic": "Lógica", - "Loops": "Ciclos", - "Math": "Matemática", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Cor", - "Variables": "Variáveis", - "Procedures": "Funções" - }, - "ro": { - "Logic": "Logic", - "Loops": "Bucle", - "Math": "Matematică", - "Text": "Text", - "Lists": "Liste", - "Colour": "Culoare", - "Variables": "Variabile", - "Procedures": "Funcții" - }, - "ru": { - "Logic": "Логика", - "Loops": "Циклы", - "Math": "Математика", - "Text": "Текст", - "Lists": "Списки", - "Colour": "Цвет", - "Variables": "Переменные", - "Procedures": "Функции" - }, - "sc": { - "Logic": "Lògica", - "Loops": "Lòrigas", - "Math": "Matemàtica", - "Text": "Testu", - "Lists": "Lista", - "Colour": "Colori", - "Variables": "Variabilis", - "Procedures": "Funtzionis" - }, - "sco": { - "Logic": "Logeec", - "Loops": "Luips", - "Math": "Maths", - "Text": "Tex", - "Lists": "Leets", - "Colour": "Colour", - "Variables": "Variables", - "Procedures": "Functions" - }, - "sd": { - "Logic": "منطق", - "Loops": "چڪر", - "Math": "رياضي", - "Text": "اکر", - "Lists": "فھرست", - "Colour": "رنگ", - "Variables": "ڦرڻا", - "Procedures": "عمل" - }, - "si": { - "Logic": "තර්කය", - "Math": "ගණිතමය", - "Text": "පෙළ", - "Lists": "ලැයිස්තු", - "Colour": "පාට", - "Variables": "විචල්‍යයන්", - "Procedures": "ශ්‍රිත" - }, - "sk": { - "Logic": "Logické", - "Loops": "Slučky", - "Math": "Matematika", - "Text": "Textové", - "Lists": "Zoznamy", - "Colour": "Farba", - "Variables": "Premenné", - "Procedures": "Funkcie" - }, - "skr-arab": { - "Logic": "منطق", - "Loops": "لوپاں", - "Math": "ریاضی", - "Text": "ٹیکسٹ", - "Lists": "فہرستاں", - "Colour": "رنگ", - "Variables": "متغیرات", - "Procedures": "فنکشن" - }, - "sl": { - "Logic": "Logika", - "Loops": "Zanke", - "Math": "Matematika", - "Text": "Besedilo", - "Lists": "Seznami", - "Colour": "Barva", - "Variables": "Spremenljivke", - "Procedures": "Funkcije" - }, - "smn": { - "Logic": "Loogiik", - "Loops": "Váárvuh", - "Math": "Matematiik", - "Text": "Tekstâ", - "Lists": "Listoh", - "Colour": "Ivne", - "Variables": "Muttojeijee", - "Procedures": "Funktioh" - }, - "sq": { - "Logic": "Logjikë", - "Loops": "Qark", - "Math": "Matematikë", - "Text": "Tekst", - "Lists": "Listat", - "Colour": "Ngjyrë", - "Variables": "Variablat", - "Procedures": "Funksionet" - }, - "sr-latn": { - "Logic": "Logika", - "Loops": "Petlje", - "Math": "Matematika", - "Text": "Tekst", - "Lists": "Spiskovi", - "Colour": "Boja", - "Variables": "Promenljive", - "Procedures": "Funkcije" - }, - "sr": { - "Logic": "Логика", - "Loops": "Петље", - "Math": "Математика", - "Text": "Текст", - "Lists": "Спискови", - "Colour": "Боја", - "Variables": "Променљиве", - "Procedures": "Функције" - }, - "sv": { - "Logic": "Logik", - "Loops": "Loopar", - "Math": "Matematik", - "Text": "Text", - "Lists": "Listor", - "Colour": "Färg", - "Variables": "Variabler", - "Procedures": "Funktioner" - }, - "ta": { - "Logic": "தர்க்கம்", - "Loops": "மடக்குக்கட்டளை", - "Math": "கணிதம்", - "Text": "உரை", - "Lists": "பட்டியல்", - "Colour": "நிறம்", - "Variables": "மாறி", - "Procedures": "செயலாற்றிகள்" - }, - "tcy": { - "Logic": "ವಾದೊ", - "Loops": "ಲೂಪ್‍ಲು", - "Math": "ಲೆಕ್ಕೊ", - "Text": "ಪಟ್ಯೊ", - "Lists": "ಪಟ್ಟಿಲು", - "Colour": "ಬನ್ನೊ", - "Variables": "ವ್ಯತ್ಯಯೊಲು", - "Procedures": "ಲೇಸ್‍ಲು" - }, - "te": { - "Logic": "తర్కం", - "Loops": "లూప్స్", - "Math": "గణితం", - "Text": "పాఠ్యం", - "Lists": "జాబితాలు", - "Colour": "రంగు", - "Variables": "చరరాశులు", - "Procedures": "ప్రమేయాలు" - }, - "th": { - "Logic": "ตรรกะ", - "Loops": "การวนซ้ำ", - "Math": "คณิตศาสตร์", - "Text": "ข้อความ", - "Lists": "รายการ", - "Colour": "สี", - "Variables": "ตัวแปร", - "Procedures": "ฟังก์ชัน" - }, - "ti": { - "Logic": "ሎጂክ", - "Loops": "ኣዝዋሪታት", - "Math": "ሒሳብ", - "Text": "ጽሑፍ", - "Lists": "ዝርዝር", - "Colour": "ሕብሪ", - "Variables": "ተተካእቲ", - "Procedures": "ፋንክሽናት" - }, - "tr": { - "Logic": "Mantık", - "Loops": "Döngüler", - "Math": "Matematik", - "Text": "Metin", - "Lists": "Listeler", - "Colour": "Renk", - "Variables": "Değişkenler", - "Procedures": "İşlevler" - }, - "uk": { - "Logic": "Логіка", - "Loops": "Цикли", - "Math": "Математика", - "Text": "Текст", - "Lists": "Списки", - "Colour": "Колір", - "Variables": "Змінні", - "Procedures": "Функції" - }, - "ur": { - "Logic": "منطق", - "Loops": "لوپیں", - "Math": "ریاضی", - "Text": "متن", - "Lists": "فہرستیں", - "Colour": "رنگ", - "Variables": "متغیرات", - "Procedures": "افعال" - }, - "uz": { - "Logic": "Mantiq", - "Loops": "Tsikllar", - "Math": "Matematika", - "Text": "Matn", - "Lists": "Roʻyxatlar", - "Colour": "Rang", - "Variables": "O'zgaruvchilar", - "Procedures": "Funksiyalar" - }, - "vi": { - "Logic": "Logic", - "Loops": "Vòng lặp", - "Math": "Công thức toán", - "Text": "Văn bản", - "Lists": "Danh sách", - "Colour": "Màu", - "Variables": "Biến", - "Procedures": "Hàm" - }, - "yo": { - "Logic": "Irogun", - "Loops": "Ilosiwaju losehin", - "Math": "Isiro", - "Text": "Ọrọ", - "Lists": "Akojọ", - "Colour": "Awọ", - "Variables": "Oniruru", - "Procedures": "Iṣe" - }, - "yue": { - "Logic": "邏輯", - "Loops": "循環", - "Math": "數學", - "Text": "發短信", - "Lists": "一覽", - "Colour": "顏色", - "Variables": "變數", - "Procedures": "功能" - }, - "zh-hans": { - "Logic": "逻辑", - "Loops": "循环", - "Math": "数学", - "Text": "文本", - "Lists": "列表", - "Colour": "颜色", - "Variables": "变量", - "Procedures": "函数" - }, - "zh-hant": { - "Logic": "邏輯", - "Loops": "迴圈", - "Math": "運算", - "Text": "文字", - "Lists": "清單", - "Colour": "顏色", - "Variables": "變數", - "Procedures": "函式" - } + 'ab': { + Logic: 'Алогика', + Loops: 'Ациклқәа', + Math: 'Аматематика', + Text: 'Атеқст', + Lists: 'Ахьӡынҵақәа', + Colour: 'Аԥштәы', + Variables: 'Аҽеиҭакқәа', + Procedures: 'Афункциақәа', + }, + 'ace': { + Logic: 'Logis', + Loops: 'Kuwien', + Math: 'Matematik', + Text: 'Haraih', + Lists: 'Dapeuta', + Colour: 'Wareuna', + Variables: 'Meumacam', + Procedures: 'Prosedur', + }, + 'am': { + Logic: 'የሁኔታዊ መገንቢያ ብሎኮች', + Loops: 'የዙሮች መገንቢያ ብሎኮች', + Math: 'የሂሳብ መገንቢያ ብሎኮች', + Text: 'የጽሕፈት መገንቢያ ብሎኮች', + Lists: 'የዝርዝር መገንቢያ ብሎኮች', + Colour: 'የቀለም መገንቢያ ብሎኮች', + Variables: 'የተላውጠ ቃላት መገንቢያ ብሎኮች', + Procedures: 'የመላዎች መገንቢያ ብሎኮች', + }, + 'ar': { + Logic: 'منطق', + Loops: 'الحلقات', + Math: 'رياضيات', + Text: 'نص', + Lists: 'قوائم', + Colour: 'لون', + Variables: 'متغيرات', + Procedures: 'إجراءات', + }, + 'ast': { + Logic: 'Lóxica', + Loops: 'Bucles', + Math: 'Matemátiques', + Text: 'Testu', + Lists: 'Llistes', + Colour: 'Color', + Variables: 'Variables', + Procedures: 'Funciones', + }, + 'az': { + Logic: 'Məntiq', + Loops: 'Dövrə', + Math: 'Riyazi', + Text: 'Mətn', + Lists: 'Siyahılar', + Colour: 'Rəng', + Variables: 'Dəyişənlər', + Procedures: 'Funksiyalar', + }, + 'ba': { + Logic: ' Танылыу', + Loops: ' Циклдар', + Math: 'Математика', + Text: 'Текст', + Lists: 'Исемлектәр', + Colour: 'Төҫ', + Variables: ' Үҙгәреүсән дәүмәлдәр', + Procedures: ' Функциялар', + }, + 'be-tarask': { + Logic: 'Лёгіка', + Loops: 'Петлі', + Math: 'Матэматычныя формулы', + Text: 'Тэкст', + Lists: 'Сьпісы', + Colour: 'Колер', + Variables: 'Зьменныя', + Procedures: 'Функцыі', + }, + 'be': { + Logic: 'Логіка', + Loops: 'Цыклы', + Math: 'Матэматыка', + Text: 'Тэкст', + Lists: 'Спісы', + Colour: 'Колер', + Variables: 'Пераменныя', + Procedures: 'Функцыі', + }, + 'bg': { + Logic: 'Логика', + Loops: 'Цикли', + Math: 'Математика', + Text: 'Текст', + Lists: 'Списъци', + Colour: 'Цвят', + Variables: 'Променливи', + Procedures: 'Функции', + }, + 'bn': { + Logic: 'যুক্তি', + Loops: 'লুপসমূহ', + Math: 'গণিত', + Text: 'লেখা', + Lists: 'তালিকাসমূহ', + Colour: 'রং', + Variables: 'চলকগুলো', + Procedures: 'ক্রিয়া', + }, + 'br': { + Logic: 'Poell', + Loops: 'Rodelloù', + Math: 'Matematik', + Text: 'Testenn', + Lists: 'Rolloù', + Colour: 'Liv', + Variables: 'Argemmennoù', + Procedures: "Arc'hwelioù", + }, + 'ca': { + Logic: 'Lògica', + Loops: 'Bucles', + Math: 'Matemàtiques', + Text: 'Text', + Lists: 'Llistes', + Colour: 'Color', + Variables: 'Variables', + Procedures: 'Procediments', + }, + 'cs': { + Logic: 'Logika', + Loops: 'Smyčky', + Math: 'Matika', + Text: 'Text', + Lists: 'Seznamy', + Colour: 'Barva', + Variables: 'Proměnné', + Procedures: 'Procedury', + }, + 'da': { + Logic: 'Logik', + Loops: 'Løkker', + Math: 'Matematik', + Text: 'Tekst', + Lists: 'Lister', + Colour: 'Farve', + Variables: 'Variabler', + Procedures: 'Funktioner', + }, + 'de': { + Logic: 'Logik', + Loops: 'Schleifen', + Math: 'Mathematik', + Text: 'Text', + Lists: 'Listen', + Colour: 'Farbe', + Variables: 'Variablen', + Procedures: 'Funktionen', + }, + 'diq': { + Logic: 'Mentıq', + Loops: 'Dingeki', + Math: 'Matematik', + Text: 'Metın', + Lists: 'Listeyi', + Colour: 'Reng', + Variables: 'Vırneyeni', + Procedures: 'Fonksiyoni', + }, + 'el': { + Logic: 'Λογική', + Loops: 'Επαναλήψεις', + Math: 'Μαθηματικά', + Text: 'Κείμενο', + Lists: 'Λίστες', + Colour: 'Χρώμα', + Variables: 'Μεταβλητές', + Procedures: 'Συναρτήσεις', + }, + 'en': { + Logic: 'Logic', + Loops: 'Loops', + Math: 'Math', + Text: 'Text', + Lists: 'Lists', + Colour: 'Colour', + Variables: 'Variables', + Procedures: 'Functions', + }, + 'eo': { + Logic: 'Logika', + Loops: 'Cikloj', + Math: 'Matematika', + Text: 'Teksto', + Lists: 'Listoj', + Colour: 'Koloro', + Variables: 'Variabloj', + Procedures: 'Funkcioj', + }, + 'es': { + Logic: 'Lógica', + Loops: 'Bucles', + Math: 'Matemáticas', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Color', + Variables: 'Variables', + Procedures: 'Funciones', + }, + 'et': { + Logic: 'Loogika', + Loops: 'Silmad', + Math: 'Matemaatika', + Text: 'Tekst', + Lists: 'Loendid', + Colour: 'Värv', + Variables: 'Muutujad', + Procedures: 'Funktsioonid', + }, + 'eu': { + Logic: 'Logika', + Loops: 'Begiztak', + Math: 'Matematika', + Text: 'Testua', + Lists: 'Zerrendak', + Colour: 'Kolorea', + Variables: 'Aldagaiak', + Procedures: 'Prozedurak', + }, + 'fa': { + Logic: 'منطق', + Loops: 'حلقه‌ها', + Math: 'ریاضی', + Text: 'متن', + Lists: 'فهرست‌ها', + Colour: 'رنگ', + Variables: 'متغییرها', + Procedures: 'توابع', + }, + 'fi': { + Logic: 'Logiikka', + Loops: 'Silmukat', + Math: 'Matematiikka', + Text: 'Teksti', + Lists: 'Listat', + Colour: 'Väri', + Variables: 'Muuttujat', + Procedures: 'Funktiot', + }, + 'fo': { + Logic: 'Logikkur', + Loops: 'Lykkjur', + Math: 'Støddfrøði', + Text: 'Tekstur', + Lists: 'Listar', + Colour: 'Litur', + Variables: 'Variablar', + Procedures: 'Funktiónir', + }, + 'fr': { + Logic: 'Logique', + Loops: 'Boucles', + Math: 'Mathématiques', + Text: 'Texte', + Lists: 'Listes', + Colour: 'Couleur', + Variables: 'Variables', + Procedures: 'Fonctions', + }, + 'gl': { + Logic: 'Lóxica', + Loops: 'Bucles', + Math: 'Matemáticas', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Cor', + Variables: 'Variables', + Procedures: 'Funcións', + }, + 'gn': { + Logic: 'Kuaarape', + Loops: 'Tapykuegua', + Math: 'Papapykuaa', + Text: 'Jehaipy', + Lists: 'Tysýi', + Colour: "Sa'y", + Variables: 'Ñemoambuéva', + Procedures: 'Aporeko', + }, + 'ha': { + Logic: 'Dabara', + Loops: 'Tsallake-tsallake', + Math: 'Lissafi', + Text: 'Rubutu', + Lists: 'Jeri', + Colour: 'Launi', + Variables: 'Siffofi', + Procedures: 'Aikace-aikace', + }, + 'hak': { + Math: 'Sṳ-ho̍k kûng-sṳt', + Text: '文字', + Lists: '列表', + Colour: '顏色', + Variables: '變量', + Procedures: '函數', + }, + 'he': { + Logic: 'לוגיקה', + Loops: 'לולאות', + Math: 'מתמטיקה', + Text: 'טקסט', + Lists: 'רשימות', + Colour: 'צבע', + Variables: 'משתנים', + Procedures: 'פונקציות', + }, + 'hi': { + Logic: 'तर्क', + Loops: 'लूप', + Math: 'गणित', + Text: 'टेक्स्ट', + Lists: 'सूचियाँ', + Colour: 'रंग', + Variables: 'चर', + Procedures: 'प्रोसीजर', + }, + 'hr': { + Logic: 'Logika', + Loops: 'Petlje', + Math: 'Matematika', + Text: 'Tekst', + Lists: 'Liste', + Colour: 'Boja', + Variables: 'Varijable', + Procedures: 'Funkcije', + }, + 'hrx': { + Logic: 'Logik', + Loops: 'Schleife', + Math: 'Mathematik', + Text: 'Text', + Lists: 'Liste', + Colour: 'Farreb', + Variables: 'Variable', + Procedures: 'Funktione', + }, + 'hu': { + Logic: 'Logika', + Loops: 'Ciklusok', + Math: 'Matek', + Text: 'Szövegkezelés', + Lists: 'Listakezelés', + Colour: 'Színek', + Variables: 'Változók', + Procedures: 'Eljárások', + }, + 'hy': { + Logic: 'Տրամաբանական', + Loops: 'Կրկնող հանգույցներ', + Math: 'Մաթեմատիկա', + Text: 'Տեքստ', + Lists: 'Ցանկեր', + Colour: 'Գույն', + Variables: 'Փոփոխականներ', + Procedures: 'Գործառույթներ', + }, + 'ia': { + Logic: 'Logica', + Loops: 'Buclas', + Math: 'Mathematica', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Color', + Variables: 'Variabiles', + Procedures: 'Functiones', + }, + 'id': { + Logic: 'Logika', + Loops: 'Perulangan', + Math: 'Matematika', + Text: 'Teks', + Lists: 'Daftar', + Colour: 'Warna', + Variables: 'Variabel', + Procedures: 'Fungsi', + }, + 'ig': { + Logic: 'Lọgịk', + Loops: 'Meghachi', + Math: 'Mgbakọ na mwepụ', + Text: 'Ederede', + Lists: 'Ndepụta', + Colour: 'Agba', + Variables: 'Agbanwe', + Procedures: 'Ọrụ', + }, + 'inh': { + Logic: 'Логика', + Loops: 'Циклаш', + Math: 'Математика', + Text: 'Текст', + Lists: 'Спискаш', + Colour: 'Бoс', + Variables: 'Хувцалушъяраш', + Procedures: 'Функцеш', + }, + 'is': { + Logic: 'Rökvísi', + Loops: 'Lykkjur', + Math: 'Reikningur', + Text: 'Texti', + Lists: 'Listar', + Colour: 'Litir', + Variables: 'Breytur', + Procedures: 'Föll', + }, + 'it': { + Logic: 'Logica', + Loops: 'Cicli', + Math: 'Matematica', + Text: 'Testo', + Lists: 'Elenchi', + Colour: 'Colore', + Variables: 'Variabili', + Procedures: 'Funzioni', + }, + 'ja': { + Logic: '論理', + Loops: '繰り返し', + Math: '数学', + Text: 'テキスト', + Lists: 'リスト', + Colour: '色', + Variables: '変数', + Procedures: '関数', + }, + 'kab': { + Logic: 'Tameẓla', + Loops: 'Tiyerrisin', + Math: 'Tusnakt', + Text: 'Aḍris', + Lists: 'Tibdarin', + Colour: 'Ini', + Variables: 'Imuttiyen', + Procedures: 'Tiwuriwin', + }, + 'kbd-cyrl': { + Math: 'Математикэ', + Text: 'Тхыгъэ', + Lists: 'КъебжэкI', + Colour: 'Плъыфэ', + }, + 'kn': { + Logic: 'ತರ್ಕ', + Loops: 'ಸುತ್ತುಗಳು', + Math: 'ಗಣಿತ', + Text: 'ಪಠ್ಯ', + Lists: 'ಪಟ್ಟಿಗಳು', + Colour: 'ಬಣ್ಣ', + Variables: 'ಚರಾಂಶಗಳು', + Procedures: 'ಕಾರ್ಯಘಟಕಗಳು', + }, + 'ko': { + Logic: '논리', + Loops: '반복', + Math: '수학', + Text: '문자열', + Lists: '목록', + Colour: '색', + Variables: '변수', + Procedures: '함수', + }, + 'ku-latn': { + Text: 'Nivîs', + Lists: 'Lîste', + Colour: 'Reng', + }, + 'lb': { + Logic: 'Logik', + Loops: 'Schleefen', + Math: 'Mathematik', + Text: 'Text', + Lists: 'Lëschten', + Colour: 'Faarf', + Variables: 'Variabelen', + Procedures: 'Funktiounen', + }, + 'lki': { + Logic: 'منطق', + Loops: 'حلقه‌ها', + Math: 'ریاضی', + Text: 'متن', + Lists: 'لیستةل', + Colour: 'رةنگ', + Variables: 'متغییرها', + Procedures: 'توابع', + }, + 'lrc': { + Logic: 'عٱقلمٱنی', + Loops: 'هٱلقٱیا', + Math: 'هساو کتاو', + Text: 'مٱتن', + Lists: 'نومگٱیا', + Colour: 'رٱنڳ', + Variables: 'آلشتؽا', + Procedures: 'رویٱیا', + }, + 'lt': { + Logic: 'Logika', + Loops: 'Kartojimas', + Math: 'Matematika', + Text: 'Tekstas', + Lists: 'Sąrašai', + Colour: 'Spalva', + Variables: 'Kintamieji', + Procedures: 'Funkcijos', + }, + 'lv': { + Logic: 'Loģika', + Loops: 'Cikli', + Math: 'Matemātika', + Text: 'Teksts', + Lists: 'Saraksti', + Colour: 'Krāsa', + Variables: 'Mainīgie', + Procedures: 'Funkcijas', + }, + 'mg': { + Logic: 'Lôjika', + Loops: 'Tondro mifolaka', + Math: 'Matematika', + Text: 'Soratra', + Lists: 'Lisitra', + Colour: 'Loko', + Variables: 'Ova', + Procedures: 'Paika', + }, + 'mk': { + Logic: 'Логика', + Loops: 'Јамки', + Math: 'Математика', + Text: 'Текст', + Lists: 'Списоци', + Colour: 'Боја', + Variables: 'Променливи', + Procedures: 'Функции', + }, + 'mr': { + Loops: 'वेटोळ्या(लूप्स)', + Text: 'मजकूर', + Colour: 'रंग', + Variables: 'अस्थिरके', + }, + 'ms': { + Logic: 'Logik', + Loops: 'Gelung', + Math: 'Matematik', + Text: 'Teks', + Lists: 'Senarai', + Colour: 'Warna', + Variables: 'Pemboleh ubah', + Procedures: 'Fungsi', + }, + 'my': { + Logic: 'ယုတ္တိ', + Loops: 'ကွင်း', + Math: 'သင်္ချာ', + Text: 'စာသား', + Lists: 'စာရင်းများ', + Colour: 'အရောင်', + Variables: 'အမျိုးမျိုးပြောင်းလဲနိုင်သော', + Procedures: 'လုပ်ဆောင်ချက်များ', + }, + 'nb': { + Logic: 'Logikk', + Loops: 'Løkker', + Math: 'Matte', + Text: 'Tekst', + Lists: 'Lister', + Colour: 'Farge', + Variables: 'Variabler', + Procedures: 'Funksjoner', + }, + 'ne': { + Logic: 'लजिक', + Loops: 'लुपहरू', + Math: 'गणित', + Text: 'पाठ', + Lists: 'सूची', + Colour: 'रंग', + Variables: 'चल राशी(variables)', + Procedures: 'अनुक्रियाहरु', + }, + 'nl': { + Logic: 'Logica', + Loops: 'Lussen', + Math: 'Formules', + Text: 'Tekst', + Lists: 'Lijsten', + Colour: 'Kleur', + Variables: 'Variabelen', + Procedures: 'Functies', + }, + 'oc': { + Logic: 'Logic', + Loops: 'Boclas', + Math: 'Math', + Text: 'Tèxte', + Lists: 'Listas', + Colour: 'Color', + Variables: 'Variablas', + Procedures: 'Foncions', + }, + 'olo': { + Logic: 'Lougiekku', + Loops: 'Čiepit', + Math: 'Matemuatiekku', + Text: 'Tekstu', + Lists: 'Listat', + Colour: 'Väri', + Variables: 'Variantat', + }, + 'pa': { + Math: 'ਹਿਸਾਬ', + Text: 'ਲਿਖਤ', + Lists: 'ਸੂਚੀਆਂ', + Colour: 'ਰੰਗ', + Variables: 'ਬਦਲਣਹਾਰ', + }, + 'pl': { + Logic: 'Logika', + Loops: 'Pętle', + Math: 'Matematyka', + Text: 'Tekst', + Lists: 'Listy', + Colour: 'Kolor', + Variables: 'Zmienne', + Procedures: 'Funkcje', + }, + 'pms': { + Logic: 'Lògica', + Loops: 'Liasse', + Math: 'Matemàtica', + Text: 'Test', + Lists: 'Liste', + Colour: 'Color', + Variables: 'Variàbij', + Procedures: 'Fonsion', + }, + 'ps': { + Logic: 'منطق', + Math: 'شمېرپوهنه', + Text: 'متن', + Lists: 'لړليکونه', + Colour: 'رنگ', + }, + 'pt-br': { + Logic: 'Lógica', + Loops: 'Laços', + Math: 'Matemática', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Cor', + Variables: 'Variáveis', + Procedures: 'Funções', + }, + 'pt': { + Logic: 'Lógica', + Loops: 'Ciclos', + Math: 'Matemática', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Cor', + Variables: 'Variáveis', + Procedures: 'Funções', + }, + 'ro': { + Logic: 'Logic', + Loops: 'Bucle', + Math: 'Matematică', + Text: 'Text', + Lists: 'Liste', + Colour: 'Culoare', + Variables: 'Variabile', + Procedures: 'Funcții', + }, + 'ru': { + Logic: 'Логика', + Loops: 'Циклы', + Math: 'Математика', + Text: 'Текст', + Lists: 'Списки', + Colour: 'Цвет', + Variables: 'Переменные', + Procedures: 'Функции', + }, + 'sc': { + Logic: 'Lògica', + Loops: 'Lòrigas', + Math: 'Matemàtica', + Text: 'Testu', + Lists: 'Lista', + Colour: 'Colori', + Variables: 'Variabilis', + Procedures: 'Funtzionis', + }, + 'sco': { + Logic: 'Logeec', + Loops: 'Luips', + Math: 'Maths', + Text: 'Tex', + Lists: 'Leets', + Colour: 'Colour', + Variables: 'Variables', + Procedures: 'Functions', + }, + 'sd': { + Logic: 'منطق', + Loops: 'چڪر', + Math: 'رياضي', + Text: 'اکر', + Lists: 'فھرست', + Colour: 'رنگ', + Variables: 'ڦرڻا', + Procedures: 'عمل', + }, + 'si': { + Logic: 'තර්කය', + Math: 'ගණිතමය', + Text: 'පෙළ', + Lists: 'ලැයිස්තු', + Colour: 'පාට', + Variables: 'විචල්‍යයන්', + Procedures: 'ශ්‍රිත', + }, + 'sk': { + Logic: 'Logické', + Loops: 'Slučky', + Math: 'Matematika', + Text: 'Textové', + Lists: 'Zoznamy', + Colour: 'Farba', + Variables: 'Premenné', + Procedures: 'Funkcie', + }, + 'skr-arab': { + Logic: 'منطق', + Loops: 'لوپاں', + Math: 'ریاضی', + Text: 'ٹیکسٹ', + Lists: 'فہرستاں', + Colour: 'رنگ', + Variables: 'متغیرات', + Procedures: 'فنکشن', + }, + 'sl': { + Logic: 'Logika', + Loops: 'Zanke', + Math: 'Matematika', + Text: 'Besedilo', + Lists: 'Seznami', + Colour: 'Barva', + Variables: 'Spremenljivke', + Procedures: 'Funkcije', + }, + 'smn': { + Logic: 'Loogiik', + Loops: 'Váárvuh', + Math: 'Matematiik', + Text: 'Tekstâ', + Lists: 'Listoh', + Colour: 'Ivne', + Variables: 'Muttojeijee', + Procedures: 'Funktioh', + }, + 'sq': { + Logic: 'Logjikë', + Loops: 'Qark', + Math: 'Matematikë', + Text: 'Tekst', + Lists: 'Listat', + Colour: 'Ngjyrë', + Variables: 'Variablat', + Procedures: 'Funksionet', + }, + 'sr-latn': { + Logic: 'Logika', + Loops: 'Petlje', + Math: 'Matematika', + Text: 'Tekst', + Lists: 'Spiskovi', + Colour: 'Boja', + Variables: 'Promenljive', + Procedures: 'Funkcije', + }, + 'sr': { + Logic: 'Логика', + Loops: 'Петље', + Math: 'Математика', + Text: 'Текст', + Lists: 'Спискови', + Colour: 'Боја', + Variables: 'Променљиве', + Procedures: 'Функције', + }, + 'sv': { + Logic: 'Logik', + Loops: 'Loopar', + Math: 'Matematik', + Text: 'Text', + Lists: 'Listor', + Colour: 'Färg', + Variables: 'Variabler', + Procedures: 'Funktioner', + }, + 'ta': { + Logic: 'தர்க்கம்', + Loops: 'மடக்குக்கட்டளை', + Math: 'கணிதம்', + Text: 'உரை', + Lists: 'பட்டியல்', + Colour: 'நிறம்', + Variables: 'மாறி', + Procedures: 'செயலாற்றிகள்', + }, + 'tcy': { + Logic: 'ವಾದೊ', + Loops: 'ಲೂಪ್‍ಲು', + Math: 'ಲೆಕ್ಕೊ', + Text: 'ಪಟ್ಯೊ', + Lists: 'ಪಟ್ಟಿಲು', + Colour: 'ಬನ್ನೊ', + Variables: 'ವ್ಯತ್ಯಯೊಲು', + Procedures: 'ಲೇಸ್‍ಲು', + }, + 'te': { + Logic: 'తర్కం', + Loops: 'లూప్స్', + Math: 'గణితం', + Text: 'పాఠ్యం', + Lists: 'జాబితాలు', + Colour: 'రంగు', + Variables: 'చరరాశులు', + Procedures: 'ప్రమేయాలు', + }, + 'th': { + Logic: 'ตรรกะ', + Loops: 'การวนซ้ำ', + Math: 'คณิตศาสตร์', + Text: 'ข้อความ', + Lists: 'รายการ', + Colour: 'สี', + Variables: 'ตัวแปร', + Procedures: 'ฟังก์ชัน', + }, + 'ti': { + Logic: 'ሎጂክ', + Loops: 'ኣዝዋሪታት', + Math: 'ሒሳብ', + Text: 'ጽሑፍ', + Lists: 'ዝርዝር', + Colour: 'ሕብሪ', + Variables: 'ተተካእቲ', + Procedures: 'ፋንክሽናት', + }, + 'tr': { + Logic: 'Mantık', + Loops: 'Döngüler', + Math: 'Matematik', + Text: 'Metin', + Lists: 'Listeler', + Colour: 'Renk', + Variables: 'Değişkenler', + Procedures: 'İşlevler', + }, + 'uk': { + Logic: 'Логіка', + Loops: 'Цикли', + Math: 'Математика', + Text: 'Текст', + Lists: 'Списки', + Colour: 'Колір', + Variables: 'Змінні', + Procedures: 'Функції', + }, + 'ur': { + Logic: 'منطق', + Loops: 'لوپیں', + Math: 'ریاضی', + Text: 'متن', + Lists: 'فہرستیں', + Colour: 'رنگ', + Variables: 'متغیرات', + Procedures: 'افعال', + }, + 'uz': { + Logic: 'Mantiq', + Loops: 'Tsikllar', + Math: 'Matematika', + Text: 'Matn', + Lists: 'Roʻyxatlar', + Colour: 'Rang', + Variables: "O'zgaruvchilar", + Procedures: 'Funksiyalar', + }, + 'vi': { + Logic: 'Logic', + Loops: 'Vòng lặp', + Math: 'Công thức toán', + Text: 'Văn bản', + Lists: 'Danh sách', + Colour: 'Màu', + Variables: 'Biến', + Procedures: 'Hàm', + }, + 'yo': { + Logic: 'Irogun', + Loops: 'Ilosiwaju losehin', + Math: 'Isiro', + Text: 'Ọrọ', + Lists: 'Akojọ', + Colour: 'Awọ', + Variables: 'Oniruru', + Procedures: 'Iṣe', + }, + 'yue': { + Logic: '邏輯', + Loops: '循環', + Math: '數學', + Text: '發短信', + Lists: '一覽', + Colour: '顏色', + Variables: '變數', + Procedures: '功能', + }, + 'zh-hans': { + Logic: '逻辑', + Loops: '循环', + Math: '数学', + Text: '文本', + Lists: '列表', + Colour: '颜色', + Variables: '变量', + Procedures: '函数', + }, + 'zh-hant': { + Logic: '邏輯', + Loops: '迴圈', + Math: '運算', + Text: '文字', + Lists: '清單', + Colour: '顏色', + Variables: '變數', + Procedures: '函式', + }, }; diff --git a/examples/devsite-demo/script.js b/examples/devsite-demo/script.js index 15eb13600f..4c4e266514 100644 --- a/examples/devsite-demo/script.js +++ b/examples/devsite-demo/script.js @@ -9,11 +9,10 @@ */ 'use strict'; - -let language = 'en'; // Default to English. +let language = 'en'; // Default to English. // Run this setup code once while still rendering the head. -(function() { +(function () { const m = location.search.match(/[?&]hl=([^&]+)($|&)/); if (m) { if (LANGUAGE_NAME[m[1]]) { @@ -21,7 +20,9 @@ let language = 'en'; // Default to English. } } // Load Blockly's language strings. - document.write('\n'); + document.write( + '\n', + ); })(); /** @@ -38,7 +39,7 @@ function init() { if (a[0] > b[0]) return 1; if (a[0] < b[0]) return -1; return 0; - }; + } languages.sort(comp_); // Populate the language selection dropdown. const languageMenu = document.getElementById('languageDropdown'); @@ -59,7 +60,7 @@ function init() { loadOnce = window.sessionStorage.getItem('loadOnceBlocks'); window.sessionStorage.removeItem('loadOnceBlocks'); loadOnce = JSON.parse(loadOnce); - } catch(e) { + } catch (e) { // Storage can be flakey. console.log(e); } @@ -78,17 +79,19 @@ function init() { // Inject default variable name. // https://github.com/google/blockly/issues/5238 let toolboxString = JSON.stringify(toolboxJson); - toolboxString = toolboxString.replace(/%\{BKY_VARIABLES_DEFAULT_NAME\}/g, - Blockly.Msg.VARIABLES_DEFAULT_NAME); + toolboxString = toolboxString.replace( + /%\{BKY_VARIABLES_DEFAULT_NAME\}/g, + Blockly.Msg.VARIABLES_DEFAULT_NAME, + ); const toolbox = JSON.parse(toolboxString); // Inject Blockly. - const workspace = Blockly.inject('blocklyDiv', - { - media: "./node_modules/blockly/media/", - toolbox, - rtl: LANGUAGE_RTL.includes(language), - }); + const workspace = Blockly.inject('blocklyDiv', { + media: './node_modules/blockly/media/', + toolbox, + rtl: LANGUAGE_RTL.includes(language), + }); + Blockly.serialization.workspaces.load(loadOnce || startBlocks, workspace); workspace.addChangeListener(regenerate); } @@ -112,10 +115,11 @@ function getMsg(name) { function languageChange() { // Store the blocks in sessionStorage for the duration of the reload. const text = JSON.stringify( - Blockly.serialization.workspaces.save(Blockly.getMainWorkspace())); + Blockly.serialization.workspaces.save(Blockly.getMainWorkspace()), + ); try { window.sessionStorage.setItem('loadOnceBlocks', text); - } catch(e) { + } catch (e) { // Storage can be flakey. console.log(e); } @@ -130,15 +134,15 @@ function languageChange() { */ function regenerate(_e) { if (Blockly.getMainWorkspace().isDragging()) { - return; // Don't update code mid-drag. + return; // Don't update code mid-drag. } const generateLang = document.getElementById('generateDropdown').value; const generator = window[generateLang][`${generateLang}Generator`]; const playButton = document.getElementById('playButton'); - playButton.style.display = (generateLang === 'javascript') ? 'block' : 'none'; + playButton.style.display = generateLang === 'javascript' ? 'block' : 'none'; const code = generator.workspaceToCode(Blockly.getMainWorkspace()); const codeHolder = document.getElementById('codeHolder'); - codeHolder.innerHTML = ''; // Delete old code. + codeHolder.innerHTML = ''; // Delete old code. codeHolder.classList.remove('prettyprinted'); codeHolder.appendChild(document.createTextNode(code)); if (typeof PR === 'object') { @@ -150,22 +154,32 @@ function regenerate(_e) { * Generate JavaScript from the blocks, then execute it using JS-Interpreter. */ function execute() { - const initFunc = function(interpreter, globalObject) { + const initFunc = function (interpreter, globalObject) { const alertWrapper = function alert(text) { return window.alert(arguments.length ? text : ''); }; - interpreter.setProperty(globalObject, 'alert', - interpreter.createNativeFunction(alertWrapper)); + interpreter.setProperty( + globalObject, + 'alert', + interpreter.createNativeFunction(alertWrapper), + ); const promptWrapper = function prompt(text, defaultValue) { - return window.prompt(arguments.length > 0 ? text : '', - arguments.length > 1 ? defaultValue : ''); + return window.prompt( + arguments.length > 0 ? text : '', + arguments.length > 1 ? defaultValue : '', + ); }; - interpreter.setProperty(globalObject, 'prompt', - interpreter.createNativeFunction(promptWrapper)); + interpreter.setProperty( + globalObject, + 'prompt', + interpreter.createNativeFunction(promptWrapper), + ); }; - const code = javascript.javascriptGenerator.workspaceToCode(Blockly.getMainWorkspace()); + const code = javascript.javascriptGenerator.workspaceToCode( + Blockly.getMainWorkspace(), + ); const myInterpreter = new Interpreter(code, initFunc); let stepsAllowed = 10000; while (myInterpreter.step() && stepsAllowed) { @@ -180,106 +194,106 @@ function execute() { * Initial blocks when loading page. */ const startBlocks = { - "blocks": { - "languageVersion": 0, - "blocks": [ + blocks: { + languageVersion: 0, + blocks: [ { - "type": "variables_set", - "x": 10, - "y": 10, - "fields": { - "VAR": {"id": "Count"} + type: 'variables_set', + x: 10, + y: 10, + fields: { + VAR: {id: 'Count'}, }, - "inputs": { - "VALUE": { - "block": { - "type": "math_number", - "fields": {"NUM": 1} - } - } + inputs: { + VALUE: { + block: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, }, - "next": { - "block": { - "type": "controls_whileUntil", - "fields": {"MODE": "WHILE"}, - "inputs": { - "BOOL": { - "block": { - "type": "logic_compare", - "fields": {"OP": "LTE"}, - "inputs": { - "A": { - "block": { - "type": "variables_get", - "fields": { - "VAR": {"id": "Count"} - } - } + next: { + block: { + type: 'controls_whileUntil', + fields: {MODE: 'WHILE'}, + inputs: { + BOOL: { + block: { + type: 'logic_compare', + fields: {OP: 'LTE'}, + inputs: { + A: { + block: { + type: 'variables_get', + fields: { + VAR: {id: 'Count'}, + }, + }, + }, + B: { + block: { + type: 'math_number', + fields: {NUM: 3}, + }, }, - "B": { - "block": { - "type": "math_number", - "fields": {"NUM": 3} - } - } - } - } + }, + }, }, - "DO": { - "block": { - "type": "text_print", - "inputs": { - "TEXT": { - "block": { - "type": "text", - "fields": {"TEXT": "Hello World!"} - } - } + DO: { + block: { + type: 'text_print', + inputs: { + TEXT: { + block: { + type: 'text', + fields: {TEXT: 'Hello World!'}, + }, + }, }, - "next": { - "block": { - "type": "variables_set", - "fields": { - "VAR": {"id": "Count"} + next: { + block: { + type: 'variables_set', + fields: { + VAR: {id: 'Count'}, }, - "inputs": { - "VALUE": { - "block": { - "type": "math_arithmetic", - "fields": {"OP": "ADD"}, - "inputs": { - "A": { - "block": { - "type": "variables_get", - "fields": { - "VAR": {"id": "Count"} - } - } + inputs: { + VALUE: { + block: { + type: 'math_arithmetic', + fields: {OP: 'ADD'}, + inputs: { + A: { + block: { + type: 'variables_get', + fields: { + VAR: {id: 'Count'}, + }, + }, + }, + B: { + block: { + type: 'math_number', + fields: {NUM: 1}, + }, }, - "B": { - "block": { - "type": "math_number", - "fields": {"NUM": 1} - } - } - } - } - } - } - } - } - } - } - } - } - } - } - ] + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + ], }, - "variables": [ + variables: [ { - "name": "Count", - "id": "Count" - } - ] + name: 'Count', + id: 'Count', + }, + ], }; diff --git a/examples/devsite-demo/style.css b/examples/devsite-demo/style.css index 250e083e6b..e45cacbed7 100644 --- a/examples/devsite-demo/style.css +++ b/examples/devsite-demo/style.css @@ -1,4 +1,4 @@ -@import url("https://fonts.googleapis.com/icon?family=Material+Icons"); +@import url('https://fonts.googleapis.com/icon?family=Material+Icons'); .app-container { position: absolute; @@ -8,7 +8,9 @@ right: 0; overflow: visible; background-color: #12b5cd; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.14), 0 4px 8px rgba(0, 0, 0, 0.3); + box-shadow: + 0 0 4px rgba(0, 0, 0, 0.14), + 0 4px 8px rgba(0, 0, 0, 0.3); margin: 10px; } @@ -67,7 +69,9 @@ hr { } .play-button:hover { - box-shadow: 0 2px 2px rgba(0, 0, 0, 0.2), 0 6px 10px rgba(0, 0, 0, 0.3); + box-shadow: + 0 2px 2px rgba(0, 0, 0, 0.2), + 0 6px 10px rgba(0, 0, 0, 0.3); transition: box-shadow 0.3s ease-in-out; } diff --git a/examples/devsite-demo/toolbox.js b/examples/devsite-demo/toolbox.js index 579fca69d0..a5a974d1ec 100644 --- a/examples/devsite-demo/toolbox.js +++ b/examples/devsite-demo/toolbox.js @@ -9,727 +9,726 @@ */ 'use strict'; - const toolboxJson = { - "contents": [ + contents: [ { // Logic Category - "kind": "CATEGORY", - "colour": "%{BKY_LOGIC_HUE}", - "contents": [ + kind: 'CATEGORY', + colour: '%{BKY_LOGIC_HUE}', + contents: [ { - "kind": "BLOCK", - "type": "controls_if" + kind: 'BLOCK', + type: 'controls_if', }, { - "kind": "BLOCK", - "type": "logic_compare" + kind: 'BLOCK', + type: 'logic_compare', }, { - "kind": "BLOCK", - "type": "logic_operation" + kind: 'BLOCK', + type: 'logic_operation', }, { - "kind": "BLOCK", - "type": "logic_negate" + kind: 'BLOCK', + type: 'logic_negate', }, { - "kind": "BLOCK", - "type": "logic_boolean" + kind: 'BLOCK', + type: 'logic_boolean', }, { - "kind": "BLOCK", - "type": "logic_ternary" + kind: 'BLOCK', + type: 'logic_ternary', }, - ] + ], }, { // Loops Category - "kind": "CATEGORY", - "colour": "%{BKY_LOOPS_HUE}", - "contents": [ - { - "kind": "BLOCK", - "type": "controls_repeat_ext", - "inputs": { - "TIMES": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 10} - } - } - } - }, - { - "kind": "BLOCK", - "type": "controls_whileUntil" - }, - { - "kind": "BLOCK", - "type": "controls_for", - "inputs": { - "FROM": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } - }, - "TO": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 10} - } - }, - "BY": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } - } - } - }, - { - "kind": "BLOCK", - "type": "controls_forEach", - }, - { - "kind": "BLOCK", - "type": "controls_flow_statements", - }, - ] + kind: 'CATEGORY', + colour: '%{BKY_LOOPS_HUE}', + contents: [ + { + kind: 'BLOCK', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: {NUM: 10}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'controls_whileUntil', + }, + { + kind: 'BLOCK', + type: 'controls_for', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: {NUM: 10}, + }, + }, + BY: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'controls_forEach', + }, + { + kind: 'BLOCK', + type: 'controls_flow_statements', + }, + ], }, { // Math Category - "kind": "CATEGORY", - "colour": "%{BKY_MATH_HUE}", - "contents": [ - { - "kind": "BLOCK", - "type": "math_number", - "fields": {"NUM": 123} - }, - { - "kind": "BLOCK", - "type": "math_arithmetic", - "inputs": { - "A": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } - }, - "B": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } - } - } - }, - { - "kind": "BLOCK", - "type": "math_single", - "inputs": { - "NUM": { - "shadow": { - "type":"math_number", - "fields": {"NUM": 9} - } - } - } - }, - { - "kind": "BLOCK", - "type": "math_trig", - "inputs": { - "NUM": { - "shadow": { - "type":"math_number", - "fields": {"NUM": 45} - } - } - } - }, - { - "kind": "BLOCK", - "type": "math_atan2", - "inputs": { - "X": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } - }, - "Y": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } - } - } - }, - { - "kind": "BLOCK", - "type": "math_constant", - }, - { - "kind": "BLOCK", - "type": "math_number_property", - "inputs": { - "NUMBER_TO_CHECK": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 0} - } - } - } - }, - { - "kind": "BLOCK", - "type": "math_round", - "inputs": { - "NUM": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 3.1} - } - } - } - }, - { - "kind": "BLOCK", - "type": "math_on_list", - }, - { - "kind": "BLOCK", - "type": "math_modulo", - "inputs": { - "DIVIDEND": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 64} - } - }, - "DIVISOR": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 10} - } - } - } - }, - { - "kind": "BLOCK", - "type": "math_constrain", - "inputs": { - "VALUE": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 50} - } - }, - "LOW": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } - }, - "HIGH": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 100} - } - } - } - }, - { - "kind": "BLOCK", - "type": "math_random_int", - "inputs": { - "FROM": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } - }, - "TO": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 100} - } - } - } - }, - { - "kind": "BLOCK", - "type": "math_random_float", - }, - ] + kind: 'CATEGORY', + colour: '%{BKY_MATH_HUE}', + contents: [ + { + kind: 'BLOCK', + type: 'math_number', + fields: {NUM: 123}, + }, + { + kind: 'BLOCK', + type: 'math_arithmetic', + inputs: { + A: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, + B: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'math_single', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: {NUM: 9}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'math_trig', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: {NUM: 45}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'math_atan2', + inputs: { + X: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, + Y: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'math_constant', + }, + { + kind: 'BLOCK', + type: 'math_number_property', + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: {NUM: 0}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'math_round', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: {NUM: 3.1}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'math_on_list', + }, + { + kind: 'BLOCK', + type: 'math_modulo', + inputs: { + DIVIDEND: { + shadow: { + type: 'math_number', + fields: {NUM: 64}, + }, + }, + DIVISOR: { + shadow: { + type: 'math_number', + fields: {NUM: 10}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'math_constrain', + inputs: { + VALUE: { + shadow: { + type: 'math_number', + fields: {NUM: 50}, + }, + }, + LOW: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, + HIGH: { + shadow: { + type: 'math_number', + fields: {NUM: 100}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'math_random_int', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, + TO: { + shadow: { + type: 'math_number', + fields: {NUM: 100}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'math_random_float', + }, + ], }, { // Text Category - "kind": "CATEGORY", - "colour": "%{BKY_TEXTS_HUE}", - "contents": [ - { - "kind": "BLOCK", - "type": "text" - }, - { - "kind": "BLOCK", - "type": "text_multiline", - }, - { - "kind": "BLOCK", - "type": "text_join", - "extraState": {"itemCount": 2} - }, - { - "kind": "BLOCK", - "type": "text_append", - "fields": { - "VAR": { - "name": "text", - "type": "String" - } - }, - "inputs": { - "TEXT": { - "shadow": {"type": "text"} - } - } - }, - { - "kind": "BLOCK", - "type": "text_length", - "inputs": { - "VALUE": { - "shadow": { - "type": "text", - "fields": {"TEXT": "abc"} - } - } - } - }, - { - "kind": "BLOCK", - "type": "text_isEmpty", - "inputs": { - "VALUE": { - "shadow": {"type": "text"} - } - } - }, - { - "kind": "BLOCK", - "type": "text_indexOf", - "inputs": { - "VALUE": { - "shadow": { - "type": "text", - "fields": {"TEXT": "abc"} - } - }, - "FIND": { - "shadow": { - "type": "text", - "fields": {"TEXT": "b"} - } - } - } - }, - { - "kind": "BLOCK", - "type": "text_charAt", - "inputs": { - "VALUE": { - "shadow": { - "type": "text", - "fields": {"TEXT": "abc"} - } - } - } - }, - { - "kind": "BLOCK", - "type": "text_getSubstring", - "inputs": { - "STRING": { - "shadow": { - "type": "text", - "fields": {"TEXT": "abc"} - } - } - } - }, - { - "kind": "BLOCK", - "type": "text_changeCase", - "inputs": { - "TEXT": { - "shadow": { - "type": "text", - "fields": { - "TEXT": "abc" - } - } - } - } - }, - { - "kind": "BLOCK", - "type": "text_trim", - "inputs": { - "TEXT": { - "shadow": { - "type": "text", - "fields": {"TEXT": " abc "} - } - } - } - }, - { - "kind": "BLOCK", - "type": "text_count", - "inputs": { - "SUB": { - "shadow": { - "type": "text", - "fields": {"TEXT": "a"} - } - }, - "TEXT": { - "shadow": { - "type": "text", - "fields": {"TEXT": "banana"} - } - } - } - }, - { - "kind": "BLOCK", - "type": "text_replace", - "inputs": { - "FROM": { - "shadow": { - "type": "text", - "fields": {"TEXT": "m"} - } - }, - "TO": { - "shadow": { - "type": "text", - "fields": {"TEXT": "w"} - } - }, - "TEXT": { - "shadow": { - "type": "text", - "fields": {"TEXT": "mom"} - } - } - } - }, - { - "kind": "BLOCK", - "type": "text_reverse", - "inputs": { - "TEXT": { - "shadow": { - "type": "text", - "fields": { - "TEXT": "cba" - } - } - } - } - }, - { - "kind": "label", - "text": "" + kind: 'CATEGORY', + colour: '%{BKY_TEXTS_HUE}', + contents: [ + { + kind: 'BLOCK', + type: 'text', + }, + { + kind: 'BLOCK', + type: 'text_multiline', + }, + { + kind: 'BLOCK', + type: 'text_join', + extraState: {itemCount: 2}, + }, + { + kind: 'BLOCK', + type: 'text_append', + fields: { + VAR: { + name: 'text', + type: 'String', + }, + }, + inputs: { + TEXT: { + shadow: {type: 'text'}, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_length', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_isEmpty', + inputs: { + VALUE: { + shadow: {type: 'text'}, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_indexOf', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, + }, + }, + FIND: { + shadow: { + type: 'text', + fields: {TEXT: 'b'}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_charAt', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_getSubstring', + inputs: { + STRING: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_changeCase', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', + }, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_trim', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: ' abc '}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_count', + inputs: { + SUB: { + shadow: { + type: 'text', + fields: {TEXT: 'a'}, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'banana'}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_replace', + inputs: { + FROM: { + shadow: { + type: 'text', + fields: {TEXT: 'm'}, + }, + }, + TO: { + shadow: { + type: 'text', + fields: {TEXT: 'w'}, + }, + }, + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'mom'}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_reverse', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'cba', + }, + }, + }, + }, + }, + { + kind: 'label', + text: '', }, { - "kind": "BLOCK", - "type": "text_print", - "inputs": { - "TEXT": { - "shadow": { - "type": "text", - "fields": {"TEXT": "abc"} - } - } - } - }, - { - "kind": "BLOCK", - "type": "text_prompt_ext", - "inputs": { - "TEXT": { - "shadow": { - "type": "text", - "fields": {"TEXT": "abc"} - } - } - } - }, - ] + kind: 'BLOCK', + type: 'text_print', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'text_prompt_ext', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, + }, + }, + }, + }, + ], }, { // Lists Category - "kind": "CATEGORY", - "colour": "%{BKY_LISTS_HUE}", - "contents": [ - { - "kind": "BLOCK", - "type": "lists_create_with", - "extraState": {"itemCount": 0} - }, - { - "kind": "BLOCK", - "type": "lists_create_with", - "extraState": {"itemCount": 3} - }, - { - "kind": "BLOCK", - "type": "lists_repeat", - "inputs": { - "NUM": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 5} - } - } - } - }, - { - "kind": "BLOCK", - "type": "lists_length", - }, - { - "kind": "BLOCK", - "type": "lists_isEmpty", - }, - { - "kind": "BLOCK", - "type": "lists_indexOf", - "inputs": { - "VALUE": { - "block": { - "type": "variables_get", - "fields": { - "VAR": { - "name": "%{BKY_VARIABLES_DEFAULT_NAME}", - "type": "List" - } - } - } - } - } - }, - { - "kind": "BLOCK", - "type": "lists_getIndex", - "inputs": { - "VALUE": { - "block": { - "type": "variables_get", - "fields": { - "VAR": { - "name": "%{BKY_VARIABLES_DEFAULT_NAME}", - "type": "List" - } - } - } - } - } - }, - { - "kind": "BLOCK", - "type": "lists_setIndex", - "inputs": { - "LIST": { - "block": { - "type": "variables_get", - "fields": { - "VAR": { - "name": "%{BKY_VARIABLES_DEFAULT_NAME}", - "type": "List" - } - } - } - } - } - }, - { - "kind": "BLOCK", - "type": "lists_getSublist", - "inputs": { - "LIST": { - "block": { - "type": "variables_get", - "fields": { - "VAR": { - "name": "%{BKY_VARIABLES_DEFAULT_NAME}", - "type": "List" - } - } - } - } - } - }, - { - "kind": "BLOCK", - "type": "lists_getSublist", - "inputs": { - "LIST": { - "block": { - "type": "variables_get", - "fields": { - "VAR": { - "name": "%{BKY_VARIABLES_DEFAULT_NAME}", - "type": "List" - } - } - } - } - } - }, - { - "kind": "BLOCK", - "type": "lists_split", - "inputs": { - "DELIM": { - "shadow": { - "type": "text", - "fields": {"TEXT": ","} - } - } - } - }, - { - "kind": "BLOCK", - "type": "lists_sort", - "inputs": { - "LIST": { - "block": { - "type": "variables_get", - "fields": { - "VAR": { - "name": "%{BKY_VARIABLES_DEFAULT_NAME}", - "type": "List" - } - } - } - } - } - }, - { - "kind": "BLOCK", - "type": "lists_reverse", - "inputs": { - "LIST": { - "block": { - "type": "variables_get", - "id": "Jyppgi#k[zERF`IH{gqY", - "fields": { - "VAR": { - "name": "%{BKY_VARIABLES_DEFAULT_NAME}", - "type": "List" - } - } - } - } - } - }, - ] + kind: 'CATEGORY', + colour: '%{BKY_LISTS_HUE}', + contents: [ + { + kind: 'BLOCK', + type: 'lists_create_with', + extraState: {itemCount: 0}, + }, + { + kind: 'BLOCK', + type: 'lists_create_with', + extraState: {itemCount: 3}, + }, + { + kind: 'BLOCK', + type: 'lists_repeat', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: {NUM: 5}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'lists_length', + }, + { + kind: 'BLOCK', + type: 'lists_isEmpty', + }, + { + kind: 'BLOCK', + type: 'lists_indexOf', + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', + }, + }, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'lists_getIndex', + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', + }, + }, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'lists_setIndex', + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', + }, + }, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'lists_getSublist', + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', + }, + }, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'lists_getSublist', + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', + }, + }, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'lists_split', + inputs: { + DELIM: { + shadow: { + type: 'text', + fields: {TEXT: ','}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'lists_sort', + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', + }, + }, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'lists_reverse', + inputs: { + LIST: { + block: { + type: 'variables_get', + id: 'Jyppgi#k[zERF`IH{gqY', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', + }, + }, + }, + }, + }, + }, + ], }, { // Colour Category - "kind": "CATEGORY", - "colour": "%{BKY_COLOUR_HUE}", - "contents": [ - { - "kind": "BLOCK", - "type": "colour_picker", - "fields": {"COLOUR": "#ff0000"} - }, - { - "kind": "BLOCK", - "type": "colour_random", - }, - { - "kind": "BLOCK", - "type": "colour_rgb", - "inputs": { - "RED": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 100} - } - }, - "GREEN": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 50} - } - }, - "BLUE": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 0} - } - } - } - }, - { - "kind": "BLOCK", - "type": "colour_blend", - "inputs": { - "COLOUR1": { - "shadow": { - "type": "colour_picker", - "fields": {"COLOUR": "#ff0000"} - } - }, - "COLOUR2": { - "shadow": { - "type": "colour_picker", - "fields": {"COLOUR": "#3333ff"} - } - }, - "RATIO": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 0.5} - } - } - } - }, - ] + kind: 'CATEGORY', + colour: '%{BKY_COLOUR_HUE}', + contents: [ + { + kind: 'BLOCK', + type: 'colour_picker', + fields: {COLOUR: '#ff0000'}, + }, + { + kind: 'BLOCK', + type: 'colour_random', + }, + { + kind: 'BLOCK', + type: 'colour_rgb', + inputs: { + RED: { + shadow: { + type: 'math_number', + fields: {NUM: 100}, + }, + }, + GREEN: { + shadow: { + type: 'math_number', + fields: {NUM: 50}, + }, + }, + BLUE: { + shadow: { + type: 'math_number', + fields: {NUM: 0}, + }, + }, + }, + }, + { + kind: 'BLOCK', + type: 'colour_blend', + inputs: { + COLOUR1: { + shadow: { + type: 'colour_picker', + fields: {COLOUR: '#ff0000'}, + }, + }, + COLOUR2: { + shadow: { + type: 'colour_picker', + fields: {COLOUR: '#3333ff'}, + }, + }, + RATIO: { + shadow: { + type: 'math_number', + fields: {NUM: 0.5}, + }, + }, + }, + }, + ], }, { - "kind": "SEP" + kind: 'SEP', }, { // Variable Category - "kind": "CATEGORY", - "custom": "VARIABLE", - "colour": "%{BKY_VARIABLES_HUE}", + kind: 'CATEGORY', + custom: 'VARIABLE', + colour: '%{BKY_VARIABLES_HUE}', }, { // Function Category - "kind": "CATEGORY", - "custom": "PROCEDURE", - "colour": "%{BKY_PROCEDURES_HUE}", - } - ] + kind: 'CATEGORY', + custom: 'PROCEDURE', + colour: '%{BKY_PROCEDURES_HUE}', + }, + ], }; diff --git a/examples/devsite-landing-demo/index.html b/examples/devsite-landing-demo/index.html index 87ee905970..80fe3dc704 100644 --- a/examples/devsite-landing-demo/index.html +++ b/examples/devsite-landing-demo/index.html @@ -1,12 +1,11 @@ - Blockly Demo - - - - + + + + @@ -37,7 +36,10 @@

       
       
- Run
+ Run + diff --git a/examples/devsite-landing-demo/msgs.js b/examples/devsite-landing-demo/msgs.js index eadb904ab3..79a3428256 100644 --- a/examples/devsite-landing-demo/msgs.js +++ b/examples/devsite-landing-demo/msgs.js @@ -13,18 +13,18 @@ * Lookup for names of languages. Keys should be in ISO 639 format. */ const LANGUAGE_NAME = { -// 'ace': 'بهسا اچيه', // RTL -// 'af': 'Afrikaans', + // 'ace': 'بهسا اچيه', // RTL + // 'af': 'Afrikaans', 'am': 'አማርኛ', - 'ar': 'العربية', // RTL -// 'az': 'Azərbaycanca', + 'ar': 'العربية', // RTL + // 'az': 'Azərbaycanca', 'be': 'беларускі', 'be-tarask': 'Taraškievica', 'bg': 'български език', 'bn': 'বাংলা', 'br': 'Brezhoneg', 'ca': 'Català', -// 'cdo': '閩東語', + // 'cdo': '閩東語', 'cs': 'Česky', 'da': 'Dansk', 'de': 'Deutsch', @@ -33,18 +33,18 @@ const LANGUAGE_NAME = { 'eo': 'Esperanto', 'es': 'Español', 'eu': 'Euskara', - 'fa': 'فارسی', // RTL + 'fa': 'فارسی', // RTL 'fi': 'Suomi', 'fo': 'Føroyskt', 'fr': 'Français', -// 'frr': 'Frasch', + // 'frr': 'Frasch', 'gl': 'Galego', 'ha': 'Hausa', -// 'hak': '客家話', - 'he': 'עברית', // RTL + // 'hak': '客家話', + 'he': 'עברית', // RTL 'hi': 'हिन्दी', 'hr': 'Hrvatski', -// 'hrx': 'Hunsrik', + // 'hrx': 'Hunsrik', 'hu': 'Magyar', 'hy': 'հայերէն', 'ia': 'Interlingua', @@ -53,1025 +53,1023 @@ const LANGUAGE_NAME = { 'is': 'Íslenska', 'it': 'Italiano', 'ja': '日本語', -// 'ka': 'ქართული', + // 'ka': 'ქართული', 'kab': 'Taqbaylit', -// 'km': 'ភាសាខ្មែរ', + // 'km': 'ភាសាខ្មែរ', 'kn': 'ಕನ್ನಡ', 'ko': '한국어', -// 'ksh': 'Ripoarėsch', -// 'ky': 'Кыргызча', -// 'la': 'Latine', -// 'lb': 'Lëtzebuergesch', + // 'ksh': 'Ripoarėsch', + // 'ky': 'Кыргызча', + // 'la': 'Latine', + // 'lb': 'Lëtzebuergesch', 'lt': 'Lietuvių', 'lv': 'Latviešu', -// 'mg': 'Malagasy', -// 'ml': 'മലയാളം', -// 'mk': 'Македонски', -// 'mr': 'मराठी', + // 'mg': 'Malagasy', + // 'ml': 'മലയാളം', + // 'mk': 'Македонски', + // 'mr': 'मराठी', 'ms': 'Bahasa Melayu', 'my': 'မြန်မာစာ', -// 'mzn': 'مازِرونی', // RTL + // 'mzn': 'مازِرونی', // RTL 'nb': 'Norsk (bokmål)', 'nl': 'Nederlands, Vlaams', -// 'oc': 'Lenga d\'òc', -// 'pa': 'पंजाबी', + // 'oc': 'Lenga d\'òc', + // 'pa': 'पंजाबी', 'pl': 'Polski', 'pms': 'Piemontèis', -// 'ps': 'پښتو', // RTL + // 'ps': 'پښتو', // RTL 'pt': 'Português', 'pt-br': 'Português Brasileiro', 'ro': 'Română', 'ru': 'Русский', 'sc': 'Sardu', -// 'sco': 'Scots', -// 'si': 'සිංහල', + // 'sco': 'Scots', + // 'si': 'සිංහල', 'sk': 'Slovenčina', 'sl': 'Slovenščina', -// 'smn': 'Anarâškielâ', + // 'smn': 'Anarâškielâ', 'sq': 'Shqip', 'sr': 'Српски', 'sr-latn': 'Srpski', 'sv': 'Svenska', -// 'sw': 'Kishwahili', -// 'ta': 'தமிழ்', + // 'sw': 'Kishwahili', + // 'ta': 'தமிழ்', 'th': 'ภาษาไทย', 'ti': 'ትግርኛ', -// 'tl': 'Tagalog', + // 'tl': 'Tagalog', 'tr': 'Türkçe', 'uk': 'Українська', - 'ur': 'اُردُو‬', // RTL + 'ur': 'اُردُو‬', // RTL 'vi': 'Tiếng Việt', 'yo': 'Èdè Yorùbá', 'zh-hans': '简体中文', 'zh-hant': '正體中文', }; - /** * List of RTL languages. */ const LANGUAGE_RTL = [/* 'ace',*/ 'ar', 'fa', 'he', /* 'mzn', 'ps',*/ 'ur']; - /** * Category names in every language. */ const msgs = { - "ab": { - "Logic": "Алогика", - "Loops": "Ациклқәа", - "Math": "Аматематика", - "Text": "Атеқст", - "Lists": "Ахьӡынҵақәа", - "Colour": "Аԥштәы", - "Variables": "Аҽеиҭакқәа", - "Procedures": "Афункциақәа" - }, - "ace": { - "Logic": "Logis", - "Loops": "Kuwien", - "Math": "Matematik", - "Text": "Haraih", - "Lists": "Dapeuta", - "Colour": "Wareuna", - "Variables": "Meumacam", - "Procedures": "Prosedur" - }, - "am": { - "Logic": "የሁኔታዊ መገንቢያ ብሎኮች", - "Loops": "የዙሮች መገንቢያ ብሎኮች", - "Math": "የሂሳብ መገንቢያ ብሎኮች", - "Text": "የጽሕፈት መገንቢያ ብሎኮች", - "Lists": "የዝርዝር መገንቢያ ብሎኮች", - "Colour": "የቀለም መገንቢያ ብሎኮች", - "Variables": "የተላውጠ ቃላት መገንቢያ ብሎኮች", - "Procedures": "የመላዎች መገንቢያ ብሎኮች" - }, - "ar": { - "Logic": "منطق", - "Loops": "الحلقات", - "Math": "رياضيات", - "Text": "نص", - "Lists": "قوائم", - "Colour": "لون", - "Variables": "متغيرات", - "Procedures": "إجراءات" - }, - "ast": { - "Logic": "Lóxica", - "Loops": "Bucles", - "Math": "Matemátiques", - "Text": "Testu", - "Lists": "Llistes", - "Colour": "Color", - "Variables": "Variables", - "Procedures": "Funciones" - }, - "az": { - "Logic": "Məntiq", - "Loops": "Dövrə", - "Math": "Riyazi", - "Text": "Mətn", - "Lists": "Siyahılar", - "Colour": "Rəng", - "Variables": "Dəyişənlər", - "Procedures": "Funksiyalar" - }, - "ba": { - "Logic": " Танылыу", - "Loops": " Циклдар", - "Math": "Математика", - "Text": "Текст", - "Lists": "Исемлектәр", - "Colour": "Төҫ", - "Variables": " Үҙгәреүсән дәүмәлдәр", - "Procedures": " Функциялар" - }, - "be-tarask": { - "Logic": "Лёгіка", - "Loops": "Петлі", - "Math": "Матэматычныя формулы", - "Text": "Тэкст", - "Lists": "Сьпісы", - "Colour": "Колер", - "Variables": "Зьменныя", - "Procedures": "Функцыі" - }, - "be": { - "Logic": "Логіка", - "Loops": "Цыклы", - "Math": "Матэматыка", - "Text": "Тэкст", - "Lists": "Спісы", - "Colour": "Колер", - "Variables": "Пераменныя", - "Procedures": "Функцыі" - }, - "bg": { - "Logic": "Логика", - "Loops": "Цикли", - "Math": "Математика", - "Text": "Текст", - "Lists": "Списъци", - "Colour": "Цвят", - "Variables": "Променливи", - "Procedures": "Функции" - }, - "bn": { - "Logic": "যুক্তি", - "Loops": "লুপসমূহ", - "Math": "গণিত", - "Text": "লেখা", - "Lists": "তালিকাসমূহ", - "Colour": "রং", - "Variables": "চলকগুলো", - "Procedures": "ক্রিয়া" - }, - "br": { - "Logic": "Poell", - "Loops": "Rodelloù", - "Math": "Matematik", - "Text": "Testenn", - "Lists": "Rolloù", - "Colour": "Liv", - "Variables": "Argemmennoù", - "Procedures": "Arc'hwelioù" - }, - "ca": { - "Logic": "Lògica", - "Loops": "Bucles", - "Math": "Matemàtiques", - "Text": "Text", - "Lists": "Llistes", - "Colour": "Color", - "Variables": "Variables", - "Procedures": "Procediments" - }, - "cs": { - "Logic": "Logika", - "Loops": "Smyčky", - "Math": "Matika", - "Text": "Text", - "Lists": "Seznamy", - "Colour": "Barva", - "Variables": "Proměnné", - "Procedures": "Procedury" - }, - "da": { - "Logic": "Logik", - "Loops": "Løkker", - "Math": "Matematik", - "Text": "Tekst", - "Lists": "Lister", - "Colour": "Farve", - "Variables": "Variabler", - "Procedures": "Funktioner" - }, - "de": { - "Logic": "Logik", - "Loops": "Schleifen", - "Math": "Mathematik", - "Text": "Text", - "Lists": "Listen", - "Colour": "Farbe", - "Variables": "Variablen", - "Procedures": "Funktionen" - }, - "diq": { - "Logic": "Mentıq", - "Loops": "Dingeki", - "Math": "Matematik", - "Text": "Metın", - "Lists": "Listeyi", - "Colour": "Reng", - "Variables": "Vırneyeni", - "Procedures": "Fonksiyoni" - }, - "el": { - "Logic": "Λογική", - "Loops": "Επαναλήψεις", - "Math": "Μαθηματικά", - "Text": "Κείμενο", - "Lists": "Λίστες", - "Colour": "Χρώμα", - "Variables": "Μεταβλητές", - "Procedures": "Συναρτήσεις" - }, - "en": { - "Logic": "Logic", - "Loops": "Loops", - "Math": "Math", - "Text": "Text", - "Lists": "Lists", - "Colour": "Colour", - "Variables": "Variables", - "Procedures": "Functions" - }, - "eo": { - "Logic": "Logika", - "Loops": "Cikloj", - "Math": "Matematika", - "Text": "Teksto", - "Lists": "Listoj", - "Colour": "Koloro", - "Variables": "Variabloj", - "Procedures": "Funkcioj" - }, - "es": { - "Logic": "Lógica", - "Loops": "Bucles", - "Math": "Matemáticas", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Color", - "Variables": "Variables", - "Procedures": "Funciones" - }, - "et": { - "Logic": "Loogika", - "Loops": "Silmad", - "Math": "Matemaatika", - "Text": "Tekst", - "Lists": "Loendid", - "Colour": "Värv", - "Variables": "Muutujad", - "Procedures": "Funktsioonid" - }, - "eu": { - "Logic": "Logika", - "Loops": "Begiztak", - "Math": "Matematika", - "Text": "Testua", - "Lists": "Zerrendak", - "Colour": "Kolorea", - "Variables": "Aldagaiak", - "Procedures": "Prozedurak" - }, - "fa": { - "Logic": "منطق", - "Loops": "حلقه‌ها", - "Math": "ریاضی", - "Text": "متن", - "Lists": "فهرست‌ها", - "Colour": "رنگ", - "Variables": "متغییرها", - "Procedures": "توابع" - }, - "fi": { - "Logic": "Logiikka", - "Loops": "Silmukat", - "Math": "Matematiikka", - "Text": "Teksti", - "Lists": "Listat", - "Colour": "Väri", - "Variables": "Muuttujat", - "Procedures": "Funktiot" - }, - "fo": { - "Logic": "Logikkur", - "Loops": "Lykkjur", - "Math": "Støddfrøði", - "Text": "Tekstur", - "Lists": "Listar", - "Colour": "Litur", - "Variables": "Variablar", - "Procedures": "Funktiónir" - }, - "fr": { - "Logic": "Logique", - "Loops": "Boucles", - "Math": "Mathématiques", - "Text": "Texte", - "Lists": "Listes", - "Colour": "Couleur", - "Variables": "Variables", - "Procedures": "Fonctions" - }, - "gl": { - "Logic": "Lóxica", - "Loops": "Bucles", - "Math": "Matemáticas", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Cor", - "Variables": "Variables", - "Procedures": "Funcións" - }, - "gn": { - "Logic": "Kuaarape", - "Loops": "Tapykuegua", - "Math": "Papapykuaa", - "Text": "Jehaipy", - "Lists": "Tysýi", - "Colour": "Sa'y", - "Variables": "Ñemoambuéva", - "Procedures": "Aporeko" - }, - "ha": { - "Logic": "Dabara", - "Loops": "Tsallake-tsallake", - "Math": "Lissafi", - "Text": "Rubutu", - "Lists": "Jeri", - "Colour": "Launi", - "Variables": "Siffofi", - "Procedures": "Aikace-aikace" - }, - "hak": { - "Math": "Sṳ-ho̍k kûng-sṳt", - "Text": "文字", - "Lists": "列表", - "Colour": "顏色", - "Variables": "變量", - "Procedures": "函數" - }, - "he": { - "Logic": "לוגיקה", - "Loops": "לולאות", - "Math": "מתמטיקה", - "Text": "טקסט", - "Lists": "רשימות", - "Colour": "צבע", - "Variables": "משתנים", - "Procedures": "פונקציות" - }, - "hi": { - "Logic": "तर्क", - "Loops": "लूप", - "Math": "गणित", - "Text": "टेक्स्ट", - "Lists": "सूचियाँ", - "Colour": "रंग", - "Variables": "चर", - "Procedures": "प्रोसीजर" - }, - "hr": { - "Logic": "Logika", - "Loops": "Petlje", - "Math": "Matematika", - "Text": "Tekst", - "Lists": "Liste", - "Colour": "Boja", - "Variables": "Varijable", - "Procedures": "Funkcije" - }, - "hrx": { - "Logic": "Logik", - "Loops": "Schleife", - "Math": "Mathematik", - "Text": "Text", - "Lists": "Liste", - "Colour": "Farreb", - "Variables": "Variable", - "Procedures": "Funktione" - }, - "hu": { - "Logic": "Logika", - "Loops": "Ciklusok", - "Math": "Matek", - "Text": "Szövegkezelés", - "Lists": "Listakezelés", - "Colour": "Színek", - "Variables": "Változók", - "Procedures": "Eljárások" - }, - "hy": { - "Logic": "Տրամաբանական", - "Loops": "Կրկնող հանգույցներ", - "Math": "Մաթեմատիկա", - "Text": "Տեքստ", - "Lists": "Ցանկեր", - "Colour": "Գույն", - "Variables": "Փոփոխականներ", - "Procedures": "Գործառույթներ" - }, - "ia": { - "Logic": "Logica", - "Loops": "Buclas", - "Math": "Mathematica", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Color", - "Variables": "Variabiles", - "Procedures": "Functiones" - }, - "id": { - "Logic": "Logika", - "Loops": "Perulangan", - "Math": "Matematika", - "Text": "Teks", - "Lists": "Daftar", - "Colour": "Warna", - "Variables": "Variabel", - "Procedures": "Fungsi" - }, - "ig": { - "Logic": "Lọgịk", - "Loops": "Meghachi", - "Math": "Mgbakọ na mwepụ", - "Text": "Ederede", - "Lists": "Ndepụta", - "Colour": "Agba", - "Variables": "Agbanwe", - "Procedures": "Ọrụ" - }, - "inh": { - "Logic": "Логика", - "Loops": "Циклаш", - "Math": "Математика", - "Text": "Текст", - "Lists": "Спискаш", - "Colour": "Бoс", - "Variables": "Хувцалушъяраш", - "Procedures": "Функцеш" - }, - "is": { - "Logic": "Rökvísi", - "Loops": "Lykkjur", - "Math": "Reikningur", - "Text": "Texti", - "Lists": "Listar", - "Colour": "Litir", - "Variables": "Breytur", - "Procedures": "Föll" - }, - "it": { - "Logic": "Logica", - "Loops": "Cicli", - "Math": "Matematica", - "Text": "Testo", - "Lists": "Elenchi", - "Colour": "Colore", - "Variables": "Variabili", - "Procedures": "Funzioni" - }, - "ja": { - "Logic": "論理", - "Loops": "繰り返し", - "Math": "数学", - "Text": "テキスト", - "Lists": "リスト", - "Colour": "色", - "Variables": "変数", - "Procedures": "関数" - }, - "kab": { - "Logic": "Tameẓla", - "Loops": "Tiyerrisin", - "Math": "Tusnakt", - "Text": "Aḍris", - "Lists": "Tibdarin", - "Colour": "Ini", - "Variables": "Imuttiyen", - "Procedures": "Tiwuriwin" - }, - "kbd-cyrl": { - "Math": "Математикэ", - "Text": "Тхыгъэ", - "Lists": "КъебжэкI", - "Colour": "Плъыфэ" - }, - "kn": { - "Logic": "ತರ್ಕ", - "Loops": "ಸುತ್ತುಗಳು", - "Math": "ಗಣಿತ", - "Text": "ಪಠ್ಯ", - "Lists": "ಪಟ್ಟಿಗಳು", - "Colour": "ಬಣ್ಣ", - "Variables": "ಚರಾಂಶಗಳು", - "Procedures": "ಕಾರ್ಯಘಟಕಗಳು" - }, - "ko": { - "Logic": "논리", - "Loops": "반복", - "Math": "수학", - "Text": "문자열", - "Lists": "목록", - "Colour": "색", - "Variables": "변수", - "Procedures": "함수" - }, - "ku-latn": { - "Text": "Nivîs", - "Lists": "Lîste", - "Colour": "Reng" - }, - "lb": { - "Logic": "Logik", - "Loops": "Schleefen", - "Math": "Mathematik", - "Text": "Text", - "Lists": "Lëschten", - "Colour": "Faarf", - "Variables": "Variabelen", - "Procedures": "Funktiounen" - }, - "lki": { - "Logic": "منطق", - "Loops": "حلقه‌ها", - "Math": "ریاضی", - "Text": "متن", - "Lists": "لیستةل", - "Colour": "رةنگ", - "Variables": "متغییرها", - "Procedures": "توابع" - }, - "lrc": { - "Logic": "عٱقلمٱنی", - "Loops": "هٱلقٱیا", - "Math": "هساو کتاو", - "Text": "مٱتن", - "Lists": "نومگٱیا", - "Colour": "رٱنڳ", - "Variables": "آلشتؽا", - "Procedures": "رویٱیا" - }, - "lt": { - "Logic": "Logika", - "Loops": "Kartojimas", - "Math": "Matematika", - "Text": "Tekstas", - "Lists": "Sąrašai", - "Colour": "Spalva", - "Variables": "Kintamieji", - "Procedures": "Funkcijos" - }, - "lv": { - "Logic": "Loģika", - "Loops": "Cikli", - "Math": "Matemātika", - "Text": "Teksts", - "Lists": "Saraksti", - "Colour": "Krāsa", - "Variables": "Mainīgie", - "Procedures": "Funkcijas" - }, - "mg": { - "Logic": "Lôjika", - "Loops": "Tondro mifolaka", - "Math": "Matematika", - "Text": "Soratra", - "Lists": "Lisitra", - "Colour": "Loko", - "Variables": "Ova", - "Procedures": "Paika" - }, - "mk": { - "Logic": "Логика", - "Loops": "Јамки", - "Math": "Математика", - "Text": "Текст", - "Lists": "Списоци", - "Colour": "Боја", - "Variables": "Променливи", - "Procedures": "Функции" - }, - "mr": { - "Loops": "वेटोळ्या(लूप्स)", - "Text": "मजकूर", - "Colour": "रंग", - "Variables": "अस्थिरके" - }, - "ms": { - "Logic": "Logik", - "Loops": "Gelung", - "Math": "Matematik", - "Text": "Teks", - "Lists": "Senarai", - "Colour": "Warna", - "Variables": "Pemboleh ubah", - "Procedures": "Fungsi" - }, - "my": { - "Logic": "ယုတ္တိ", - "Loops": "ကွင်း", - "Math": "သင်္ချာ", - "Text": "စာသား", - "Lists": "စာရင်းများ", - "Colour": "အရောင်", - "Variables": "အမျိုးမျိုးပြောင်းလဲနိုင်သော", - "Procedures": "လုပ်ဆောင်ချက်များ" - }, - "nb": { - "Logic": "Logikk", - "Loops": "Løkker", - "Math": "Matte", - "Text": "Tekst", - "Lists": "Lister", - "Colour": "Farge", - "Variables": "Variabler", - "Procedures": "Funksjoner" - }, - "ne": { - "Logic": "लजिक", - "Loops": "लुपहरू", - "Math": "गणित", - "Text": "पाठ", - "Lists": "सूची", - "Colour": "रंग", - "Variables": "चल राशी(variables)", - "Procedures": "अनुक्रियाहरु" - }, - "nl": { - "Logic": "Logica", - "Loops": "Lussen", - "Math": "Formules", - "Text": "Tekst", - "Lists": "Lijsten", - "Colour": "Kleur", - "Variables": "Variabelen", - "Procedures": "Functies" - }, - "oc": { - "Logic": "Logic", - "Loops": "Boclas", - "Math": "Math", - "Text": "Tèxte", - "Lists": "Listas", - "Colour": "Color", - "Variables": "Variablas", - "Procedures": "Foncions" - }, - "olo": { - "Logic": "Lougiekku", - "Loops": "Čiepit", - "Math": "Matemuatiekku", - "Text": "Tekstu", - "Lists": "Listat", - "Colour": "Väri", - "Variables": "Variantat" - }, - "pa": { - "Math": "ਹਿਸਾਬ", - "Text": "ਲਿਖਤ", - "Lists": "ਸੂਚੀਆਂ", - "Colour": "ਰੰਗ", - "Variables": "ਬਦਲਣਹਾਰ" - }, - "pl": { - "Logic": "Logika", - "Loops": "Pętle", - "Math": "Matematyka", - "Text": "Tekst", - "Lists": "Listy", - "Colour": "Kolor", - "Variables": "Zmienne", - "Procedures": "Funkcje" - }, - "pms": { - "Logic": "Lògica", - "Loops": "Liasse", - "Math": "Matemàtica", - "Text": "Test", - "Lists": "Liste", - "Colour": "Color", - "Variables": "Variàbij", - "Procedures": "Fonsion" - }, - "ps": { - "Logic": "منطق", - "Math": "شمېرپوهنه", - "Text": "متن", - "Lists": "لړليکونه", - "Colour": "رنگ" - }, - "pt-br": { - "Logic": "Lógica", - "Loops": "Laços", - "Math": "Matemática", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Cor", - "Variables": "Variáveis", - "Procedures": "Funções" - }, - "pt": { - "Logic": "Lógica", - "Loops": "Ciclos", - "Math": "Matemática", - "Text": "Texto", - "Lists": "Listas", - "Colour": "Cor", - "Variables": "Variáveis", - "Procedures": "Funções" - }, - "ro": { - "Logic": "Logic", - "Loops": "Bucle", - "Math": "Matematică", - "Text": "Text", - "Lists": "Liste", - "Colour": "Culoare", - "Variables": "Variabile", - "Procedures": "Funcții" - }, - "ru": { - "Logic": "Логика", - "Loops": "Циклы", - "Math": "Математика", - "Text": "Текст", - "Lists": "Списки", - "Colour": "Цвет", - "Variables": "Переменные", - "Procedures": "Функции" - }, - "sc": { - "Logic": "Lògica", - "Loops": "Lòrigas", - "Math": "Matemàtica", - "Text": "Testu", - "Lists": "Lista", - "Colour": "Colori", - "Variables": "Variabilis", - "Procedures": "Funtzionis" - }, - "sco": { - "Logic": "Logeec", - "Loops": "Luips", - "Math": "Maths", - "Text": "Tex", - "Lists": "Leets", - "Colour": "Colour", - "Variables": "Variables", - "Procedures": "Functions" - }, - "sd": { - "Logic": "منطق", - "Loops": "چڪر", - "Math": "رياضي", - "Text": "اکر", - "Lists": "فھرست", - "Colour": "رنگ", - "Variables": "ڦرڻا", - "Procedures": "عمل" - }, - "si": { - "Logic": "තර්කය", - "Math": "ගණිතමය", - "Text": "පෙළ", - "Lists": "ලැයිස්තු", - "Colour": "පාට", - "Variables": "විචල්‍යයන්", - "Procedures": "ශ්‍රිත" - }, - "sk": { - "Logic": "Logické", - "Loops": "Slučky", - "Math": "Matematika", - "Text": "Textové", - "Lists": "Zoznamy", - "Colour": "Farba", - "Variables": "Premenné", - "Procedures": "Funkcie" - }, - "skr-arab": { - "Logic": "منطق", - "Loops": "لوپاں", - "Math": "ریاضی", - "Text": "ٹیکسٹ", - "Lists": "فہرستاں", - "Colour": "رنگ", - "Variables": "متغیرات", - "Procedures": "فنکشن" - }, - "sl": { - "Logic": "Logika", - "Loops": "Zanke", - "Math": "Matematika", - "Text": "Besedilo", - "Lists": "Seznami", - "Colour": "Barva", - "Variables": "Spremenljivke", - "Procedures": "Funkcije" - }, - "smn": { - "Logic": "Loogiik", - "Loops": "Váárvuh", - "Math": "Matematiik", - "Text": "Tekstâ", - "Lists": "Listoh", - "Colour": "Ivne", - "Variables": "Muttojeijee", - "Procedures": "Funktioh" - }, - "sq": { - "Logic": "Logjikë", - "Loops": "Qark", - "Math": "Matematikë", - "Text": "Tekst", - "Lists": "Listat", - "Colour": "Ngjyrë", - "Variables": "Variablat", - "Procedures": "Funksionet" - }, - "sr-latn": { - "Logic": "Logika", - "Loops": "Petlje", - "Math": "Matematika", - "Text": "Tekst", - "Lists": "Spiskovi", - "Colour": "Boja", - "Variables": "Promenljive", - "Procedures": "Funkcije" - }, - "sr": { - "Logic": "Логика", - "Loops": "Петље", - "Math": "Математика", - "Text": "Текст", - "Lists": "Спискови", - "Colour": "Боја", - "Variables": "Променљиве", - "Procedures": "Функције" - }, - "sv": { - "Logic": "Logik", - "Loops": "Loopar", - "Math": "Matematik", - "Text": "Text", - "Lists": "Listor", - "Colour": "Färg", - "Variables": "Variabler", - "Procedures": "Funktioner" - }, - "ta": { - "Logic": "தர்க்கம்", - "Loops": "மடக்குக்கட்டளை", - "Math": "கணிதம்", - "Text": "உரை", - "Lists": "பட்டியல்", - "Colour": "நிறம்", - "Variables": "மாறி", - "Procedures": "செயலாற்றிகள்" - }, - "tcy": { - "Logic": "ವಾದೊ", - "Loops": "ಲೂಪ್‍ಲು", - "Math": "ಲೆಕ್ಕೊ", - "Text": "ಪಟ್ಯೊ", - "Lists": "ಪಟ್ಟಿಲು", - "Colour": "ಬನ್ನೊ", - "Variables": "ವ್ಯತ್ಯಯೊಲು", - "Procedures": "ಲೇಸ್‍ಲು" - }, - "te": { - "Logic": "తర్కం", - "Loops": "లూప్స్", - "Math": "గణితం", - "Text": "పాఠ్యం", - "Lists": "జాబితాలు", - "Colour": "రంగు", - "Variables": "చరరాశులు", - "Procedures": "ప్రమేయాలు" - }, - "th": { - "Logic": "ตรรกะ", - "Loops": "การวนซ้ำ", - "Math": "คณิตศาสตร์", - "Text": "ข้อความ", - "Lists": "รายการ", - "Colour": "สี", - "Variables": "ตัวแปร", - "Procedures": "ฟังก์ชัน" - }, - "ti": { - "Logic": "ሎጂክ", - "Loops": "ኣዝዋሪታት", - "Math": "ሒሳብ", - "Text": "ጽሑፍ", - "Lists": "ዝርዝር", - "Colour": "ሕብሪ", - "Variables": "ተተካእቲ", - "Procedures": "ፋንክሽናት" - }, - "tr": { - "Logic": "Mantık", - "Loops": "Döngüler", - "Math": "Matematik", - "Text": "Metin", - "Lists": "Listeler", - "Colour": "Renk", - "Variables": "Değişkenler", - "Procedures": "İşlevler" - }, - "uk": { - "Logic": "Логіка", - "Loops": "Цикли", - "Math": "Математика", - "Text": "Текст", - "Lists": "Списки", - "Colour": "Колір", - "Variables": "Змінні", - "Procedures": "Функції" - }, - "ur": { - "Logic": "منطق", - "Loops": "لوپیں", - "Math": "ریاضی", - "Text": "متن", - "Lists": "فہرستیں", - "Colour": "رنگ", - "Variables": "متغیرات", - "Procedures": "افعال" - }, - "uz": { - "Logic": "Mantiq", - "Loops": "Tsikllar", - "Math": "Matematika", - "Text": "Matn", - "Lists": "Roʻyxatlar", - "Colour": "Rang", - "Variables": "O'zgaruvchilar", - "Procedures": "Funksiyalar" - }, - "vi": { - "Logic": "Logic", - "Loops": "Vòng lặp", - "Math": "Công thức toán", - "Text": "Văn bản", - "Lists": "Danh sách", - "Colour": "Màu", - "Variables": "Biến", - "Procedures": "Hàm" - }, - "yo": { - "Logic": "Irogun", - "Loops": "Ilosiwaju losehin", - "Math": "Isiro", - "Text": "Ọrọ", - "Lists": "Akojọ", - "Colour": "Awọ", - "Variables": "Oniruru", - "Procedures": "Iṣe" - }, - "yue": { - "Logic": "邏輯", - "Loops": "循環", - "Math": "數學", - "Text": "發短信", - "Lists": "一覽", - "Colour": "顏色", - "Variables": "變數", - "Procedures": "功能" - }, - "zh-hans": { - "Logic": "逻辑", - "Loops": "循环", - "Math": "数学", - "Text": "文本", - "Lists": "列表", - "Colour": "颜色", - "Variables": "变量", - "Procedures": "函数" - }, - "zh-hant": { - "Logic": "邏輯", - "Loops": "迴圈", - "Math": "運算", - "Text": "文字", - "Lists": "清單", - "Colour": "顏色", - "Variables": "變數", - "Procedures": "函式" - } + 'ab': { + Logic: 'Алогика', + Loops: 'Ациклқәа', + Math: 'Аматематика', + Text: 'Атеқст', + Lists: 'Ахьӡынҵақәа', + Colour: 'Аԥштәы', + Variables: 'Аҽеиҭакқәа', + Procedures: 'Афункциақәа', + }, + 'ace': { + Logic: 'Logis', + Loops: 'Kuwien', + Math: 'Matematik', + Text: 'Haraih', + Lists: 'Dapeuta', + Colour: 'Wareuna', + Variables: 'Meumacam', + Procedures: 'Prosedur', + }, + 'am': { + Logic: 'የሁኔታዊ መገንቢያ ብሎኮች', + Loops: 'የዙሮች መገንቢያ ብሎኮች', + Math: 'የሂሳብ መገንቢያ ብሎኮች', + Text: 'የጽሕፈት መገንቢያ ብሎኮች', + Lists: 'የዝርዝር መገንቢያ ብሎኮች', + Colour: 'የቀለም መገንቢያ ብሎኮች', + Variables: 'የተላውጠ ቃላት መገንቢያ ብሎኮች', + Procedures: 'የመላዎች መገንቢያ ብሎኮች', + }, + 'ar': { + Logic: 'منطق', + Loops: 'الحلقات', + Math: 'رياضيات', + Text: 'نص', + Lists: 'قوائم', + Colour: 'لون', + Variables: 'متغيرات', + Procedures: 'إجراءات', + }, + 'ast': { + Logic: 'Lóxica', + Loops: 'Bucles', + Math: 'Matemátiques', + Text: 'Testu', + Lists: 'Llistes', + Colour: 'Color', + Variables: 'Variables', + Procedures: 'Funciones', + }, + 'az': { + Logic: 'Məntiq', + Loops: 'Dövrə', + Math: 'Riyazi', + Text: 'Mətn', + Lists: 'Siyahılar', + Colour: 'Rəng', + Variables: 'Dəyişənlər', + Procedures: 'Funksiyalar', + }, + 'ba': { + Logic: ' Танылыу', + Loops: ' Циклдар', + Math: 'Математика', + Text: 'Текст', + Lists: 'Исемлектәр', + Colour: 'Төҫ', + Variables: ' Үҙгәреүсән дәүмәлдәр', + Procedures: ' Функциялар', + }, + 'be-tarask': { + Logic: 'Лёгіка', + Loops: 'Петлі', + Math: 'Матэматычныя формулы', + Text: 'Тэкст', + Lists: 'Сьпісы', + Colour: 'Колер', + Variables: 'Зьменныя', + Procedures: 'Функцыі', + }, + 'be': { + Logic: 'Логіка', + Loops: 'Цыклы', + Math: 'Матэматыка', + Text: 'Тэкст', + Lists: 'Спісы', + Colour: 'Колер', + Variables: 'Пераменныя', + Procedures: 'Функцыі', + }, + 'bg': { + Logic: 'Логика', + Loops: 'Цикли', + Math: 'Математика', + Text: 'Текст', + Lists: 'Списъци', + Colour: 'Цвят', + Variables: 'Променливи', + Procedures: 'Функции', + }, + 'bn': { + Logic: 'যুক্তি', + Loops: 'লুপসমূহ', + Math: 'গণিত', + Text: 'লেখা', + Lists: 'তালিকাসমূহ', + Colour: 'রং', + Variables: 'চলকগুলো', + Procedures: 'ক্রিয়া', + }, + 'br': { + Logic: 'Poell', + Loops: 'Rodelloù', + Math: 'Matematik', + Text: 'Testenn', + Lists: 'Rolloù', + Colour: 'Liv', + Variables: 'Argemmennoù', + Procedures: "Arc'hwelioù", + }, + 'ca': { + Logic: 'Lògica', + Loops: 'Bucles', + Math: 'Matemàtiques', + Text: 'Text', + Lists: 'Llistes', + Colour: 'Color', + Variables: 'Variables', + Procedures: 'Procediments', + }, + 'cs': { + Logic: 'Logika', + Loops: 'Smyčky', + Math: 'Matika', + Text: 'Text', + Lists: 'Seznamy', + Colour: 'Barva', + Variables: 'Proměnné', + Procedures: 'Procedury', + }, + 'da': { + Logic: 'Logik', + Loops: 'Løkker', + Math: 'Matematik', + Text: 'Tekst', + Lists: 'Lister', + Colour: 'Farve', + Variables: 'Variabler', + Procedures: 'Funktioner', + }, + 'de': { + Logic: 'Logik', + Loops: 'Schleifen', + Math: 'Mathematik', + Text: 'Text', + Lists: 'Listen', + Colour: 'Farbe', + Variables: 'Variablen', + Procedures: 'Funktionen', + }, + 'diq': { + Logic: 'Mentıq', + Loops: 'Dingeki', + Math: 'Matematik', + Text: 'Metın', + Lists: 'Listeyi', + Colour: 'Reng', + Variables: 'Vırneyeni', + Procedures: 'Fonksiyoni', + }, + 'el': { + Logic: 'Λογική', + Loops: 'Επαναλήψεις', + Math: 'Μαθηματικά', + Text: 'Κείμενο', + Lists: 'Λίστες', + Colour: 'Χρώμα', + Variables: 'Μεταβλητές', + Procedures: 'Συναρτήσεις', + }, + 'en': { + Logic: 'Logic', + Loops: 'Loops', + Math: 'Math', + Text: 'Text', + Lists: 'Lists', + Colour: 'Colour', + Variables: 'Variables', + Procedures: 'Functions', + }, + 'eo': { + Logic: 'Logika', + Loops: 'Cikloj', + Math: 'Matematika', + Text: 'Teksto', + Lists: 'Listoj', + Colour: 'Koloro', + Variables: 'Variabloj', + Procedures: 'Funkcioj', + }, + 'es': { + Logic: 'Lógica', + Loops: 'Bucles', + Math: 'Matemáticas', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Color', + Variables: 'Variables', + Procedures: 'Funciones', + }, + 'et': { + Logic: 'Loogika', + Loops: 'Silmad', + Math: 'Matemaatika', + Text: 'Tekst', + Lists: 'Loendid', + Colour: 'Värv', + Variables: 'Muutujad', + Procedures: 'Funktsioonid', + }, + 'eu': { + Logic: 'Logika', + Loops: 'Begiztak', + Math: 'Matematika', + Text: 'Testua', + Lists: 'Zerrendak', + Colour: 'Kolorea', + Variables: 'Aldagaiak', + Procedures: 'Prozedurak', + }, + 'fa': { + Logic: 'منطق', + Loops: 'حلقه‌ها', + Math: 'ریاضی', + Text: 'متن', + Lists: 'فهرست‌ها', + Colour: 'رنگ', + Variables: 'متغییرها', + Procedures: 'توابع', + }, + 'fi': { + Logic: 'Logiikka', + Loops: 'Silmukat', + Math: 'Matematiikka', + Text: 'Teksti', + Lists: 'Listat', + Colour: 'Väri', + Variables: 'Muuttujat', + Procedures: 'Funktiot', + }, + 'fo': { + Logic: 'Logikkur', + Loops: 'Lykkjur', + Math: 'Støddfrøði', + Text: 'Tekstur', + Lists: 'Listar', + Colour: 'Litur', + Variables: 'Variablar', + Procedures: 'Funktiónir', + }, + 'fr': { + Logic: 'Logique', + Loops: 'Boucles', + Math: 'Mathématiques', + Text: 'Texte', + Lists: 'Listes', + Colour: 'Couleur', + Variables: 'Variables', + Procedures: 'Fonctions', + }, + 'gl': { + Logic: 'Lóxica', + Loops: 'Bucles', + Math: 'Matemáticas', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Cor', + Variables: 'Variables', + Procedures: 'Funcións', + }, + 'gn': { + Logic: 'Kuaarape', + Loops: 'Tapykuegua', + Math: 'Papapykuaa', + Text: 'Jehaipy', + Lists: 'Tysýi', + Colour: "Sa'y", + Variables: 'Ñemoambuéva', + Procedures: 'Aporeko', + }, + 'ha': { + Logic: 'Dabara', + Loops: 'Tsallake-tsallake', + Math: 'Lissafi', + Text: 'Rubutu', + Lists: 'Jeri', + Colour: 'Launi', + Variables: 'Siffofi', + Procedures: 'Aikace-aikace', + }, + 'hak': { + Math: 'Sṳ-ho̍k kûng-sṳt', + Text: '文字', + Lists: '列表', + Colour: '顏色', + Variables: '變量', + Procedures: '函數', + }, + 'he': { + Logic: 'לוגיקה', + Loops: 'לולאות', + Math: 'מתמטיקה', + Text: 'טקסט', + Lists: 'רשימות', + Colour: 'צבע', + Variables: 'משתנים', + Procedures: 'פונקציות', + }, + 'hi': { + Logic: 'तर्क', + Loops: 'लूप', + Math: 'गणित', + Text: 'टेक्स्ट', + Lists: 'सूचियाँ', + Colour: 'रंग', + Variables: 'चर', + Procedures: 'प्रोसीजर', + }, + 'hr': { + Logic: 'Logika', + Loops: 'Petlje', + Math: 'Matematika', + Text: 'Tekst', + Lists: 'Liste', + Colour: 'Boja', + Variables: 'Varijable', + Procedures: 'Funkcije', + }, + 'hrx': { + Logic: 'Logik', + Loops: 'Schleife', + Math: 'Mathematik', + Text: 'Text', + Lists: 'Liste', + Colour: 'Farreb', + Variables: 'Variable', + Procedures: 'Funktione', + }, + 'hu': { + Logic: 'Logika', + Loops: 'Ciklusok', + Math: 'Matek', + Text: 'Szövegkezelés', + Lists: 'Listakezelés', + Colour: 'Színek', + Variables: 'Változók', + Procedures: 'Eljárások', + }, + 'hy': { + Logic: 'Տրամաբանական', + Loops: 'Կրկնող հանգույցներ', + Math: 'Մաթեմատիկա', + Text: 'Տեքստ', + Lists: 'Ցանկեր', + Colour: 'Գույն', + Variables: 'Փոփոխականներ', + Procedures: 'Գործառույթներ', + }, + 'ia': { + Logic: 'Logica', + Loops: 'Buclas', + Math: 'Mathematica', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Color', + Variables: 'Variabiles', + Procedures: 'Functiones', + }, + 'id': { + Logic: 'Logika', + Loops: 'Perulangan', + Math: 'Matematika', + Text: 'Teks', + Lists: 'Daftar', + Colour: 'Warna', + Variables: 'Variabel', + Procedures: 'Fungsi', + }, + 'ig': { + Logic: 'Lọgịk', + Loops: 'Meghachi', + Math: 'Mgbakọ na mwepụ', + Text: 'Ederede', + Lists: 'Ndepụta', + Colour: 'Agba', + Variables: 'Agbanwe', + Procedures: 'Ọrụ', + }, + 'inh': { + Logic: 'Логика', + Loops: 'Циклаш', + Math: 'Математика', + Text: 'Текст', + Lists: 'Спискаш', + Colour: 'Бoс', + Variables: 'Хувцалушъяраш', + Procedures: 'Функцеш', + }, + 'is': { + Logic: 'Rökvísi', + Loops: 'Lykkjur', + Math: 'Reikningur', + Text: 'Texti', + Lists: 'Listar', + Colour: 'Litir', + Variables: 'Breytur', + Procedures: 'Föll', + }, + 'it': { + Logic: 'Logica', + Loops: 'Cicli', + Math: 'Matematica', + Text: 'Testo', + Lists: 'Elenchi', + Colour: 'Colore', + Variables: 'Variabili', + Procedures: 'Funzioni', + }, + 'ja': { + Logic: '論理', + Loops: '繰り返し', + Math: '数学', + Text: 'テキスト', + Lists: 'リスト', + Colour: '色', + Variables: '変数', + Procedures: '関数', + }, + 'kab': { + Logic: 'Tameẓla', + Loops: 'Tiyerrisin', + Math: 'Tusnakt', + Text: 'Aḍris', + Lists: 'Tibdarin', + Colour: 'Ini', + Variables: 'Imuttiyen', + Procedures: 'Tiwuriwin', + }, + 'kbd-cyrl': { + Math: 'Математикэ', + Text: 'Тхыгъэ', + Lists: 'КъебжэкI', + Colour: 'Плъыфэ', + }, + 'kn': { + Logic: 'ತರ್ಕ', + Loops: 'ಸುತ್ತುಗಳು', + Math: 'ಗಣಿತ', + Text: 'ಪಠ್ಯ', + Lists: 'ಪಟ್ಟಿಗಳು', + Colour: 'ಬಣ್ಣ', + Variables: 'ಚರಾಂಶಗಳು', + Procedures: 'ಕಾರ್ಯಘಟಕಗಳು', + }, + 'ko': { + Logic: '논리', + Loops: '반복', + Math: '수학', + Text: '문자열', + Lists: '목록', + Colour: '색', + Variables: '변수', + Procedures: '함수', + }, + 'ku-latn': { + Text: 'Nivîs', + Lists: 'Lîste', + Colour: 'Reng', + }, + 'lb': { + Logic: 'Logik', + Loops: 'Schleefen', + Math: 'Mathematik', + Text: 'Text', + Lists: 'Lëschten', + Colour: 'Faarf', + Variables: 'Variabelen', + Procedures: 'Funktiounen', + }, + 'lki': { + Logic: 'منطق', + Loops: 'حلقه‌ها', + Math: 'ریاضی', + Text: 'متن', + Lists: 'لیستةل', + Colour: 'رةنگ', + Variables: 'متغییرها', + Procedures: 'توابع', + }, + 'lrc': { + Logic: 'عٱقلمٱنی', + Loops: 'هٱلقٱیا', + Math: 'هساو کتاو', + Text: 'مٱتن', + Lists: 'نومگٱیا', + Colour: 'رٱنڳ', + Variables: 'آلشتؽا', + Procedures: 'رویٱیا', + }, + 'lt': { + Logic: 'Logika', + Loops: 'Kartojimas', + Math: 'Matematika', + Text: 'Tekstas', + Lists: 'Sąrašai', + Colour: 'Spalva', + Variables: 'Kintamieji', + Procedures: 'Funkcijos', + }, + 'lv': { + Logic: 'Loģika', + Loops: 'Cikli', + Math: 'Matemātika', + Text: 'Teksts', + Lists: 'Saraksti', + Colour: 'Krāsa', + Variables: 'Mainīgie', + Procedures: 'Funkcijas', + }, + 'mg': { + Logic: 'Lôjika', + Loops: 'Tondro mifolaka', + Math: 'Matematika', + Text: 'Soratra', + Lists: 'Lisitra', + Colour: 'Loko', + Variables: 'Ova', + Procedures: 'Paika', + }, + 'mk': { + Logic: 'Логика', + Loops: 'Јамки', + Math: 'Математика', + Text: 'Текст', + Lists: 'Списоци', + Colour: 'Боја', + Variables: 'Променливи', + Procedures: 'Функции', + }, + 'mr': { + Loops: 'वेटोळ्या(लूप्स)', + Text: 'मजकूर', + Colour: 'रंग', + Variables: 'अस्थिरके', + }, + 'ms': { + Logic: 'Logik', + Loops: 'Gelung', + Math: 'Matematik', + Text: 'Teks', + Lists: 'Senarai', + Colour: 'Warna', + Variables: 'Pemboleh ubah', + Procedures: 'Fungsi', + }, + 'my': { + Logic: 'ယုတ္တိ', + Loops: 'ကွင်း', + Math: 'သင်္ချာ', + Text: 'စာသား', + Lists: 'စာရင်းများ', + Colour: 'အရောင်', + Variables: 'အမျိုးမျိုးပြောင်းလဲနိုင်သော', + Procedures: 'လုပ်ဆောင်ချက်များ', + }, + 'nb': { + Logic: 'Logikk', + Loops: 'Løkker', + Math: 'Matte', + Text: 'Tekst', + Lists: 'Lister', + Colour: 'Farge', + Variables: 'Variabler', + Procedures: 'Funksjoner', + }, + 'ne': { + Logic: 'लजिक', + Loops: 'लुपहरू', + Math: 'गणित', + Text: 'पाठ', + Lists: 'सूची', + Colour: 'रंग', + Variables: 'चल राशी(variables)', + Procedures: 'अनुक्रियाहरु', + }, + 'nl': { + Logic: 'Logica', + Loops: 'Lussen', + Math: 'Formules', + Text: 'Tekst', + Lists: 'Lijsten', + Colour: 'Kleur', + Variables: 'Variabelen', + Procedures: 'Functies', + }, + 'oc': { + Logic: 'Logic', + Loops: 'Boclas', + Math: 'Math', + Text: 'Tèxte', + Lists: 'Listas', + Colour: 'Color', + Variables: 'Variablas', + Procedures: 'Foncions', + }, + 'olo': { + Logic: 'Lougiekku', + Loops: 'Čiepit', + Math: 'Matemuatiekku', + Text: 'Tekstu', + Lists: 'Listat', + Colour: 'Väri', + Variables: 'Variantat', + }, + 'pa': { + Math: 'ਹਿਸਾਬ', + Text: 'ਲਿਖਤ', + Lists: 'ਸੂਚੀਆਂ', + Colour: 'ਰੰਗ', + Variables: 'ਬਦਲਣਹਾਰ', + }, + 'pl': { + Logic: 'Logika', + Loops: 'Pętle', + Math: 'Matematyka', + Text: 'Tekst', + Lists: 'Listy', + Colour: 'Kolor', + Variables: 'Zmienne', + Procedures: 'Funkcje', + }, + 'pms': { + Logic: 'Lògica', + Loops: 'Liasse', + Math: 'Matemàtica', + Text: 'Test', + Lists: 'Liste', + Colour: 'Color', + Variables: 'Variàbij', + Procedures: 'Fonsion', + }, + 'ps': { + Logic: 'منطق', + Math: 'شمېرپوهنه', + Text: 'متن', + Lists: 'لړليکونه', + Colour: 'رنگ', + }, + 'pt-br': { + Logic: 'Lógica', + Loops: 'Laços', + Math: 'Matemática', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Cor', + Variables: 'Variáveis', + Procedures: 'Funções', + }, + 'pt': { + Logic: 'Lógica', + Loops: 'Ciclos', + Math: 'Matemática', + Text: 'Texto', + Lists: 'Listas', + Colour: 'Cor', + Variables: 'Variáveis', + Procedures: 'Funções', + }, + 'ro': { + Logic: 'Logic', + Loops: 'Bucle', + Math: 'Matematică', + Text: 'Text', + Lists: 'Liste', + Colour: 'Culoare', + Variables: 'Variabile', + Procedures: 'Funcții', + }, + 'ru': { + Logic: 'Логика', + Loops: 'Циклы', + Math: 'Математика', + Text: 'Текст', + Lists: 'Списки', + Colour: 'Цвет', + Variables: 'Переменные', + Procedures: 'Функции', + }, + 'sc': { + Logic: 'Lògica', + Loops: 'Lòrigas', + Math: 'Matemàtica', + Text: 'Testu', + Lists: 'Lista', + Colour: 'Colori', + Variables: 'Variabilis', + Procedures: 'Funtzionis', + }, + 'sco': { + Logic: 'Logeec', + Loops: 'Luips', + Math: 'Maths', + Text: 'Tex', + Lists: 'Leets', + Colour: 'Colour', + Variables: 'Variables', + Procedures: 'Functions', + }, + 'sd': { + Logic: 'منطق', + Loops: 'چڪر', + Math: 'رياضي', + Text: 'اکر', + Lists: 'فھرست', + Colour: 'رنگ', + Variables: 'ڦرڻا', + Procedures: 'عمل', + }, + 'si': { + Logic: 'තර්කය', + Math: 'ගණිතමය', + Text: 'පෙළ', + Lists: 'ලැයිස්තු', + Colour: 'පාට', + Variables: 'විචල්‍යයන්', + Procedures: 'ශ්‍රිත', + }, + 'sk': { + Logic: 'Logické', + Loops: 'Slučky', + Math: 'Matematika', + Text: 'Textové', + Lists: 'Zoznamy', + Colour: 'Farba', + Variables: 'Premenné', + Procedures: 'Funkcie', + }, + 'skr-arab': { + Logic: 'منطق', + Loops: 'لوپاں', + Math: 'ریاضی', + Text: 'ٹیکسٹ', + Lists: 'فہرستاں', + Colour: 'رنگ', + Variables: 'متغیرات', + Procedures: 'فنکشن', + }, + 'sl': { + Logic: 'Logika', + Loops: 'Zanke', + Math: 'Matematika', + Text: 'Besedilo', + Lists: 'Seznami', + Colour: 'Barva', + Variables: 'Spremenljivke', + Procedures: 'Funkcije', + }, + 'smn': { + Logic: 'Loogiik', + Loops: 'Váárvuh', + Math: 'Matematiik', + Text: 'Tekstâ', + Lists: 'Listoh', + Colour: 'Ivne', + Variables: 'Muttojeijee', + Procedures: 'Funktioh', + }, + 'sq': { + Logic: 'Logjikë', + Loops: 'Qark', + Math: 'Matematikë', + Text: 'Tekst', + Lists: 'Listat', + Colour: 'Ngjyrë', + Variables: 'Variablat', + Procedures: 'Funksionet', + }, + 'sr-latn': { + Logic: 'Logika', + Loops: 'Petlje', + Math: 'Matematika', + Text: 'Tekst', + Lists: 'Spiskovi', + Colour: 'Boja', + Variables: 'Promenljive', + Procedures: 'Funkcije', + }, + 'sr': { + Logic: 'Логика', + Loops: 'Петље', + Math: 'Математика', + Text: 'Текст', + Lists: 'Спискови', + Colour: 'Боја', + Variables: 'Променљиве', + Procedures: 'Функције', + }, + 'sv': { + Logic: 'Logik', + Loops: 'Loopar', + Math: 'Matematik', + Text: 'Text', + Lists: 'Listor', + Colour: 'Färg', + Variables: 'Variabler', + Procedures: 'Funktioner', + }, + 'ta': { + Logic: 'தர்க்கம்', + Loops: 'மடக்குக்கட்டளை', + Math: 'கணிதம்', + Text: 'உரை', + Lists: 'பட்டியல்', + Colour: 'நிறம்', + Variables: 'மாறி', + Procedures: 'செயலாற்றிகள்', + }, + 'tcy': { + Logic: 'ವಾದೊ', + Loops: 'ಲೂಪ್‍ಲು', + Math: 'ಲೆಕ್ಕೊ', + Text: 'ಪಟ್ಯೊ', + Lists: 'ಪಟ್ಟಿಲು', + Colour: 'ಬನ್ನೊ', + Variables: 'ವ್ಯತ್ಯಯೊಲು', + Procedures: 'ಲೇಸ್‍ಲು', + }, + 'te': { + Logic: 'తర్కం', + Loops: 'లూప్స్', + Math: 'గణితం', + Text: 'పాఠ్యం', + Lists: 'జాబితాలు', + Colour: 'రంగు', + Variables: 'చరరాశులు', + Procedures: 'ప్రమేయాలు', + }, + 'th': { + Logic: 'ตรรกะ', + Loops: 'การวนซ้ำ', + Math: 'คณิตศาสตร์', + Text: 'ข้อความ', + Lists: 'รายการ', + Colour: 'สี', + Variables: 'ตัวแปร', + Procedures: 'ฟังก์ชัน', + }, + 'ti': { + Logic: 'ሎጂክ', + Loops: 'ኣዝዋሪታት', + Math: 'ሒሳብ', + Text: 'ጽሑፍ', + Lists: 'ዝርዝር', + Colour: 'ሕብሪ', + Variables: 'ተተካእቲ', + Procedures: 'ፋንክሽናት', + }, + 'tr': { + Logic: 'Mantık', + Loops: 'Döngüler', + Math: 'Matematik', + Text: 'Metin', + Lists: 'Listeler', + Colour: 'Renk', + Variables: 'Değişkenler', + Procedures: 'İşlevler', + }, + 'uk': { + Logic: 'Логіка', + Loops: 'Цикли', + Math: 'Математика', + Text: 'Текст', + Lists: 'Списки', + Colour: 'Колір', + Variables: 'Змінні', + Procedures: 'Функції', + }, + 'ur': { + Logic: 'منطق', + Loops: 'لوپیں', + Math: 'ریاضی', + Text: 'متن', + Lists: 'فہرستیں', + Colour: 'رنگ', + Variables: 'متغیرات', + Procedures: 'افعال', + }, + 'uz': { + Logic: 'Mantiq', + Loops: 'Tsikllar', + Math: 'Matematika', + Text: 'Matn', + Lists: 'Roʻyxatlar', + Colour: 'Rang', + Variables: "O'zgaruvchilar", + Procedures: 'Funksiyalar', + }, + 'vi': { + Logic: 'Logic', + Loops: 'Vòng lặp', + Math: 'Công thức toán', + Text: 'Văn bản', + Lists: 'Danh sách', + Colour: 'Màu', + Variables: 'Biến', + Procedures: 'Hàm', + }, + 'yo': { + Logic: 'Irogun', + Loops: 'Ilosiwaju losehin', + Math: 'Isiro', + Text: 'Ọrọ', + Lists: 'Akojọ', + Colour: 'Awọ', + Variables: 'Oniruru', + Procedures: 'Iṣe', + }, + 'yue': { + Logic: '邏輯', + Loops: '循環', + Math: '數學', + Text: '發短信', + Lists: '一覽', + Colour: '顏色', + Variables: '變數', + Procedures: '功能', + }, + 'zh-hans': { + Logic: '逻辑', + Loops: '循环', + Math: '数学', + Text: '文本', + Lists: '列表', + Colour: '颜色', + Variables: '变量', + Procedures: '函数', + }, + 'zh-hant': { + Logic: '邏輯', + Loops: '迴圈', + Math: '運算', + Text: '文字', + Lists: '清單', + Colour: '顏色', + Variables: '變數', + Procedures: '函式', + }, }; diff --git a/examples/devsite-landing-demo/script.js b/examples/devsite-landing-demo/script.js index df1be555ae..08c3c534af 100644 --- a/examples/devsite-landing-demo/script.js +++ b/examples/devsite-landing-demo/script.js @@ -13,10 +13,10 @@ */ 'use strict'; -let language = 'en' // Default to English. +let language = 'en'; // Default to English. // Run this setup code once while still rendering the head. -;(function() { +(function () { const m = location.search.match(/[?&]hl=([^&]+)($|&)/); if (m) { if (LANGUAGE_NAME[m[1]]) { @@ -25,7 +25,7 @@ let language = 'en' // Default to English. } // Load Blockly's language strings. document.write( - '\n' + '\n', ); })(); @@ -89,15 +89,15 @@ function init() { // https://github.com/google/blockly/issues/5238 let toolboxString = JSON.stringify(toolboxJson); toolboxString = toolboxString.replace( - /%\{BKY_VARIABLES_DEFAULT_NAME\}/g, - Blockly.Msg.VARIABLES_DEFAULT_NAME + /%\{BKY_VARIABLES_DEFAULT_NAME\}/g, + Blockly.Msg.VARIABLES_DEFAULT_NAME, ); - toolboxJson = JSON.parse(toolboxString); + const toolbox = JSON.parse(toolboxString); // Inject Blockly. const workspace = Blockly.inject('blocklyDiv', { media: './node_modules/blockly/media/', - toolbox: toolboxJson, + toolbox, rtl: LANGUAGE_RTL.includes(language), renderer: 'thrasos', zoom: { @@ -109,9 +109,9 @@ function init() { trashcan: false, theme: Blockly.Theme.defineTheme('modest', { fontStyle: { - 'family': 'Google Sans', - 'weight': 'bold', - 'size': 16, + family: 'Google Sans', + weight: 'bold', + size: 16, }, blockStyles: { logic_blocks: { @@ -187,7 +187,7 @@ function getMsg(name) { function languageChange() { // Store the blocks in sessionStorage for the duration of the reload. const text = JSON.stringify( - Blockly.serialization.workspaces.save(Blockly.getMainWorkspace()) + Blockly.serialization.workspaces.save(Blockly.getMainWorkspace()), ); try { window.sessionStorage.setItem('loadOnceBlocks', text); @@ -227,31 +227,31 @@ function regenerate(_e) { * Generate JavaScript from the blocks, then execute it using JS-Interpreter. */ function execute() { - const initFunc = function(interpreter, globalObject) { + const initFunc = function (interpreter, globalObject) { const alertWrapper = function alert(text) { return window.alert(arguments.length ? text : ''); }; interpreter.setProperty( - globalObject, - 'alert', - interpreter.createNativeFunction(alertWrapper) + globalObject, + 'alert', + interpreter.createNativeFunction(alertWrapper), ); const promptWrapper = function prompt(text, defaultValue) { return window.prompt( arguments.length > 0 ? text : '', - arguments.length > 1 ? defaultValue : '' + arguments.length > 1 ? defaultValue : '', ); }; interpreter.setProperty( - globalObject, - 'prompt', - interpreter.createNativeFunction(promptWrapper) + globalObject, + 'prompt', + interpreter.createNativeFunction(promptWrapper), ); }; const code = javascript.javascriptGenerator.workspaceToCode( - Blockly.getMainWorkspace() + Blockly.getMainWorkspace(), ); const myInterpreter = new Interpreter(code, initFunc); let stepsAllowed = 10000; diff --git a/examples/devsite-landing-demo/style.css b/examples/devsite-landing-demo/style.css index 3a71637219..921af1c822 100644 --- a/examples/devsite-landing-demo/style.css +++ b/examples/devsite-landing-demo/style.css @@ -1,5 +1,5 @@ -@import url("https://fonts.googleapis.com/css?family=Google+Sans:400,500"); -@import url("https://fonts.googleapis.com/icon?family=Material+Icons"); +@import url('https://fonts.googleapis.com/css?family=Google+Sans:400,500'); +@import url('https://fonts.googleapis.com/icon?family=Material+Icons'); body { background: white !important; @@ -76,11 +76,11 @@ option { } #blockly-0 { - border-left: 15px solid #D1C4E9 !important; + border-left: 15px solid #d1c4e9 !important; } #blockly-1 { - border-left: 15px solid #A5D6A7 !important; + border-left: 15px solid #a5d6a7 !important; } #blockly-2 { @@ -88,23 +88,23 @@ option { } #blockly-3 { - border-left: 15px solid #FFCA28 !important; + border-left: 15px solid #ffca28 !important; } #blockly-4 { - border-left: 15px solid #4DB6AC !important; + border-left: 15px solid #4db6ac !important; } #blockly-5 { - border-left: 15px solid #FFCDD2 !important; + border-left: 15px solid #ffcdd2 !important; } #blockly-7 { - border-left: 15px solid #EF9A9A !important; + border-left: 15px solid #ef9a9a !important; } #blockly-8 { - border-left: 15px solid #D7CCC8 !important; + border-left: 15px solid #d7ccc8 !important; } .blocklyTreeSeparator { diff --git a/examples/devsite-landing-demo/toolbox.js b/examples/devsite-landing-demo/toolbox.js index 3033dca6a8..1544e53c5c 100644 --- a/examples/devsite-landing-demo/toolbox.js +++ b/examples/devsite-landing-demo/toolbox.js @@ -9,470 +9,469 @@ */ 'use strict'; - // eslint-disable-next-line no-unused-vars, prefer-const let toolboxJson = { - 'contents': [ + contents: [ { // Logic Category - 'kind': 'CATEGORY', - 'colour': 262, - 'contents': [ + kind: 'CATEGORY', + colour: 262, + contents: [ { - 'kind': 'BLOCK', - 'type': 'controls_if', + kind: 'BLOCK', + type: 'controls_if', }, { - 'kind': 'BLOCK', - 'type': 'logic_compare', + kind: 'BLOCK', + type: 'logic_compare', }, { - 'kind': 'BLOCK', - 'type': 'logic_operation', + kind: 'BLOCK', + type: 'logic_operation', }, { - 'kind': 'BLOCK', - 'type': 'logic_negate', + kind: 'BLOCK', + type: 'logic_negate', }, { - 'kind': 'BLOCK', - 'type': 'logic_boolean', + kind: 'BLOCK', + type: 'logic_boolean', }, { - 'kind': 'BLOCK', - 'type': 'logic_ternary', + kind: 'BLOCK', + type: 'logic_ternary', }, ], }, { // Loops Category - 'kind': 'CATEGORY', - 'colour': 122, - 'contents': [ + kind: 'CATEGORY', + colour: 122, + contents: [ { - 'kind': 'BLOCK', - 'type': 'controls_repeat_ext', - 'inputs': { - 'TIMES': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 10}, + kind: 'BLOCK', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: {NUM: 10}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'controls_whileUntil', + kind: 'BLOCK', + type: 'controls_whileUntil', }, { - 'kind': 'BLOCK', - 'type': 'controls_for', - 'inputs': { - 'FROM': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 1}, + kind: 'BLOCK', + type: 'controls_for', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, }, }, - 'TO': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 10}, + TO: { + shadow: { + type: 'math_number', + fields: {NUM: 10}, }, }, - 'BY': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 1}, + BY: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'controls_forEach', + kind: 'BLOCK', + type: 'controls_forEach', }, { - 'kind': 'BLOCK', - 'type': 'controls_flow_statements', + kind: 'BLOCK', + type: 'controls_flow_statements', }, ], }, { // Math Category - 'kind': 'CATEGORY', - 'colour': 206, - 'contents': [ + kind: 'CATEGORY', + colour: 206, + contents: [ { - 'kind': 'BLOCK', - 'type': 'math_number', - 'fields': {'NUM': 123}, + kind: 'BLOCK', + type: 'math_number', + fields: {NUM: 123}, }, { - 'kind': 'BLOCK', - 'type': 'math_arithmetic', - 'inputs': { - 'A': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 1}, + kind: 'BLOCK', + type: 'math_arithmetic', + inputs: { + A: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, }, }, - 'B': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 1}, + B: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'math_single', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 9}, + kind: 'BLOCK', + type: 'math_single', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: {NUM: 9}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'math_trig', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 45}, + kind: 'BLOCK', + type: 'math_trig', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: {NUM: 45}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'math_atan2', - 'inputs': { - 'X': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 1}, + kind: 'BLOCK', + type: 'math_atan2', + inputs: { + X: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, }, }, - 'Y': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 1}, + Y: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'math_constant', + kind: 'BLOCK', + type: 'math_constant', }, { - 'kind': 'BLOCK', - 'type': 'math_number_property', - 'inputs': { - 'NUMBER_TO_CHECK': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 0}, + kind: 'BLOCK', + type: 'math_number_property', + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: {NUM: 0}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'math_round', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 3.1}, + kind: 'BLOCK', + type: 'math_round', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: {NUM: 3.1}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'math_on_list', + kind: 'BLOCK', + type: 'math_on_list', }, { - 'kind': 'BLOCK', - 'type': 'math_modulo', - 'inputs': { - 'DIVIDEND': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 64}, + kind: 'BLOCK', + type: 'math_modulo', + inputs: { + DIVIDEND: { + shadow: { + type: 'math_number', + fields: {NUM: 64}, }, }, - 'DIVISOR': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 10}, + DIVISOR: { + shadow: { + type: 'math_number', + fields: {NUM: 10}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'math_constrain', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 50}, + kind: 'BLOCK', + type: 'math_constrain', + inputs: { + VALUE: { + shadow: { + type: 'math_number', + fields: {NUM: 50}, }, }, - 'LOW': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 1}, + LOW: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, }, }, - 'HIGH': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 100}, + HIGH: { + shadow: { + type: 'math_number', + fields: {NUM: 100}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'math_random_int', - 'inputs': { - 'FROM': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 1}, + kind: 'BLOCK', + type: 'math_random_int', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, }, }, - 'TO': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 100}, + TO: { + shadow: { + type: 'math_number', + fields: {NUM: 100}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'math_random_float', + kind: 'BLOCK', + type: 'math_random_float', }, ], }, { // Text Category - 'kind': 'CATEGORY', - 'colour': 46, - 'contents': [ + kind: 'CATEGORY', + colour: 46, + contents: [ { - 'kind': 'BLOCK', - 'type': 'text', + kind: 'BLOCK', + type: 'text', }, { - 'kind': 'BLOCK', - 'type': 'text_multiline', + kind: 'BLOCK', + type: 'text_multiline', }, { - 'kind': 'BLOCK', - 'type': 'text_join', - 'extraState': {'itemCount': 2}, + kind: 'BLOCK', + type: 'text_join', + extraState: {itemCount: 2}, }, { - 'kind': 'BLOCK', - 'type': 'text_append', - 'fields': { - 'VAR': { - 'name': 'text', - 'type': 'String', + kind: 'BLOCK', + type: 'text_append', + fields: { + VAR: { + name: 'text', + type: 'String', }, }, - 'inputs': { - 'TEXT': { - 'shadow': {'type': 'text'}, + inputs: { + TEXT: { + shadow: {type: 'text'}, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_length', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'abc'}, + kind: 'BLOCK', + type: 'text_length', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_isEmpty', - 'inputs': { - 'VALUE': { - 'shadow': {'type': 'text'}, + kind: 'BLOCK', + type: 'text_isEmpty', + inputs: { + VALUE: { + shadow: {type: 'text'}, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_indexOf', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'abc'}, + kind: 'BLOCK', + type: 'text_indexOf', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, }, }, - 'FIND': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'b'}, + FIND: { + shadow: { + type: 'text', + fields: {TEXT: 'b'}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_charAt', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'abc'}, + kind: 'BLOCK', + type: 'text_charAt', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_getSubstring', - 'inputs': { - 'STRING': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'abc'}, + kind: 'BLOCK', + type: 'text_getSubstring', + inputs: { + STRING: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_changeCase', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + kind: 'BLOCK', + type: 'text_changeCase', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_trim', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': ' abc '}, + kind: 'BLOCK', + type: 'text_trim', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: ' abc '}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_count', - 'inputs': { - 'SUB': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'a'}, + kind: 'BLOCK', + type: 'text_count', + inputs: { + SUB: { + shadow: { + type: 'text', + fields: {TEXT: 'a'}, }, }, - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'banana'}, + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'banana'}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_replace', - 'inputs': { - 'FROM': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'm'}, + kind: 'BLOCK', + type: 'text_replace', + inputs: { + FROM: { + shadow: { + type: 'text', + fields: {TEXT: 'm'}, }, }, - 'TO': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'w'}, + TO: { + shadow: { + type: 'text', + fields: {TEXT: 'w'}, }, }, - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'mom'}, + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'mom'}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_reverse', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'cba', + kind: 'BLOCK', + type: 'text_reverse', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'cba', }, }, }, }, }, { - 'kind': 'label', - 'text': '', + kind: 'label', + text: '', }, { - 'kind': 'BLOCK', - 'type': 'text_print', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'abc'}, + kind: 'BLOCK', + type: 'text_print', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'text_prompt_ext', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': 'abc'}, + kind: 'BLOCK', + type: 'text_prompt_ext', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, }, }, }, @@ -482,50 +481,50 @@ let toolboxJson = { { // Lists Category - 'kind': 'CATEGORY', - 'colour': 172, - 'contents': [ + kind: 'CATEGORY', + colour: 172, + contents: [ { - 'kind': 'BLOCK', - 'type': 'lists_create_with', - 'extraState': {'itemCount': 0}, + kind: 'BLOCK', + type: 'lists_create_with', + extraState: {itemCount: 0}, }, { - 'kind': 'BLOCK', - 'type': 'lists_create_with', - 'extraState': {'itemCount': 3}, + kind: 'BLOCK', + type: 'lists_create_with', + extraState: {itemCount: 3}, }, { - 'kind': 'BLOCK', - 'type': 'lists_repeat', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 5}, + kind: 'BLOCK', + type: 'lists_repeat', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: {NUM: 5}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'lists_length', + kind: 'BLOCK', + type: 'lists_length', }, { - 'kind': 'BLOCK', - 'type': 'lists_isEmpty', + kind: 'BLOCK', + type: 'lists_isEmpty', }, { - 'kind': 'BLOCK', - 'type': 'lists_indexOf', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', - 'fields': { - 'VAR': { - 'name': '%{BKY_VARIABLES_DEFAULT_NAME}', - 'type': 'List', + kind: 'BLOCK', + type: 'lists_indexOf', + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', }, }, }, @@ -533,16 +532,16 @@ let toolboxJson = { }, }, { - 'kind': 'BLOCK', - 'type': 'lists_getIndex', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', - 'fields': { - 'VAR': { - 'name': '%{BKY_VARIABLES_DEFAULT_NAME}', - 'type': 'List', + kind: 'BLOCK', + type: 'lists_getIndex', + inputs: { + VALUE: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', }, }, }, @@ -550,16 +549,16 @@ let toolboxJson = { }, }, { - 'kind': 'BLOCK', - 'type': 'lists_setIndex', - 'inputs': { - 'LIST': { - 'block': { - 'type': 'variables_get', - 'fields': { - 'VAR': { - 'name': '%{BKY_VARIABLES_DEFAULT_NAME}', - 'type': 'List', + kind: 'BLOCK', + type: 'lists_setIndex', + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', }, }, }, @@ -567,16 +566,16 @@ let toolboxJson = { }, }, { - 'kind': 'BLOCK', - 'type': 'lists_getSublist', - 'inputs': { - 'LIST': { - 'block': { - 'type': 'variables_get', - 'fields': { - 'VAR': { - 'name': '%{BKY_VARIABLES_DEFAULT_NAME}', - 'type': 'List', + kind: 'BLOCK', + type: 'lists_getSublist', + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', }, }, }, @@ -584,16 +583,16 @@ let toolboxJson = { }, }, { - 'kind': 'BLOCK', - 'type': 'lists_getSublist', - 'inputs': { - 'LIST': { - 'block': { - 'type': 'variables_get', - 'fields': { - 'VAR': { - 'name': '%{BKY_VARIABLES_DEFAULT_NAME}', - 'type': 'List', + kind: 'BLOCK', + type: 'lists_getSublist', + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', }, }, }, @@ -601,28 +600,28 @@ let toolboxJson = { }, }, { - 'kind': 'BLOCK', - 'type': 'lists_split', - 'inputs': { - 'DELIM': { - 'shadow': { - 'type': 'text', - 'fields': {'TEXT': ','}, + kind: 'BLOCK', + type: 'lists_split', + inputs: { + DELIM: { + shadow: { + type: 'text', + fields: {TEXT: ','}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'lists_sort', - 'inputs': { - 'LIST': { - 'block': { - 'type': 'variables_get', - 'fields': { - 'VAR': { - 'name': '%{BKY_VARIABLES_DEFAULT_NAME}', - 'type': 'List', + kind: 'BLOCK', + type: 'lists_sort', + inputs: { + LIST: { + block: { + type: 'variables_get', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', }, }, }, @@ -630,17 +629,17 @@ let toolboxJson = { }, }, { - 'kind': 'BLOCK', - 'type': 'lists_reverse', - 'inputs': { - 'LIST': { - 'block': { - 'type': 'variables_get', - 'id': 'Jyppgi#k[zERF`IH{gqY', - 'fields': { - 'VAR': { - 'name': '%{BKY_VARIABLES_DEFAULT_NAME}', - 'type': 'List', + kind: 'BLOCK', + type: 'lists_reverse', + inputs: { + LIST: { + block: { + type: 'variables_get', + id: 'Jyppgi#k[zERF`IH{gqY', + fields: { + VAR: { + name: '%{BKY_VARIABLES_DEFAULT_NAME}', + type: 'List', }, }, }, @@ -652,62 +651,62 @@ let toolboxJson = { { // Colour Category - 'kind': 'CATEGORY', - 'colour': 354, - 'contents': [ + kind: 'CATEGORY', + colour: 354, + contents: [ { - 'kind': 'BLOCK', - 'type': 'colour_picker', - 'fields': {'COLOUR': '#ff0000'}, + kind: 'BLOCK', + type: 'colour_picker', + fields: {COLOUR: '#ff0000'}, }, { - 'kind': 'BLOCK', - 'type': 'colour_random', + kind: 'BLOCK', + type: 'colour_random', }, { - 'kind': 'BLOCK', - 'type': 'colour_rgb', - 'inputs': { - 'RED': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 100}, + kind: 'BLOCK', + type: 'colour_rgb', + inputs: { + RED: { + shadow: { + type: 'math_number', + fields: {NUM: 100}, }, }, - 'GREEN': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 50}, + GREEN: { + shadow: { + type: 'math_number', + fields: {NUM: 50}, }, }, - 'BLUE': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 0}, + BLUE: { + shadow: { + type: 'math_number', + fields: {NUM: 0}, }, }, }, }, { - 'kind': 'BLOCK', - 'type': 'colour_blend', - 'inputs': { - 'COLOUR1': { - 'shadow': { - 'type': 'colour_picker', - 'fields': {'COLOUR': '#ff0000'}, + kind: 'BLOCK', + type: 'colour_blend', + inputs: { + COLOUR1: { + shadow: { + type: 'colour_picker', + fields: {COLOUR: '#ff0000'}, }, }, - 'COLOUR2': { - 'shadow': { - 'type': 'colour_picker', - 'fields': {'COLOUR': '#3333ff'}, + COLOUR2: { + shadow: { + type: 'colour_picker', + fields: {COLOUR: '#3333ff'}, }, }, - 'RATIO': { - 'shadow': { - 'type': 'math_number', - 'fields': {'NUM': 0.5}, + RATIO: { + shadow: { + type: 'math_number', + fields: {NUM: 0.5}, }, }, }, @@ -716,21 +715,21 @@ let toolboxJson = { }, { - 'kind': 'SEP', + kind: 'SEP', }, { // Variable Category - 'kind': 'CATEGORY', - 'custom': 'VARIABLE', - 'colour': 4, + kind: 'CATEGORY', + custom: 'VARIABLE', + colour: 4, }, { // Function Category - 'kind': 'CATEGORY', - 'custom': 'PROCEDURE', - 'colour': 16, + kind: 'CATEGORY', + custom: 'PROCEDURE', + colour: 16, }, ], }; diff --git a/examples/fixed-demo/index.html b/examples/fixed-demo/index.html index 33db0c3737..f0eeafce81 100644 --- a/examples/fixed-demo/index.html +++ b/examples/fixed-demo/index.html @@ -1,76 +1,85 @@ - + - - - Blockly Demo: Fixed Blockly - - - + + + Blockly Demo: Fixed Blockly + + + - - -
-

This is a simple demo of injecting Blockly into a fixed-sized 'div' element.

+ body { + background-color: #fff; + font-family: sans-serif; + } + h1 { + font-weight: normal; + font-size: 140%; + } + .demo { + padding: 1rem; + } + + + +
+

+ This is a simple demo of injecting Blockly into a fixed-sized 'div' + element. +

-

→ More info on injecting fixed-sized Blockly

+

+ → More info on + injecting fixed-sized Blockly… +

-
-
+
+
- - - + const demoWorkspace = Blockly.inject('blocklyDiv', { + media: './node_modules/blockly/media/', + toolbox: toolbox, + }); + + diff --git a/examples/generator-demo/index.html b/examples/generator-demo/index.html index 0d3cf15da2..08545fd324 100644 --- a/examples/generator-demo/index.html +++ b/examples/generator-demo/index.html @@ -1,257 +1,271 @@ - + - - - Blockly Demo: Generating JavaScript - - - - + + + Blockly Demo: Generating JavaScript + + + + - - - -

This is a simple demo of generating code from blocks and running - the code using eval.

+ + + +

+ This is a simple demo of generating code from blocks and running the code + using eval. +

-

→ More info on Code Generators and Running JavaScript.

+

+ → More info on + Code Generators + and + Running JavaScript. +

-

- - -

+

+ + +

-
+
- - - + + diff --git a/examples/getting-started-codelab/README.md b/examples/getting-started-codelab/README.md index 25da1b884f..d55fb23955 100644 --- a/examples/getting-started-codelab/README.md +++ b/examples/getting-started-codelab/README.md @@ -7,10 +7,10 @@ to add a block code editor to a web application. ## What you'll learn -* How to add Blockly to a sample web app. -* How to set up a Blockly workspace. -* How to create a new block in Blockly. -* How to generate and run JavaScript code from blocks. +- How to add Blockly to a sample web app. +- How to set up a Blockly workspace. +- How to create a new block in Blockly. +- How to generate and run JavaScript code from blocks. Example code for each step of the codelab is available from the [completed](complete-code/) directory. diff --git a/examples/getting-started-codelab/complete-code/index.html b/examples/getting-started-codelab/complete-code/index.html index 5547a3ebd1..c92e4214df 100644 --- a/examples/getting-started-codelab/complete-code/index.html +++ b/examples/getting-started-codelab/complete-code/index.html @@ -1,55 +1,60 @@ - + - - - - - - Blockly for the Web Codelab - - - - - - -
-

Music Maker

-

Music Maker Configuration

-
- -
- - - -

Tap any button to edit its code.
When complete, press Done.

- -
-
-
1
-
2
-
3
+ + + + + + Blockly for the Web Codelab + + + + + + +
+

Music Maker

+

Music Maker Configuration

+
+ +
+ + + +

+ Tap any button to edit its code.
When complete, press Done. +

+ +
+
+
1
+
2
+
3
+
+
+
4
+
5
+
6
+
+
+
7
+
8
+
9
+
-
-
4
-
5
-
6
-
-
-
7
-
8
-
9
-
-
-
-
-
-
- - - - - +
+
+
+ - + + + + + diff --git a/examples/getting-started-codelab/complete-code/scripts/main.js b/examples/getting-started-codelab/complete-code/scripts/main.js index b507a17630..e1a54cd71d 100644 --- a/examples/getting-started-codelab/complete-code/scripts/main.js +++ b/examples/getting-started-codelab/complete-code/scripts/main.js @@ -3,13 +3,14 @@ * Copyright 2017 Google LLC * SPDX-License-Identifier: Apache-2.0 */ - (function() { - +(function () { let currentButton; function handlePlay(event) { loadWorkspace(event.target); - let code = javascript.javascriptGenerator.workspaceToCode(Blockly.getMainWorkspace()); + let code = javascript.javascriptGenerator.workspaceToCode( + Blockly.getMainWorkspace(), + ); code += 'MusicMaker.play();'; // Eval can be dangerous. For more controlled execution, check // https://github.com/NeilFraser/JS-Interpreter. @@ -31,7 +32,8 @@ function save(button) { button.blocklySave = Blockly.serialization.workspaces.save( - Blockly.getMainWorkspace()); + Blockly.getMainWorkspace(), + ); } function handleSave() { @@ -41,7 +43,7 @@ function enableEditMode() { document.body.setAttribute('mode', 'edit'); - document.querySelectorAll('.button').forEach(btn => { + document.querySelectorAll('.button').forEach((btn) => { btn.removeEventListener('click', handlePlay); btn.addEventListener('click', enableBlocklyMode); }); @@ -49,7 +51,7 @@ function enableMakerMode() { document.body.setAttribute('mode', 'maker'); - document.querySelectorAll('.button').forEach(btn => { + document.querySelectorAll('.button').forEach((btn) => { btn.addEventListener('click', handlePlay); btn.removeEventListener('click', enableBlocklyMode); }); @@ -68,25 +70,25 @@ enableMakerMode(); const toolbox = { - 'kind': 'flyoutToolbox', - 'contents': [ + kind: 'flyoutToolbox', + contents: [ { - 'kind': 'block', - 'type': 'controls_repeat_ext', - 'inputs': { - 'TIMES': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 5, + kind: 'block', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, }, }, }, }, }, { - 'kind': 'block', - 'type': 'play_sound', + kind: 'block', + type: 'play_sound', }, ], }; diff --git a/examples/getting-started-codelab/complete-code/scripts/music_maker.js b/examples/getting-started-codelab/complete-code/scripts/music_maker.js index a730ce46ed..7959de10a8 100644 --- a/examples/getting-started-codelab/complete-code/scripts/music_maker.js +++ b/examples/getting-started-codelab/complete-code/scripts/music_maker.js @@ -3,13 +3,13 @@ * Copyright 2017 Google LLC * SPDX-License-Identifier: Apache-2.0 */ - const MusicMaker = { +const MusicMaker = { queue_: [], player_: new Audio(), - queueSound: function(soundUrl) { + queueSound: function (soundUrl) { this.queue_.push(soundUrl); }, - play: function() { + play: function () { const next = this.queue_.shift(); if (next) { this.player_.src = next; @@ -18,5 +18,4 @@ }, }; -MusicMaker.player_.addEventListener( - 'ended', MusicMaker.play.bind(MusicMaker)); +MusicMaker.player_.addEventListener('ended', MusicMaker.play.bind(MusicMaker)); diff --git a/examples/getting-started-codelab/complete-code/scripts/sound_blocks.js b/examples/getting-started-codelab/complete-code/scripts/sound_blocks.js index 4cb5fa2a17..81101c1051 100644 --- a/examples/getting-started-codelab/complete-code/scripts/sound_blocks.js +++ b/examples/getting-started-codelab/complete-code/scripts/sound_blocks.js @@ -7,28 +7,28 @@ Blockly.defineBlocksWithJsonArray([ // Block for colour picker. { - "type": "play_sound", - "message0": "Play %1", - "args0": [ + type: 'play_sound', + message0: 'Play %1', + args0: [ { - "type": "field_dropdown", - "name": "VALUE", - "options": [ - ["C4", "sounds/c4.m4a"], - ["D4", "sounds/d4.m4a"], - ["E4", "sounds/e4.m4a"], - ["F4", "sounds/f4.m4a"], - ["G4", "sounds/g4.m4a"] - ] - } + type: 'field_dropdown', + name: 'VALUE', + options: [ + ['C4', 'sounds/c4.m4a'], + ['D4', 'sounds/d4.m4a'], + ['E4', 'sounds/e4.m4a'], + ['F4', 'sounds/f4.m4a'], + ['G4', 'sounds/g4.m4a'], + ], + }, ], - "previousStatement": null, - "nextStatement": null, - "colour": 355, - } + previousStatement: null, + nextStatement: null, + colour: 355, + }, ]); -javascript.javascriptGenerator.forBlock['play_sound'] = function(block) { - const value = '\'' + block.getFieldValue('VALUE') + '\''; +javascript.javascriptGenerator.forBlock['play_sound'] = function (block) { + const value = "'" + block.getFieldValue('VALUE') + "'"; return 'MusicMaker.queueSound(' + value + ');\n'; }; diff --git a/examples/getting-started-codelab/complete-code/styles/index.css b/examples/getting-started-codelab/complete-code/styles/index.css index bf34c9246e..988bb49ecb 100644 --- a/examples/getting-started-codelab/complete-code/styles/index.css +++ b/examples/getting-started-codelab/complete-code/styles/index.css @@ -2,7 +2,7 @@ main { width: 400px; position: relative; margin: 0 auto; - overflow:hidden; + overflow: hidden; height: 600px; } @@ -26,9 +26,9 @@ h1 { display: none; } -[mode="maker"] .mode-maker, -[mode="edit"] .mode-edit, -[mode="blockly"] .mode-blockly { +[mode='maker'] .mode-maker, +[mode='edit'] .mode-edit, +[mode='blockly'] .mode-blockly { display: block; } @@ -42,7 +42,7 @@ h1 { background-color: #eee; } -[mode="blockly"] .blockly-editor { +[mode='blockly'] .blockly-editor { left: 0; } diff --git a/examples/getting-started-codelab/starter-code/index.html b/examples/getting-started-codelab/starter-code/index.html index 099293892a..c821256a3b 100644 --- a/examples/getting-started-codelab/starter-code/index.html +++ b/examples/getting-started-codelab/starter-code/index.html @@ -1,53 +1,58 @@ - + - - - - - - Blockly for the Web Codelab - - - - - - -
-

Music Maker

-

Music Maker Configuration

-
- -
- - - -

Tap any button to edit its code.
When complete, press Done.

- -
-
-
1
-
2
-
3
+ + + + + + Blockly for the Web Codelab + + + + + + +
+

Music Maker

+

Music Maker Configuration

+
+ +
+ + + +

+ Tap any button to edit its code.
When complete, press Done. +

+ +
+
+
1
+
2
+
3
+
+
+
4
+
5
+
6
+
+
+
7
+
8
+
9
+
-
-
4
-
5
-
6
-
-
-
7
-
8
-
9
-
-
-
-
-
-
- - - +
+
+
+ - + + + diff --git a/examples/getting-started-codelab/starter-code/scripts/main.js b/examples/getting-started-codelab/starter-code/scripts/main.js index 9eef2f96a5..33cf91446d 100644 --- a/examples/getting-started-codelab/starter-code/scripts/main.js +++ b/examples/getting-started-codelab/starter-code/scripts/main.js @@ -3,8 +3,7 @@ * Copyright 2017 Google LLC * SPDX-License-Identifier: Apache-2.0 */ - (function() { - +(function () { let currentButton; function handlePlay(event) { @@ -22,7 +21,7 @@ function enableEditMode() { document.body.setAttribute('mode', 'edit'); - document.querySelectorAll('.button').forEach(btn => { + document.querySelectorAll('.button').forEach((btn) => { btn.removeEventListener('click', handlePlay); btn.addEventListener('click', enableBlocklyMode); }); @@ -30,7 +29,7 @@ function enableMakerMode() { document.body.setAttribute('mode', 'maker'); - document.querySelectorAll('.button').forEach(btn => { + document.querySelectorAll('.button').forEach((btn) => { btn.addEventListener('click', handlePlay); btn.removeEventListener('click', enableBlocklyMode); }); @@ -46,5 +45,4 @@ document.querySelector('#save').addEventListener('click', handleSave); enableMakerMode(); - })(); diff --git a/examples/getting-started-codelab/starter-code/scripts/music_maker.js b/examples/getting-started-codelab/starter-code/scripts/music_maker.js index a730ce46ed..7959de10a8 100644 --- a/examples/getting-started-codelab/starter-code/scripts/music_maker.js +++ b/examples/getting-started-codelab/starter-code/scripts/music_maker.js @@ -3,13 +3,13 @@ * Copyright 2017 Google LLC * SPDX-License-Identifier: Apache-2.0 */ - const MusicMaker = { +const MusicMaker = { queue_: [], player_: new Audio(), - queueSound: function(soundUrl) { + queueSound: function (soundUrl) { this.queue_.push(soundUrl); }, - play: function() { + play: function () { const next = this.queue_.shift(); if (next) { this.player_.src = next; @@ -18,5 +18,4 @@ }, }; -MusicMaker.player_.addEventListener( - 'ended', MusicMaker.play.bind(MusicMaker)); +MusicMaker.player_.addEventListener('ended', MusicMaker.play.bind(MusicMaker)); diff --git a/examples/getting-started-codelab/starter-code/styles/index.css b/examples/getting-started-codelab/starter-code/styles/index.css index bf34c9246e..988bb49ecb 100644 --- a/examples/getting-started-codelab/starter-code/styles/index.css +++ b/examples/getting-started-codelab/starter-code/styles/index.css @@ -2,7 +2,7 @@ main { width: 400px; position: relative; margin: 0 auto; - overflow:hidden; + overflow: hidden; height: 600px; } @@ -26,9 +26,9 @@ h1 { display: none; } -[mode="maker"] .mode-maker, -[mode="edit"] .mode-edit, -[mode="blockly"] .mode-blockly { +[mode='maker'] .mode-maker, +[mode='edit'] .mode-edit, +[mode='blockly'] .mode-blockly { display: block; } @@ -42,7 +42,7 @@ h1 { background-color: #eee; } -[mode="blockly"] .blockly-editor { +[mode='blockly'] .blockly-editor { left: 0; } diff --git a/examples/graph-demo/index.html b/examples/graph-demo/index.html index ec918dc772..6c9db7af63 100644 --- a/examples/graph-demo/index.html +++ b/examples/graph-demo/index.html @@ -1,542 +1,572 @@ - + - - - Blockly Demo: Graph - - - - - + + + Blockly Demo: Graph + + + + + - - - -

This is a demo of giving instant feedback as blocks are changed.

+ + + +

This is a demo of giving instant feedback as blocks are changed.

-

→ More info on Realtime generation

+

+ → More info on + Realtime generation… +

- - - - - -
-
-
-
-
+ + + + + +
+
+
+
+
-
- - ... -
+
+ + ... +
- + - + // When Blockly changes, update the graph. + Graph.workspace.addChangeListener(Graph.drawVisualization); + Graph.workspace.addChangeListener(Blockly.Events.disableOrphans); + Graph.resize(); + }; - + window.addEventListener('load', Graph.init); + window.addEventListener('resize', Graph.resize); + + diff --git a/examples/headless-demo/index.html b/examples/headless-demo/index.html index 9eaa283248..855eec6e48 100644 --- a/examples/headless-demo/index.html +++ b/examples/headless-demo/index.html @@ -1,38 +1,40 @@ - + - - - Blockly Demo: Headless - - - - - - - -

This is a simple demo of generating Python code from JSON with no graphics. - This might be useful for server-side code generation.

+ + + Blockly Demo: Headless + + + + + + + +

+ This is a simple demo of generating Python code from JSON with no + graphics. This might be useful for server-side code generation. +

- - - - - - -
- - - - -
+ + + + + + + + -
- -
+
+ +
- - - + + diff --git a/examples/interpreter-demo/async-execution.html b/examples/interpreter-demo/async-execution.html index a693781615..6e3b6aa379 100644 --- a/examples/interpreter-demo/async-execution.html +++ b/examples/interpreter-demo/async-execution.html @@ -1,406 +1,432 @@ - + - - - Blockly Demo: Asynchronous Execution with JS-Interpreter - - + - - - - - - - - -

Asynchronous Execution with JS-Interpreter

+ + + + + + + + +

Asynchronous Execution with JS-Interpreter

-

This is a demo of executing code asynchronously (e.g., waiting for delays or user input) using the JavaScript interpreter.

+

+ This is a demo of executing code asynchronously (e.g., waiting for delays + or user input) using the JavaScript interpreter. +

-

More info on running code with JS-Interpreter

+

+ → + More info on running code with JS-Interpreter +

-

- -

+

+ +

-
-
+
- -
+ +
- - + demoWorkspace.addChangeListener(function (event) { + if (!event.isUiEvent) { + // Something changed. Interpreter needs to be reloaded. + resetStepUi(true); + } + }); + + diff --git a/examples/interpreter-demo/backwards.html b/examples/interpreter-demo/backwards.html index cfe88119d5..1cf0a06a3b 100644 --- a/examples/interpreter-demo/backwards.html +++ b/examples/interpreter-demo/backwards.html @@ -1,352 +1,393 @@ - + - - - Blockly Demo: Backwards Stepping with JS-Interpreter - - - - - - - - - - - - - - - -

Blockly > - Demos > Backwards Stepping with JS-Interpreter

- -

This is a demo of executing code step-by-step with a sandboxed JavaScript - interpreter -- both forwards and backwards.

- -

Each step forwards saves the current state to a stack. Each state - backwards restores to the previous state on the stack. Compression is used - to keep only the deltas between stack frames. Note that because serialization - reaches deep beyond the public API for the JS-Interpreter, the uncompiled - acorn.js and interpreter.js must be used in place of acorn_interpreter.js.

- -

More info on running code with JS-Interpreter

- -

- - -

- -
-
+ + + + + + + + +

+ Blockly > + Demos > Backwards Stepping with + JS-Interpreter +

+ +

+ This is a demo of executing code step-by-step with a sandboxed JavaScript + interpreter -- both forwards and backwards. +

+ +

+ Each step forwards saves the current state to a stack. Each state + backwards restores to the previous state on the stack. Compression is used + to keep only the deltas between stack frames. Note that because + serialization reaches deep beyond the public API for the JS-Interpreter, + the uncompiled acorn.js and interpreter.js must be used in place of + acorn_interpreter.js. +

+ +

+ → + More info on running code with JS-Interpreter +

+ +

+ + +

+ +
+
- -
- - - + + demoWorkspace.addChangeListener(function (event) { + if (!event.isUiEvent) { + // Something changed. Interpreter needs to be reloaded. + resetStepUi(true); + } + }); + + diff --git a/examples/interpreter-demo/index.html b/examples/interpreter-demo/index.html index 52e49eee4f..1da27baf48 100644 --- a/examples/interpreter-demo/index.html +++ b/examples/interpreter-demo/index.html @@ -1,11 +1,12 @@ - + - - - Redirecting... - - - -Redirecting to step execution JS-Interpreter demo. - + + + Redirecting... + + + + Redirecting to + step execution JS-Interpreter demo. + diff --git a/examples/interpreter-demo/serialize.js b/examples/interpreter-demo/serialize.js index a9ca6d0635..26b4881aae 100644 --- a/examples/interpreter-demo/serialize.js +++ b/examples/interpreter-demo/serialize.js @@ -10,7 +10,6 @@ */ 'use strict'; - // Constructors for objects within Acorn. var NODE_CONSTRUCTOR; var NODE_LOC_CONSTRUCTOR; @@ -32,7 +31,6 @@ if (typeof Map === 'function') { objectMap = new Map(); } - /** * Inspect an interpreter and record the constructors used to create new nodes. * @param {!Interpreter} interpreter JS-Interpreter instance. @@ -42,14 +40,15 @@ function recordAcornConstructors_(interpreter) { // Constructors for objects within Acorn. if (!interpreter.ast) { // The 'ast' property has been renamed by the compiler. - throw Error('Cannot serialize/deserialize compressed JS-Interpreter. ' + - 'Use acorn.js and interpreter.js instead of acorn_interpreter.js') + throw Error( + 'Cannot serialize/deserialize compressed JS-Interpreter. ' + + 'Use acorn.js and interpreter.js instead of acorn_interpreter.js', + ); } NODE_CONSTRUCTOR = interpreter.ast.constructor; - NODE_LOC_CONSTRUCTOR = interpreter.ast.loc && - interpreter.ast.loc.constructor; - LINE_LOC_CONSTRUCTOR = interpreter.ast.loc && - interpreter.ast.loc.end.constructor; + NODE_LOC_CONSTRUCTOR = interpreter.ast.loc && interpreter.ast.loc.constructor; + LINE_LOC_CONSTRUCTOR = + interpreter.ast.loc && interpreter.ast.loc.end.constructor; } /** @@ -105,7 +104,7 @@ function deserialize(json, interpreter) { * @returns {!Object} Stub of real object. * @private */ - function createObjectStub_(jsonObj, functionMap) { +function createObjectStub_(jsonObj, functionMap) { switch (jsonObj['type']) { case 'Map': return Object.create(null); @@ -208,7 +207,7 @@ function populateObject_(jsonObj, obj) { var name = names[j]; var descriptor = { configurable: nonConfigurable.indexOf(name) === -1, - enumerable: nonEnumerable.indexOf(name) === -1 + enumerable: nonEnumerable.indexOf(name) === -1, }; var hasGetter = getter.indexOf(name) !== -1; var hasSetter = setter.indexOf(name) !== -1; @@ -245,7 +244,7 @@ function populateObject_(jsonObj, obj) { * @returns {*} Real value. * @private */ - function decodeValue_(value) { +function decodeValue_(value) { if (value && typeof value === 'object') { var data; if ((data = value['#'])) { @@ -276,10 +275,14 @@ function populateObject_(jsonObj, obj) { function serialize(interpreter) { // Shallow-copy all properties of interest onto a root object. var properties = [ - 'OBJECT', 'OBJECT_PROTO', - 'FUNCTION', 'FUNCTION_PROTO', - 'ARRAY', 'ARRAY_PROTO', - 'REGEXP', 'REGEXP_PROTO', + 'OBJECT', + 'OBJECT_PROTO', + 'FUNCTION', + 'FUNCTION_PROTO', + 'ARRAY', + 'ARRAY_PROTO', + 'REGEXP', + 'REGEXP_PROTO', 'BOOLEAN', 'DATE', 'NUMBER', @@ -321,7 +324,7 @@ function serialize(interpreter) { case Object.prototype: if (obj === Interpreter.SCOPE_REFERENCE) { jsonObj['type'] = 'ScopeReference'; - continue; // No need to index properties. + continue; // No need to index properties. } jsonObj['type'] = 'Object'; break; @@ -331,23 +334,23 @@ function serialize(interpreter) { if (obj.id === undefined) { throw Error('Native function has no ID: ' + obj); } - continue; // No need to index properties. + continue; // No need to index properties. case Array.prototype: // Currently we assume that Arrays are not sparse. jsonObj['type'] = 'Array'; if (obj.length) { jsonObj['data'] = obj.map(encodeValue_); } - continue; // No need to index properties. + continue; // No need to index properties. case Date.prototype: jsonObj['type'] = 'Date'; jsonObj['data'] = obj.toJSON(); - continue; // No need to index properties. + continue; // No need to index properties. case RegExp.prototype: jsonObj['type'] = 'RegExp'; jsonObj['source'] = obj.source; jsonObj['flags'] = obj.flags; - continue; // No need to index properties. + continue; // No need to index properties. case Interpreter.Object.prototype: jsonObj['type'] = 'PseudoObject'; break; @@ -462,7 +465,7 @@ function encodeLoc_(loc) { * @param {*} value Real value. * @returns {*} Serialized value. */ - function encodeValue_(value) { +function encodeValue_(value) { if (value && (typeof value === 'object' || typeof value === 'function')) { var ref = objectMap ? objectMap.get(value) : objectList.indexOf(value); if (ref === undefined || ref === -1) { @@ -471,17 +474,17 @@ function encodeLoc_(loc) { return {'#': ref}; } if (value === undefined) { - return {'Value': 'undefined'}; + return {Value: 'undefined'}; } if (typeof value === 'number') { if (value === Infinity) { - return {'Value': 'Infinity'}; + return {Value: 'Infinity'}; } else if (value === -Infinity) { - return {'Value': '-Infinity'}; + return {Value: '-Infinity'}; } else if (isNaN(value)) { - return {'Value': 'NaN'}; + return {Value: 'NaN'}; } else if (1 / value === -Infinity) { - return {'Value': '-0'}; + return {Value: '-0'}; } } return value; @@ -499,14 +502,15 @@ function objectHunt_(node) { } objectMap && objectMap.set(node, objectList.length); objectList.push(node); - if (typeof node === 'object') { // Recurse. + if (typeof node === 'object') { + // Recurse. var isAcornNode = - Object.getPrototypeOf(node) === NODE_CONSTRUCTOR.prototype; + Object.getPrototypeOf(node) === NODE_CONSTRUCTOR.prototype; var names = Object.getOwnPropertyNames(node); for (var i = 0; i < names.length; i++) { var name = names[i]; if (isAcornNode && name === 'loc') { - continue; // Skip over node locations, they are specially handled. + continue; // Skip over node locations, they are specially handled. } try { var nextNode = node[name]; diff --git a/examples/interpreter-demo/step-execution.html b/examples/interpreter-demo/step-execution.html index fe048bbcb9..66e073ddfc 100644 --- a/examples/interpreter-demo/step-execution.html +++ b/examples/interpreter-demo/step-execution.html @@ -1,254 +1,286 @@ - + - - - Blockly Demo: Step Execution with JS-Interpreter - - - - - - - - - - - -

Step Execution with JS-Interpreter

- -

This is a demo of executing code step-by-step with a sandboxed JavaScript interpreter.

- -

The generator's javascript.javascriptGenerator.STATEMENT_PREFIX is assigned - 'highlightBlock(%1);\n', where %1 is the block ID. - The call to highlightBlock() will highlight the identified block - and set the variable highlightPause to true.

- -

Each press of the "Step JavaScript" button will run the interpreter one - step after another until highlightPause is true. - That is, until highlightBlock() has highlighted the block that - will be executed on the next step.

- -

More info on running code with JS-Interpreter

- -

- -

- -
-
+ + + + + + + + +

Step Execution with JS-Interpreter

+ +

+ This is a demo of executing code step-by-step with a sandboxed JavaScript + interpreter. +

+ +

+ The generator's + javascript.javascriptGenerator.STATEMENT_PREFIX is assigned + 'highlightBlock(%1);\n', where %1 is the block + ID. The call to highlightBlock() will highlight the + identified block and set the variable highlightPause to + true. +

+ +

+ Each press of the "Step JavaScript" button will run the interpreter one + step after another until highlightPause is true. That is, + until highlightBlock() has highlighted the block that will be + executed on the next step. +

+ +

+ → + More info on running code with JS-Interpreter +

+ +

+ +

+ +
+
- -
- - - + + demoWorkspace.addChangeListener(function (event) { + if (!event.isUiEvent) { + // Something changed. Interpreter needs to be reloaded. + resetStepUi(true); + } + }); + + diff --git a/examples/interpreter-demo/toolbox.js b/examples/interpreter-demo/toolbox.js index 9c93633901..0af6623edd 100644 --- a/examples/interpreter-demo/toolbox.js +++ b/examples/interpreter-demo/toolbox.js @@ -9,159 +9,159 @@ */ const toolboxJson = { - "contents": [ + contents: [ { - "kind": "CATEGORY", - "name": "Logic", - "colour": "%{BKY_LOGIC_HUE}", - "contents": [ + kind: 'CATEGORY', + name: 'Logic', + colour: '%{BKY_LOGIC_HUE}', + contents: [ { - "kind": "BLOCK", - "type": "controls_if" + kind: 'BLOCK', + type: 'controls_if', }, { - "kind": "BLOCK", - "type": "logic_compare" + kind: 'BLOCK', + type: 'logic_compare', }, { - "kind": "BLOCK", - "type": "logic_operation" + kind: 'BLOCK', + type: 'logic_operation', }, { - "kind": "BLOCK", - "type": "logic_negate" + kind: 'BLOCK', + type: 'logic_negate', }, { - "kind": "BLOCK", - "type": "logic_boolean" - } - ] + kind: 'BLOCK', + type: 'logic_boolean', + }, + ], }, { - "kind": "CATEGORY", - "name": "Loops", - "colour": "%{BKY_LOOPS_HUE}", - "contents": [ + kind: 'CATEGORY', + name: 'Loops', + colour: '%{BKY_LOOPS_HUE}', + contents: [ { - "kind": "BLOCK", - "type": "controls_repeat_ext", - "inputs": { - "TIMES": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 10} - } - } - } + kind: 'BLOCK', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: {NUM: 10}, + }, + }, + }, }, { - "kind": "BLOCK", - "type": "controls_whileUntil" - } - ] + kind: 'BLOCK', + type: 'controls_whileUntil', + }, + ], }, { - "kind": "CATEGORY", - "name": "Math", - "colour": "%{BKY_MATH_HUE}", - "contents": [ + kind: 'CATEGORY', + name: 'Math', + colour: '%{BKY_MATH_HUE}', + contents: [ { - "kind": "BLOCK", - "type": "math_number" + kind: 'BLOCK', + type: 'math_number', }, { - "kind": "BLOCK", - "type": "math_arithmetic", - "inputs": { - "A": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } + kind: 'BLOCK', + type: 'math_arithmetic', + inputs: { + A: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, }, - "B": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 1} - } - } - } + B: { + shadow: { + type: 'math_number', + fields: {NUM: 1}, + }, + }, + }, }, { - "kind": "BLOCK", - "type": "math_single", - "inputs": { - "NUM": { - "shadow": { - "type": "math_number", - "fields": {"NUM": 9} - } - } - } - } - ] + kind: 'BLOCK', + type: 'math_single', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: {NUM: 9}, + }, + }, + }, + }, + ], }, { - "kind": "CATEGORY", - "name": "Text", - "colour": "%{BKY_TEXTS_HUE}", - "contents": [ + kind: 'CATEGORY', + name: 'Text', + colour: '%{BKY_TEXTS_HUE}', + contents: [ { - "kind": "BLOCK", - "type": "text" + kind: 'BLOCK', + type: 'text', }, { - "kind": "BLOCK", - "type": "text_length", - "inputs": { - "VALUE": { - "shadow": { - "type": "text", - "fields": {"TEXT": "abc"} - } - } - } + kind: 'BLOCK', + type: 'text_length', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, + }, + }, + }, }, { - "kind": "BLOCK", - "type": "text_print", - "inputs": { - "TEXT": { - "shadow": { - "type": "text", - "fields": {"TEXT": "abc"} - } - } - } + kind: 'BLOCK', + type: 'text_print', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, + }, + }, + }, }, { - "kind": "BLOCK", - "type": "text_prompt_ext", - "inputs": { - "TEXT": { - "shadow": { - "type": "text", - "fields": {"TEXT": "abc"} - } - } - } - } - ] + kind: 'BLOCK', + type: 'text_prompt_ext', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: {TEXT: 'abc'}, + }, + }, + }, + }, + ], }, { - "kind": "SEP" + kind: 'SEP', }, { - "kind": "CATEGORY", - "name": "Variables", - "custom": "VARIABLE", - "colour": "%{BKY_VARIABLES_HUE}", + kind: 'CATEGORY', + name: 'Variables', + custom: 'VARIABLE', + colour: '%{BKY_VARIABLES_HUE}', }, { - "kind": "CATEGORY", - "name": "Functions", - "custom": "PROCEDURE", - "colour": "%{BKY_PROCEDURES_HUE}", - } - ] + kind: 'CATEGORY', + name: 'Functions', + custom: 'PROCEDURE', + colour: '%{BKY_PROCEDURES_HUE}', + }, + ], }; diff --git a/examples/interpreter-demo/wait_block.js b/examples/interpreter-demo/wait_block.js index e89b3a572c..6b6ca961f1 100644 --- a/examples/interpreter-demo/wait_block.js +++ b/examples/interpreter-demo/wait_block.js @@ -12,26 +12,30 @@ * See https://neil.fraser.name/software/JS-Interpreter/docs.html */ -Blockly.defineBlocksWithJsonArray([{ - 'type': 'wait_seconds', - 'message0': ' wait %1 seconds', - 'args0': [{ - 'type': 'field_number', - 'name': 'SECONDS', - 'min': 0, - 'max': 600, - 'value': 1, - }], - 'previousStatement': null, - 'nextStatement': null, - 'colour': '%{BKY_LOOPS_HUE}', -}]); +Blockly.defineBlocksWithJsonArray([ + { + type: 'wait_seconds', + message0: ' wait %1 seconds', + args0: [ + { + type: 'field_number', + name: 'SECONDS', + min: 0, + max: 600, + value: 1, + }, + ], + previousStatement: null, + nextStatement: null, + colour: '%{BKY_LOOPS_HUE}', + }, +]); /** * Generator for wait block creates call to new method * waitForSeconds(). */ -javascript.javascriptGenerator.forBlock['wait_seconds'] = function(block) { +javascript.javascriptGenerator.forBlock['wait_seconds'] = function (block) { const seconds = Number(block.getFieldValue('SECONDS')); const code = 'waitForSeconds(' + seconds + ');\n'; return code; @@ -46,9 +50,10 @@ function initInterpreterWaitForSeconds(interpreter, globalObject) { javascript.javascriptGenerator.addReservedWords('waitForSeconds'); const wrapper = interpreter.createAsyncFunction( - function(timeInSeconds, callback) { + function (timeInSeconds, callback) { // Delay the call to the callback. - setTimeout(callback, timeInSeconds * 1000); - }); + setTimeout(callback, timeInSeconds * 1000); + }, + ); interpreter.setProperty(globalObject, 'waitForSeconds', wrapper); } diff --git a/examples/keyboard-navigation-codelab/package-lock.json b/examples/keyboard-navigation-codelab/package-lock.json index 2be1728761..e6ce7654b7 100644 --- a/examples/keyboard-navigation-codelab/package-lock.json +++ b/examples/keyboard-navigation-codelab/package-lock.json @@ -1695,9 +1695,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true, "funding": [ { @@ -5897,9 +5897,9 @@ } }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true }, "form-data": { diff --git a/examples/keyboard-navigation-codelab/src/blocks/text.js b/examples/keyboard-navigation-codelab/src/blocks/text.js index 30159e8df3..83408ea00a 100644 --- a/examples/keyboard-navigation-codelab/src/blocks/text.js +++ b/examples/keyboard-navigation-codelab/src/blocks/text.js @@ -11,29 +11,30 @@ import * as Blockly from 'blockly/core'; // This is just an example and you should replace this with your // own custom blocks. const addText = { - 'type': 'add_text', - 'message0': 'Add text %1 with color %2', - 'args0': [ + type: 'add_text', + message0: 'Add text %1 with color %2', + args0: [ { - 'type': 'input_value', - 'name': 'TEXT', - 'check': 'String', + type: 'input_value', + name: 'TEXT', + check: 'String', }, { - 'type': 'input_value', - 'name': 'COLOR', - 'check': 'Colour', + type: 'input_value', + name: 'COLOR', + check: 'Colour', }, ], - 'previousStatement': null, - 'nextStatement': null, - 'colour': 160, - 'tooltip': '', - 'helpUrl': '', + previousStatement: null, + nextStatement: null, + colour: 160, + tooltip: '', + helpUrl: '', }; // Create the block definitions for the JSON-only blocks. // This does not register their definitions with Blockly. // This file has no side effects! -export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray( - [addText]); +export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray([ + addText, +]); diff --git a/examples/keyboard-navigation-codelab/src/cursors/custom.js b/examples/keyboard-navigation-codelab/src/cursors/custom.js index 4599eedc84..4562da6adf 100644 --- a/examples/keyboard-navigation-codelab/src/cursors/custom.js +++ b/examples/keyboard-navigation-codelab/src/cursors/custom.js @@ -13,8 +13,11 @@ export class CustomCursor extends Blockly.Cursor { let newNode = curNode.next(); // While the newNode exists and is either a previous or next type go to the // next value. - while (newNode && (newNode.getType() === Blockly.ASTNode.types.PREVIOUS || - newNode.getType() === Blockly.ASTNode.types.NEXT)) { + while ( + newNode && + (newNode.getType() === Blockly.ASTNode.types.PREVIOUS || + newNode.getType() === Blockly.ASTNode.types.NEXT) + ) { newNode = newNode.next(); } if (newNode) { @@ -48,8 +51,11 @@ export class CustomCursor extends Blockly.Cursor { let newNode = curNode.prev(); // While the newNode exists and is either a previous or next connection go // to the previous value. - while (newNode && (newNode.getType() === Blockly.ASTNode.types.PREVIOUS || - newNode.getType() === Blockly.ASTNode.types.NEXT)) { + while ( + newNode && + (newNode.getType() === Blockly.ASTNode.types.PREVIOUS || + newNode.getType() === Blockly.ASTNode.types.NEXT) + ) { newNode = newNode.prev(); } if (newNode) { diff --git a/examples/keyboard-navigation-codelab/src/generators/javascript.js b/examples/keyboard-navigation-codelab/src/generators/javascript.js index f2af8c19ac..1ee6bc2364 100644 --- a/examples/keyboard-navigation-codelab/src/generators/javascript.js +++ b/examples/keyboard-navigation-codelab/src/generators/javascript.js @@ -11,14 +11,14 @@ import {Order} from 'blockly/javascript'; // This file has no side effects! export const forBlock = Object.create(null); -forBlock['add_text'] = function(block, generator) { - const text = generator.valueToCode(block, 'TEXT', Order.NONE) || '\'\''; +forBlock['add_text'] = function (block, generator) { + const text = generator.valueToCode(block, 'TEXT', Order.NONE) || "''"; const color = - generator.valueToCode(block, 'COLOR', Order.ATOMIC) || '\'#ffffff\''; + generator.valueToCode(block, 'COLOR', Order.ATOMIC) || "'#ffffff'"; const addText = generator.provideFunction_( - 'addText', - `function ${generator.FUNCTION_NAME_PLACEHOLDER_}(text, color) { + 'addText', + `function ${generator.FUNCTION_NAME_PLACEHOLDER_}(text, color) { // Add text to the output area. const outputDiv = document.getElementById('output'); @@ -26,7 +26,7 @@ forBlock['add_text'] = function(block, generator) { textEl.innerText = text; textEl.style.color = color; outputDiv.appendChild(textEl); -}` +}`, ); // Generate the function call for this block. const code = `${addText}(${text}, ${color});\n`; diff --git a/examples/keyboard-navigation-codelab/src/index.css b/examples/keyboard-navigation-codelab/src/index.css index 4a05dbfd9f..f282700701 100644 --- a/examples/keyboard-navigation-codelab/src/index.css +++ b/examples/keyboard-navigation-codelab/src/index.css @@ -1,39 +1,40 @@ body { - margin: 0; - max-width: 100vw; + margin: 0; + max-width: 100vw; } -pre, code { - overflow: auto; +pre, +code { + overflow: auto; } #pageContainer { - display: flex; - width: 100%; - max-width: 100vw; - height: 100vh; + display: flex; + width: 100%; + max-width: 100vw; + height: 100vh; } #blocklyDiv { - flex-basis: 100%; - height: 100%; - min-width: 600px; + flex-basis: 100%; + height: 100%; + min-width: 600px; } #outputPane { - display: flex; - flex-direction: column; - width: 400px; - flex: 0 0 400px; - overflow: auto; - margin: 1rem; + display: flex; + flex-direction: column; + width: 400px; + flex: 0 0 400px; + overflow: auto; + margin: 1rem; } #generatedCode { - height: 50%; - background-color: rgb(247, 240, 228); + height: 50%; + background-color: rgb(247, 240, 228); } #output { - height: 50%; -} \ No newline at end of file + height: 50%; +} diff --git a/examples/keyboard-navigation-codelab/src/index.html b/examples/keyboard-navigation-codelab/src/index.html index 2f81d3c111..36d8eeacd9 100644 --- a/examples/keyboard-navigation-codelab/src/index.html +++ b/examples/keyboard-navigation-codelab/src/index.html @@ -1,10 +1,10 @@ - - - - - Blockly Sample App - - + + + + + Blockly Sample App + +
@@ -12,5 +12,5 @@
- - + + diff --git a/examples/keyboard-navigation-codelab/src/index.js b/examples/keyboard-navigation-codelab/src/index.js index 8b584e5ca3..b09618ea3f 100644 --- a/examples/keyboard-navigation-codelab/src/index.js +++ b/examples/keyboard-navigation-codelab/src/index.js @@ -60,14 +60,16 @@ ws.addChangeListener((e) => { save(ws); }); - // Whenever the workspace changes meaningfully, run the code again. ws.addChangeListener((e) => { // Don't run the code when the workspace finishes loading; we're // already running it once when the application starts. // Don't run the code during drags; we might have invalid state. - if (e.isUiEvent || e.type == Blockly.Events.FINISHED_LOADING || - ws.isDragging()) { + if ( + e.isUiEvent || + e.type == Blockly.Events.FINISHED_LOADING || + ws.isDragging() + ) { return; } runCode(); @@ -75,15 +77,17 @@ ws.addChangeListener((e) => { // Create a serialized key from the primary key and any modifiers. const ctrlW = Blockly.ShortcutRegistry.registry.createSerializedKey( - Blockly.utils.KeyCodes.W, [Blockly.ShortcutRegistry.modifierKeys.Control]); + Blockly.utils.KeyCodes.W, + [Blockly.ShortcutRegistry.modifierKeys.Control], +); const moveToStack = { name: 'moveToStack', keyCodes: [ctrlW], // The custom key mapping. - preconditionFn: function(workspace) { + preconditionFn: function (workspace) { return workspace.keyboardAccessibilityMode; }, - callback: function(workspace) { + callback: function (workspace) { const cursor = workspace.getCursor(); // Gets the current node. const currentNode = cursor.getCurNode(); @@ -91,7 +95,7 @@ const moveToStack = { const currentBlock = currentNode.getSourceBlock(); // If we are on a workspace node there will be no source block. if (currentBlock) { - // Gets the top block in the stack. + // Gets the top block in the stack. const rootBlock = currentBlock.getRootBlock(); // Gets the top node on a block. This is either the previous connection, // output connection, or the block itself. @@ -106,21 +110,33 @@ const moveToStack = { Blockly.ShortcutRegistry.registry.register(moveToStack); Blockly.ShortcutRegistry.registry.removeAllKeyMappings( - Constants.SHORTCUT_NAMES.OUT); + Constants.SHORTCUT_NAMES.OUT, +); Blockly.ShortcutRegistry.registry.addKeyMapping( - Blockly.utils.KeyCodes.LEFT, Constants.SHORTCUT_NAMES.OUT); + Blockly.utils.KeyCodes.LEFT, + Constants.SHORTCUT_NAMES.OUT, +); Blockly.ShortcutRegistry.registry.removeAllKeyMappings( - Constants.SHORTCUT_NAMES.IN); + Constants.SHORTCUT_NAMES.IN, +); Blockly.ShortcutRegistry.registry.addKeyMapping( - Blockly.utils.KeyCodes.RIGHT, Constants.SHORTCUT_NAMES.IN); + Blockly.utils.KeyCodes.RIGHT, + Constants.SHORTCUT_NAMES.IN, +); Blockly.ShortcutRegistry.registry.removeAllKeyMappings( - Constants.SHORTCUT_NAMES.PREVIOUS); + Constants.SHORTCUT_NAMES.PREVIOUS, +); Blockly.ShortcutRegistry.registry.addKeyMapping( - Blockly.utils.KeyCodes.UP, Constants.SHORTCUT_NAMES.PREVIOUS); + Blockly.utils.KeyCodes.UP, + Constants.SHORTCUT_NAMES.PREVIOUS, +); Blockly.ShortcutRegistry.registry.removeAllKeyMappings( - Constants.SHORTCUT_NAMES.NEXT); + Constants.SHORTCUT_NAMES.NEXT, +); Blockly.ShortcutRegistry.registry.addKeyMapping( - Blockly.utils.KeyCodes.DOWN, Constants.SHORTCUT_NAMES.NEXT); + Blockly.utils.KeyCodes.DOWN, + Constants.SHORTCUT_NAMES.NEXT, +); diff --git a/examples/keyboard-navigation-codelab/src/markers/custom_marker_svg.js b/examples/keyboard-navigation-codelab/src/markers/custom_marker_svg.js index 160e8101f3..f4f676b65b 100644 --- a/examples/keyboard-navigation-codelab/src/markers/custom_marker_svg.js +++ b/examples/keyboard-navigation-codelab/src/markers/custom_marker_svg.js @@ -14,13 +14,19 @@ class CustomMarkerSvg extends Blockly.blockRendering.MarkerSvg { // Create the svg element for the marker when it is on a block and set the // parent to markerSvg_. this.blockPath_ = Blockly.utils.dom.createSvgElement( - 'path', {}, this.markerSvg_); + 'path', + {}, + this.markerSvg_, + ); // If this is a cursor make the cursor blink. if (this.isCursor()) { const blinkProperties = this.getBlinkProperties_(); - Blockly.utils.dom.createSvgElement('animate', blinkProperties, - this.blockPath_); + Blockly.utils.dom.createSvgElement( + 'animate', + blinkProperties, + this.blockPath_, + ); } } diff --git a/examples/keyboard-navigation-codelab/src/serialization.js b/examples/keyboard-navigation-codelab/src/serialization.js index 0cf9a6377f..685eaf2fd7 100644 --- a/examples/keyboard-navigation-codelab/src/serialization.js +++ b/examples/keyboard-navigation-codelab/src/serialization.js @@ -12,7 +12,7 @@ const storageKey = 'mainWorkspace'; * Saves the state of the workspace to browser's local storage. * @param {Blockly.Workspace} workspace Blockly workspace to save. */ -export const save = function(workspace) { +export const save = function (workspace) { const data = Blockly.serialization.workspaces.save(workspace); window.localStorage?.setItem(storageKey, JSON.stringify(data)); }; @@ -21,7 +21,7 @@ export const save = function(workspace) { * Loads saved state from local storage into the given workspace. * @param {Blockly.Workspace} workspace Blockly workspace to load into. */ -export const load = function(workspace) { +export const load = function (workspace) { const data = window.localStorage?.getItem(storageKey); if (!data) return; diff --git a/examples/keyboard-navigation-codelab/src/toolbox.js b/examples/keyboard-navigation-codelab/src/toolbox.js index 4162ee4b55..0da9795cbb 100644 --- a/examples/keyboard-navigation-codelab/src/toolbox.js +++ b/examples/keyboard-navigation-codelab/src/toolbox.js @@ -13,305 +13,305 @@ listed here. */ export const toolbox = { - 'kind': 'categoryToolbox', - 'contents': [ + kind: 'categoryToolbox', + contents: [ { - 'kind': 'category', - 'name': 'Logic', - 'categorystyle': 'logic_category', - 'contents': [ + kind: 'category', + name: 'Logic', + categorystyle: 'logic_category', + contents: [ { - 'kind': 'block', - 'type': 'controls_if', + kind: 'block', + type: 'controls_if', }, { - 'kind': 'block', - 'type': 'logic_compare', + kind: 'block', + type: 'logic_compare', }, { - 'kind': 'block', - 'type': 'logic_operation', + kind: 'block', + type: 'logic_operation', }, { - 'kind': 'block', - 'type': 'logic_negate', + kind: 'block', + type: 'logic_negate', }, { - 'kind': 'block', - 'type': 'logic_boolean', + kind: 'block', + type: 'logic_boolean', }, { - 'kind': 'block', - 'type': 'logic_null', + kind: 'block', + type: 'logic_null', }, { - 'kind': 'block', - 'type': 'logic_ternary', + kind: 'block', + type: 'logic_ternary', }, ], }, { - 'kind': 'category', - 'name': 'Loops', - 'categorystyle': 'loop_category', - 'contents': [ + kind: 'category', + name: 'Loops', + categorystyle: 'loop_category', + contents: [ { - 'kind': 'block', - 'type': 'controls_repeat_ext', - 'inputs': { - 'TIMES': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 10, + kind: 'block', + type: 'controls_repeat_ext', + inputs: { + TIMES: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, }, }, }, }, }, { - 'kind': 'block', - 'type': 'controls_whileUntil', + kind: 'block', + type: 'controls_whileUntil', }, { - 'kind': 'block', - 'type': 'controls_for', - 'inputs': { - 'FROM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + kind: 'block', + type: 'controls_for', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'TO': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 10, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, }, }, }, - 'BY': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + BY: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, }, }, { - 'kind': 'block', - 'type': 'controls_forEach', + kind: 'block', + type: 'controls_forEach', }, { - 'kind': 'block', - 'type': 'controls_flow_statements', + kind: 'block', + type: 'controls_flow_statements', }, ], }, { - 'kind': 'category', - 'name': 'Math', - 'categorystyle': 'math_category', - 'contents': [ + kind: 'category', + name: 'Math', + categorystyle: 'math_category', + contents: [ { - 'kind': 'block', - 'type': 'math_number', - 'fields': { - 'NUM': 123, + kind: 'block', + type: 'math_number', + fields: { + NUM: 123, }, }, { - 'kind': 'block', - 'type': 'math_arithmetic', - 'inputs': { - 'A': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + kind: 'block', + type: 'math_arithmetic', + inputs: { + A: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'B': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + B: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_single', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 9, + kind: 'block', + type: 'math_single', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 9, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_trig', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 45, + kind: 'block', + type: 'math_trig', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 45, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_constant', + kind: 'block', + type: 'math_constant', }, { - 'kind': 'block', - 'type': 'math_number_property', - 'inputs': { - 'NUMBER_TO_CHECK': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 0, + kind: 'block', + type: 'math_number_property', + inputs: { + NUMBER_TO_CHECK: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_round', - 'fields': { - 'OP': 'ROUND', + kind: 'block', + type: 'math_round', + fields: { + OP: 'ROUND', }, - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 3.1, + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 3.1, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_on_list', - 'fields': { - 'OP': 'SUM', + kind: 'block', + type: 'math_on_list', + fields: { + OP: 'SUM', }, }, { - 'kind': 'block', - 'type': 'math_modulo', - 'inputs': { - 'DIVIDEND': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 64, + kind: 'block', + type: 'math_modulo', + inputs: { + DIVIDEND: { + shadow: { + type: 'math_number', + fields: { + NUM: 64, }, }, }, - 'DIVISOR': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 10, + DIVISOR: { + shadow: { + type: 'math_number', + fields: { + NUM: 10, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_constrain', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 50, + kind: 'block', + type: 'math_constrain', + inputs: { + VALUE: { + shadow: { + type: 'math_number', + fields: { + NUM: 50, }, }, }, - 'LOW': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + LOW: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'HIGH': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 100, + HIGH: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_random_int', - 'inputs': { - 'FROM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + kind: 'block', + type: 'math_random_int', + inputs: { + FROM: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'TO': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 100, + TO: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, }, }, }, }, }, { - 'kind': 'block', - 'type': 'math_random_float', + kind: 'block', + type: 'math_random_float', }, { - 'kind': 'block', - 'type': 'math_atan2', - 'inputs': { - 'X': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + kind: 'block', + type: 'math_atan2', + inputs: { + X: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, - 'Y': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 1, + Y: { + shadow: { + type: 'math_number', + fields: { + NUM: 1, }, }, }, @@ -320,198 +320,198 @@ export const toolbox = { ], }, { - 'kind': 'category', - 'name': 'Text', - 'categorystyle': 'text_category', - 'contents': [ + kind: 'category', + name: 'Text', + categorystyle: 'text_category', + contents: [ { - 'kind': 'block', - 'type': 'text', + kind: 'block', + type: 'text', }, { - 'kind': 'block', - 'type': 'text_multiline', + kind: 'block', + type: 'text_multiline', }, { - 'kind': 'block', - 'type': 'text_join', + kind: 'block', + type: 'text_join', }, { - 'kind': 'block', - 'type': 'text_append', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': '', + kind: 'block', + type: 'text_append', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: '', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_length', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + kind: 'block', + type: 'text_length', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_isEmpty', - 'inputs': { - 'VALUE': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': '', + kind: 'block', + type: 'text_isEmpty', + inputs: { + VALUE: { + shadow: { + type: 'text', + fields: { + TEXT: '', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_indexOf', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'text_indexOf', + inputs: { + VALUE: { + block: { + type: 'variables_get', }, }, - 'FIND': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + FIND: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_charAt', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'text_charAt', + inputs: { + VALUE: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'text_getSubstring', - 'inputs': { - 'STRING': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'text_getSubstring', + inputs: { + STRING: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'text_changeCase', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + kind: 'block', + type: 'text_changeCase', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_trim', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + kind: 'block', + type: 'text_trim', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, }, }, { - 'kind': 'block', - 'type': 'text_count', - 'inputs': { - 'SUB': { - 'shadow': { - 'type': 'text', + kind: 'block', + type: 'text_count', + inputs: { + SUB: { + shadow: { + type: 'text', }, }, - 'TEXT': { - 'shadow': { - 'type': 'text', + TEXT: { + shadow: { + type: 'text', }, }, }, }, { - 'kind': 'block', - 'type': 'text_replace', - 'inputs': { - 'FROM': { - 'shadow': { - 'type': 'text', + kind: 'block', + type: 'text_replace', + inputs: { + FROM: { + shadow: { + type: 'text', }, }, - 'TO': { - 'shadow': { - 'type': 'text', + TO: { + shadow: { + type: 'text', }, }, - 'TEXT': { - 'shadow': { - 'type': 'text', + TEXT: { + shadow: { + type: 'text', }, }, }, }, { - 'kind': 'block', - 'type': 'text_reverse', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', + kind: 'block', + type: 'text_reverse', + inputs: { + TEXT: { + shadow: { + type: 'text', }, }, }, }, { - 'kind': 'block', - 'type': 'add_text', - 'inputs': { - 'TEXT': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': 'abc', + kind: 'block', + type: 'add_text', + inputs: { + TEXT: { + shadow: { + type: 'text', + fields: { + TEXT: 'abc', }, }, }, - 'COLOR': { - 'shadow': { - 'type': 'colour_picker', - 'fields': { - 'COLOUR': '#aa00cc', + COLOR: { + shadow: { + type: 'colour_picker', + fields: { + COLOUR: '#aa00cc', }, }, }, @@ -520,176 +520,176 @@ export const toolbox = { ], }, { - 'kind': 'category', - 'name': 'Lists', - 'categorystyle': 'list_category', - 'contents': [ + kind: 'category', + name: 'Lists', + categorystyle: 'list_category', + contents: [ { - 'kind': 'block', - 'type': 'lists_create_with', + kind: 'block', + type: 'lists_create_with', }, { - 'kind': 'block', - 'type': 'lists_create_with', + kind: 'block', + type: 'lists_create_with', }, { - 'kind': 'block', - 'type': 'lists_repeat', - 'inputs': { - 'NUM': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 5, + kind: 'block', + type: 'lists_repeat', + inputs: { + NUM: { + shadow: { + type: 'math_number', + fields: { + NUM: 5, }, }, }, }, }, { - 'kind': 'block', - 'type': 'lists_length', + kind: 'block', + type: 'lists_length', }, { - 'kind': 'block', - 'type': 'lists_isEmpty', + kind: 'block', + type: 'lists_isEmpty', }, { - 'kind': 'block', - 'type': 'lists_indexOf', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'lists_indexOf', + inputs: { + VALUE: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'lists_getIndex', - 'inputs': { - 'VALUE': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'lists_getIndex', + inputs: { + VALUE: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'lists_setIndex', - 'inputs': { - 'LIST': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'lists_setIndex', + inputs: { + LIST: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'lists_getSublist', - 'inputs': { - 'LIST': { - 'block': { - 'type': 'variables_get', + kind: 'block', + type: 'lists_getSublist', + inputs: { + LIST: { + block: { + type: 'variables_get', }, }, }, }, { - 'kind': 'block', - 'type': 'lists_split', - 'inputs': { - 'DELIM': { - 'shadow': { - 'type': 'text', - 'fields': { - 'TEXT': ',', + kind: 'block', + type: 'lists_split', + inputs: { + DELIM: { + shadow: { + type: 'text', + fields: { + TEXT: ',', }, }, }, }, }, { - 'kind': 'block', - 'type': 'lists_sort', + kind: 'block', + type: 'lists_sort', }, { - 'kind': 'block', - 'type': 'lists_reverse', + kind: 'block', + type: 'lists_reverse', }, ], }, { - 'kind': 'category', - 'name': 'Color', - 'categorystyle': 'colour_category', - 'contents': [ + kind: 'category', + name: 'Color', + categorystyle: 'colour_category', + contents: [ { - 'kind': 'block', - 'type': 'colour_picker', + kind: 'block', + type: 'colour_picker', }, { - 'kind': 'block', - 'type': 'colour_random', + kind: 'block', + type: 'colour_random', }, { - 'kind': 'block', - 'type': 'colour_rgb', - 'inputs': { - 'RED': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 100, + kind: 'block', + type: 'colour_rgb', + inputs: { + RED: { + shadow: { + type: 'math_number', + fields: { + NUM: 100, }, }, }, - 'GREEN': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 50, + GREEN: { + shadow: { + type: 'math_number', + fields: { + NUM: 50, }, }, }, - 'BLUE': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 0, + BLUE: { + shadow: { + type: 'math_number', + fields: { + NUM: 0, }, }, }, }, }, { - 'kind': 'block', - 'type': 'colour_blend', - 'inputs': { - 'COLOUR1': { - 'shadow': { - 'type': 'colour_picker', - 'fields': { - 'COLOUR': '#ff0000', + kind: 'block', + type: 'colour_blend', + inputs: { + COLOUR1: { + shadow: { + type: 'colour_picker', + fields: { + COLOUR: '#ff0000', }, }, }, - 'COLOUR2': { - 'shadow': { - 'type': 'colour_picker', - 'fields': { - 'COLOUR': '#3333ff', + COLOUR2: { + shadow: { + type: 'colour_picker', + fields: { + COLOUR: '#3333ff', }, }, }, - 'RATIO': { - 'shadow': { - 'type': 'math_number', - 'fields': { - 'NUM': 0.5, + RATIO: { + shadow: { + type: 'math_number', + fields: { + NUM: 0.5, }, }, }, @@ -698,19 +698,19 @@ export const toolbox = { ], }, { - 'kind': 'sep', + kind: 'sep', }, { - 'kind': 'category', - 'name': 'Variables', - 'categorystyle': 'variable_category', - 'custom': 'VARIABLE', + kind: 'category', + name: 'Variables', + categorystyle: 'variable_category', + custom: 'VARIABLE', }, { - 'kind': 'category', - 'name': 'Functions', - 'categorystyle': 'procedure_category', - 'custom': 'PROCEDURE', + kind: 'category', + name: 'Functions', + categorystyle: 'procedure_category', + custom: 'PROCEDURE', }, ], }; diff --git a/examples/lerna.json b/examples/lerna.json index 5d0528d040..fe472d92ea 100644 --- a/examples/lerna.json +++ b/examples/lerna.json @@ -1,8 +1,5 @@ { - "packages": [ - "blockly-**", - "**-demo" - ], + "packages": ["blockly-**", "**-demo"], "version": "independent", "npmClient": "npm", "useNx": false diff --git a/examples/max-blocks-demo/index.html b/examples/max-blocks-demo/index.html index c1e7f1c533..9fd8f7c51c 100644 --- a/examples/max-blocks-demo/index.html +++ b/examples/max-blocks-demo/index.html @@ -1,97 +1,104 @@ - + - - - Blockly Demo: Maximum Block Limit - - - - - - -

This is a demo of Blockly which has been restricted to a maximum of - five blocks.

+ + + Blockly Demo: Maximum Block Limit + + + + + + +

+ This is a demo of Blockly which has been restricted to a maximum of five + blocks. +

-

You have block(s) left.

+

+ You have block(s) left. +

-
+
- + - - - + demoWorkspace.addChangeListener(onchange); + onchange(); + + diff --git a/examples/mirror-demo/index.html b/examples/mirror-demo/index.html index f13ca665c5..3ea0a8841b 100644 --- a/examples/mirror-demo/index.html +++ b/examples/mirror-demo/index.html @@ -1,127 +1,137 @@ - + - - - Blockly Demo: Mirrored Blockly - - - - - - -

This is a simple demo of a primary Blockly instance that controls a secondary Blockly instance with events. - Open the JavaScript console to see the event passing.

+ + + Blockly Demo: Mirrored Blockly + + + + + + +

+ This is a simple demo of a primary Blockly instance that controls a + secondary Blockly instance with events. Open the JavaScript console to see + the event passing. +

-

→ More info on events

+

+ → More info on + events… +

- - - - - -
-
-
-
-
+ + + + + +
+
+
+
+
- - - + + diff --git a/examples/package-lock.json b/examples/package-lock.json index 40cec27dc0..01714be113 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -3051,9 +3051,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true, "funding": [ { @@ -9752,9 +9752,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", + "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "dev": true }, "form-data": { diff --git a/examples/pitch-field-demo/blocks.js b/examples/pitch-field-demo/blocks.js index 948ca688da..a59a47f092 100644 --- a/examples/pitch-field-demo/blocks.js +++ b/examples/pitch-field-demo/blocks.js @@ -10,10 +10,10 @@ */ Blockly.Blocks['test_pitch_field'] = { - init: function() { + init: function () { this.appendDummyInput() - .appendField('pitch') - .appendField(new FieldPitch('7'), 'PITCH'); + .appendField('pitch') + .appendField(new FieldPitch('7'), 'PITCH'); this.setStyle('loop_blocks'); }, }; diff --git a/examples/pitch-field-demo/field_pitch.js b/examples/pitch-field-demo/field_pitch.js index 12a644a28d..8892de3b6f 100644 --- a/examples/pitch-field-demo/field_pitch.js +++ b/examples/pitch-field-demo/field_pitch.js @@ -66,22 +66,31 @@ class FieldPitch extends Blockly.FieldTextInput { const editor = this.dropdownCreate_(); Blockly.DropDownDiv.getContentDiv().appendChild(editor); - Blockly.DropDownDiv.setColour(this.sourceBlock_.style.colourPrimary, - this.sourceBlock_.style.colourTertiary); + Blockly.DropDownDiv.setColour( + this.sourceBlock_.style.colourPrimary, + this.sourceBlock_.style.colourTertiary, + ); Blockly.DropDownDiv.showPositionedByField( - this, this.dropdownDispose_.bind(this)); + this, + this.dropdownDispose_.bind(this), + ); // The pitch picker is different from other fields in that it updates on // mousemove even if it's not in the middle of a drag. In future we may // change this behaviour. For now, using `bind` instead of // `conditionalBind` allows it to work without a mousedown/touchstart. this.boundEvents_.push( - Blockly.browserEvents.bind(this.imageElement_, 'click', this, - this.hide_)); + Blockly.browserEvents.bind(this.imageElement_, 'click', this, this.hide_), + ); this.boundEvents_.push( - Blockly.browserEvents.bind(this.imageElement_, 'mousemove', this, - this.onMouseMove)); + Blockly.browserEvents.bind( + this.imageElement_, + 'mousemove', + this, + this.onMouseMove, + ), + ); this.updateGraph_(); } @@ -127,7 +136,7 @@ class FieldPitch extends Blockly.FieldTextInput { const bBox = this.imageElement_.getBoundingClientRect(); const dy = e.clientY - bBox.top; const note = Blockly.utils.math.clamp(Math.round(13.5 - dy / 7.5), 0, 12); - this.imageElement_.style.backgroundPosition = (-note * 37) + 'px 0'; + this.imageElement_.style.backgroundPosition = -note * 37 + 'px 0'; this.setEditorValue_(note); } @@ -202,7 +211,7 @@ class FieldPitch extends Blockly.FieldTextInput { return; } const i = this.getValue(); - this.imageElement_.style.backgroundPosition = (-i * 37) + 'px 0'; + this.imageElement_.style.backgroundPosition = -i * 37 + 'px 0'; } /** diff --git a/examples/pitch-field-demo/index.html b/examples/pitch-field-demo/index.html index e0ad656d85..6574d8768e 100644 --- a/examples/pitch-field-demo/index.html +++ b/examples/pitch-field-demo/index.html @@ -1,7 +1,7 @@ - + - + Blockly Demo: Custom Pitch Field @@ -24,31 +24,38 @@ border: none; } - + - -

This is a demo of creating custom block fields. In this case the field - is used to select a note pitch. +

+ This is a demo of creating custom block fields. In this case the field is + used to select a note pitch.

-

→ More info on creating a custom field

+

+ → More info on + creating a custom field… +

- - + +

- + -
+
@@ -86,7 +93,7 @@ grid: { spacing: 25, length: 3, - colour: '#ccc' + colour: '#ccc', }, move: { scrollbars: true, @@ -98,14 +105,16 @@ startScale: 1.0, maxScale: 4, minScale: 0.25, - scaleSpeed: 1.1 - } + scaleSpeed: 1.1, + }, /*toolbox: document.getElementById('toolbox')*/ - } - + }; -