├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── LICENSE ├── README.md ├── SECURITY.md ├── index.html ├── index.js ├── package-lock.json ├── package.json ├── showcase.html ├── vote.html └── web ├── .jshintignore ├── .npmrc ├── .travis.yml ├── DragandDrop.js ├── LICENSE ├── appengine ├── .gcloudignore ├── README.txt ├── app.yaml ├── apple-touch-icon.png ├── deploy ├── favicon.ico ├── index.yaml ├── main.py ├── redirect.html ├── requirements.txt ├── robots.txt ├── storage.js └── storage.py ├── blockly_compressed.js ├── blockly_compressed.js.map ├── blocks ├── colour.js ├── lists.js ├── logic.js ├── loops.js ├── math.js ├── procedures.js ├── text.js ├── variables.js └── variables_dynamic.js ├── blocks_compressed.js ├── blocks_compressed.js.map ├── build.py ├── chatblocks.js ├── closure ├── bin │ └── calcdeps.py └── goog │ └── base.js ├── core ├── block.js ├── block_animations.js ├── block_drag_surface.js ├── block_dragger.js ├── block_events.js ├── block_svg.js ├── blockly.js ├── blocks.js ├── bubble.js ├── bubble_dragger.js ├── comment.js ├── components │ ├── component.js │ └── tree │ │ ├── basenode.js │ │ ├── treecontrol.js │ │ └── treenode.js ├── connection.js ├── connection_db.js ├── constants.js ├── contextmenu.js ├── css.js ├── dropdowndiv.js ├── events.js ├── events_abstract.js ├── extensions.js ├── field.js ├── field_angle.js ├── field_checkbox.js ├── field_colour.js ├── field_dropdown.js ├── field_image.js ├── field_label.js ├── field_label_serializable.js ├── field_multilineinput.js ├── field_number.js ├── field_registry.js ├── field_textinput.js ├── field_variable.js ├── flyout_base.js ├── flyout_button.js ├── flyout_dragger.js ├── flyout_horizontal.js ├── flyout_vertical.js ├── generator.js ├── gesture.js ├── grid.js ├── icon.js ├── inject.js ├── input.js ├── insertion_marker_manager.js ├── interfaces │ ├── i_accessibility.js │ ├── i_bounded_element.js │ ├── i_copyable.js │ ├── i_deletable.js │ ├── i_deletearea.js │ ├── i_movable.js │ ├── i_registrable.js │ ├── i_selectable.js │ ├── i_styleable.js │ └── i_toolbox.js ├── keyboard_nav │ ├── action.js │ ├── ast_node.js │ ├── basic_cursor.js │ ├── cursor.js │ ├── flyout_cursor.js │ ├── key_map.js │ ├── marker.js │ ├── navigation.js │ └── tab_navigate_cursor.js ├── marker_manager.js ├── menu.js ├── menuitem.js ├── msg.js ├── mutator.js ├── names.js ├── options.js ├── procedures.js ├── registry.js ├── rendered_connection.js ├── renderers │ ├── common │ │ ├── block_rendering.js │ │ ├── constants.js │ │ ├── debugger.js │ │ ├── drawer.js │ │ ├── i_path_object.js │ │ ├── info.js │ │ ├── marker_svg.js │ │ ├── path_object.js │ │ └── renderer.js │ ├── geras │ │ ├── constants.js │ │ ├── drawer.js │ │ ├── highlight_constants.js │ │ ├── highlighter.js │ │ ├── info.js │ │ ├── measurables │ │ │ └── inputs.js │ │ ├── path_object.js │ │ └── renderer.js │ ├── measurables │ │ ├── base.js │ │ ├── connections.js │ │ ├── inputs.js │ │ ├── row_elements.js │ │ ├── rows.js │ │ └── types.js │ ├── minimalist │ │ ├── constants.js │ │ ├── drawer.js │ │ ├── info.js │ │ └── renderer.js │ ├── thrasos │ │ ├── info.js │ │ └── renderer.js │ └── zelos │ │ ├── constants.js │ │ ├── drawer.js │ │ ├── info.js │ │ ├── marker_svg.js │ │ ├── measurables │ │ ├── inputs.js │ │ ├── row_elements.js │ │ └── rows.js │ │ ├── path_object.js │ │ └── renderer.js ├── requires.js ├── scrollbar.js ├── theme.js ├── theme │ ├── classic.js │ ├── dark.js │ ├── deuteranopia.js │ ├── highcontrast.js │ ├── modern.js │ ├── tritanopia.js │ └── zelos.js ├── theme_manager.js ├── toolbox.js ├── tooltip.js ├── touch.js ├── touch_gesture.js ├── trashcan.js ├── ui_events.js ├── utils.js ├── utils │ ├── aria.js │ ├── colour.js │ ├── coordinate.js │ ├── dom.js │ ├── global.js │ ├── idgenerator.js │ ├── keycodes.js │ ├── math.js │ ├── metrics.js │ ├── object.js │ ├── rect.js │ ├── size.js │ ├── string.js │ ├── style.js │ ├── svg_paths.js │ ├── toolbox.js │ ├── useragent.js │ └── xml.js ├── variable_events.js ├── variable_map.js ├── variable_model.js ├── variables.js ├── variables_dynamic.js ├── warning.js ├── widgetdiv.js ├── workspace.js ├── workspace_audio.js ├── workspace_comment.js ├── workspace_comment_render_svg.js ├── workspace_comment_svg.js ├── workspace_drag_surface_svg.js ├── workspace_dragger.js ├── workspace_events.js ├── workspace_svg.js ├── ws_comment_events.js ├── xml.js └── zoom_controls.js ├── externs ├── block-externs.js ├── generator-externs.js ├── goog-externs.js └── svg-externs.js ├── field-slider ├── index.js └── index.js.map ├── fonts ├── OpenDyslexic-Bold-Italic.otf ├── OpenDyslexic-Bold-Italic.woff ├── OpenDyslexic-Bold.otf ├── OpenDyslexic-Bold.woff ├── OpenDyslexic-Italic.otf ├── OpenDyslexic-Italic.woff ├── OpenDyslexic-Regular.otf └── OpenDyslexic-Regular.woff ├── generators ├── javascript.js └── javascript │ ├── colour.js │ ├── lists.js │ ├── logic.js │ ├── loops.js │ ├── math.js │ ├── procedures.js │ ├── text.js │ ├── variables.js │ └── variables_dynamic.js ├── gulpfile.js ├── i18n ├── common.py ├── create_messages.py ├── dedup_json.py ├── js_to_json.py └── tests.py ├── javascript_compressed.js ├── javascript_compressed.js.map ├── jsconfig.json ├── media ├── 1x1.gif ├── click.mp3 ├── click.ogg ├── click.wav ├── delete.mp3 ├── delete.ogg ├── delete.wav ├── disconnect.mp3 ├── disconnect.ogg ├── disconnect.wav ├── dropdown-arrow.svg ├── handclosed.cur ├── handdelete.cur ├── handopen.cur ├── pilcrow.png ├── quote0.png ├── quote1.png ├── sprites.png └── sprites.svg ├── msg ├── js │ ├── ab.js │ ├── ar.js │ ├── az.js │ ├── ba.js │ ├── bcc.js │ ├── be-tarask.js │ ├── be.js │ ├── bg.js │ ├── bn.js │ ├── br.js │ ├── ca.js │ ├── cs.js │ ├── da.js │ ├── de.js │ ├── diq.js │ ├── dty.js │ ├── ee.js │ ├── el.js │ ├── en-gb.js │ ├── en.js │ ├── eo.js │ ├── es.js │ ├── et.js │ ├── eu.js │ ├── fa.js │ ├── fi.js │ ├── fr.js │ ├── gl.js │ ├── gor.js │ ├── ha.js │ ├── he.js │ ├── hi.js │ ├── hrx.js │ ├── hu.js │ ├── hy.js │ ├── ia.js │ ├── id.js │ ├── ig.js │ ├── is.js │ ├── it.js │ ├── ja.js │ ├── kab.js │ ├── kn.js │ ├── ko.js │ ├── lb.js │ ├── lki.js │ ├── lo.js │ ├── lrc.js │ ├── lt.js │ ├── lv.js │ ├── mk.js │ ├── mnw.js │ ├── ms.js │ ├── nb.js │ ├── nl.js │ ├── oc.js │ ├── pl.js │ ├── pms.js │ ├── pt-br.js │ ├── pt.js │ ├── ro.js │ ├── ru.js │ ├── sc.js │ ├── sd.js │ ├── shn.js │ ├── sk.js │ ├── skr-arab.js │ ├── sl.js │ ├── sq.js │ ├── sr-latn.js │ ├── sr.js │ ├── sv.js │ ├── ta.js │ ├── tcy.js │ ├── te.js │ ├── th.js │ ├── tl.js │ ├── tlh.js │ ├── tr.js │ ├── ug-arab.js │ ├── uk.js │ ├── ur.js │ ├── vi.js │ ├── xmf.js │ ├── yo.js │ ├── zh-hans.js │ └── zh-hant.js ├── json │ ├── ab.json │ ├── ar.json │ ├── az.json │ ├── ba.json │ ├── bcc.json │ ├── be-tarask.json │ ├── be.json │ ├── bg.json │ ├── bn.json │ ├── br.json │ ├── ca.json │ ├── constants.json │ ├── cs.json │ ├── da.json │ ├── de.json │ ├── diq.json │ ├── dty.json │ ├── ee.json │ ├── el.json │ ├── en-gb.json │ ├── en.json │ ├── eo.json │ ├── es.json │ ├── et.json │ ├── eu.json │ ├── fa.json │ ├── fi.json │ ├── fr.json │ ├── gl.json │ ├── gor.json │ ├── ha.json │ ├── he.json │ ├── hi.json │ ├── hrx.json │ ├── hu.json │ ├── hy.json │ ├── ia.json │ ├── id.json │ ├── ig.json │ ├── is.json │ ├── it.json │ ├── ja.json │ ├── kab.json │ ├── kn.json │ ├── ko.json │ ├── lb.json │ ├── lki.json │ ├── lo.json │ ├── lrc.json │ ├── lt.json │ ├── lv.json │ ├── mk.json │ ├── mnw.json │ ├── ms.json │ ├── nb.json │ ├── nl.json │ ├── oc.json │ ├── pl.json │ ├── pms.json │ ├── pt-br.json │ ├── pt.json │ ├── qqq.json │ ├── ro.json │ ├── ru.json │ ├── sc.json │ ├── sd.json │ ├── shn.json │ ├── sk.json │ ├── skr-arab.json │ ├── sl.json │ ├── sq.json │ ├── sr-latn.json │ ├── sr.json │ ├── sv.json │ ├── synonyms.json │ ├── ta.json │ ├── tcy.json │ ├── te.json │ ├── th.json │ ├── tl.json │ ├── tlh.json │ ├── tr.json │ ├── ug-arab.json │ ├── uk.json │ ├── ur.json │ ├── vi.json │ ├── xmf.json │ ├── yo.json │ ├── zh-hans.json │ └── zh-hant.json └── messages.js ├── package-lock.json ├── package.json ├── package ├── README.md ├── blockly.js ├── blocks.js ├── browser │ ├── core.js │ └── index.js ├── dart.js ├── index.js ├── javascript.js ├── lua.js ├── node │ ├── core.js │ └── index.js ├── php.js ├── python.js └── templates │ ├── node.template │ └── umd.template ├── theme_scripts ├── blockStyles_example.json └── create_blockStyles.py ├── vote1 ├── 10_weather.cbs ├── 10_weather_01.png ├── 10_weather_02.png ├── 11_rollinit.cbs ├── 11_rollinit_01.png ├── 12_passwordfinder.cbs ├── 12_passwordfinder_01.png ├── 13_fishing.cbs ├── 13_fishing_01.png ├── 13_fishing_02.png ├── 13_fishing_03.png ├── 13_fishing_04.png ├── 13_fishing_05.png ├── 1_superhero.cbs ├── 1_superhero_01.png ├── 1_superhero_02.png ├── 2_fluffyfacts.cbs ├── 2_fluffyfacts_01.png ├── 3_subhandler.cbs ├── 3_subhandler_01.png ├── 4_speciesspotlight.cbs ├── 4_speciesspotlight_01.png ├── 5_inspireme.cbs ├── 5_inspireme_01.png ├── 6_trackthor.cbs ├── 6_trackthor_01.png ├── 6_trackthor_02.png ├── 6_trackthor_03.png ├── 7_localdroptracker.cbs ├── 7_localdroptracker_01.png ├── 8_gilokk0.cbs ├── 8_gilokk0_01.png ├── 9_smile.cbs └── 9_smile_01.jpg ├── vote2 ├── 1_quest.cbs ├── 1_quest_01.png ├── 2_mathlete.cbs ├── 2_mathlete_01.png ├── 2_mathlete_02.png ├── 3_windwaker.cbs ├── 3_windwaker_01.png ├── 4_cleanbot.cbs ├── 4_cleanbot_01.jpg ├── 4_cleanbot_02.jpg ├── 5_funtranslations.cbs ├── 5_funtranslations_01.png ├── 6_counter.cbs ├── 6_counter_01.png ├── 6_counter_02.png ├── 7_fishing.cbs ├── 7_fishing_01.png ├── 8_eventtts.cbs ├── 8_eventtts_01.png ├── 9_cbwinodds.cbs └── 9_cbwinodds_01.png └── vote3 ├── 1_pokeball.cbs ├── 1_pokeball_01.png ├── 1_pokeball_02.png ├── 2_bean.cbs ├── 2_bean_01.jpg ├── 3_cooldown.cbs ├── 3_cooldown_01.png ├── 3_cooldown_02.png ├── 4_questions.cbs ├── 4_questions_01.png ├── 4_questions_02.jpg ├── 5_sketch.cbs ├── 5_sketch_01.png ├── 6_username.cbs ├── 6_username_01.png ├── 7_wiki.cbs ├── 7_wiki_01.png ├── 8_stretch.cbs ├── 8_stretch_01.png └── 8_stretch_02.png /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: short description [BUG] 5 | labels: Bug, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Computer Information** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | 30 | **Logs** 31 | Add screenshots of the console here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: short description [FEATURE] 5 | labels: Feature, needs triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a block? Please describe.** 11 | 12 | 13 | If related to a block fill in the following questions! Otherwise skip these questions. 14 | **Describe what the block should do?** 15 | A clear and concise description of what you want to happen. 16 | Add as much info as needed. Examples: 17 | - pseudo-code 18 | - Block inputs 19 | 20 | **Under what category should the block fall?** 21 | The categories are the names in the right sidebar in the application. 22 | 23 | **Why is this block usefull?** 24 | A clear and concise explanation on why the block is usefull and should be added. 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Instafluff 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | All versions are supported for our security updates 5 | 6 | | Version | Supported | 7 | | ------- | ------------------ | 8 | | * | :white_check_mark: | 9 | 10 | ## Reporting a Vulnerability 11 | 12 | If you find a vulnerability. Immideatly report it! Create a issue and call it 'VULNERABILITY REPORT'. 13 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require( "webwebweb" ).Run( 20626 ); 2 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chatblocks", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "webwebweb": { 8 | "version": "1.4.0", 9 | "resolved": "https://registry.npmjs.org/webwebweb/-/webwebweb-1.4.0.tgz", 10 | "integrity": "sha512-r9XbdXH/iuPQp8WUzkmJ54lMyjE9fr8H30df1vk9cledDl5Ahe2DXu6ppebHtp+/KUHhEfqmMdLOvYCpy5vvSg==" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chatblocks", 3 | "version": "1.0.0", 4 | "description": "Build a Twitch Chatbot Using Blocks!", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/instafluff/ChatBlocks.git" 12 | }, 13 | "keywords": [ 14 | "Instafluff", 15 | "Build", 16 | "Twitch", 17 | "Chatbot", 18 | "Blocks", 19 | "Blockly", 20 | "Graphical", 21 | "UI", 22 | "Coding", 23 | "Scratch" 24 | ], 25 | "author": "Instafluff", 26 | "contributors": [ 27 | "Instafluff", 28 | "Daan Breur (https://daanbreur.systems/)" 29 | ], 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/instafluff/ChatBlocks/issues" 33 | }, 34 | "homepage": "https://github.com/instafluff/ChatBlocks#readme", 35 | "dependencies": { 36 | "webwebweb": "^1.4.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /web/.jshintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | tests/ 3 | demos/ 4 | **/*_compressed.js 5 | **/*_uncompressed.js 6 | **/*_test.js -------------------------------------------------------------------------------- /web/.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /web/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | os: linux 3 | dist: xenial 4 | node_js: 5 | - 8 6 | - 10 7 | - 12 8 | addons: 9 | chrome: stable 10 | firefox: latest 11 | # TODO (#2114): reenable osx build. 12 | # - os: osx 13 | # node_js: stable 14 | # osx_image: xcode8.3 15 | # addons: 16 | # firefox: latest 17 | env: 18 | - TRAVIS_CI=true 19 | before_script: 20 | - export DISPLAY=:99.0 21 | - if [ "${TRAVIS_OS_NAME}" == "linux" ]; then ( tests/scripts/setup_linux_env.sh ) fi 22 | - if [ "${TRAVIS_OS_NAME}" == "osx" ]; then ( tests/scripts/setup_osx_env.sh ) fi 23 | - sleep 2 24 | script: 25 | - npm run test:run 26 | -------------------------------------------------------------------------------- /web/DragandDrop.js: -------------------------------------------------------------------------------- 1 | // TODO: Implement Modal That says: "You can drop your .cbs file here" 2 | 3 | let dropArea = document.getElementsByClassName( 'container' )[ 0 ]; 4 | 5 | ;[ 'dragenter', 'dragover', 'dragleave', 'drop' ].forEach(eventName => { 6 | dropArea.addEventListener(eventName, preventDefaults, false) 7 | }) 8 | 9 | ;[ 'dragenter', 'dragover' ].forEach(eventName => { 10 | dropArea.addEventListener(eventName, blockEditor, false) 11 | }) 12 | ;[ 'dragleave', 'drop' ].forEach(eventName => { 13 | dropArea.addEventListener(eventName, unblockEditor, false) 14 | }) 15 | 16 | 17 | dropArea.addEventListener('drop', handleDrop, false) 18 | 19 | 20 | function handleDrop(e) { 21 | let dt = e.dataTransfer 22 | let file = dt.files[ 0 ] 23 | 24 | let Reader = new FileReader(); 25 | Reader.onload = (readerEvt) => { 26 | xmlStrToWorkspace(undefined, readerEvt.target.result); 27 | } 28 | Reader.readAsText(file) 29 | 30 | } 31 | 32 | 33 | function blockEditor(e) { 34 | // TODO: Enable Modal 35 | document.getElementById( "workspace" ).classList.add( "blocks-blocker" ); 36 | } 37 | function unblockEditor(e) { 38 | // TODO: Disable Modal 39 | document.getElementById( "workspace" ).classList.remove( "blocks-blocker" ); 40 | 41 | } 42 | 43 | function preventDefaults (e) { 44 | e.stopPropagation(); 45 | e.preventDefault(); 46 | e.dataTransfer.dropEffect = 'copy'; 47 | } 48 | -------------------------------------------------------------------------------- /web/appengine/.gcloudignore: -------------------------------------------------------------------------------- 1 | # Do not upload these files. 2 | .* 3 | *.soy 4 | *.komodoproject 5 | /deploy 6 | /static/appengine/ 7 | /static/closure/ 8 | /static/demos/plane/soy/*.jar 9 | /static/demos/plane/xlf/ 10 | /static/externs/ 11 | /static/i18n/ 12 | /static/msg/json/ 13 | /static/node_modules/ 14 | /static/package/ 15 | /static/theme_scripts/ 16 | /static/typings/ 17 | 18 | /static/build.py 19 | /static/gulpfile.js 20 | /static/jsconfig.json 21 | /static/LICENSE 22 | /static/package-lock.json 23 | /static/package.json 24 | /static/README.md 25 | -------------------------------------------------------------------------------- /web/appengine/README.txt: -------------------------------------------------------------------------------- 1 | 2 | Running an App Engine server 3 | 4 | This directory contains the files needed to setup the optional Blockly server. 5 | Although Blockly itself is 100% client-side, the server enables cloud storage 6 | and sharing. Store your programs in Datastore and get a unique URL that allows 7 | you to load the program on any computer. 8 | 9 | To run your own App Engine instance you'll need to create this directory 10 | structure: 11 | 12 | blockly/ 13 | |- app.yaml 14 | |- deploy 15 | |- index.yaml 16 | |- main.py 17 | |- README.txt 18 | |- requirements.txt 19 | |- storage.js 20 | |- storage.py 21 | `- static/ 22 | |- blocks/ 23 | |- core/ 24 | |- demos/ 25 | |- generators/ 26 | |- media/ 27 | |- msg/ 28 | |- tests/ 29 | |- blockly_compressed.js 30 | |- blockly_uncompressed.js 31 | |- blocks_compressed.js 32 | |- dart_compressed.js 33 | |- javascript_compressed.js 34 | |- lua_compressed.js 35 | |- php_compressed.js 36 | `- python_compressed.js 37 | 38 | Go to https://appengine.google.com/ and create your App Engine application. 39 | Modify the 'PROJECT' name in the 'deploy' file to your App Engine application name. 40 | 41 | Finally, upload this directory structure to your App Engine account, 42 | then go to http://YOURAPPNAME.appspot.com/ 43 | -------------------------------------------------------------------------------- /web/appengine/app.yaml: -------------------------------------------------------------------------------- 1 | runtime: python37 2 | 3 | handlers: 4 | # Redirect obsolete URLs. 5 | # Blockly files moved from /blockly to /static on 5 Dec 2012. 6 | - url: /blockly/.* 7 | static_files: redirect.html 8 | upload: redirect.html 9 | # Code, Maze and Turtle moved from demos on 29 Dec 2012. 10 | - url: /static/demos/(maze|turtle)/.* 11 | static_files: redirect.html 12 | upload: redirect.html 13 | # Apps was disbanded on 20 Nov 2014. 14 | - url: /static/apps/.* 15 | static_files: redirect.html 16 | upload: redirect.html 17 | 18 | # Blockly files. 19 | - url: /static 20 | static_dir: static 21 | secure: always 22 | 23 | # Storage API. 24 | - url: /storage\.js 25 | static_files: storage.js 26 | upload: storage\.js 27 | secure: always 28 | 29 | # Favicon. 30 | - url: /favicon\.ico 31 | static_files: favicon.ico 32 | upload: favicon\.ico 33 | secure: always 34 | expiration: "30d" 35 | 36 | # Apple icon. 37 | - url: /apple-touch-icon\.png 38 | static_files: apple-touch-icon.png 39 | upload: apple-touch-icon\.png 40 | secure: always 41 | expiration: "30d" 42 | 43 | # robot.txt 44 | - url: /robots\.txt 45 | static_files: robots.txt 46 | upload: robots\.txt 47 | secure: always 48 | 49 | # Dynamic content. 50 | - url: /.* 51 | script: auto 52 | secure: always 53 | -------------------------------------------------------------------------------- /web/appengine/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/appengine/apple-touch-icon.png -------------------------------------------------------------------------------- /web/appengine/deploy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Script to deploy on GAE. 4 | 5 | APP=./app.yaml 6 | if ! [ -f $APP ] ; then 7 | echo $APP not found 1>&2 8 | exit 1 9 | fi 10 | 11 | PROJECT=blockly-demo 12 | VERSION=37 13 | 14 | echo 'Beginning deployment...' 15 | gcloud app deploy --project $PROJECT --version $VERSION --no-promote 16 | echo 'Deployment finished.' 17 | -------------------------------------------------------------------------------- /web/appengine/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/appengine/favicon.ico -------------------------------------------------------------------------------- /web/appengine/index.yaml: -------------------------------------------------------------------------------- 1 | indexes: 2 | 3 | # AUTOGENERATED 4 | 5 | # This index.yaml is automatically updated whenever the dev_appserver 6 | # detects that a new type of query is run. If you want to manage the 7 | # index.yaml file manually, remove the above marker line (the line 8 | # saying "# AUTOGENERATED"). If you want to manage some indexes 9 | # manually, move them above the marker line. The index.yaml file is 10 | # automatically uploaded to the admin console when you next deploy 11 | # your application using appcfg.py. 12 | -------------------------------------------------------------------------------- /web/appengine/main.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright 2020 Google LLC 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | """ 16 | 17 | import storage 18 | 19 | 20 | # Route to requested handler. 21 | def app(environ, start_response): 22 | if environ["PATH_INFO"] == "/": 23 | return redirect(environ, start_response) 24 | if environ["PATH_INFO"] == "/storage": 25 | return storage.app(environ, start_response) 26 | start_response("404 Not Found", []) 27 | return [b"Page not found."] 28 | 29 | 30 | # Redirect for root directory. 31 | def redirect(environ, start_response): 32 | headers = [ 33 | ("Location", "static/demos/index.html") 34 | ] 35 | start_response("301 Found", headers) 36 | return [] 37 | -------------------------------------------------------------------------------- /web/appengine/redirect.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /web/appengine/requirements.txt: -------------------------------------------------------------------------------- 1 | google-cloud-ndb 2 | -------------------------------------------------------------------------------- /web/appengine/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /storage 3 | -------------------------------------------------------------------------------- /web/appengine/storage.py: -------------------------------------------------------------------------------- 1 | """Blockly Demo: Storage 2 | 3 | Copyright 2012 Google LLC 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | """ 17 | 18 | """Store and retrieve XML with App Engine. 19 | """ 20 | 21 | __author__ = "q.neutron@gmail.com (Quynh Neutron)" 22 | 23 | import cgi 24 | import hashlib 25 | from random import randint 26 | from google.cloud import ndb 27 | 28 | 29 | class Xml(ndb.Model): 30 | # A row in the database. 31 | xml_hash = ndb.IntegerProperty() 32 | xml_content = ndb.TextProperty() 33 | 34 | 35 | def keyGen(): 36 | # Generate a random string of length KEY_LEN. 37 | KEY_LEN = 6 38 | CHARS = "abcdefghijkmnopqrstuvwxyz23456789" # Exclude l, 0, 1. 39 | max_index = len(CHARS) - 1 40 | return "".join([CHARS[randint(0, max_index)] for x in range(KEY_LEN)]) 41 | 42 | 43 | def xmlToKey(xml_content): 44 | # Store XML and return a generated key. 45 | xml_hash = int(hashlib.sha1(xml_content.encode("utf-8")).hexdigest(), 16) 46 | xml_hash = int(xml_hash % (2 ** 64) - (2 ** 63)) 47 | lookup_query = Xml.query(Xml.xml_hash == xml_hash) 48 | client = ndb.Client() 49 | with client.context(): 50 | lookup_result = lookup_query.get() 51 | if lookup_result: 52 | xml_key = lookup_result.key.string_id() 53 | else: 54 | trials = 0 55 | result = True 56 | while result: 57 | trials += 1 58 | if trials == 100: 59 | raise Exception("Sorry, the generator failed to get a key for you.") 60 | xml_key = keyGen() 61 | result = Xml.get_by_id(xml_key) 62 | row = Xml(id = xml_key, xml_hash = xml_hash, xml_content = xml_content) 63 | row.put() 64 | return xml_key 65 | 66 | 67 | def keyToXml(key_provided): 68 | # Retrieve stored XML based on the provided key. 69 | # Normalize the string. 70 | key_provided = key_provided.lower().strip() 71 | # Check datastore for a match. 72 | client = ndb.Client() 73 | with client.context(): 74 | result = Xml.get_by_id(key_provided) 75 | if not result: 76 | xml = "" 77 | else: 78 | xml = result.xml_content 79 | return xml 80 | 81 | 82 | def app(environ, start_response): 83 | forms = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ) 84 | if "xml" in forms: 85 | out = xmlToKey(forms["xml"].value) 86 | elif "key" in forms: 87 | out = keyToXml(forms["key"].value) 88 | else: 89 | out = "" 90 | 91 | headers = [ 92 | ("Content-Type", "text/plain") 93 | ] 94 | start_response("200 OK", headers) 95 | return [out.encode("utf-8")] 96 | -------------------------------------------------------------------------------- /web/blocks/colour.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2012 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Colour blocks for Blockly. 9 | * 10 | * This file is scraped to extract a .json file of block definitions. The array 11 | * passed to defineBlocksWithJsonArray(..) must be strict JSON: double quotes 12 | * only, no outside references, no functions, no trailing commas, etc. The one 13 | * exception is end-of-line comments, which the scraper will remove. 14 | * @author fraser@google.com (Neil Fraser) 15 | */ 16 | 'use strict'; 17 | 18 | goog.provide('Blockly.Blocks.colour'); // Deprecated 19 | goog.provide('Blockly.Constants.Colour'); 20 | 21 | goog.require('Blockly'); 22 | goog.require('Blockly.Blocks'); 23 | goog.require('Blockly.FieldColour'); 24 | goog.require('Blockly.FieldLabel'); 25 | 26 | 27 | /** 28 | * Unused constant for the common HSV hue for all blocks in this category. 29 | * @deprecated Use Blockly.Msg['COLOUR_HUE']. (2018 April 5) 30 | */ 31 | Blockly.Constants.Colour.HUE = 20; 32 | 33 | Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT 34 | // Block for colour picker. 35 | { 36 | "type": "colour_picker", 37 | "message0": "%1", 38 | "args0": [ 39 | { 40 | "type": "field_colour", 41 | "name": "COLOUR", 42 | "colour": "#ff0000" 43 | } 44 | ], 45 | "output": "Colour", 46 | "helpUrl": "%{BKY_COLOUR_PICKER_HELPURL}", 47 | "style": "colour_blocks", 48 | "tooltip": "%{BKY_COLOUR_PICKER_TOOLTIP}", 49 | "extensions": ["parent_tooltip_when_inline"] 50 | }, 51 | 52 | // Block for random colour. 53 | { 54 | "type": "colour_random", 55 | "message0": "%{BKY_COLOUR_RANDOM_TITLE}", 56 | "output": "Colour", 57 | "helpUrl": "%{BKY_COLOUR_RANDOM_HELPURL}", 58 | "style": "colour_blocks", 59 | "tooltip": "%{BKY_COLOUR_RANDOM_TOOLTIP}" 60 | }, 61 | 62 | // Block for composing a colour from RGB components. 63 | { 64 | "type": "colour_rgb", 65 | "message0": "%{BKY_COLOUR_RGB_TITLE} %{BKY_COLOUR_RGB_RED} %1 %{BKY_COLOUR_RGB_GREEN} %2 %{BKY_COLOUR_RGB_BLUE} %3", 66 | "args0": [ 67 | { 68 | "type": "input_value", 69 | "name": "RED", 70 | "check": "Number", 71 | "align": "RIGHT" 72 | }, 73 | { 74 | "type": "input_value", 75 | "name": "GREEN", 76 | "check": "Number", 77 | "align": "RIGHT" 78 | }, 79 | { 80 | "type": "input_value", 81 | "name": "BLUE", 82 | "check": "Number", 83 | "align": "RIGHT" 84 | } 85 | ], 86 | "output": "Colour", 87 | "helpUrl": "%{BKY_COLOUR_RGB_HELPURL}", 88 | "style": "colour_blocks", 89 | "tooltip": "%{BKY_COLOUR_RGB_TOOLTIP}" 90 | }, 91 | 92 | // Block for blending two colours together. 93 | { 94 | "type": "colour_blend", 95 | "message0": "%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} " + 96 | "%1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3", 97 | "args0": [ 98 | { 99 | "type": "input_value", 100 | "name": "COLOUR1", 101 | "check": "Colour", 102 | "align": "RIGHT" 103 | }, 104 | { 105 | "type": "input_value", 106 | "name": "COLOUR2", 107 | "check": "Colour", 108 | "align": "RIGHT" 109 | }, 110 | { 111 | "type": "input_value", 112 | "name": "RATIO", 113 | "check": "Number", 114 | "align": "RIGHT" 115 | } 116 | ], 117 | "output": "Colour", 118 | "helpUrl": "%{BKY_COLOUR_BLEND_HELPURL}", 119 | "style": "colour_blocks", 120 | "tooltip": "%{BKY_COLOUR_BLEND_TOOLTIP}" 121 | } 122 | ]); // END JSON EXTRACT (Do not delete this comment.) 123 | -------------------------------------------------------------------------------- /web/core/blocks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2013 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview A mapping of block type names to block prototype objects. 9 | * @author spertus@google.com (Ellen Spertus) 10 | */ 11 | 'use strict'; 12 | 13 | /** 14 | * A mapping of block type names to block prototype objects. 15 | * @name Blockly.Blocks 16 | */ 17 | goog.provide('Blockly.Blocks'); 18 | 19 | /** 20 | * A mapping of block type names to block prototype objects. 21 | * @type {!Object.} 22 | */ 23 | Blockly.Blocks = Object.create(null); 24 | -------------------------------------------------------------------------------- /web/core/events_abstract.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Abstract class for events fired as a result of actions in 9 | * Blockly's editor. 10 | * @author fraser@google.com (Neil Fraser) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.Events.Abstract'); 15 | 16 | goog.require('Blockly.Events'); 17 | 18 | 19 | /** 20 | * Abstract class for an event. 21 | * @constructor 22 | */ 23 | Blockly.Events.Abstract = function() { 24 | /** 25 | * The workspace identifier for this event. 26 | * @type {string|undefined} 27 | */ 28 | this.workspaceId = undefined; 29 | 30 | /** 31 | * The event group id for the group this event belongs to. Groups define 32 | * events that should be treated as an single action from the user's 33 | * perspective, and should be undone together. 34 | * @type {string} 35 | */ 36 | this.group = Blockly.Events.getGroup(); 37 | 38 | /** 39 | * Sets whether the event should be added to the undo stack. 40 | * @type {boolean} 41 | */ 42 | this.recordUndo = Blockly.Events.recordUndo; 43 | }; 44 | 45 | /** 46 | * Encode the event as JSON. 47 | * @return {!Object} JSON representation. 48 | */ 49 | Blockly.Events.Abstract.prototype.toJson = function() { 50 | var json = { 51 | 'type': this.type 52 | }; 53 | if (this.group) { 54 | json['group'] = this.group; 55 | } 56 | return json; 57 | }; 58 | 59 | /** 60 | * Decode the JSON event. 61 | * @param {!Object} json JSON representation. 62 | */ 63 | Blockly.Events.Abstract.prototype.fromJson = function(json) { 64 | this.group = json['group']; 65 | }; 66 | 67 | /** 68 | * Does this event record any change of state? 69 | * @return {boolean} True if null, false if something changed. 70 | */ 71 | Blockly.Events.Abstract.prototype.isNull = function() { 72 | return false; 73 | }; 74 | 75 | /** 76 | * Run an event. 77 | * @param {boolean} _forward True if run forward, false if run backward (undo). 78 | */ 79 | Blockly.Events.Abstract.prototype.run = function(_forward) { 80 | // Defined by subclasses. 81 | }; 82 | 83 | /** 84 | * Get workspace the event belongs to. 85 | * @return {!Blockly.Workspace} The workspace the event belongs to. 86 | * @throws {Error} if workspace is null. 87 | * @protected 88 | */ 89 | Blockly.Events.Abstract.prototype.getEventWorkspace_ = function() { 90 | if (this.workspaceId) { 91 | var workspace = Blockly.Workspace.getById(this.workspaceId); 92 | } 93 | if (!workspace) { 94 | throw Error('Workspace is null. Event must have been generated from real' + 95 | ' Blockly events.'); 96 | } 97 | return workspace; 98 | }; 99 | -------------------------------------------------------------------------------- /web/core/field_label.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2012 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Non-editable, non-serializable text field. Used for titles, 9 | * labels, etc. 10 | * @author fraser@google.com (Neil Fraser) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.FieldLabel'); 15 | 16 | goog.require('Blockly.Field'); 17 | goog.require('Blockly.fieldRegistry'); 18 | goog.require('Blockly.utils'); 19 | goog.require('Blockly.utils.dom'); 20 | goog.require('Blockly.utils.object'); 21 | goog.require('Blockly.utils.Size'); 22 | 23 | 24 | /** 25 | * Class for a non-editable, non-serializable text field. 26 | * @param {string=} opt_value The initial value of the field. Should cast to a 27 | * string. Defaults to an empty string if null or undefined. 28 | * @param {string=} opt_class Optional CSS class for the field's text. 29 | * @param {Object=} opt_config A map of options used to configure the field. 30 | * See the [field creation documentation]{@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/label#creation} 31 | * for a list of properties this parameter supports. 32 | * @extends {Blockly.Field} 33 | * @constructor 34 | */ 35 | Blockly.FieldLabel = function(opt_value, opt_class, opt_config) { 36 | /** 37 | * The html class name to use for this field. 38 | * @type {?string} 39 | * @private 40 | */ 41 | this.class_ = null; 42 | 43 | Blockly.FieldLabel.superClass_.constructor.call( 44 | this, opt_value, null, opt_config); 45 | 46 | if (!opt_config) { // If the config was not passed use old configuration. 47 | this.class_ = opt_class || null; 48 | } 49 | }; 50 | Blockly.utils.object.inherits(Blockly.FieldLabel, Blockly.Field); 51 | 52 | /** 53 | * The default value for this field. 54 | * @type {*} 55 | * @protected 56 | */ 57 | Blockly.FieldLabel.prototype.DEFAULT_VALUE = ''; 58 | 59 | /** 60 | * Construct a FieldLabel from a JSON arg object, 61 | * dereferencing any string table references. 62 | * @param {!Object} options A JSON object with options (text, and class). 63 | * @return {!Blockly.FieldLabel} The new field instance. 64 | * @package 65 | * @nocollapse 66 | */ 67 | Blockly.FieldLabel.fromJson = function(options) { 68 | var text = Blockly.utils.replaceMessageReferences(options['text']); 69 | return new Blockly.FieldLabel(text, undefined, options); 70 | }; 71 | 72 | /** 73 | * Editable fields usually show some sort of UI indicating they are 74 | * editable. This field should not. 75 | * @type {boolean} 76 | */ 77 | Blockly.FieldLabel.prototype.EDITABLE = false; 78 | 79 | /** 80 | * @override 81 | */ 82 | Blockly.FieldLabel.prototype.configure_ = function(config) { 83 | Blockly.FieldLabel.superClass_.configure_.call(this, config); 84 | this.class_ = config['class']; 85 | }; 86 | 87 | /** 88 | * Create block UI for this label. 89 | * @package 90 | */ 91 | Blockly.FieldLabel.prototype.initView = function() { 92 | this.createTextElement_(); 93 | if (this.class_) { 94 | Blockly.utils.dom.addClass( 95 | /** @type {!SVGTextElement} */ (this.textElement_), this.class_); 96 | } 97 | }; 98 | 99 | /** 100 | * Ensure that the input value casts to a valid string. 101 | * @param {*=} opt_newValue The input value. 102 | * @return {?string} A valid string, or null if invalid. 103 | * @protected 104 | */ 105 | Blockly.FieldLabel.prototype.doClassValidation_ = function(opt_newValue) { 106 | if (opt_newValue === null || opt_newValue === undefined) { 107 | return null; 108 | } 109 | return String(opt_newValue); 110 | }; 111 | 112 | /** 113 | * Set the css class applied to the field's textElement_. 114 | * @param {?string} cssClass The new css class name, or null to remove. 115 | */ 116 | Blockly.FieldLabel.prototype.setClass = function(cssClass) { 117 | if (this.textElement_) { 118 | // This check isn't necessary, but it's faster than letting removeClass 119 | // figure it out. 120 | if (this.class_) { 121 | Blockly.utils.dom.removeClass(this.textElement_, this.class_); 122 | } 123 | if (cssClass) { 124 | Blockly.utils.dom.addClass(this.textElement_, cssClass); 125 | } 126 | } 127 | this.class_ = cssClass; 128 | }; 129 | 130 | Blockly.fieldRegistry.register('field_label', Blockly.FieldLabel); 131 | -------------------------------------------------------------------------------- /web/core/field_label_serializable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Non-editable, serializable text field. Behaves like a 9 | * normal label but is serialized to XML. It may only be 10 | * edited programmatically. 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.FieldLabelSerializable'); 15 | 16 | goog.require('Blockly.FieldLabel'); 17 | goog.require('Blockly.fieldRegistry'); 18 | goog.require('Blockly.utils'); 19 | goog.require('Blockly.utils.object'); 20 | 21 | 22 | /** 23 | * Class for a non-editable, serializable text field. 24 | * @param {*} opt_value The initial value of the field. Should cast to a 25 | * string. Defaults to an empty string if null or undefined. 26 | * @param {string=} opt_class Optional CSS class for the field's text. 27 | * @param {Object=} opt_config A map of options used to configure the field. 28 | * See the [field creation documentation]{@link https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/label-serializable#creation} 29 | * for a list of properties this parameter supports. 30 | * @extends {Blockly.FieldLabel} 31 | * @constructor 32 | * 33 | */ 34 | Blockly.FieldLabelSerializable = function(opt_value, opt_class, opt_config) { 35 | Blockly.FieldLabelSerializable.superClass_.constructor.call( 36 | this, opt_value, opt_class, opt_config); 37 | }; 38 | Blockly.utils.object.inherits(Blockly.FieldLabelSerializable, 39 | Blockly.FieldLabel); 40 | 41 | /** 42 | * Construct a FieldLabelSerializable from a JSON arg object, 43 | * dereferencing any string table references. 44 | * @param {!Object} options A JSON object with options (text, and class). 45 | * @return {!Blockly.FieldLabelSerializable} The new field instance. 46 | * @package 47 | * @nocollapse 48 | */ 49 | Blockly.FieldLabelSerializable.fromJson = function(options) { 50 | var text = Blockly.utils.replaceMessageReferences(options['text']); 51 | return new Blockly.FieldLabelSerializable(text, undefined, options); 52 | }; 53 | 54 | /** 55 | * Editable fields usually show some sort of UI indicating they are 56 | * editable. This field should not. 57 | * @type {boolean} 58 | */ 59 | Blockly.FieldLabelSerializable.prototype.EDITABLE = false; 60 | 61 | /** 62 | * Serializable fields are saved by the XML renderer, non-serializable fields 63 | * are not. This field should be serialized, but only edited programmatically. 64 | * @type {boolean} 65 | */ 66 | Blockly.FieldLabelSerializable.prototype.SERIALIZABLE = true; 67 | 68 | Blockly.fieldRegistry.register( 69 | 'field_label_serializable', Blockly.FieldLabelSerializable); 70 | -------------------------------------------------------------------------------- /web/core/field_registry.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Fields can be created based on a JSON definition. This file 9 | * contains methods for registering those JSON definitions, and building the 10 | * fields based on JSON. 11 | * @author bekawestberg@gmail.com (Beka Westberg) 12 | */ 13 | 'use strict'; 14 | 15 | goog.provide('Blockly.fieldRegistry'); 16 | 17 | goog.require('Blockly.registry'); 18 | 19 | 20 | /** 21 | * Registers a field type. 22 | * Blockly.fieldRegistry.fromJson uses this registry to 23 | * find the appropriate field type. 24 | * @param {string} type The field type name as used in the JSON definition. 25 | * @param {?function(new:Blockly.Field, ...?)} fieldClass The field class 26 | * containing a fromJson function that can construct an instance of the 27 | * field. 28 | * @throws {Error} if the type name is empty, the field is already 29 | * registered, or the fieldClass is not an object containing a fromJson 30 | * function. 31 | */ 32 | Blockly.fieldRegistry.register = function(type, fieldClass) { 33 | Blockly.registry.register(Blockly.registry.Type.FIELD, type, fieldClass); 34 | }; 35 | 36 | /** 37 | * Unregisters the field registered with the given type. 38 | * @param {string} type The field type name as used in the JSON definition. 39 | */ 40 | Blockly.fieldRegistry.unregister = function(type) { 41 | Blockly.registry.unregister(Blockly.registry.Type.FIELD, type); 42 | }; 43 | 44 | /** 45 | * Construct a Field from a JSON arg object. 46 | * Finds the appropriate registered field by the type name as registered using 47 | * Blockly.fieldRegistry.register. 48 | * @param {!Object} options A JSON object with a type and options specific 49 | * to the field type. 50 | * @return {Blockly.Field} The new field instance or null if a field wasn't 51 | * found with the given type name 52 | * @package 53 | */ 54 | Blockly.fieldRegistry.fromJson = function(options) { 55 | var fieldClass = /** @type {{fromJson:function(!Object):!Blockly.Field}} */ ( 56 | Blockly.registry.getClass(Blockly.registry.Type.FIELD, options['type'])); 57 | if (!fieldClass) { 58 | console.warn('Blockly could not create a field of type ' + options['type'] + 59 | '. The field is probably not being registered. This could be because' + 60 | ' the file is not loaded, the field does not register itself (Issue' + 61 | ' #1584), or the registration is not being reached.'); 62 | return null; 63 | } 64 | return fieldClass.fromJson(options); 65 | }; 66 | -------------------------------------------------------------------------------- /web/core/flyout_dragger.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2017 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Methods for dragging a flyout visually. 9 | * @author fenichel@google.com (Rachel Fenichel) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.FlyoutDragger'); 14 | 15 | goog.require('Blockly.utils.object'); 16 | goog.require('Blockly.WorkspaceDragger'); 17 | 18 | 19 | /** 20 | * Class for a flyout dragger. It moves a flyout workspace around when it is 21 | * being dragged by a mouse or touch. 22 | * Note that the workspace itself manages whether or not it has a drag surface 23 | * and how to do translations based on that. This simply passes the right 24 | * commands based on events. 25 | * @param {!Blockly.Flyout} flyout The flyout to drag. 26 | * @extends {Blockly.WorkspaceDragger} 27 | * @constructor 28 | */ 29 | Blockly.FlyoutDragger = function(flyout) { 30 | Blockly.FlyoutDragger.superClass_.constructor.call(this, 31 | flyout.getWorkspace()); 32 | 33 | /** 34 | * The scrollbar to update to move the flyout. 35 | * Unlike the main workspace, the flyout has only one scrollbar, in either the 36 | * horizontal or the vertical direction. 37 | * @type {!Blockly.Scrollbar} 38 | * @private 39 | */ 40 | this.scrollbar_ = flyout.scrollbar; 41 | 42 | /** 43 | * Whether the flyout scrolls horizontally. If false, the flyout scrolls 44 | * vertically. 45 | * @type {boolean} 46 | * @private 47 | */ 48 | this.horizontalLayout_ = flyout.horizontalLayout; 49 | }; 50 | Blockly.utils.object.inherits(Blockly.FlyoutDragger, Blockly.WorkspaceDragger); 51 | 52 | /** 53 | * Move the flyout based on the most recent mouse movements. 54 | * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has 55 | * moved from the position at the start of the drag, in pixel coordinates. 56 | * @package 57 | */ 58 | Blockly.FlyoutDragger.prototype.drag = function(currentDragDeltaXY) { 59 | // startScrollXY_ is assigned by the superclass. 60 | var newXY = Blockly.utils.Coordinate.sum(this.startScrollXY_, 61 | currentDragDeltaXY); 62 | 63 | // We can't call workspace.scroll because the flyout's workspace doesn't own 64 | // it's own scrollbars. This is because (as of 2.20190722.1) the 65 | // workspace's scrollbar property must be a scrollbar pair, rather than a 66 | // single scrollbar. 67 | // Instead we'll just expect setting the scrollbar to update the scroll of 68 | // the workspace as well. 69 | if (this.horizontalLayout_) { 70 | this.scrollbar_.set(-newXY.x); 71 | } else { 72 | this.scrollbar_.set(-newXY.y); 73 | } 74 | }; 75 | -------------------------------------------------------------------------------- /web/core/interfaces/i_accessibility.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview AST Node and keyboard navigation interfaces. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.IASTNodeLocation'); 15 | goog.provide('Blockly.IASTNodeLocationSvg'); 16 | goog.provide('Blockly.IASTNodeLocationWithBlock'); 17 | goog.provide('Blockly.IBlocklyActionable'); 18 | 19 | /** 20 | * An AST node location interface. 21 | * @interface 22 | */ 23 | Blockly.IASTNodeLocation = function() {}; 24 | 25 | /** 26 | * An AST node location SVG interface. 27 | * @interface 28 | * @extends {Blockly.IASTNodeLocation} 29 | */ 30 | Blockly.IASTNodeLocationSvg = function() {}; 31 | 32 | /** 33 | * Add the marker svg to this node's svg group. 34 | * @param {SVGElement} markerSvg The svg root of the marker to be added to the 35 | * svg group. 36 | */ 37 | Blockly.IASTNodeLocationSvg.prototype.setMarkerSvg; 38 | 39 | /** 40 | * Add the cursor svg to this node's svg group. 41 | * @param {SVGElement} cursorSvg The svg root of the cursor to be added to the 42 | * svg group. 43 | */ 44 | Blockly.IASTNodeLocationSvg.prototype.setCursorSvg; 45 | 46 | /** 47 | * An AST node location that has an associated block. 48 | * @interface 49 | * @extends {Blockly.IASTNodeLocation} 50 | */ 51 | Blockly.IASTNodeLocationWithBlock = function() {}; 52 | 53 | /** 54 | * Get the source block associated with this node. 55 | * @return {Blockly.Block} The source block. 56 | */ 57 | Blockly.IASTNodeLocationWithBlock.prototype.getSourceBlock; 58 | 59 | 60 | /** 61 | * An interface for an object that handles Blockly actions when keyboard 62 | * navigation is enabled. 63 | * @interface 64 | */ 65 | Blockly.IBlocklyActionable = function() {}; 66 | 67 | /** 68 | * Handles the given action. 69 | * @param {!Blockly.Action} action The action to be handled. 70 | * @return {boolean} True if the action has been handled, false otherwise. 71 | */ 72 | Blockly.IBlocklyActionable.prototype.onBlocklyAction; 73 | -------------------------------------------------------------------------------- /web/core/interfaces/i_bounded_element.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The interface for a bounded element. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.IBoundedElement'); 15 | 16 | goog.requireType('Blockly.utils.Rect'); 17 | 18 | 19 | /** 20 | * A bounded element interface. 21 | * @interface 22 | */ 23 | Blockly.IBoundedElement = function() {}; 24 | 25 | /** 26 | * Returns the coordinates of a bounded element describing the dimensions of the 27 | * element. 28 | * Coordinate system: workspace coordinates. 29 | * @return {!Blockly.utils.Rect} Object with coordinates of the bounded element. 30 | */ 31 | Blockly.IBoundedElement.prototype.getBoundingRectangle; 32 | -------------------------------------------------------------------------------- /web/core/interfaces/i_copyable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The interface for an object that is copyable. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.ICopyable'); 15 | 16 | goog.requireType('Blockly.ISelectable'); 17 | goog.requireType('Blockly.WorkspaceSvg'); 18 | 19 | 20 | /** 21 | * @extends {Blockly.ISelectable} 22 | * @interface 23 | */ 24 | Blockly.ICopyable = function() {}; 25 | 26 | /** 27 | * Encode for copying. 28 | * @return {!Blockly.ICopyable.CopyData} Copy metadata. 29 | */ 30 | Blockly.ICopyable.prototype.toCopyData; 31 | 32 | /** 33 | * Copy Metadata. 34 | * @typedef {{ 35 | * xml:!Element, 36 | * source:Blockly.WorkspaceSvg, 37 | * typeCounts:?Object 38 | * }} 39 | */ 40 | Blockly.ICopyable.CopyData; 41 | -------------------------------------------------------------------------------- /web/core/interfaces/i_deletable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The interface for an object that is deletable. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.IDeletable'); 15 | 16 | 17 | /** 18 | * The interface for an object that can be deleted. 19 | * @interface 20 | */ 21 | Blockly.IDeletable = function() {}; 22 | 23 | /** 24 | * Get whether this object is deletable or not. 25 | * @return {boolean} True if deletable. 26 | */ 27 | Blockly.IDeletable.prototype.isDeletable; 28 | -------------------------------------------------------------------------------- /web/core/interfaces/i_deletearea.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The interface for a component that can delete a block that is 9 | * dropped on top of it. 10 | * @author aschmiedt@google.com (Abby Schmiedt) 11 | */ 12 | 13 | 'use strict'; 14 | 15 | goog.provide('Blockly.IDeleteArea'); 16 | 17 | 18 | /** 19 | * Interface for a component that can delete a block that is dropped on top of it. 20 | * @interface 21 | */ 22 | Blockly.IDeleteArea = function() {}; 23 | 24 | /** 25 | * Return the deletion rectangle. 26 | * @return {Blockly.utils.Rect} Rectangle in which to delete. 27 | */ 28 | Blockly.IDeleteArea.prototype.getClientRect; 29 | -------------------------------------------------------------------------------- /web/core/interfaces/i_movable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The interface for an object that is movable. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.IMovable'); 15 | 16 | 17 | /** 18 | * The interface for an object that is movable. 19 | * @interface 20 | */ 21 | Blockly.IMovable = function() {}; 22 | 23 | /** 24 | * Get whether this is movable or not. 25 | * @return {boolean} True if movable. 26 | */ 27 | Blockly.IMovable.prototype.isMovable; 28 | -------------------------------------------------------------------------------- /web/core/interfaces/i_registrable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The interface for a Blockly component that can be registered. 9 | * (Ex. Toolbox, Fields, Renderers) 10 | * @author aschmiedt@google.com (Abby Schmiedt) 11 | */ 12 | 13 | 'use strict'; 14 | 15 | goog.provide('Blockly.IRegistrable'); 16 | 17 | 18 | /** 19 | * The interface for a Blockly component that can be registered. 20 | * @interface 21 | * */ 22 | Blockly.IRegistrable = function() {}; 23 | -------------------------------------------------------------------------------- /web/core/interfaces/i_selectable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The interface for an object that is selectable. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.ISelectable'); 15 | 16 | goog.requireType('Blockly.IDeletable'); 17 | goog.requireType('Blockly.IMovable'); 18 | 19 | 20 | /** 21 | * The interface for an object that is selectable. 22 | * @extends {Blockly.IDeletable} 23 | * @extends {Blockly.IMovable} 24 | * @interface 25 | */ 26 | Blockly.ISelectable = function() {}; 27 | 28 | /** 29 | * @type {string} 30 | */ 31 | Blockly.ISelectable.prototype.id; 32 | 33 | /** 34 | * Select this. Highlight it visually. 35 | * @return {void} 36 | */ 37 | Blockly.ISelectable.prototype.select; 38 | 39 | /** 40 | * Unselect this. Unhighlight it visually. 41 | * @return {void} 42 | */ 43 | Blockly.ISelectable.prototype.unselect; 44 | -------------------------------------------------------------------------------- /web/core/interfaces/i_styleable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The interface for an object that a style can be added to. 9 | * @author aschmiedt@google.com (Abby Schmiedt) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.IStyleable'); 15 | 16 | 17 | /** 18 | * Interface for an object that a style can be added to. 19 | * @interface 20 | */ 21 | Blockly.IStyleable = function() {}; 22 | 23 | /** 24 | * Adds a style on the toolbox. Usually used to change the cursor. 25 | * @param {string} style The name of the class to add. 26 | */ 27 | Blockly.IStyleable.prototype.addStyle; 28 | 29 | /** 30 | * Removes a style from the toolbox. Usually used to change the cursor. 31 | * @param {string} style The name of the class to remove. 32 | */ 33 | Blockly.IStyleable.prototype.removeStyle; 34 | -------------------------------------------------------------------------------- /web/core/interfaces/i_toolbox.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The interface for a toolbox. 9 | * @author aschmiedt@google.com (Abby Schmiedt) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.IToolbox'); 15 | 16 | goog.requireType('Blockly.IRegistrable'); 17 | 18 | 19 | /** 20 | * Interface for a toolbox. 21 | * @extends {Blockly.IRegistrable} 22 | * @interface 23 | */ 24 | Blockly.IToolbox = function() {}; 25 | 26 | /** 27 | * Initializes the toolbox. 28 | * @return {void} 29 | */ 30 | Blockly.IToolbox.prototype.init; 31 | 32 | /** 33 | * Fill the toolbox with categories and blocks. 34 | * @param {Array.} toolboxDef Array holding objects 35 | * containing information on the contents of the toolbox. 36 | */ 37 | Blockly.IToolbox.prototype.render; 38 | 39 | /** 40 | * Dispose of this toolbox. 41 | * @return {void} 42 | */ 43 | Blockly.IToolbox.prototype.dispose; 44 | 45 | /** 46 | * Get the width of the toolbox. 47 | * @return {number} The width of the toolbox. 48 | */ 49 | Blockly.IToolbox.prototype.getWidth; 50 | 51 | /** 52 | * Get the height of the toolbox. 53 | * @return {number} The width of the toolbox. 54 | */ 55 | Blockly.IToolbox.prototype.getHeight; 56 | 57 | /** 58 | * Get the toolbox flyout. 59 | * @return {Blockly.Flyout} The toolbox flyout. 60 | */ 61 | Blockly.IToolbox.prototype.getFlyout; 62 | 63 | /** 64 | * Move the toolbox to the edge. 65 | * @return {void} 66 | */ 67 | Blockly.IToolbox.prototype.position; 68 | 69 | /** 70 | * Unhighlight any previously specified option. 71 | * @return {void} 72 | */ 73 | Blockly.IToolbox.prototype.clearSelection; 74 | 75 | /** 76 | * Updates the category colours and background colour of selected categories. 77 | * @return {void} 78 | */ 79 | Blockly.IToolbox.prototype.refreshTheme; 80 | 81 | /** 82 | * Update the flyout's contents without closing it. Should be used in response 83 | * to a change in one of the dynamic categories, such as variables or 84 | * procedures. 85 | * @return {void} 86 | */ 87 | Blockly.IToolbox.prototype.refreshSelection; 88 | 89 | /** 90 | * Toggles the visibility of the toolbox. 91 | * @param {boolean} isVisible True if the toolbox should be visible. 92 | */ 93 | Blockly.IToolbox.prototype.setVisible; 94 | 95 | /** 96 | * Select the first toolbox category if no category is selected. 97 | * @return {void} 98 | */ 99 | Blockly.IToolbox.prototype.selectFirstCategory; 100 | -------------------------------------------------------------------------------- /web/core/keyboard_nav/action.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The class representing an action. 9 | * Used primarily for keyboard navigation. 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.Action'); 14 | 15 | 16 | /** 17 | * Class for a single action. 18 | * An action describes user intent. (ex go to next or go to previous) 19 | * @param {string} name The name of the action. 20 | * @param {string} desc The description of the action. 21 | * @constructor 22 | */ 23 | Blockly.Action = function(name, desc) { 24 | this.name = name; 25 | this.desc = desc; 26 | }; 27 | -------------------------------------------------------------------------------- /web/core/keyboard_nav/flyout_cursor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The class representing a cursor used to navigate the flyout. 9 | * Used primarily for keyboard navigation. 10 | * @author aschmiedt@google.com (Abby Schmiedt) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.FlyoutCursor'); 15 | 16 | goog.require('Blockly.Cursor'); 17 | goog.require('Blockly.navigation'); 18 | goog.require('Blockly.utils.object'); 19 | 20 | 21 | /** 22 | * Class for a flyout cursor. 23 | * This controls how a user navigates blocks in the flyout. 24 | * @constructor 25 | * @extends {Blockly.Cursor} 26 | */ 27 | Blockly.FlyoutCursor = function() { 28 | Blockly.FlyoutCursor.superClass_.constructor.call(this); 29 | }; 30 | Blockly.utils.object.inherits(Blockly.FlyoutCursor, Blockly.Cursor); 31 | 32 | /** 33 | * Handles the given action. 34 | * This is only triggered when keyboard navigation is enabled. 35 | * @param {!Blockly.Action} action The action to be handled. 36 | * @return {boolean} True if the action has been handled, false otherwise. 37 | * @override 38 | */ 39 | Blockly.FlyoutCursor.prototype.onBlocklyAction = function(action) { 40 | switch (action.name) { 41 | case Blockly.navigation.actionNames.PREVIOUS: 42 | this.prev(); 43 | return true; 44 | case Blockly.navigation.actionNames.NEXT: 45 | this.next(); 46 | return true; 47 | default: 48 | return false; 49 | } 50 | }; 51 | 52 | /** 53 | * Find the next connection, field, or block. 54 | * @return {Blockly.ASTNode} The next element, or null if the current node is 55 | * not set or there is no next value. 56 | * @override 57 | */ 58 | Blockly.FlyoutCursor.prototype.next = function() { 59 | var curNode = this.getCurNode(); 60 | if (!curNode) { 61 | return null; 62 | } 63 | var newNode = curNode.next(); 64 | 65 | if (newNode) { 66 | this.setCurNode(newNode); 67 | } 68 | return newNode; 69 | }; 70 | 71 | /** 72 | * This is a no-op since a flyout cursor can not go in. 73 | * @return {null} Always null. 74 | * @override 75 | */ 76 | Blockly.FlyoutCursor.prototype.in = function() { 77 | return null; 78 | }; 79 | 80 | /** 81 | * Find the previous connection, field, or block. 82 | * @return {Blockly.ASTNode} The previous element, or null if the current node 83 | * is not set or there is no previous value. 84 | * @override 85 | */ 86 | Blockly.FlyoutCursor.prototype.prev = function() { 87 | var curNode = this.getCurNode(); 88 | if (!curNode) { 89 | return null; 90 | } 91 | var newNode = curNode.prev(); 92 | 93 | if (newNode) { 94 | this.setCurNode(newNode); 95 | } 96 | return newNode; 97 | }; 98 | 99 | /** 100 | * This is a no-op since a flyout cursor can not go out. 101 | * @return {null} Always null. 102 | * @override 103 | */ 104 | Blockly.FlyoutCursor.prototype.out = function() { 105 | return null; 106 | }; 107 | -------------------------------------------------------------------------------- /web/core/keyboard_nav/marker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The class representing a marker. 9 | * Used primarily for keyboard navigation to show a marked location. 10 | * @author aschmiedt@google.com (Abby Schmiedt) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.Marker'); 15 | 16 | goog.require('Blockly.ASTNode'); 17 | goog.require('Blockly.navigation'); 18 | 19 | 20 | /** 21 | * Class for a marker. 22 | * This is used in keyboard navigation to save a location in the Blockly AST. 23 | * @constructor 24 | */ 25 | Blockly.Marker = function() { 26 | /** 27 | * The colour of the marker. 28 | * @type {?string} 29 | */ 30 | this.colour = null; 31 | 32 | /** 33 | * The current location of the marker. 34 | * @type {Blockly.ASTNode} 35 | * @private 36 | */ 37 | this.curNode_ = null; 38 | 39 | /** 40 | * The object in charge of drawing the visual representation of the current node. 41 | * @type {Blockly.blockRendering.MarkerSvg} 42 | * @private 43 | */ 44 | this.drawer_ = null; 45 | 46 | /** 47 | * The type of the marker. 48 | * @type {string} 49 | */ 50 | this.type = 'marker'; 51 | }; 52 | 53 | /** 54 | * Sets the object in charge of drawing the marker. 55 | * @param {Blockly.blockRendering.MarkerSvg} drawer The object in charge of 56 | * drawing the marker. 57 | */ 58 | Blockly.Marker.prototype.setDrawer = function(drawer) { 59 | this.drawer_ = drawer; 60 | }; 61 | 62 | /** 63 | * Get the current drawer for the marker. 64 | * @return {Blockly.blockRendering.MarkerSvg} The object in charge of drawing 65 | * the marker. 66 | */ 67 | Blockly.Marker.prototype.getDrawer = function() { 68 | return this.drawer_; 69 | }; 70 | 71 | /** 72 | * Gets the current location of the marker. 73 | * @return {Blockly.ASTNode} The current field, connection, or block the marker 74 | * is on. 75 | */ 76 | Blockly.Marker.prototype.getCurNode = function() { 77 | return this.curNode_; 78 | }; 79 | 80 | /** 81 | * Set the location of the marker and call the update method. 82 | * Setting isStack to true will only work if the newLocation is the top most 83 | * output or previous connection on a stack. 84 | * @param {Blockly.ASTNode} newNode The new location of the marker. 85 | */ 86 | Blockly.Marker.prototype.setCurNode = function(newNode) { 87 | var oldNode = this.curNode_; 88 | this.curNode_ = newNode; 89 | if (this.drawer_) { 90 | this.drawer_.draw(oldNode, this.curNode_); 91 | } 92 | }; 93 | 94 | /** 95 | * Redraw the current marker. 96 | * @package 97 | */ 98 | Blockly.Marker.prototype.draw = function() { 99 | if (this.drawer_) { 100 | this.drawer_.draw(this.curNode_, this.curNode_); 101 | } 102 | }; 103 | 104 | /** 105 | * Hide the marker SVG. 106 | */ 107 | Blockly.Marker.prototype.hide = function() { 108 | if (this.drawer_) { 109 | this.drawer_.hide(); 110 | } 111 | }; 112 | 113 | /** 114 | * Dispose of this marker. 115 | */ 116 | Blockly.Marker.prototype.dispose = function() { 117 | if (this.getDrawer()) { 118 | this.getDrawer().dispose(); 119 | } 120 | }; 121 | -------------------------------------------------------------------------------- /web/core/keyboard_nav/tab_navigate_cursor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview The class representing a cursor that is used to navigate 9 | * between tab navigable fields. 10 | * @author samelh@google.com (Sam El-Husseini) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.TabNavigateCursor'); 15 | 16 | goog.require('Blockly.ASTNode'); 17 | goog.require('Blockly.BasicCursor'); 18 | goog.require('Blockly.utils.object'); 19 | 20 | 21 | /** 22 | * A cursor for navigating between tab navigable fields. 23 | * @constructor 24 | * @extends {Blockly.BasicCursor} 25 | */ 26 | Blockly.TabNavigateCursor = function() { 27 | Blockly.TabNavigateCursor.superClass_.constructor.call(this); 28 | }; 29 | Blockly.utils.object.inherits(Blockly.TabNavigateCursor, Blockly.BasicCursor); 30 | 31 | /** 32 | * Skip all nodes except for tab navigable fields. 33 | * @param {Blockly.ASTNode} node The AST node to check whether it is valid. 34 | * @return {boolean} True if the node should be visited, false otherwise. 35 | * @override 36 | */ 37 | Blockly.TabNavigateCursor.prototype.validNode_ = function(node) { 38 | var isValid = false; 39 | var type = node && node.getType(); 40 | if (node) { 41 | var location = /** @type {Blockly.Field} */ (node.getLocation()); 42 | if (type == Blockly.ASTNode.types.FIELD && 43 | location && location.isTabNavigable() && location.isClickable()) { 44 | isValid = true; 45 | } 46 | } 47 | return isValid; 48 | }; 49 | -------------------------------------------------------------------------------- /web/core/msg.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2013 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Empty name space for the Message singleton. 9 | * @author scr@google.com (Sheridan Rawlins) 10 | */ 11 | 'use strict'; 12 | 13 | /** 14 | * Name space for the Msg singleton. 15 | * Msg gets populated in the message files. 16 | */ 17 | goog.provide('Blockly.Msg'); 18 | 19 | goog.require('Blockly.utils.global'); 20 | 21 | 22 | /** 23 | * Exported so that if Blockly is compiled with ADVANCED_COMPILATION, 24 | * the Blockly.Msg object exists for message files included in script tags. 25 | */ 26 | if (!Blockly.utils.global['Blockly']) { 27 | Blockly.utils.global['Blockly'] = {}; 28 | } 29 | if (!Blockly.utils.global['Blockly']['Msg']) { 30 | Blockly.utils.global['Blockly']['Msg'] = Blockly.Msg; 31 | } 32 | -------------------------------------------------------------------------------- /web/core/renderers/common/block_rendering.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Namespace for block rendering functionality. 9 | * @author fenichel@google.com (Rachel Fenichel) 10 | */ 11 | 'use strict'; 12 | 13 | /** 14 | * The top level namespace for block rendering. 15 | * @namespace Blockly.blockRendering 16 | */ 17 | goog.provide('Blockly.blockRendering'); 18 | 19 | goog.require('Blockly.registry'); 20 | goog.require('Blockly.utils.object'); 21 | 22 | 23 | /** 24 | * Whether or not the debugger is turned on. 25 | * @type {boolean} 26 | * @package 27 | */ 28 | Blockly.blockRendering.useDebugger = false; 29 | 30 | /** 31 | * Registers a new renderer. 32 | * @param {string} name The name of the renderer. 33 | * @param {!Function} rendererClass The new renderer class 34 | * to register. 35 | * @throws {Error} if a renderer with the same name has already been registered. 36 | */ 37 | Blockly.blockRendering.register = function(name, rendererClass) { 38 | Blockly.registry.register(Blockly.registry.Type.RENDERER, name, 39 | rendererClass); 40 | }; 41 | 42 | /** 43 | * Unregisters the renderer registered with the given name. 44 | * @param {string} name The name of the renderer. 45 | */ 46 | Blockly.blockRendering.unregister = function(name) { 47 | Blockly.registry.unregister(Blockly.registry.Type.RENDERER, name); 48 | }; 49 | /** 50 | * Turn on the blocks debugger. 51 | * @package 52 | */ 53 | Blockly.blockRendering.startDebugger = function() { 54 | Blockly.blockRendering.useDebugger = true; 55 | }; 56 | 57 | /** 58 | * Turn off the blocks debugger. 59 | * @package 60 | */ 61 | Blockly.blockRendering.stopDebugger = function() { 62 | Blockly.blockRendering.useDebugger = false; 63 | }; 64 | 65 | /** 66 | * Initialize anything needed for rendering (constants, etc). 67 | * @param {!string} name Name of the renderer to initialize. 68 | * @param {!Blockly.Theme} theme The workspace theme object. 69 | * @param {Object=} opt_rendererOverrides Rendering constant overrides. 70 | * @return {!Blockly.blockRendering.Renderer} The new instance of a renderer. 71 | * Already initialized. 72 | * @package 73 | */ 74 | 75 | Blockly.blockRendering.init = function(name, theme, opt_rendererOverrides) { 76 | var rendererClass = Blockly.registry.getClass( 77 | Blockly.registry.Type.RENDERER, name); 78 | var renderer = new rendererClass(name); 79 | renderer.init(theme, opt_rendererOverrides); 80 | return renderer; 81 | }; 82 | -------------------------------------------------------------------------------- /web/core/renderers/geras/constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview An object that provides constants for rendering blocks in Geras 9 | * mode. 10 | * @author kozbial@google.com (Monica Kozbial) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.geras.ConstantProvider'); 15 | 16 | goog.require('Blockly.blockRendering.ConstantProvider'); 17 | goog.require('Blockly.utils.object'); 18 | 19 | 20 | /** 21 | * An object that provides constants for rendering blocks in Geras mode. 22 | * @constructor 23 | * @package 24 | * @extends {Blockly.blockRendering.ConstantProvider} 25 | */ 26 | Blockly.geras.ConstantProvider = function() { 27 | Blockly.geras.ConstantProvider.superClass_.constructor.call(this); 28 | 29 | /** 30 | * @override 31 | */ 32 | this.FIELD_TEXT_BASELINE_CENTER = false; 33 | 34 | // The dark/shadow path in classic rendering is the same as the normal block 35 | // path, but translated down one and right one. 36 | this.DARK_PATH_OFFSET = 1; 37 | 38 | /** 39 | * The maximum width of a bottom row that follows a statement input and has 40 | * inputs inline. 41 | * @type {number} 42 | */ 43 | this.MAX_BOTTOM_WIDTH = 30; 44 | }; 45 | Blockly.utils.object.inherits(Blockly.geras.ConstantProvider, 46 | Blockly.blockRendering.ConstantProvider); 47 | 48 | 49 | /** 50 | * @override 51 | */ 52 | Blockly.geras.ConstantProvider.prototype.getCSS_ = function(selector) { 53 | return Blockly.geras.ConstantProvider.superClass_.getCSS_.call(this, selector) 54 | .concat([ 55 | /* eslint-disable indent */ 56 | // Insertion marker. 57 | selector + ' .blocklyInsertionMarker>.blocklyPathLight,', 58 | selector + ' .blocklyInsertionMarker>.blocklyPathDark {', 59 | 'fill-opacity: ' + this.INSERTION_MARKER_OPACITY + ';', 60 | 'stroke: none;', 61 | '}', 62 | /* eslint-enable indent */ 63 | ]); 64 | }; 65 | -------------------------------------------------------------------------------- /web/core/renderers/geras/measurables/inputs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Objects representing inputs with connections on a rendered 9 | * block. 10 | * @author kozbial@google.com (Monica Kozbial) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.geras.InlineInput'); 15 | goog.provide('Blockly.geras.StatementInput'); 16 | 17 | goog.require('Blockly.utils.object'); 18 | 19 | 20 | /** 21 | * An object containing information about the space an inline input takes up 22 | * during rendering 23 | * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering 24 | * constants provider. 25 | * @param {!Blockly.Input} input The inline input to measure and store 26 | * information for. 27 | * @package 28 | * @constructor 29 | * @extends {Blockly.blockRendering.InlineInput} 30 | */ 31 | Blockly.geras.InlineInput = function(constants, input) { 32 | Blockly.geras.InlineInput.superClass_.constructor.call( 33 | this, constants, input); 34 | 35 | if (this.connectedBlock) { 36 | // We allow the dark path to show on the parent block so that the child 37 | // block looks embossed. This takes up an extra pixel in both x and y. 38 | this.width += this.constants_.DARK_PATH_OFFSET; 39 | this.height += this.constants_.DARK_PATH_OFFSET; 40 | } 41 | }; 42 | Blockly.utils.object.inherits(Blockly.geras.InlineInput, 43 | Blockly.blockRendering.InlineInput); 44 | 45 | /** 46 | * An object containing information about the space a statement input takes up 47 | * during rendering 48 | * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering 49 | * constants provider. 50 | * @param {!Blockly.Input} input The statement input to measure and store 51 | * information for. 52 | * @package 53 | * @constructor 54 | * @extends {Blockly.blockRendering.StatementInput} 55 | */ 56 | Blockly.geras.StatementInput = function(constants, input) { 57 | Blockly.geras.StatementInput.superClass_.constructor.call( 58 | this, constants, input); 59 | 60 | if (this.connectedBlock) { 61 | // We allow the dark path to show on the parent block so that the child 62 | // block looks embossed. This takes up an extra pixel in both x and y. 63 | this.height += this.constants_.DARK_PATH_OFFSET; 64 | } 65 | }; 66 | Blockly.utils.object.inherits(Blockly.geras.StatementInput, 67 | Blockly.blockRendering.StatementInput); 68 | -------------------------------------------------------------------------------- /web/core/renderers/measurables/base.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Methods for graphically rendering a block as SVG. 9 | * @author fenichel@google.com (Rachel Fenichel) 10 | */ 11 | 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.blockRendering.Measurable'); 15 | 16 | goog.require('Blockly.blockRendering.Types'); 17 | 18 | 19 | /** 20 | * The base class to represent a part of a block that takes up space during 21 | * rendering. The constructor for each non-spacer Measurable records the size 22 | * of the block element (e.g. field, statement input). 23 | * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering 24 | * constants provider. 25 | * @package 26 | * @constructor 27 | */ 28 | Blockly.blockRendering.Measurable = function(constants) { 29 | this.width = 0; 30 | this.height = 0; 31 | this.type = Blockly.blockRendering.Types.NONE; 32 | 33 | this.xPos = 0; 34 | this.centerline = 0; 35 | 36 | /** 37 | * The renderer's constant provider. 38 | * @type {!Blockly.blockRendering.ConstantProvider} 39 | * @protected 40 | */ 41 | this.constants_ = constants; 42 | 43 | this.notchOffset = this.constants_.NOTCH_OFFSET_LEFT; 44 | }; 45 | -------------------------------------------------------------------------------- /web/core/renderers/minimalist/constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview An object that provides constants for rendering blocks in the 9 | * minimalist renderer. 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.minimalist.ConstantProvider'); 14 | 15 | goog.require('Blockly.blockRendering.ConstantProvider'); 16 | goog.require('Blockly.utils.object'); 17 | 18 | 19 | /** 20 | * An object that provides constants for rendering blocks in the sample. 21 | * @constructor 22 | * @package 23 | * @extends {Blockly.blockRendering.ConstantProvider} 24 | */ 25 | Blockly.minimalist.ConstantProvider = function() { 26 | Blockly.minimalist.ConstantProvider.superClass_.constructor.call(this); 27 | }; 28 | Blockly.utils.object.inherits(Blockly.minimalist.ConstantProvider, 29 | Blockly.blockRendering.ConstantProvider); 30 | -------------------------------------------------------------------------------- /web/core/renderers/minimalist/drawer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Minimalist rendering drawer. 9 | */ 10 | 'use strict'; 11 | 12 | goog.provide('Blockly.minimalist.Drawer'); 13 | 14 | goog.require('Blockly.blockRendering.Drawer'); 15 | goog.require('Blockly.utils.object'); 16 | goog.require('Blockly.minimalist.RenderInfo'); 17 | 18 | 19 | /** 20 | * An object that draws a block based on the given rendering information. 21 | * @param {!Blockly.BlockSvg} block The block to render. 22 | * @param {!Blockly.minimalist.RenderInfo} info An object containing all 23 | * information needed to render this block. 24 | * @package 25 | * @constructor 26 | * @extends {Blockly.blockRendering.Drawer} 27 | */ 28 | Blockly.minimalist.Drawer = function(block, info) { 29 | Blockly.minimalist.Drawer.superClass_.constructor.call(this, block, info); 30 | }; 31 | Blockly.utils.object.inherits(Blockly.minimalist.Drawer, 32 | Blockly.blockRendering.Drawer); 33 | -------------------------------------------------------------------------------- /web/core/renderers/minimalist/info.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Minimalist render info object. 9 | */ 10 | 'use strict'; 11 | 12 | goog.provide('Blockly.minimalist'); 13 | goog.provide('Blockly.minimalist.RenderInfo'); 14 | 15 | goog.require('Blockly.utils.object'); 16 | 17 | 18 | /** 19 | * An object containing all sizing information needed to draw this block. 20 | * 21 | * This measure pass does not propagate changes to the block (although fields 22 | * may choose to rerender when getSize() is called). However, calling it 23 | * repeatedly may be expensive. 24 | * 25 | * @param {!Blockly.minimalist.Renderer} renderer The renderer in use. 26 | * @param {!Blockly.BlockSvg} block The block to measure. 27 | * @constructor 28 | * @package 29 | * @extends {Blockly.blockRendering.RenderInfo} 30 | */ 31 | Blockly.minimalist.RenderInfo = function(renderer, block) { 32 | Blockly.minimalist.RenderInfo.superClass_.constructor.call(this, renderer, block); 33 | 34 | }; 35 | Blockly.utils.object.inherits(Blockly.minimalist.RenderInfo, 36 | Blockly.blockRendering.RenderInfo); 37 | 38 | /** 39 | * Get the block renderer in use. 40 | * @return {!Blockly.minimalist.Renderer} The block renderer in use. 41 | * @package 42 | */ 43 | Blockly.minimalist.RenderInfo.prototype.getRenderer = function() { 44 | return /** @type {!Blockly.minimalist.Renderer} */ (this.renderer_); 45 | }; 46 | -------------------------------------------------------------------------------- /web/core/renderers/minimalist/renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Minimalist renderer. 9 | */ 10 | 'use strict'; 11 | 12 | goog.provide('Blockly.minimalist.Renderer'); 13 | 14 | goog.require('Blockly.blockRendering'); 15 | goog.require('Blockly.blockRendering.Renderer'); 16 | goog.require('Blockly.utils.object'); 17 | goog.require('Blockly.minimalist.ConstantProvider'); 18 | goog.require('Blockly.minimalist.Drawer'); 19 | goog.require('Blockly.minimalist.RenderInfo'); 20 | 21 | 22 | /** 23 | * The minimalist renderer. 24 | * @param {string} name The renderer name. 25 | * @package 26 | * @constructor 27 | * @extends {Blockly.blockRendering.Renderer} 28 | */ 29 | Blockly.minimalist.Renderer = function(name) { 30 | Blockly.minimalist.Renderer.superClass_.constructor.call(this, name); 31 | }; 32 | Blockly.utils.object.inherits(Blockly.minimalist.Renderer, 33 | Blockly.blockRendering.Renderer); 34 | 35 | /** 36 | * Create a new instance of the renderer's constant provider. 37 | * @return {!Blockly.minimalist.ConstantProvider} The constant provider. 38 | * @protected 39 | * @override 40 | */ 41 | Blockly.minimalist.Renderer.prototype.makeConstants_ = function() { 42 | return new Blockly.minimalist.ConstantProvider(); 43 | }; 44 | 45 | /** 46 | * Create a new instance of the renderer's render info object. 47 | * @param {!Blockly.BlockSvg} block The block to measure. 48 | * @return {!Blockly.minimalist.RenderInfo} The render info object. 49 | * @protected 50 | * @override 51 | */ 52 | Blockly.minimalist.Renderer.prototype.makeRenderInfo_ = function(block) { 53 | return new Blockly.minimalist.RenderInfo(this, block); 54 | }; 55 | 56 | /** 57 | * Create a new instance of the renderer's drawer. 58 | * @param {!Blockly.BlockSvg} block The block to render. 59 | * @param {!Blockly.blockRendering.RenderInfo} info An object containing all 60 | * information needed to render this block. 61 | * @return {!Blockly.minimalist.Drawer} The drawer. 62 | * @protected 63 | * @override 64 | */ 65 | Blockly.minimalist.Renderer.prototype.makeDrawer_ = function(block, info) { 66 | return new Blockly.minimalist.Drawer(block, 67 | /** @type {!Blockly.minimalist.RenderInfo} */ (info)); 68 | }; 69 | 70 | Blockly.blockRendering.register('minimalist', Blockly.minimalist.Renderer); 71 | -------------------------------------------------------------------------------- /web/core/renderers/thrasos/renderer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Thrasos renderer. 9 | * @author fenichel@google.com (Rachel Fenichel) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.thrasos.Renderer'); 14 | 15 | goog.require('Blockly.blockRendering'); 16 | goog.require('Blockly.blockRendering.Renderer'); 17 | goog.require('Blockly.thrasos.RenderInfo'); 18 | goog.require('Blockly.utils.object'); 19 | 20 | /** 21 | * The thrasos renderer. 22 | * @param {string} name The renderer name. 23 | * @package 24 | * @constructor 25 | * @extends {Blockly.blockRendering.Renderer} 26 | */ 27 | Blockly.thrasos.Renderer = function(name) { 28 | Blockly.thrasos.Renderer.superClass_.constructor.call(this, name); 29 | }; 30 | Blockly.utils.object.inherits(Blockly.thrasos.Renderer, 31 | Blockly.blockRendering.Renderer); 32 | 33 | /** 34 | * Create a new instance of the renderer's render info object. 35 | * @param {!Blockly.BlockSvg} block The block to measure. 36 | * @return {!Blockly.thrasos.RenderInfo} The render info object. 37 | * @protected 38 | * @override 39 | */ 40 | Blockly.thrasos.Renderer.prototype.makeRenderInfo_ = function(block) { 41 | return new Blockly.thrasos.RenderInfo(this, block); 42 | }; 43 | 44 | 45 | Blockly.blockRendering.register('thrasos', Blockly.thrasos.Renderer); 46 | -------------------------------------------------------------------------------- /web/core/renderers/zelos/measurables/inputs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Zelos specific objects representing inputs with connections on 9 | * a rendered block. 10 | * @author samelh@google.com (Sam El-Husseini) 11 | */ 12 | 13 | goog.provide('Blockly.zelos.StatementInput'); 14 | 15 | goog.require('Blockly.blockRendering.StatementInput'); 16 | goog.require('Blockly.utils.object'); 17 | 18 | 19 | /** 20 | * An object containing information about the space a statement input takes up 21 | * during rendering 22 | * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering 23 | * constants provider. 24 | * @param {!Blockly.Input} input The statement input to measure and store 25 | * information for. 26 | * @package 27 | * @constructor 28 | * @extends {Blockly.blockRendering.StatementInput} 29 | */ 30 | Blockly.zelos.StatementInput = function(constants, input) { 31 | Blockly.zelos.StatementInput.superClass_.constructor.call(this, 32 | constants, input); 33 | 34 | if (this.connectedBlock) { 35 | // Find the bottom-most connected block in the stack. 36 | var block = this.connectedBlock; 37 | while (block.getNextBlock()) { 38 | block = block.getNextBlock(); 39 | } 40 | if (!block.nextConnection) { 41 | this.height = this.connectedBlockHeight; 42 | this.connectedBottomNextConnection = true; 43 | } 44 | } 45 | }; 46 | Blockly.utils.object.inherits(Blockly.zelos.StatementInput, 47 | Blockly.blockRendering.StatementInput); 48 | -------------------------------------------------------------------------------- /web/core/renderers/zelos/measurables/row_elements.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Zelos specific objects representing elements in a row of a 9 | * rendered block. 10 | * @author samelh@google.com (Sam El-Husseini) 11 | */ 12 | 13 | goog.provide('Blockly.zelos.RightConnectionShape'); 14 | 15 | goog.require('Blockly.blockRendering.Measurable'); 16 | goog.require('Blockly.blockRendering.Types'); 17 | goog.require('Blockly.utils.object'); 18 | 19 | 20 | /** 21 | * An object containing information about the space a right connection shape 22 | * takes up during rendering. 23 | * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering 24 | * constants provider. 25 | * @package 26 | * @constructor 27 | * @extends {Blockly.blockRendering.Measurable} 28 | */ 29 | Blockly.zelos.RightConnectionShape = function(constants) { 30 | Blockly.zelos.RightConnectionShape.superClass_.constructor.call(this, constants); 31 | this.type |= Blockly.blockRendering.Types.getType('RIGHT_CONNECTION'); 32 | // Size is dynamic 33 | this.height = 0; 34 | this.width = 0; 35 | }; 36 | Blockly.utils.object.inherits(Blockly.zelos.RightConnectionShape, 37 | Blockly.blockRendering.Measurable); 38 | -------------------------------------------------------------------------------- /web/core/renderers/zelos/measurables/rows.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview An object representing a single row on a rendered block and all 9 | * of its subcomponents. 10 | * @author samelh@google.com (Sam El-Husseini) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.zelos.BottomRow'); 15 | goog.provide('Blockly.zelos.TopRow'); 16 | 17 | goog.require('Blockly.blockRendering.BottomRow'); 18 | goog.require('Blockly.blockRendering.TopRow'); 19 | goog.require('Blockly.blockRendering.SpacerRow'); 20 | goog.require('Blockly.utils.object'); 21 | 22 | 23 | /** 24 | * An object containing information about what elements are in the top row of a 25 | * block as well as sizing information for the top row. 26 | * Elements in a top row can consist of corners, hats, spacers, and previous 27 | * connections. 28 | * After this constructor is called, the row will contain all non-spacer 29 | * elements it needs. 30 | * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering 31 | * constants provider. 32 | * @package 33 | * @constructor 34 | * @extends {Blockly.blockRendering.TopRow} 35 | */ 36 | Blockly.zelos.TopRow = function(constants) { 37 | Blockly.zelos.TopRow.superClass_.constructor.call(this, constants); 38 | }; 39 | Blockly.utils.object.inherits(Blockly.zelos.TopRow, 40 | Blockly.blockRendering.TopRow); 41 | 42 | /** 43 | * @override 44 | */ 45 | Blockly.zelos.TopRow.prototype.endsWithElemSpacer = function() { 46 | return false; 47 | }; 48 | 49 | /** 50 | * Render a round corner unless the block has an output connection. 51 | * @override 52 | */ 53 | Blockly.zelos.TopRow.prototype.hasLeftSquareCorner = function(block) { 54 | var hasHat = (block.hat ? 55 | block.hat === 'cap' : this.constants_.ADD_START_HATS) && 56 | !block.outputConnection && !block.previousConnection; 57 | return !!block.outputConnection || hasHat; 58 | }; 59 | 60 | /** 61 | * Render a round corner unless the block has an output connection. 62 | * @override 63 | */ 64 | Blockly.zelos.TopRow.prototype.hasRightSquareCorner = function(block) { 65 | return !!block.outputConnection && !block.statementInputCount && 66 | !block.nextConnection; 67 | }; 68 | 69 | /** 70 | * An object containing information about what elements are in the bottom row of 71 | * a block as well as spacing information for the top row. 72 | * Elements in a bottom row can consist of corners, spacers and next 73 | * connections. 74 | * @param {!Blockly.blockRendering.ConstantProvider} constants The rendering 75 | * constants provider. 76 | * @package 77 | * @constructor 78 | * @extends {Blockly.blockRendering.BottomRow} 79 | */ 80 | Blockly.zelos.BottomRow = function(constants) { 81 | Blockly.zelos.BottomRow.superClass_.constructor.call(this, constants); 82 | }; 83 | Blockly.utils.object.inherits(Blockly.zelos.BottomRow, 84 | Blockly.blockRendering.BottomRow); 85 | 86 | /** 87 | * @override 88 | */ 89 | Blockly.zelos.BottomRow.prototype.endsWithElemSpacer = function() { 90 | return false; 91 | }; 92 | 93 | /** 94 | * Render a round corner unless the block has an output connection. 95 | * @override 96 | */ 97 | Blockly.zelos.BottomRow.prototype.hasLeftSquareCorner = function(block) { 98 | return !!block.outputConnection; 99 | }; 100 | 101 | /** 102 | * Render a round corner unless the block has an output connection. 103 | * @override 104 | */ 105 | Blockly.zelos.BottomRow.prototype.hasRightSquareCorner = function(block) { 106 | return !!block.outputConnection && !block.statementInputCount && 107 | !block.nextConnection; 108 | }; 109 | -------------------------------------------------------------------------------- /web/core/requires.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Default Blockly entry point. Use this to pick and choose which 9 | * fields and renderers to include in your Blockly bundle. 10 | * @author samelh@google.com (Sam El-Husseini) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.requires'); 15 | 16 | // Blockly Core (absolutely mandatory). 17 | goog.require('Blockly'); 18 | 19 | 20 | // If block comments aren't required, then Blockly.inject's "comments" 21 | // configuration must be false, and no blocks may be loaded from XML which 22 | // define comments. 23 | goog.require('Blockly.Comment'); 24 | // One of these two will almost certainly be needed (usually VerticalFlyout). 25 | goog.require('Blockly.HorizontalFlyout'); 26 | goog.require('Blockly.VerticalFlyout'); 27 | // Flyout buttons are needed by the variable category, 28 | // and by any custom toolbox that has a button or a label. 29 | goog.require('Blockly.FlyoutButton'); 30 | // If there is code generation into any language, then the generator is needed. 31 | // Should not be required when using advanced compilation since 32 | // individual generator files should already have this require. 33 | goog.require('Blockly.Generator'); 34 | // If the toolbox does not have categories and only has a simple flyout, then 35 | // 'Blockly.Toolbox' is not needed. 36 | goog.require('Blockly.Toolbox'); 37 | // If a trashcan on the workspace isn't required, then Blockly.inject's 38 | // "trashcan" configuration must be false. 39 | goog.require('Blockly.Trashcan'); 40 | // Only needed if one is using the 'VARIABLE_DYNAMIC' typed variables category. 41 | goog.require('Blockly.VariablesDynamic'); 42 | // Only need to require these two if you're using workspace comments. 43 | // goog.require('Blockly.WorkspaceCommentSvg'); 44 | // goog.require('Blockly.WorkspaceCommentSvg.render'); 45 | // If zoom controls aren't required, then Blockly.inject's 46 | // "zoom"/"controls" configuration must be false. 47 | goog.require('Blockly.ZoomControls'); 48 | 49 | 50 | // Block dependencies. 51 | // None of these should be required when using advanced compilation since 52 | // individual block files should include the requirements they depend on. 53 | goog.require('Blockly.Mutator'); 54 | goog.require('Blockly.Warning'); 55 | goog.require('Blockly.FieldAngle'); 56 | goog.require('Blockly.FieldCheckbox'); 57 | goog.require('Blockly.FieldColour'); 58 | goog.require('Blockly.FieldDropdown'); 59 | goog.require('Blockly.FieldLabelSerializable'); 60 | goog.require('Blockly.FieldImage'); 61 | goog.require('Blockly.FieldTextInput'); 62 | goog.require('Blockly.FieldMultilineInput'); 63 | goog.require('Blockly.FieldNumber'); 64 | goog.require('Blockly.FieldVariable'); 65 | 66 | 67 | // Blockly Renderers. 68 | // At least one renderer is mandatory. Geras is the default one. 69 | // Others may be chosen using Blockly.inject's "renderer" configuration. 70 | goog.require('Blockly.geras.Renderer'); 71 | goog.require('Blockly.thrasos.Renderer'); 72 | goog.require('Blockly.zelos.Renderer'); 73 | // The debug renderer, which shows simplified versions of the blocks for 74 | // developer use. 75 | // goog.require('Blockly.blockRendering.Debug'); 76 | 77 | // Blockly Themes. 78 | // Classic is the default theme. 79 | goog.require('Blockly.Themes.Classic'); 80 | goog.require('Blockly.Themes.Dark'); 81 | goog.require('Blockly.Themes.Deuteranopia'); 82 | goog.require('Blockly.Themes.HighContrast'); 83 | goog.require('Blockly.Themes.Tritanopia'); 84 | // goog.require('Blockly.Themes.Modern'); 85 | -------------------------------------------------------------------------------- /web/core/theme/classic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Classic theme. 9 | * Contains multi-coloured border to create shadow effect. 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.Themes.Classic'); 14 | 15 | goog.require('Blockly.Theme'); 16 | 17 | 18 | // Temporary holding object. 19 | Blockly.Themes.Classic = {}; 20 | 21 | Blockly.Themes.Classic.defaultBlockStyles = { 22 | "colour_blocks": { 23 | "colourPrimary": "20" 24 | }, 25 | "list_blocks": { 26 | "colourPrimary": "260" 27 | }, 28 | "logic_blocks": { 29 | "colourPrimary": "210" 30 | }, 31 | "loop_blocks": { 32 | "colourPrimary": "120" 33 | }, 34 | "math_blocks": { 35 | "colourPrimary": "230" 36 | }, 37 | "procedure_blocks": { 38 | "colourPrimary": "290" 39 | }, 40 | "text_blocks": { 41 | "colourPrimary": "160" 42 | }, 43 | "variable_blocks": { 44 | "colourPrimary": "330" 45 | }, 46 | "variable_dynamic_blocks": { 47 | "colourPrimary": "310" 48 | }, 49 | "hat_blocks": { 50 | "colourPrimary": "330", 51 | "hat": "cap" 52 | } 53 | }; 54 | 55 | Blockly.Themes.Classic.categoryStyles = { 56 | "colour_category": { 57 | "colour": "20" 58 | }, 59 | "list_category": { 60 | "colour": "260" 61 | }, 62 | "logic_category": { 63 | "colour": "210" 64 | }, 65 | "loop_category": { 66 | "colour": "120" 67 | }, 68 | "math_category": { 69 | "colour": "230" 70 | }, 71 | "procedure_category": { 72 | "colour": "290" 73 | }, 74 | "text_category": { 75 | "colour": "160" 76 | }, 77 | "variable_category": { 78 | "colour": "330" 79 | }, 80 | "variable_dynamic_category": { 81 | "colour": "310" 82 | } 83 | }; 84 | 85 | Blockly.Themes.Classic = 86 | new Blockly.Theme('classic', Blockly.Themes.Classic.defaultBlockStyles, 87 | Blockly.Themes.Classic.categoryStyles); 88 | -------------------------------------------------------------------------------- /web/core/theme/dark.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Dark theme. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.Themes.Dark'); 14 | 15 | goog.require('Blockly.Theme'); 16 | 17 | Blockly.Themes.Dark = Blockly.Theme.defineTheme('dark', { 18 | 'base': Blockly.Themes.Classic, 19 | 'componentStyles': { 20 | 'workspaceBackgroundColour': '#1e1e1e', 21 | 'toolboxBackgroundColour': '#333', 22 | 'toolboxForegroundColour': '#fff', 23 | 'flyoutBackgroundColour': '#252526', 24 | 'flyoutForegroundColour': '#ccc', 25 | 'flyoutOpacity': 1, 26 | 'scrollbarColour': '#797979', 27 | 'insertionMarkerColour': '#fff', 28 | 'insertionMarkerOpacity': 0.3, 29 | 'scrollbarOpacity': 0.4, 30 | 'cursorColour': '#d0d0d0' 31 | } 32 | }); 33 | -------------------------------------------------------------------------------- /web/core/theme/deuteranopia.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Deuteranopia theme. 9 | * A colour palette for people that have deuteranopia (the inability to perceive 10 | * green light). This can also be used for people that have protanopia (the 11 | * inability to perceive red light). 12 | */ 13 | 'use strict'; 14 | 15 | goog.provide('Blockly.Themes.Deuteranopia'); 16 | 17 | goog.require('Blockly.Theme'); 18 | 19 | 20 | // Temporary holding object. 21 | Blockly.Themes.Deuteranopia = {}; 22 | 23 | Blockly.Themes.Deuteranopia.defaultBlockStyles = { 24 | "colour_blocks": { 25 | "colourPrimary": "#f2a72c", 26 | "colourSecondary": "#f1c172", 27 | "colourTertiary": "#da921c" 28 | }, 29 | "list_blocks": { 30 | "colourPrimary": "#7d65ab", 31 | "colourSecondary": "#a88be0", 32 | "colourTertiary": "#66518e" 33 | }, 34 | "logic_blocks": { 35 | "colourPrimary": "#9fd2f1", 36 | "colourSecondary": "#c0e0f4", 37 | "colourTertiary": "#74bae5" 38 | }, 39 | "loop_blocks": { 40 | "colourPrimary": "#795a07", 41 | "colourSecondary": "#ac8726", 42 | "colourTertiary": "#c4a03f" 43 | }, 44 | "math_blocks": { 45 | "colourPrimary": "#e6da39", 46 | "colourSecondary": "#f3ec8e", 47 | "colourTertiary": "#f2eeb7" 48 | }, 49 | "procedure_blocks": { 50 | "colourPrimary": "#590721", 51 | "colourSecondary": "#8c475d", 52 | "colourTertiary": "#885464" 53 | }, 54 | "text_blocks": { 55 | "colourPrimary": "#058863", 56 | "colourSecondary": "#5ecfaf", 57 | "colourTertiary": "#04684c" 58 | }, 59 | "variable_blocks": { 60 | "colourPrimary": "#47025a", 61 | "colourSecondary": "#820fa1", 62 | "colourTertiary": "#8e579d" 63 | }, 64 | "variable_dynamic_blocks": { 65 | "colourPrimary": "#47025a", 66 | "colourSecondary": "#820fa1", 67 | "colourTertiary": "#8e579d" 68 | } 69 | }; 70 | 71 | Blockly.Themes.Deuteranopia.categoryStyles = { 72 | "colour_category": { 73 | "colour": "#f2a72c" 74 | }, 75 | "list_category": { 76 | "colour": "#7d65ab" 77 | }, 78 | "logic_category": { 79 | "colour": "#9fd2f1" 80 | }, 81 | "loop_category": { 82 | "colour": "#795a07" 83 | }, 84 | "math_category": { 85 | "colour": "#e6da39" 86 | }, 87 | "procedure_category": { 88 | "colour": "#590721" 89 | }, 90 | "text_category": { 91 | "colour": "#058863" 92 | }, 93 | "variable_category": { 94 | "colour": "#47025a" 95 | }, 96 | "variable_dynamic_category": { 97 | "colour": "#47025a" 98 | } 99 | }; 100 | 101 | Blockly.Themes.Deuteranopia = 102 | new Blockly.Theme('deuteranopia', 103 | Blockly.Themes.Deuteranopia.defaultBlockStyles, 104 | Blockly.Themes.Deuteranopia.categoryStyles); 105 | -------------------------------------------------------------------------------- /web/core/theme/highcontrast.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview High contrast theme. 9 | * Darker colours to contrast the white font. 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.Themes.HighContrast'); 14 | 15 | goog.require('Blockly.Theme'); 16 | 17 | 18 | // Temporary holding object. 19 | Blockly.Themes.HighContrast = {}; 20 | 21 | Blockly.Themes.HighContrast.defaultBlockStyles = { 22 | "colour_blocks": { 23 | "colourPrimary": "#a52714", 24 | "colourSecondary": "#FB9B8C", 25 | "colourTertiary": "#FBE1DD" 26 | }, 27 | "list_blocks": { 28 | "colourPrimary": "#4a148c", 29 | "colourSecondary": "#AD7BE9", 30 | "colourTertiary": "#CDB6E9" 31 | }, 32 | "logic_blocks": { 33 | "colourPrimary": "#01579b", 34 | "colourSecondary": "#64C7FF", 35 | "colourTertiary": "#C5EAFF" 36 | }, 37 | "loop_blocks": { 38 | "colourPrimary": "#33691e", 39 | "colourSecondary": "#9AFF78", 40 | "colourTertiary": "#E1FFD7" 41 | }, 42 | "math_blocks": { 43 | "colourPrimary": "#1a237e", 44 | "colourSecondary": "#8A9EFF", 45 | "colourTertiary": "#DCE2FF" 46 | }, 47 | "procedure_blocks": { 48 | "colourPrimary": "#006064", 49 | "colourSecondary": "#77E6EE", 50 | "colourTertiary": "#CFECEE" 51 | }, 52 | "text_blocks": { 53 | "colourPrimary": "#004d40", 54 | "colourSecondary": "#5ae27c", 55 | "colourTertiary": "#D2FFDD" 56 | }, 57 | "variable_blocks": { 58 | "colourPrimary": "#880e4f", 59 | "colourSecondary": "#FF73BE", 60 | "colourTertiary": "#FFD4EB" 61 | }, 62 | "variable_dynamic_blocks": { 63 | "colourPrimary": "#880e4f", 64 | "colourSecondary": "#FF73BE", 65 | "colourTertiary": "#FFD4EB" 66 | }, 67 | "hat_blocks": { 68 | "colourPrimary": "#880e4f", 69 | "colourSecondary": "#FF73BE", 70 | "colourTertiary": "#FFD4EB", 71 | "hat": "cap" 72 | } 73 | }; 74 | 75 | Blockly.Themes.HighContrast.categoryStyles = { 76 | "colour_category": { 77 | "colour": "#a52714" 78 | }, 79 | "list_category": { 80 | "colour": "#4a148c" 81 | }, 82 | "logic_category": { 83 | "colour": "#01579b" 84 | }, 85 | "loop_category": { 86 | "colour": "#33691e" 87 | }, 88 | "math_category": { 89 | "colour": "#1a237e" 90 | }, 91 | "procedure_category": { 92 | "colour": "#006064" 93 | }, 94 | "text_category": { 95 | "colour": "#004d40" 96 | }, 97 | "variable_category": { 98 | "colour": "#880e4f" 99 | }, 100 | "variable_dynamic_category": { 101 | "colour": "#880e4f" 102 | } 103 | }; 104 | 105 | // This style is still being fleshed out and may change. 106 | Blockly.Themes.HighContrast = 107 | new Blockly.Theme('highcontrast', 108 | Blockly.Themes.HighContrast.defaultBlockStyles, 109 | Blockly.Themes.HighContrast.categoryStyles); 110 | 111 | Blockly.Themes.HighContrast.setComponentStyle('selectedGlowColour', '#000000'); 112 | Blockly.Themes.HighContrast.setComponentStyle('selectedGlowSize', 1); 113 | Blockly.Themes.HighContrast.setComponentStyle('replacementGlowColour', '#000000'); 114 | 115 | Blockly.Themes.HighContrast.setFontStyle({ 116 | 'family': null, // Use default font-family 117 | 'weight': null, // Use default font-weight 118 | 'size': 16 119 | }); 120 | -------------------------------------------------------------------------------- /web/core/theme/modern.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Modern theme. 9 | * Same colours as classic, but single coloured border. 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.Themes.Modern'); 14 | 15 | goog.require('Blockly.Theme'); 16 | 17 | 18 | // Temporary holding object. 19 | Blockly.Themes.Modern = {}; 20 | 21 | Blockly.Themes.Modern.defaultBlockStyles = { 22 | "colour_blocks": { 23 | "colourPrimary": "#a5745b", 24 | "colourSecondary": "#dbc7bd", 25 | "colourTertiary": "#845d49" 26 | }, 27 | "list_blocks": { 28 | "colourPrimary": "#745ba5", 29 | "colourSecondary": "#c7bddb", 30 | "colourTertiary": "#5d4984" 31 | }, 32 | "logic_blocks": { 33 | "colourPrimary": "#5b80a5", 34 | "colourSecondary": "#bdccdb", 35 | "colourTertiary": "#496684" 36 | }, 37 | "loop_blocks": { 38 | "colourPrimary": "#5ba55b", 39 | "colourSecondary": "#bddbbd", 40 | "colourTertiary": "#498449" 41 | }, 42 | "math_blocks": { 43 | "colourPrimary": "#5b67a5", 44 | "colourSecondary": "#bdc2db", 45 | "colourTertiary": "#495284" 46 | }, 47 | "procedure_blocks": { 48 | "colourPrimary": "#995ba5", 49 | "colourSecondary": "#d6bddb", 50 | "colourTertiary": "#7a4984" 51 | }, 52 | "text_blocks": { 53 | "colourPrimary": "#5ba58c", 54 | "colourSecondary": "#bddbd1", 55 | "colourTertiary": "#498470" 56 | }, 57 | "variable_blocks": { 58 | "colourPrimary": "#a55b99", 59 | "colourSecondary": "#dbbdd6", 60 | "colourTertiary": "#84497a" 61 | }, 62 | "variable_dynamic_blocks": { 63 | "colourPrimary": "#a55b99", 64 | "colourSecondary": "#dbbdd6", 65 | "colourTertiary": "#84497a" 66 | }, 67 | "hat_blocks": { 68 | "colourPrimary": "#a55b99", 69 | "colourSecondary": "#dbbdd6", 70 | "colourTertiary": "#84497a", 71 | "hat": "cap" 72 | } 73 | }; 74 | 75 | Blockly.Themes.Modern.categoryStyles = { 76 | "colour_category": { 77 | "colour": "#a5745b" 78 | }, 79 | "list_category": { 80 | "colour": "#745ba5" 81 | }, 82 | "logic_category": { 83 | "colour": "#5b80a5" 84 | }, 85 | "loop_category": { 86 | "colour": "#5ba55b" 87 | }, 88 | "math_category": { 89 | "colour": "#5b67a5" 90 | }, 91 | "procedure_category": { 92 | "colour": "#995ba5" 93 | }, 94 | "text_category": { 95 | "colour": "#5ba58c" 96 | }, 97 | "variable_category": { 98 | "colour": "#a55b99" 99 | }, 100 | "variable_dynamic_category": { 101 | "colour": "#a55b99" 102 | } 103 | }; 104 | 105 | // This style is still being fleshed out and may change. 106 | Blockly.Themes.Modern = 107 | new Blockly.Theme('modern', Blockly.Themes.Modern.defaultBlockStyles, 108 | Blockly.Themes.Modern.categoryStyles); 109 | -------------------------------------------------------------------------------- /web/core/theme/tritanopia.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Tritanopia theme. 9 | * A color palette for people that have tritanopia (the inability to perceive 10 | * blue light). 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.Themes.Tritanopia'); 15 | 16 | goog.require('Blockly.Theme'); 17 | 18 | 19 | // Temporary holding object. 20 | Blockly.Themes.Tritanopia = {}; 21 | 22 | Blockly.Themes.Tritanopia.defaultBlockStyles = { 23 | "colour_blocks": { 24 | "colourPrimary": "#05427f", 25 | "colourSecondary": "#2974c0", 26 | "colourTertiary": "#2d74bb" 27 | }, 28 | "list_blocks": { 29 | "colourPrimary": "#b69ce8", 30 | "colourSecondary": "#ccbaef", 31 | "colourTertiary": "#9176c5" 32 | }, 33 | "logic_blocks": { 34 | "colourPrimary": "#9fd2f1", 35 | "colourSecondary": "#c0e0f4", 36 | "colourTertiary": "#74bae5" 37 | }, 38 | "loop_blocks": { 39 | "colourPrimary": "#aa1846", 40 | "colourSecondary": "#d36185", 41 | "colourTertiary": "#7c1636" 42 | }, 43 | "math_blocks": { 44 | "colourPrimary": "#e6da39", 45 | "colourSecondary": "#f3ec8e", 46 | "colourTertiary": "#f2eeb7" 47 | }, 48 | "procedure_blocks": { 49 | "colourPrimary": "#590721", 50 | "colourSecondary": "#8c475d", 51 | "colourTertiary": "#885464" 52 | }, 53 | "text_blocks": { 54 | "colourPrimary": "#058863", 55 | "colourSecondary": "#5ecfaf", 56 | "colourTertiary": "#04684c" 57 | }, 58 | "variable_blocks": { 59 | "colourPrimary": "#4b2d84", 60 | "colourSecondary": "#816ea7", 61 | "colourTertiary": "#83759e" 62 | }, 63 | "variable_dynamic_blocks": { 64 | "colourPrimary": "#4b2d84", 65 | "colourSecondary": "#816ea7", 66 | "colourTertiary": "#83759e" 67 | } 68 | }; 69 | 70 | Blockly.Themes.Tritanopia.categoryStyles = { 71 | "colour_category": { 72 | "colour": "#05427f" 73 | }, 74 | "list_category": { 75 | "colour": "#b69ce8" 76 | }, 77 | "logic_category": { 78 | "colour": "#9fd2f1" 79 | }, 80 | "loop_category": { 81 | "colour": "#aa1846" 82 | }, 83 | "math_category": { 84 | "colour": "#e6da39" 85 | }, 86 | "procedure_category": { 87 | "colour": "#590721" 88 | }, 89 | "text_category": { 90 | "colour": "#058863" 91 | }, 92 | "variable_category": { 93 | "colour": "#4b2d84" 94 | }, 95 | "variable_dynamic_category": { 96 | "colour": "#4b2d84" 97 | } 98 | }; 99 | 100 | Blockly.Themes.Tritanopia = 101 | new Blockly.Theme('tritanopia', 102 | Blockly.Themes.Tritanopia.defaultBlockStyles, 103 | Blockly.Themes.Tritanopia.categoryStyles); 104 | -------------------------------------------------------------------------------- /web/core/theme/zelos.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Zelos theme. 9 | */ 10 | 'use strict'; 11 | 12 | goog.provide('Blockly.Themes.Zelos'); 13 | 14 | goog.require('Blockly.Theme'); 15 | 16 | 17 | // Temporary holding object. 18 | Blockly.Themes.Zelos = {}; 19 | 20 | Blockly.Themes.Zelos.defaultBlockStyles = { 21 | "colour_blocks": { 22 | "colourPrimary": "#CF63CF", 23 | "colourSecondary": "#C94FC9", 24 | "colourTertiary": "#BD42BD" 25 | }, 26 | "list_blocks": { 27 | "colourPrimary": "#9966FF", 28 | "colourSecondary": "#855CD6", 29 | "colourTertiary": "#774DCB" 30 | }, 31 | "logic_blocks": { 32 | "colourPrimary": "#4C97FF", 33 | "colourSecondary": "#4280D7", 34 | "colourTertiary": "#3373CC" 35 | }, 36 | "loop_blocks": { 37 | "colourPrimary": "#0fBD8C", 38 | "colourSecondary": "#0DA57A", 39 | "colourTertiary": "#0B8E69" 40 | }, 41 | "math_blocks": { 42 | "colourPrimary": "#59C059", 43 | "colourSecondary": "#46B946", 44 | "colourTertiary": "#389438" 45 | }, 46 | "procedure_blocks": { 47 | "colourPrimary": "#FF6680", 48 | "colourSecondary": "#FF4D6A", 49 | "colourTertiary": "#FF3355" 50 | }, 51 | "text_blocks": { 52 | "colourPrimary": "#FFBF00", 53 | "colourSecondary": "#E6AC00", 54 | "colourTertiary": "#CC9900" 55 | }, 56 | "variable_blocks": { 57 | "colourPrimary": "#FF8C1A", 58 | "colourSecondary": "#FF8000", 59 | "colourTertiary": "#DB6E00" 60 | }, 61 | "variable_dynamic_blocks": { 62 | "colourPrimary": "#FF8C1A", 63 | "colourSecondary": "#FF8000", 64 | "colourTertiary": "#DB6E00" 65 | }, 66 | "hat_blocks": { 67 | "colourPrimary": "#4C97FF", 68 | "colourSecondary": "#4280D7", 69 | "colourTertiary": "#3373CC", 70 | "hat": "cap" 71 | } 72 | }; 73 | 74 | Blockly.Themes.Zelos.categoryStyles = { 75 | "colour_category": { 76 | "colour": "#CF63CF" 77 | }, 78 | "list_category": { 79 | "colour": "#9966FF" 80 | }, 81 | "logic_category": { 82 | "colour": "#4C97FF" 83 | }, 84 | "loop_category": { 85 | "colour": "#0fBD8C" 86 | }, 87 | "math_category": { 88 | "colour": "#59C059" 89 | }, 90 | "procedure_category": { 91 | "colour": "#FF6680" 92 | }, 93 | "text_category": { 94 | "colour": "#FFBF00" 95 | }, 96 | "variable_category": { 97 | "colour": "#FF8C1A" 98 | }, 99 | "variable_dynamic_category": { 100 | "colour": "#FF8C1A" 101 | } 102 | }; 103 | 104 | Blockly.Themes.Zelos = 105 | new Blockly.Theme('zelos', Blockly.Themes.Zelos.defaultBlockStyles, 106 | Blockly.Themes.Zelos.categoryStyles); 107 | -------------------------------------------------------------------------------- /web/core/ui_events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Events fired as a result of UI actions in Blockly's editor. 9 | * @author fraser@google.com (Neil Fraser) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.Events.Ui'); 14 | 15 | goog.require('Blockly.Events'); 16 | goog.require('Blockly.Events.Abstract'); 17 | goog.require('Blockly.utils.object'); 18 | 19 | 20 | /** 21 | * Class for a UI event. 22 | * UI events are events that don't need to be sent over the wire for multi-user 23 | * editing to work (e.g. scrolling the workspace, zooming, opening toolbox 24 | * categories). 25 | * UI events do not undo or redo. 26 | * @param {Blockly.Block} block The affected block. 27 | * @param {string} element One of 'selected', 'comment', 'mutatorOpen', etc. 28 | * @param {*} oldValue Previous value of element. 29 | * @param {*} newValue New value of element. 30 | * @extends {Blockly.Events.Abstract} 31 | * @constructor 32 | */ 33 | Blockly.Events.Ui = function(block, element, oldValue, newValue) { 34 | Blockly.Events.Ui.superClass_.constructor.call(this); 35 | this.blockId = block ? block.id : null; 36 | this.workspaceId = block ? block.workspace.id : undefined; 37 | this.element = element; 38 | this.oldValue = oldValue; 39 | this.newValue = newValue; 40 | // UI events do not undo or redo. 41 | this.recordUndo = false; 42 | }; 43 | Blockly.utils.object.inherits(Blockly.Events.Ui, Blockly.Events.Abstract); 44 | 45 | /** 46 | * Type of this event. 47 | * @type {string} 48 | */ 49 | Blockly.Events.Ui.prototype.type = Blockly.Events.UI; 50 | 51 | /** 52 | * Encode the event as JSON. 53 | * @return {!Object} JSON representation. 54 | */ 55 | Blockly.Events.Ui.prototype.toJson = function() { 56 | var json = Blockly.Events.Ui.superClass_.toJson.call(this); 57 | json['element'] = this.element; 58 | if (this.newValue !== undefined) { 59 | json['newValue'] = this.newValue; 60 | } 61 | if (this.blockId) { 62 | json['blockId'] = this.blockId; 63 | } 64 | return json; 65 | }; 66 | 67 | /** 68 | * Decode the JSON event. 69 | * @param {!Object} json JSON representation. 70 | */ 71 | Blockly.Events.Ui.prototype.fromJson = function(json) { 72 | Blockly.Events.Ui.superClass_.fromJson.call(this, json); 73 | this.element = json['element']; 74 | this.newValue = json['newValue']; 75 | this.blockId = json['blockId']; 76 | }; 77 | -------------------------------------------------------------------------------- /web/core/utils/coordinate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Utility methods for coordinate manipulation. 9 | * These methods are not specific to Blockly, and could be factored out into 10 | * a JavaScript framework such as Closure. 11 | * @author fraser@google.com (Neil Fraser) 12 | */ 13 | 'use strict'; 14 | 15 | /** 16 | * @name Blockly.utils.Coordinate 17 | * @namespace 18 | */ 19 | goog.provide('Blockly.utils.Coordinate'); 20 | 21 | 22 | /** 23 | * Class for representing coordinates and positions. 24 | * @param {number} x Left. 25 | * @param {number} y Top. 26 | * @struct 27 | * @constructor 28 | */ 29 | Blockly.utils.Coordinate = function(x, y) { 30 | /** 31 | * X-value 32 | * @type {number} 33 | */ 34 | this.x = x; 35 | 36 | /** 37 | * Y-value 38 | * @type {number} 39 | */ 40 | this.y = y; 41 | }; 42 | 43 | /** 44 | * Compares coordinates for equality. 45 | * @param {Blockly.utils.Coordinate} a A Coordinate. 46 | * @param {Blockly.utils.Coordinate} b A Coordinate. 47 | * @return {boolean} True iff the coordinates are equal, or if both are null. 48 | */ 49 | Blockly.utils.Coordinate.equals = function(a, b) { 50 | if (a == b) { 51 | return true; 52 | } 53 | if (!a || !b) { 54 | return false; 55 | } 56 | return a.x == b.x && a.y == b.y; 57 | }; 58 | 59 | /** 60 | * Returns the distance between two coordinates. 61 | * @param {!Blockly.utils.Coordinate} a A Coordinate. 62 | * @param {!Blockly.utils.Coordinate} b A Coordinate. 63 | * @return {number} The distance between `a` and `b`. 64 | */ 65 | Blockly.utils.Coordinate.distance = function(a, b) { 66 | var dx = a.x - b.x; 67 | var dy = a.y - b.y; 68 | return Math.sqrt(dx * dx + dy * dy); 69 | }; 70 | 71 | /** 72 | * Returns the magnitude of a coordinate. 73 | * @param {!Blockly.utils.Coordinate} a A Coordinate. 74 | * @return {number} The distance between the origin and `a`. 75 | */ 76 | Blockly.utils.Coordinate.magnitude = function(a) { 77 | return Math.sqrt(a.x * a.x + a.y * a.y); 78 | }; 79 | 80 | /** 81 | * Returns the difference between two coordinates as a new 82 | * Blockly.utils.Coordinate. 83 | * @param {!Blockly.utils.Coordinate|!SVGPoint} a An x/y coordinate. 84 | * @param {!Blockly.utils.Coordinate|!SVGPoint} b An x/y coordinate. 85 | * @return {!Blockly.utils.Coordinate} A Coordinate representing the difference 86 | * between `a` and `b`. 87 | */ 88 | Blockly.utils.Coordinate.difference = function(a, b) { 89 | return new Blockly.utils.Coordinate(a.x - b.x, a.y - b.y); 90 | }; 91 | 92 | /** 93 | * Returns the sum of two coordinates as a new Blockly.utils.Coordinate. 94 | * @param {!Blockly.utils.Coordinate|!SVGPoint} a An x/y coordinate. 95 | * @param {!Blockly.utils.Coordinate|!SVGPoint} b An x/y coordinate. 96 | * @return {!Blockly.utils.Coordinate} A Coordinate representing the sum of 97 | * the two coordinates. 98 | */ 99 | Blockly.utils.Coordinate.sum = function(a, b) { 100 | return new Blockly.utils.Coordinate(a.x + b.x, a.y + b.y); 101 | }; 102 | 103 | /** 104 | * Scales this coordinate by the given scale factor. 105 | * @param {number} s The scale factor to use for both x and y dimensions. 106 | * @return {!Blockly.utils.Coordinate} This coordinate after scaling. 107 | */ 108 | Blockly.utils.Coordinate.prototype.scale = function(s) { 109 | this.x *= s; 110 | this.y *= s; 111 | return this; 112 | }; 113 | 114 | /** 115 | * Translates this coordinate by the given offsets. 116 | * respectively. 117 | * @param {number} tx The value to translate x by. 118 | * @param {number} ty The value to translate y by. 119 | * @return {!Blockly.utils.Coordinate} This coordinate after translating. 120 | */ 121 | Blockly.utils.Coordinate.prototype.translate = function(tx, ty) { 122 | this.x += tx; 123 | this.y += ty; 124 | return this; 125 | }; 126 | -------------------------------------------------------------------------------- /web/core/utils/global.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Provides a reference to the global object. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 'use strict'; 12 | 13 | /** 14 | * @name Blockly.utils.global 15 | * @namespace 16 | */ 17 | goog.provide('Blockly.utils.global'); 18 | 19 | 20 | /** 21 | * Reference to the global object. 22 | * 23 | * More info on this implementation here: 24 | * https://docs.google.com/document/d/1NAeW4Wk7I7FV0Y2tcUFvQdGMc89k2vdgSXInw8_nvCI/edit 25 | */ 26 | Blockly.utils.global = function() { 27 | if (typeof self === 'object') { 28 | return self; 29 | } 30 | if (typeof window === 'object') { 31 | return window; 32 | } 33 | if (typeof global === 'object') { 34 | return global; 35 | } 36 | return this; 37 | }(); 38 | -------------------------------------------------------------------------------- /web/core/utils/idgenerator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Generator for unique element IDs. 9 | * For UUIDs use Blockly.utils.genUid. The ID generator should primarily be 10 | * used for IDs that end up in the DOM. 11 | * @author samelh@google.com (Sam El-Husseini) 12 | */ 13 | 'use strict'; 14 | 15 | goog.provide('Blockly.utils.IdGenerator'); 16 | 17 | 18 | /** 19 | * Next unique ID to use. 20 | * @type {number} 21 | * @private 22 | */ 23 | Blockly.utils.IdGenerator.nextId_ = 0; 24 | 25 | /** 26 | * Gets the next unique ID. 27 | * IDs are compatible with the HTML4 id attribute restrictions: 28 | * Use only ASCII letters, digits, '_', '-' and '.' 29 | * @return {string} The next unique identifier. 30 | */ 31 | Blockly.utils.IdGenerator.getNextUniqueId = function() { 32 | return 'blockly-' + (Blockly.utils.IdGenerator.nextId_++).toString(36); 33 | }; 34 | -------------------------------------------------------------------------------- /web/core/utils/math.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Utility methods for math. 9 | * These methods are not specific to Blockly, and could be factored out into 10 | * a JavaScript framework such as Closure. 11 | * @author fraser@google.com (Neil Fraser) 12 | */ 13 | 'use strict'; 14 | 15 | /** 16 | * @name Blockly.utils.math 17 | * @namespace 18 | */ 19 | goog.provide('Blockly.utils.math'); 20 | 21 | 22 | /** 23 | * Converts degrees to radians. 24 | * Copied from Closure's goog.math.toRadians. 25 | * @param {number} angleDegrees Angle in degrees. 26 | * @return {number} Angle in radians. 27 | */ 28 | Blockly.utils.math.toRadians = function(angleDegrees) { 29 | return angleDegrees * Math.PI / 180; 30 | }; 31 | 32 | /** 33 | * Converts radians to degrees. 34 | * Copied from Closure's goog.math.toDegrees. 35 | * @param {number} angleRadians Angle in radians. 36 | * @return {number} Angle in degrees. 37 | */ 38 | Blockly.utils.math.toDegrees = function(angleRadians) { 39 | return angleRadians * 180 / Math.PI; 40 | }; 41 | 42 | /** 43 | * Clamp the provided number between the lower bound and the upper bound. 44 | * @param {number} lowerBound The desired lower bound. 45 | * @param {number} number The number to clamp. 46 | * @param {number} upperBound The desired upper bound. 47 | * @return {number} The clamped number. 48 | */ 49 | Blockly.utils.math.clamp = function(lowerBound, number, upperBound) { 50 | if (upperBound < lowerBound) { 51 | var temp = upperBound; 52 | upperBound = lowerBound; 53 | lowerBound = temp; 54 | } 55 | return Math.max(lowerBound, Math.min(number, upperBound)); 56 | }; 57 | -------------------------------------------------------------------------------- /web/core/utils/metrics.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Workspace metrics definitions. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.utils.Metrics'); 14 | 15 | 16 | /** 17 | * @record 18 | */ 19 | Blockly.utils.Metrics = function() {}; 20 | 21 | /** 22 | * Height of the visible portion of the workspace. 23 | * @type {number} 24 | */ 25 | Blockly.utils.Metrics.prototype.viewHeight; 26 | 27 | /** 28 | * Width of the visible portion of the workspace. 29 | * @type {number} 30 | */ 31 | Blockly.utils.Metrics.prototype.viewWidth; 32 | 33 | /** 34 | * Height of the content. 35 | * @type {number} 36 | */ 37 | Blockly.utils.Metrics.prototype.contentHeight; 38 | 39 | /** 40 | * Width of the content. 41 | * @type {number} 42 | */ 43 | Blockly.utils.Metrics.prototype.contentWidth; 44 | 45 | /** 46 | * Top-edge of the visible portion of the workspace, relative to the workspace 47 | * origin. 48 | * @type {number} 49 | */ 50 | Blockly.utils.Metrics.prototype.viewTop; 51 | 52 | /** 53 | * Left-edge of the visible portion of the workspace, relative to the workspace 54 | * origin. 55 | * @type {number} 56 | */ 57 | Blockly.utils.Metrics.prototype.viewLeft; 58 | 59 | /** 60 | * Top-edge of the content, relative to the workspace origin. 61 | * @type {number} 62 | */ 63 | Blockly.utils.Metrics.prototype.contentTop; 64 | 65 | /** 66 | * Left-edge of the content relative to the workspace origin. 67 | * @type {number} 68 | */ 69 | Blockly.utils.Metrics.prototype.contentLeft; 70 | 71 | /** 72 | * Top-edge of the visible portion of the workspace, relative to the blocklyDiv. 73 | * @type {number} 74 | */ 75 | Blockly.utils.Metrics.prototype.absoluteTop; 76 | 77 | /** 78 | * Left-edge of the visible portion of the workspace, relative to the 79 | * blocklyDiv. 80 | * @type {number} 81 | */ 82 | Blockly.utils.Metrics.prototype.absoluteLeft; 83 | 84 | /** 85 | * Height of the Blockly div (the view + the toolbox, simple of otherwise). 86 | * @type {number|undefined} 87 | */ 88 | Blockly.utils.Metrics.prototype.svgHeight; 89 | 90 | /** 91 | * Width of the Blockly div (the view + the toolbox, simple or otherwise). 92 | * @type {number|undefined} 93 | */ 94 | Blockly.utils.Metrics.prototype.svgWidth; 95 | 96 | /** 97 | * Width of the toolbox, if it exists. Otherwise zero. 98 | * @type {number|undefined} 99 | */ 100 | Blockly.utils.Metrics.prototype.toolboxWidth; 101 | 102 | /** 103 | * Height of the toolbox, if it exists. Otherwise zero. 104 | * @type {number|undefined} 105 | */ 106 | Blockly.utils.Metrics.prototype.toolboxHeight; 107 | 108 | /** 109 | * Top, bottom, left or right. Use TOOLBOX_AT constants to compare. 110 | * @type {number|undefined} 111 | */ 112 | Blockly.utils.Metrics.prototype.toolboxPosition; 113 | 114 | /** 115 | * Width of the flyout if it is always open. Otherwise zero. 116 | * @type {number|undefined} 117 | */ 118 | Blockly.utils.Metrics.prototype.flyoutWidth; 119 | 120 | /** 121 | * Height of the flyout if it is always open. Otherwise zero. 122 | * @type {number|undefined} 123 | */ 124 | Blockly.utils.Metrics.prototype.flyoutHeight; 125 | -------------------------------------------------------------------------------- /web/core/utils/object.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Utility methods for objects. 9 | * @author samelh@google.com (Sam El-Husseini) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.utils.object'); 14 | 15 | 16 | /** 17 | * Inherit the prototype methods from one constructor into another. 18 | * 19 | * @param {!Function} childCtor Child class. 20 | * @param {!Function} parentCtor Parent class. 21 | * @suppress {strictMissingProperties} superClass_ is not defined on Function. 22 | */ 23 | Blockly.utils.object.inherits = function(childCtor, parentCtor) { 24 | childCtor.superClass_ = parentCtor.prototype; 25 | childCtor.prototype = Object.create(parentCtor.prototype); 26 | childCtor.prototype.constructor = childCtor; 27 | }; 28 | 29 | /** 30 | * Copies all the members of a source object to a target object. 31 | * @param {!Object} target Target. 32 | * @param {!Object} source Source. 33 | */ 34 | Blockly.utils.object.mixin = function(target, source) { 35 | for (var x in source) { 36 | target[x] = source[x]; 37 | } 38 | }; 39 | 40 | /** 41 | * Complete a deep merge of all members of a source object with a target object. 42 | * @param {!Object} target Target. 43 | * @param {!Object} source Source. 44 | * @return {!Object} The resulting object. 45 | */ 46 | Blockly.utils.object.deepMerge = function(target, source) { 47 | for (var x in source) { 48 | if (source[x] != null && typeof source[x] === 'object') { 49 | target[x] = Blockly.utils.object.deepMerge( 50 | target[x] || Object.create(null), source[x]); 51 | } else { 52 | target[x] = source[x]; 53 | } 54 | } 55 | return target; 56 | }; 57 | 58 | /** 59 | * Returns an array of a given object's own enumerable property values. 60 | * @param {!Object} obj Object containing values. 61 | * @return {!Array} Array of values. 62 | */ 63 | Blockly.utils.object.values = function(obj) { 64 | if (Object.values) { 65 | /* eslint-disable es5/no-es6-methods */ 66 | return Object.values(obj); 67 | /* eslint-enable es5/no-es6-methods */ 68 | } 69 | // Fallback for IE. 70 | return Object.keys(obj).map(function(e) { 71 | return obj[e]; 72 | }); 73 | }; 74 | -------------------------------------------------------------------------------- /web/core/utils/rect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Utility methods for rectangle manipulation. 9 | * These methods are not specific to Blockly, and could be factored out into 10 | * a JavaScript framework such as Closure. 11 | * @author fraser@google.com (Neil Fraser) 12 | */ 13 | 'use strict'; 14 | 15 | /** 16 | * @name Blockly.utils.Rect 17 | * @namespace 18 | */ 19 | goog.provide('Blockly.utils.Rect'); 20 | 21 | 22 | /** 23 | * Class for representing rectangular regions. 24 | * @param {number} top Top. 25 | * @param {number} bottom Bottom. 26 | * @param {number} left Left. 27 | * @param {number} right Right. 28 | * @struct 29 | * @constructor 30 | */ 31 | Blockly.utils.Rect = function(top, bottom, left, right) { 32 | /** @type {number} */ 33 | this.top = top; 34 | 35 | /** @type {number} */ 36 | this.bottom = bottom; 37 | 38 | /** @type {number} */ 39 | this.left = left; 40 | 41 | /** @type {number} */ 42 | this.right = right; 43 | }; 44 | 45 | /** 46 | * Tests whether this rectangle contains a x/y coordinate. 47 | * 48 | * @param {number} x The x coordinate to test for containment. 49 | * @param {number} y The y coordinate to test for containment. 50 | * @return {boolean} Whether this rectangle contains given coordinate. 51 | */ 52 | Blockly.utils.Rect.prototype.contains = function(x, y) { 53 | return x >= this.left && x <= this.right && y >= this.top && y <= this.bottom; 54 | }; 55 | -------------------------------------------------------------------------------- /web/core/utils/size.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Utility methods for size calculation. 9 | * These methods are not specific to Blockly, and could be factored out into 10 | * a JavaScript framework such as Closure. 11 | * @author samelh@google.com (Sam El-Husseini) 12 | */ 13 | 'use strict'; 14 | 15 | /** 16 | * @name Blockly.utils.Size 17 | * @namespace 18 | */ 19 | goog.provide('Blockly.utils.Size'); 20 | 21 | 22 | /** 23 | * Class for representing sizes consisting of a width and height. 24 | * @param {number} width Width. 25 | * @param {number} height Height. 26 | * @struct 27 | * @constructor 28 | */ 29 | Blockly.utils.Size = function(width, height) { 30 | /** 31 | * Width 32 | * @type {number} 33 | */ 34 | this.width = width; 35 | 36 | /** 37 | * Height 38 | * @type {number} 39 | */ 40 | this.height = height; 41 | }; 42 | 43 | /** 44 | * Compares sizes for equality. 45 | * @param {Blockly.utils.Size} a A Size. 46 | * @param {Blockly.utils.Size} b A Size. 47 | * @return {boolean} True iff the sizes have equal widths and equal 48 | * heights, or if both are null. 49 | */ 50 | Blockly.utils.Size.equals = function(a, b) { 51 | if (a == b) { 52 | return true; 53 | } 54 | if (!a || !b) { 55 | return false; 56 | } 57 | return a.width == b.width && a.height == b.height; 58 | }; 59 | -------------------------------------------------------------------------------- /web/core/utils/useragent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Useragent detection. 9 | * These methods are not specific to Blockly, and could be factored out into 10 | * a JavaScript framework such as Closure. 11 | * @author fraser@google.com (Neil Fraser) 12 | */ 13 | 'use strict'; 14 | 15 | /** 16 | * @name Blockly.utils.userAgent 17 | * @namespace 18 | */ 19 | goog.provide('Blockly.utils.userAgent'); 20 | 21 | goog.require('Blockly.utils.global'); 22 | 23 | /** @const {boolean} */ 24 | Blockly.utils.userAgent.IE; 25 | 26 | /** @const {boolean} */ 27 | Blockly.utils.userAgent.EDGE; 28 | 29 | /** @const {boolean} */ 30 | Blockly.utils.userAgent.JAVA_FX; 31 | 32 | /** @const {boolean} */ 33 | Blockly.utils.userAgent.CHROME; 34 | 35 | /** @const {boolean} */ 36 | Blockly.utils.userAgent.WEBKIT; 37 | 38 | /** @const {boolean} */ 39 | Blockly.utils.userAgent.GECKO; 40 | 41 | /** @const {boolean} */ 42 | Blockly.utils.userAgent.ANDROID; 43 | 44 | /** @const {boolean} */ 45 | Blockly.utils.userAgent.IPAD; 46 | 47 | /** @const {boolean} */ 48 | Blockly.utils.userAgent.IPOD; 49 | 50 | /** @const {boolean} */ 51 | Blockly.utils.userAgent.IPHONE; 52 | 53 | /** @const {boolean} */ 54 | Blockly.utils.userAgent.MAC; 55 | 56 | /** @const {boolean} */ 57 | Blockly.utils.userAgent.TABLET; 58 | 59 | /** @const {boolean} */ 60 | Blockly.utils.userAgent.MOBILE; 61 | 62 | (function(raw) { 63 | Blockly.utils.userAgent.raw = raw; 64 | var rawUpper = Blockly.utils.userAgent.raw.toUpperCase(); 65 | /** 66 | * Case-insensitive test of whether name is in the useragent string. 67 | * @param {string} name Name to test. 68 | * @return {boolean} True if name is present. 69 | */ 70 | function has(name) { 71 | return rawUpper.indexOf(name.toUpperCase()) != -1; 72 | } 73 | 74 | // Browsers. Logic from: 75 | // https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/browser.js 76 | Blockly.utils.userAgent.IE = has('Trident') || has('MSIE'); 77 | Blockly.utils.userAgent.EDGE = has('Edge'); 78 | // Useragent for JavaFX: 79 | // Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.44 80 | // (KHTML, like Gecko) JavaFX/8.0 Safari/537.44 81 | Blockly.utils.userAgent.JAVA_FX = has('JavaFX'); 82 | Blockly.utils.userAgent.CHROME = (has('Chrome') || has('CriOS')) && 83 | !Blockly.utils.userAgent.EDGE; 84 | 85 | // Engines. Logic from: 86 | // https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/engine.js 87 | Blockly.utils.userAgent.WEBKIT = has('WebKit') && 88 | !Blockly.utils.userAgent.EDGE; 89 | Blockly.utils.userAgent.GECKO = has('Gecko') && 90 | !Blockly.utils.userAgent.WEBKIT && 91 | !Blockly.utils.userAgent.IE && 92 | !Blockly.utils.userAgent.EDGE; 93 | 94 | // Platforms. Logic from: 95 | // https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/platform.js 96 | Blockly.utils.userAgent.ANDROID = has('Android'); 97 | Blockly.utils.userAgent.IPAD = has('iPad'); 98 | Blockly.utils.userAgent.IPOD = has('iPod'); 99 | Blockly.utils.userAgent.IPHONE = has('iPhone') && 100 | !Blockly.utils.userAgent.IPAD && !Blockly.utils.userAgent.IPOD; 101 | Blockly.utils.userAgent.MAC = has('Macintosh'); 102 | 103 | // Devices. Logic from: 104 | // https://github.com/google/closure-library/blob/master/closure/goog/labs/useragent/device.js 105 | Blockly.utils.userAgent.TABLET = Blockly.utils.userAgent.IPAD || 106 | (Blockly.utils.userAgent.ANDROID && !has('Mobile')) || has('Silk'); 107 | Blockly.utils.userAgent.MOBILE = !Blockly.utils.userAgent.TABLET && 108 | (Blockly.utils.userAgent.IPOD || Blockly.utils.userAgent.IPHONE || 109 | Blockly.utils.userAgent.ANDROID || has('IEMobile')); 110 | })((Blockly.utils.global.navigator && Blockly.utils.global.navigator.userAgent) || ''); 111 | -------------------------------------------------------------------------------- /web/core/utils/xml.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview XML element manipulation. 9 | * These methods are not specific to Blockly, and could be factored out into 10 | * a JavaScript framework such as Closure. 11 | * @author fraser@google.com (Neil Fraser) 12 | */ 13 | 'use strict'; 14 | 15 | /** 16 | * @name Blockly.utils.xml 17 | * @namespace 18 | */ 19 | goog.provide('Blockly.utils.xml'); 20 | 21 | /** 22 | * Namespace for Blockly's XML. 23 | */ 24 | Blockly.utils.xml.NAME_SPACE = 'https://developers.google.com/blockly/xml'; 25 | 26 | /** 27 | * Get the document object. This method is overridden in the Node.js build of 28 | * Blockly. See gulpfile.js, package-blockly-node task. 29 | * @return {!Document} The document object. 30 | * @public 31 | */ 32 | Blockly.utils.xml.document = function() { 33 | return document; 34 | }; 35 | 36 | /** 37 | * Create DOM element for XML. 38 | * @param {string} tagName Name of DOM element. 39 | * @return {!Element} New DOM element. 40 | * @public 41 | */ 42 | Blockly.utils.xml.createElement = function(tagName) { 43 | return Blockly.utils.xml.document().createElementNS( 44 | Blockly.utils.xml.NAME_SPACE, tagName); 45 | }; 46 | 47 | /** 48 | * Create text element for XML. 49 | * @param {string} text Text content. 50 | * @return {!Text} New DOM text node. 51 | * @public 52 | */ 53 | Blockly.utils.xml.createTextNode = function(text) { 54 | return Blockly.utils.xml.document().createTextNode(text); 55 | }; 56 | 57 | /** 58 | * Converts an XML string into a DOM tree. 59 | * @param {string} text XML string. 60 | * @return {Document} The DOM document. 61 | * @throws if XML doesn't parse. 62 | * @public 63 | */ 64 | Blockly.utils.xml.textToDomDocument = function(text) { 65 | var oParser = new DOMParser(); 66 | return oParser.parseFromString(text, 'text/xml'); 67 | }; 68 | 69 | /** 70 | * Converts a DOM structure into plain text. 71 | * Currently the text format is fairly ugly: all one line with no whitespace. 72 | * @param {!Node} dom A tree of XML nodes. 73 | * @return {string} Text representation. 74 | * @public 75 | */ 76 | Blockly.utils.xml.domToText = function(dom) { 77 | var oSerializer = new XMLSerializer(); 78 | return oSerializer.serializeToString(dom); 79 | }; 80 | -------------------------------------------------------------------------------- /web/core/variable_model.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2017 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Components for the variable model. 9 | * @author marisaleung@google.com (Marisa Leung) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.VariableModel'); 14 | 15 | goog.require('Blockly.Events'); 16 | goog.require('Blockly.Events.VarCreate'); 17 | goog.require('Blockly.utils'); 18 | 19 | 20 | /** 21 | * Class for a variable model. 22 | * Holds information for the variable including name, ID, and type. 23 | * @param {!Blockly.Workspace} workspace The variable's workspace. 24 | * @param {string} name The name of the variable. This must be unique across 25 | * variables and procedures. 26 | * @param {string=} opt_type The type of the variable like 'int' or 'string'. 27 | * Does not need to be unique. Field_variable can filter variables based on 28 | * their type. This will default to '' which is a specific type. 29 | * @param {string=} opt_id The unique ID of the variable. This will default to 30 | * a UUID. 31 | * @see {Blockly.FieldVariable} 32 | * @constructor 33 | */ 34 | Blockly.VariableModel = function(workspace, name, opt_type, opt_id) { 35 | /** 36 | * The workspace the variable is in. 37 | * @type {!Blockly.Workspace} 38 | */ 39 | this.workspace = workspace; 40 | 41 | /** 42 | * The name of the variable, typically defined by the user. It must be 43 | * unique across all names used for procedures and variables. It may be 44 | * changed by the user. 45 | * @type {string} 46 | */ 47 | this.name = name; 48 | 49 | /** 50 | * The type of the variable, such as 'int' or 'sound_effect'. This may be 51 | * used to build a list of variables of a specific type. By default this is 52 | * the empty string '', which is a specific type. 53 | * @see {Blockly.FieldVariable} 54 | * @type {string} 55 | */ 56 | this.type = opt_type || ''; 57 | 58 | /** 59 | * A unique id for the variable. This should be defined at creation and 60 | * not change, even if the name changes. In most cases this should be a 61 | * UUID. 62 | * @type {string} 63 | * @private 64 | */ 65 | this.id_ = opt_id || Blockly.utils.genUid(); 66 | 67 | Blockly.Events.fire(new Blockly.Events.VarCreate(this)); 68 | }; 69 | 70 | /** 71 | * @return {string} The ID for the variable. 72 | */ 73 | Blockly.VariableModel.prototype.getId = function() { 74 | return this.id_; 75 | }; 76 | 77 | /** 78 | * A custom compare function for the VariableModel objects. 79 | * @param {Blockly.VariableModel} var1 First variable to compare. 80 | * @param {Blockly.VariableModel} var2 Second variable to compare. 81 | * @return {number} -1 if name of var1 is less than name of var2, 0 if equal, 82 | * and 1 if greater. 83 | * @package 84 | */ 85 | Blockly.VariableModel.compareByName = function(var1, var2) { 86 | var name1 = var1.name.toLowerCase(); 87 | var name2 = var2.name.toLowerCase(); 88 | if (name1 < name2) { 89 | return -1; 90 | } else if (name1 == name2) { 91 | return 0; 92 | } else { 93 | return 1; 94 | } 95 | }; 96 | -------------------------------------------------------------------------------- /web/core/variables_dynamic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2017 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Utility functions for handling typed variables. 9 | * 10 | * @author duzc2dtw@gmail.com (Du Tian Wei) 11 | */ 12 | 'use strict'; 13 | 14 | goog.provide('Blockly.VariablesDynamic'); 15 | 16 | goog.require('Blockly.Variables'); 17 | goog.require('Blockly.Blocks'); 18 | goog.require('Blockly.Msg'); 19 | goog.require('Blockly.utils.xml'); 20 | goog.require('Blockly.VariableModel'); 21 | 22 | 23 | Blockly.VariablesDynamic.onCreateVariableButtonClick_String = function(button) { 24 | Blockly.Variables.createVariableButtonHandler(button.getTargetWorkspace(), 25 | undefined, 'String'); 26 | }; 27 | Blockly.VariablesDynamic.onCreateVariableButtonClick_Number = function(button) { 28 | Blockly.Variables.createVariableButtonHandler(button.getTargetWorkspace(), 29 | undefined, 'Number'); 30 | }; 31 | Blockly.VariablesDynamic.onCreateVariableButtonClick_Colour = function(button) { 32 | Blockly.Variables.createVariableButtonHandler(button.getTargetWorkspace(), 33 | undefined, 'Colour'); 34 | }; 35 | /** 36 | * Construct the elements (blocks and button) required by the flyout for the 37 | * variable category. 38 | * @param {!Blockly.Workspace} workspace The workspace containing variables. 39 | * @return {!Array.} Array of XML elements. 40 | */ 41 | Blockly.VariablesDynamic.flyoutCategory = function(workspace) { 42 | var xmlList = []; 43 | var button = document.createElement('button'); 44 | button.setAttribute('text', Blockly.Msg['NEW_STRING_VARIABLE']); 45 | button.setAttribute('callbackKey', 'CREATE_VARIABLE_STRING'); 46 | xmlList.push(button); 47 | button = document.createElement('button'); 48 | button.setAttribute('text', Blockly.Msg['NEW_NUMBER_VARIABLE']); 49 | button.setAttribute('callbackKey', 'CREATE_VARIABLE_NUMBER'); 50 | xmlList.push(button); 51 | button = document.createElement('button'); 52 | button.setAttribute('text', Blockly.Msg['NEW_COLOUR_VARIABLE']); 53 | button.setAttribute('callbackKey', 'CREATE_VARIABLE_COLOUR'); 54 | xmlList.push(button); 55 | 56 | workspace.registerButtonCallback('CREATE_VARIABLE_STRING', 57 | Blockly.VariablesDynamic.onCreateVariableButtonClick_String); 58 | workspace.registerButtonCallback('CREATE_VARIABLE_NUMBER', 59 | Blockly.VariablesDynamic.onCreateVariableButtonClick_Number); 60 | workspace.registerButtonCallback('CREATE_VARIABLE_COLOUR', 61 | Blockly.VariablesDynamic.onCreateVariableButtonClick_Colour); 62 | 63 | 64 | var blockList = Blockly.VariablesDynamic.flyoutCategoryBlocks(workspace); 65 | xmlList = xmlList.concat(blockList); 66 | return xmlList; 67 | }; 68 | 69 | /** 70 | * Construct the blocks required by the flyout for the variable category. 71 | * @param {!Blockly.Workspace} workspace The workspace containing variables. 72 | * @return {!Array.} Array of XML block elements. 73 | */ 74 | Blockly.VariablesDynamic.flyoutCategoryBlocks = function(workspace) { 75 | var variableModelList = workspace.getAllVariables(); 76 | 77 | var xmlList = []; 78 | if (variableModelList.length > 0) { 79 | if (Blockly.Blocks['variables_set_dynamic']) { 80 | var firstVariable = variableModelList[variableModelList.length - 1]; 81 | var block = Blockly.utils.xml.createElement('block'); 82 | block.setAttribute('type', 'variables_set_dynamic'); 83 | block.setAttribute('gap', 24); 84 | block.appendChild( 85 | Blockly.Variables.generateVariableFieldDom(firstVariable)); 86 | xmlList.push(block); 87 | } 88 | if (Blockly.Blocks['variables_get_dynamic']) { 89 | variableModelList.sort(Blockly.VariableModel.compareByName); 90 | for (var i = 0, variable; (variable = variableModelList[i]); i++) { 91 | var block = Blockly.utils.xml.createElement('block'); 92 | block.setAttribute('type', 'variables_get_dynamic'); 93 | block.setAttribute('gap', 8); 94 | block.appendChild(Blockly.Variables.generateVariableFieldDom(variable)); 95 | xmlList.push(block); 96 | } 97 | } 98 | } 99 | return xmlList; 100 | }; 101 | -------------------------------------------------------------------------------- /web/core/workspace_dragger.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2017 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Methods for dragging a workspace visually. 9 | * @author fenichel@google.com (Rachel Fenichel) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.WorkspaceDragger'); 14 | 15 | goog.require('Blockly.utils.Coordinate'); 16 | 17 | 18 | /** 19 | * Class for a workspace dragger. It moves the workspace around when it is 20 | * being dragged by a mouse or touch. 21 | * Note that the workspace itself manages whether or not it has a drag surface 22 | * and how to do translations based on that. This simply passes the right 23 | * commands based on events. 24 | * @param {!Blockly.WorkspaceSvg} workspace The workspace to drag. 25 | * @constructor 26 | */ 27 | Blockly.WorkspaceDragger = function(workspace) { 28 | /** 29 | * @type {!Blockly.WorkspaceSvg} 30 | * @private 31 | */ 32 | this.workspace_ = workspace; 33 | 34 | /** 35 | * The scroll position of the workspace at the beginning of the drag. 36 | * Coordinate system: pixel coordinates. 37 | * @type {!Blockly.utils.Coordinate} 38 | * @protected 39 | */ 40 | this.startScrollXY_ = new Blockly.utils.Coordinate( 41 | workspace.scrollX, workspace.scrollY); 42 | }; 43 | 44 | /** 45 | * Sever all links from this object. 46 | * @package 47 | * @suppress {checkTypes} 48 | */ 49 | Blockly.WorkspaceDragger.prototype.dispose = function() { 50 | this.workspace_ = null; 51 | }; 52 | 53 | /** 54 | * Start dragging the workspace. 55 | * @package 56 | */ 57 | Blockly.WorkspaceDragger.prototype.startDrag = function() { 58 | if (Blockly.selected) { 59 | Blockly.selected.unselect(); 60 | } 61 | this.workspace_.setupDragSurface(); 62 | }; 63 | 64 | /** 65 | * Finish dragging the workspace and put everything back where it belongs. 66 | * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has 67 | * moved from the position at the start of the drag, in pixel coordinates. 68 | * @package 69 | */ 70 | Blockly.WorkspaceDragger.prototype.endDrag = function(currentDragDeltaXY) { 71 | // Make sure everything is up to date. 72 | this.drag(currentDragDeltaXY); 73 | this.workspace_.resetDragSurface(); 74 | }; 75 | 76 | /** 77 | * Move the workspace based on the most recent mouse movements. 78 | * @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has 79 | * moved from the position at the start of the drag, in pixel coordinates. 80 | * @package 81 | */ 82 | Blockly.WorkspaceDragger.prototype.drag = function(currentDragDeltaXY) { 83 | var newXY = Blockly.utils.Coordinate.sum(this.startScrollXY_, currentDragDeltaXY); 84 | this.workspace_.scroll(newXY.x, newXY.y); 85 | }; 86 | -------------------------------------------------------------------------------- /web/core/workspace_events.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Class for a finished loading workspace event. 9 | * @author BeksOmega 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.Events.FinishedLoading'); 14 | 15 | goog.require('Blockly.Events'); 16 | goog.require('Blockly.Events.Ui'); 17 | goog.require('Blockly.utils.object'); 18 | 19 | 20 | /** 21 | * Class for a finished loading event. 22 | * Used to notify the developer when the workspace has finished loading (i.e 23 | * domToWorkspace). 24 | * Finished loading events do not record undo or redo. 25 | * @param {!Blockly.Workspace} workspace The workspace that has finished 26 | * loading. 27 | * @extends {Blockly.Events.Abstract} 28 | * @constructor 29 | */ 30 | Blockly.Events.FinishedLoading = function(workspace) { 31 | /** 32 | * The workspace identifier for this event. 33 | * @type {string} 34 | */ 35 | this.workspaceId = workspace.id; 36 | 37 | /** 38 | * The event group ID for the group this event belongs to. Groups define 39 | * events that should be treated as an single action from the user's 40 | * perspective, and should be undone together. 41 | * @type {string} 42 | */ 43 | this.group = Blockly.Events.getGroup(); 44 | 45 | // Workspace events do not undo or redo. 46 | this.recordUndo = false; 47 | }; 48 | Blockly.utils.object.inherits(Blockly.Events.FinishedLoading, 49 | Blockly.Events.Ui); 50 | 51 | /** 52 | * Type of this event. 53 | * @type {string} 54 | */ 55 | Blockly.Events.FinishedLoading.prototype.type = Blockly.Events.FINISHED_LOADING; 56 | 57 | /** 58 | * Encode the event as JSON. 59 | * @return {!Object} JSON representation. 60 | */ 61 | Blockly.Events.FinishedLoading.prototype.toJson = function() { 62 | var json = { 63 | 'type': this.type, 64 | }; 65 | if (this.group) { 66 | json['group'] = this.group; 67 | } 68 | if (this.workspaceId) { 69 | json['workspaceId'] = this.workspaceId; 70 | } 71 | return json; 72 | }; 73 | 74 | /** 75 | * Decode the JSON event. 76 | * @param {!Object} json JSON representation. 77 | */ 78 | Blockly.Events.FinishedLoading.prototype.fromJson = function(json) { 79 | this.workspaceId = json['workspaceId']; 80 | this.group = json['group']; 81 | }; 82 | -------------------------------------------------------------------------------- /web/externs/block-externs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Externs for Blockly blocks. 9 | * @externs 10 | */ 11 | 12 | goog.provide('Blockly'); 13 | goog.provide('Blockly.Blocks'); 14 | goog.provide('Blockly.Comment'); 15 | goog.provide('Blockly.FieldCheckbox'); 16 | goog.provide('Blockly.FieldColour'); 17 | goog.provide('Blockly.FieldDropdown'); 18 | goog.provide('Blockly.FieldImage'); 19 | goog.provide('Blockly.FieldLabel'); 20 | goog.provide('Blockly.FieldMultilineInput'); 21 | goog.provide('Blockly.FieldNumber'); 22 | goog.provide('Blockly.FieldTextInput'); 23 | goog.provide('Blockly.FieldVariable'); 24 | goog.provide('Blockly.Mutator'); 25 | goog.provide('Blockly.Warning'); 26 | 27 | var Blockly; -------------------------------------------------------------------------------- /web/externs/generator-externs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Externs for Blockly generators. 9 | * @externs 10 | */ 11 | 12 | goog.provide('Blockly'); 13 | goog.provide('Blockly.Generator'); 14 | goog.provide('Blockly.utils.global'); 15 | goog.provide('Blockly.utils.string'); 16 | 17 | var Blockly; 18 | -------------------------------------------------------------------------------- /web/externs/goog-externs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Externs for goog. 9 | * @externs 10 | */ 11 | 12 | /** 13 | * @type {!Object} 14 | */ 15 | var goog = {}; 16 | -------------------------------------------------------------------------------- /web/fonts/OpenDyslexic-Bold-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/fonts/OpenDyslexic-Bold-Italic.otf -------------------------------------------------------------------------------- /web/fonts/OpenDyslexic-Bold-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/fonts/OpenDyslexic-Bold-Italic.woff -------------------------------------------------------------------------------- /web/fonts/OpenDyslexic-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/fonts/OpenDyslexic-Bold.otf -------------------------------------------------------------------------------- /web/fonts/OpenDyslexic-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/fonts/OpenDyslexic-Bold.woff -------------------------------------------------------------------------------- /web/fonts/OpenDyslexic-Italic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/fonts/OpenDyslexic-Italic.otf -------------------------------------------------------------------------------- /web/fonts/OpenDyslexic-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/fonts/OpenDyslexic-Italic.woff -------------------------------------------------------------------------------- /web/fonts/OpenDyslexic-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/fonts/OpenDyslexic-Regular.otf -------------------------------------------------------------------------------- /web/fonts/OpenDyslexic-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/fonts/OpenDyslexic-Regular.woff -------------------------------------------------------------------------------- /web/generators/javascript/colour.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2012 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Generating JavaScript for colour blocks. 9 | * @author fraser@google.com (Neil Fraser) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.JavaScript.colour'); 14 | 15 | goog.require('Blockly.JavaScript'); 16 | 17 | 18 | Blockly.JavaScript['colour_picker'] = function(block) { 19 | // Colour picker. 20 | var code = Blockly.JavaScript.quote_(block.getFieldValue('COLOUR')); 21 | return [code, Blockly.JavaScript.ORDER_ATOMIC]; 22 | }; 23 | 24 | Blockly.JavaScript['colour_random'] = function(block) { 25 | // Generate a random colour. 26 | var functionName = Blockly.JavaScript.provideFunction_( 27 | 'colourRandom', 28 | ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + '() {', 29 | ' var num = Math.floor(Math.random() * Math.pow(2, 24));', 30 | ' return \'#\' + (\'00000\' + num.toString(16)).substr(-6);', 31 | '}']); 32 | var code = functionName + '()'; 33 | return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; 34 | }; 35 | 36 | Blockly.JavaScript['colour_rgb'] = function(block) { 37 | // Compose a colour from RGB components expressed as percentages. 38 | var red = Blockly.JavaScript.valueToCode(block, 'RED', 39 | Blockly.JavaScript.ORDER_COMMA) || 0; 40 | var green = Blockly.JavaScript.valueToCode(block, 'GREEN', 41 | Blockly.JavaScript.ORDER_COMMA) || 0; 42 | var blue = Blockly.JavaScript.valueToCode(block, 'BLUE', 43 | Blockly.JavaScript.ORDER_COMMA) || 0; 44 | var functionName = Blockly.JavaScript.provideFunction_( 45 | 'colourRgb', 46 | ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + 47 | '(r, g, b) {', 48 | ' r = Math.max(Math.min(Number(r), 100), 0) * 2.55;', 49 | ' g = Math.max(Math.min(Number(g), 100), 0) * 2.55;', 50 | ' b = Math.max(Math.min(Number(b), 100), 0) * 2.55;', 51 | ' r = (\'0\' + (Math.round(r) || 0).toString(16)).slice(-2);', 52 | ' g = (\'0\' + (Math.round(g) || 0).toString(16)).slice(-2);', 53 | ' b = (\'0\' + (Math.round(b) || 0).toString(16)).slice(-2);', 54 | ' return \'#\' + r + g + b;', 55 | '}']); 56 | var code = functionName + '(' + red + ', ' + green + ', ' + blue + ')'; 57 | return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; 58 | }; 59 | 60 | Blockly.JavaScript['colour_blend'] = function(block) { 61 | // Blend two colours together. 62 | var c1 = Blockly.JavaScript.valueToCode(block, 'COLOUR1', 63 | Blockly.JavaScript.ORDER_COMMA) || '\'#000000\''; 64 | var c2 = Blockly.JavaScript.valueToCode(block, 'COLOUR2', 65 | Blockly.JavaScript.ORDER_COMMA) || '\'#000000\''; 66 | var ratio = Blockly.JavaScript.valueToCode(block, 'RATIO', 67 | Blockly.JavaScript.ORDER_COMMA) || 0.5; 68 | var functionName = Blockly.JavaScript.provideFunction_( 69 | 'colourBlend', 70 | ['function ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + 71 | '(c1, c2, ratio) {', 72 | ' ratio = Math.max(Math.min(Number(ratio), 1), 0);', 73 | ' var r1 = parseInt(c1.substring(1, 3), 16);', 74 | ' var g1 = parseInt(c1.substring(3, 5), 16);', 75 | ' var b1 = parseInt(c1.substring(5, 7), 16);', 76 | ' var r2 = parseInt(c2.substring(1, 3), 16);', 77 | ' var g2 = parseInt(c2.substring(3, 5), 16);', 78 | ' var b2 = parseInt(c2.substring(5, 7), 16);', 79 | ' var r = Math.round(r1 * (1 - ratio) + r2 * ratio);', 80 | ' var g = Math.round(g1 * (1 - ratio) + g2 * ratio);', 81 | ' var b = Math.round(b1 * (1 - ratio) + b2 * ratio);', 82 | ' r = (\'0\' + (r || 0).toString(16)).slice(-2);', 83 | ' g = (\'0\' + (g || 0).toString(16)).slice(-2);', 84 | ' b = (\'0\' + (b || 0).toString(16)).slice(-2);', 85 | ' return \'#\' + r + g + b;', 86 | '}']); 87 | var code = functionName + '(' + c1 + ', ' + c2 + ', ' + ratio + ')'; 88 | return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; 89 | }; 90 | -------------------------------------------------------------------------------- /web/generators/javascript/variables.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2012 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Generating JavaScript for variable blocks. 9 | * @author fraser@google.com (Neil Fraser) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.JavaScript.variables'); 14 | 15 | goog.require('Blockly.JavaScript'); 16 | 17 | 18 | Blockly.JavaScript['variables_get'] = function(block) { 19 | // Variable getter. 20 | var code = Blockly.JavaScript.variableDB_.getName(block.getFieldValue('VAR'), 21 | Blockly.VARIABLE_CATEGORY_NAME); 22 | return [code, Blockly.JavaScript.ORDER_ATOMIC]; 23 | }; 24 | 25 | Blockly.JavaScript['variables_set'] = function(block) { 26 | // Variable setter. 27 | var argument0 = Blockly.JavaScript.valueToCode(block, 'VALUE', 28 | Blockly.JavaScript.ORDER_ASSIGNMENT) || '0'; 29 | var varName = Blockly.JavaScript.variableDB_.getName( 30 | block.getFieldValue('VAR'), Blockly.VARIABLE_CATEGORY_NAME); 31 | return varName + ' = ' + argument0 + ';\n'; 32 | }; 33 | -------------------------------------------------------------------------------- /web/generators/javascript/variables_dynamic.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Generating JavaScript for dynamic variable blocks. 9 | * @author fenichel@google.com (Rachel Fenichel) 10 | */ 11 | 'use strict'; 12 | 13 | goog.provide('Blockly.JavaScript.variablesDynamic'); 14 | 15 | goog.require('Blockly.JavaScript'); 16 | goog.require('Blockly.JavaScript.variables'); 17 | 18 | 19 | // JavaScript is dynamically typed. 20 | Blockly.JavaScript['variables_get_dynamic'] = 21 | Blockly.JavaScript['variables_get']; 22 | Blockly.JavaScript['variables_set_dynamic'] = 23 | Blockly.JavaScript['variables_set']; 24 | -------------------------------------------------------------------------------- /web/gulpfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Gulp script to build Blockly for Node & NPM. 9 | * Run this script by calling "npm install" in this directory. 10 | */ 11 | 12 | var gulp = require('gulp'); 13 | 14 | var typings = require('./scripts/gulpfiles/typings'); 15 | var buildTasks = require('./scripts/gulpfiles/build_tasks'); 16 | var packageTasks = require('./scripts/gulpfiles/package_tasks'); 17 | var gitTasks = require('./scripts/gulpfiles/git_tasks'); 18 | var licenseTasks = require('./scripts/gulpfiles/license_tasks'); 19 | 20 | module.exports = { 21 | default: buildTasks.build, 22 | build: buildTasks.build, 23 | buildCore: buildTasks.core, 24 | buildBlocks: buildTasks.blocks, 25 | buildLangfiles: buildTasks.langfiles, 26 | buildUncompressed: buildTasks.uncompressed, 27 | buildCompressed: buildTasks.compressed, 28 | buildGenerators: buildTasks.generators, 29 | gitSyncDevelop: gitTasks.syncDevelop, 30 | gitSyncMaster: gitTasks.syncMaster, 31 | gitCreateRC: gitTasks.createRC, 32 | gitPreCompile: gitTasks.preCompile, 33 | gitPostCompile: gitTasks.postCompile, 34 | gitUpdateGithubPages: gitTasks.updateGithubPages, 35 | typings: gulp.series(typings.typings, typings.msgTypings), 36 | package: packageTasks.package, 37 | checkLicenses: licenseTasks.checkLicenses 38 | }; 39 | -------------------------------------------------------------------------------- /web/i18n/dedup_json.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Consolidates duplicate key-value pairs in a JSON file. 4 | # If the same key is used with different values, no warning is given, 5 | # and there is no guarantee about which key-value pair will be output. 6 | # There is also no guarantee as to the order of the key-value pairs 7 | # output. 8 | # 9 | # Copyright 2013 Google LLC 10 | # 11 | # Licensed under the Apache License, Version 2.0 (the "License"); 12 | # you may not use this file except in compliance with the License. 13 | # You may obtain a copy of the License at 14 | # 15 | # http://www.apache.org/licenses/LICENSE-2.0 16 | # 17 | # Unless required by applicable law or agreed to in writing, software 18 | # distributed under the License is distributed on an "AS IS" BASIS, 19 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | # See the License for the specific language governing permissions and 21 | # limitations under the License. 22 | 23 | import argparse 24 | import codecs 25 | import json 26 | from common import InputError 27 | 28 | 29 | def main(): 30 | """Parses arguments and iterates over files. 31 | 32 | Raises: 33 | IOError: An I/O error occurred with an input or output file. 34 | InputError: Input JSON could not be parsed. 35 | """ 36 | 37 | # Set up argument parser. 38 | parser = argparse.ArgumentParser( 39 | description='Removes duplicate key-value pairs from JSON files.') 40 | parser.add_argument('--suffix', default='', 41 | help='optional suffix for output files; ' 42 | 'if empty, files will be changed in place') 43 | parser.add_argument('files', nargs='+', help='input files') 44 | args = parser.parse_args() 45 | 46 | # Iterate over files. 47 | for filename in args.files: 48 | # Read in json using Python libraries. This eliminates duplicates. 49 | print('Processing ' + filename + '...') 50 | try: 51 | with codecs.open(filename, 'r', 'utf-8') as infile: 52 | j = json.load(infile) 53 | except ValueError as e: 54 | print('Error reading ' + filename) 55 | raise InputError(filename, str(e)) 56 | 57 | # Built up output strings as an array to make output of delimiters easier. 58 | output = [] 59 | for key in j: 60 | if key != '@metadata': 61 | output.append('\t"' + key + '": "' + 62 | j[key].replace('\n', '\\n') + '"') 63 | 64 | # Output results. 65 | with codecs.open(filename + args.suffix, 'w', 'utf-8') as outfile: 66 | outfile.write('{\n') 67 | outfile.write(',\n'.join(output)) 68 | outfile.write('\n}\n') 69 | 70 | 71 | if __name__ == '__main__': 72 | main() 73 | -------------------------------------------------------------------------------- /web/i18n/tests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Tests of i18n scripts. 5 | # 6 | # Copyright 2013 Google LLC 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | 20 | import common 21 | import re 22 | import unittest 23 | 24 | class TestSequenceFunctions(unittest.TestCase): 25 | def test_insert_breaks(self): 26 | spaces = re.compile(r'\s+|\\n') 27 | def contains_all_chars(orig, result): 28 | return re.sub(spaces, '', orig) == re.sub(spaces, '', result) 29 | 30 | sentences = [u'Quay Pegman qua bên trái hoặc bên phải 90 độ.', 31 | u'Foo bar baz this is english that is okay bye.', 32 | u'If there is a path in the specified direction, \nthen ' + 33 | u'do some actions.', 34 | u'If there is a path in the specified direction, then do ' + 35 | u'the first block of actions. Otherwise, do the second ' + 36 | u'block of actions.'] 37 | for sentence in sentences: 38 | output = common.insert_breaks(sentence, 30, 50) 39 | self.assertTrue(contains_all_chars(sentence, output), 40 | u'Mismatch between:\n{0}\n{1}'.format( 41 | re.sub(spaces, '', sentence), 42 | re.sub(spaces, '', output))) 43 | 44 | 45 | if __name__ == '__main__': 46 | unittest.main() 47 | -------------------------------------------------------------------------------- /web/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5" 4 | }, 5 | "include": [ 6 | "core/**/**/*", 7 | "typings/blockly.d.ts" 8 | ], 9 | "exclude": [ 10 | "node_modules" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /web/media/1x1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/1x1.gif -------------------------------------------------------------------------------- /web/media/click.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/click.mp3 -------------------------------------------------------------------------------- /web/media/click.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/click.ogg -------------------------------------------------------------------------------- /web/media/click.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/click.wav -------------------------------------------------------------------------------- /web/media/delete.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/delete.mp3 -------------------------------------------------------------------------------- /web/media/delete.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/delete.ogg -------------------------------------------------------------------------------- /web/media/delete.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/delete.wav -------------------------------------------------------------------------------- /web/media/disconnect.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/disconnect.mp3 -------------------------------------------------------------------------------- /web/media/disconnect.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/disconnect.ogg -------------------------------------------------------------------------------- /web/media/disconnect.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/disconnect.wav -------------------------------------------------------------------------------- /web/media/dropdown-arrow.svg: -------------------------------------------------------------------------------- 1 | dropdown-arrow -------------------------------------------------------------------------------- /web/media/handclosed.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/handclosed.cur -------------------------------------------------------------------------------- /web/media/handdelete.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/handdelete.cur -------------------------------------------------------------------------------- /web/media/handopen.cur: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/handopen.cur -------------------------------------------------------------------------------- /web/media/pilcrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/pilcrow.png -------------------------------------------------------------------------------- /web/media/quote0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/quote0.png -------------------------------------------------------------------------------- /web/media/quote1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/quote1.png -------------------------------------------------------------------------------- /web/media/sprites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/media/sprites.png -------------------------------------------------------------------------------- /web/media/sprites.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /web/msg/json/constants.json: -------------------------------------------------------------------------------- 1 | {"MATH_HUE": "230", "LOOPS_HUE": "120", "LISTS_HUE": "260", "LOGIC_HUE": "210", "VARIABLES_HUE": "330", "TEXTS_HUE": "160", "PROCEDURES_HUE": "290", "COLOUR_HUE": "20", "VARIABLES_DYNAMIC_HUE": "310"} -------------------------------------------------------------------------------- /web/msg/json/skr-arab.json: -------------------------------------------------------------------------------- 1 | { 2 | "@metadata": { 3 | "authors": [ 4 | "Saraiki" 5 | ] 6 | }, 7 | "VARIABLES_DEFAULT_NAME": "آئٹم", 8 | "TODAY": "اڄ", 9 | "DUPLICATE_BLOCK": "ڈپلیکیٹ", 10 | "ADD_COMMENT": "تبصرہ کرو", 11 | "REMOVE_COMMENT": "رائے مٹاؤ", 12 | "EXTERNAL_INPUTS": "باہرلے انپٹ", 13 | "INLINE_INPUTS": "ان لائن ان پٹ", 14 | "DELETE_BLOCK": "بلاک مٹاؤ", 15 | "DELETE_X_BLOCKS": "%1 بلاکاں کوں مٹاؤ", 16 | "DELETE_ALL_BLOCKS": "بھلا %1 بلاکاں کوں مٹاؤں؟", 17 | "CLEAN_UP": "بلاک صاف کرو", 18 | "COLLAPSE_BLOCK": "بلا ک کٹھے کرو", 19 | "COLLAPSE_ALL": "بلاک کٹھے کرو", 20 | "EXPAND_BLOCK": "بلاک کھنڈاؤ", 21 | "EXPAND_ALL": "بلاکوں کوں کھنڈاؤ", 22 | "DISABLE_BLOCK": "بلاک ہٹاؤ", 23 | "ENABLE_BLOCK": "بلاک فعال کرو", 24 | "HELP": "مدد", 25 | "UNDO": "واپس", 26 | "REDO": "ولدا کرو", 27 | "CHANGE_VALUE_TITLE": "ویلیو تبدیل کرو:", 28 | "RENAME_VARIABLE": "متغیر دا ولدا ناں رکھو۔۔۔", 29 | "NEW_VARIABLE": "متغیر بݨاؤ۔۔۔", 30 | "NEW_VARIABLE_TITLE": "نواں متغیر ناں:", 31 | "VARIABLE_ALREADY_EXISTS": "'%1' نامی متغیر پہلے موجود ہے۔", 32 | "COLOUR_PICKER_HELPURL": "https://en.wikipedia.org/wiki/Color", 33 | "COLOUR_RANDOM_TITLE": "بنا ترتيب رنگ", 34 | "COLOUR_RGB_TITLE": "نال رن٘گ", 35 | "COLOUR_RGB_RED": "رتا", 36 | "COLOUR_RGB_GREEN": "ساوا", 37 | "COLOUR_RGB_BLUE": "نیلا", 38 | "COLOUR_BLEND_TITLE": "مرکب", 39 | "COLOUR_BLEND_COLOUR1": "رنگ 1", 40 | "COLOUR_BLEND_COLOUR2": "رنگ 2", 41 | "COLOUR_BLEND_RATIO": "نسبت", 42 | "CONTROLS_REPEAT_INPUT_DO": "کرو", 43 | "CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "تائیں دہرائے", 44 | "CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "گھیرے کنوں ٻاہر نکلݨ", 45 | "CONTROLS_IF_MSG_IF": "جے", 46 | "CONTROLS_IF_MSG_ELSEIF": "ٻیا اگر", 47 | "CONTROLS_IF_MSG_ELSE": "وکھرا", 48 | "IOS_OK": "ٹھیک ہے", 49 | "IOS_CANCEL": "منسوخ", 50 | "IOS_ERROR": "نقص", 51 | "IOS_PROCEDURES_INPUTS": "ان پٹ", 52 | "IOS_VARIABLES_ADD_VARIABLE": "+ متغیر شامل کرو", 53 | "IOS_VARIABLES_ADD_BUTTON": "شامل کرو", 54 | "IOS_VARIABLES_RENAME_BUTTON": "نواں ناں لکھو", 55 | "IOS_VARIABLES_DELETE_BUTTON": "مٹاؤ", 56 | "IOS_VARIABLES_VARIABLE_NAME": "متغیر ناں", 57 | "LOGIC_OPERATION_AND": "اتے", 58 | "LOGIC_OPERATION_OR": "یا", 59 | "LOGIC_NEGATE_TITLE": "%1 کائنی", 60 | "LOGIC_BOOLEAN_TRUE": "سچ", 61 | "LOGIC_BOOLEAN_FALSE": "غلط", 62 | "LOGIC_NULL": "کوئی وی کائنی", 63 | "LOGIC_TERNARY_CONDITION": "ٹیسٹ", 64 | "LOGIC_TERNARY_IF_TRUE": "اگر سچ ہے", 65 | "LOGIC_TERNARY_IF_FALSE": "اگر کوڑ ہے", 66 | "MATH_NUMBER_TOOLTIP": "ہک عدد", 67 | "MATH_ARITHMETIC_HELPURL": "https://en.wikipedia.org/wiki/Arithmetic", 68 | "MATH_SINGLE_OP_ROOT": "مربعی جذر", 69 | "MATH_SINGLE_OP_ABSOLUTE": "مطلق", 70 | "MATH_IS_EVEN": "جفت ہے", 71 | "MATH_IS_ODD": "طاق ہے", 72 | "MATH_IS_PRIME": "مفرد ہے", 73 | "MATH_IS_WHOLE": "مکمل ہے", 74 | "MATH_IS_POSITIVE": "مثبت ہے", 75 | "MATH_IS_NEGATIVE": "منفی ہے", 76 | "MATH_ONLIST_OPERATOR_SUM": "لسٹ دا مجموعہ", 77 | "MATH_ONLIST_OPERATOR_MIN": "لسٹ وچوں سب توں گھٹ", 78 | "MATH_ONLIST_OPERATOR_MAX": "لسٹ وچوں سب توں ودھ", 79 | "MATH_ONLIST_OPERATOR_AVERAGE": "فہرست دی اوسط", 80 | "TEXT_CREATE_JOIN_TITLE_JOIN": "شامل تھیوو", 81 | "TEXT_LENGTH_TITLE": "%1 دی لمباݨ", 82 | "TEXT_ISEMPTY_TITLE": "%1 خالی ہے", 83 | "TEXT_CHARAT_FROM_START": "# حرف گھنو", 84 | "TEXT_CHARAT_FIRST": "پہلا حرف گھنو", 85 | "TEXT_CHARAT_LAST": "چھیکڑی حرف گھنو", 86 | "TEXT_GET_SUBSTRING_INPUT_IN_TEXT": "ٹیکسٹ وچ", 87 | "TEXT_PRINT_TITLE": "%1 چھاپو", 88 | "LISTS_CREATE_EMPTY_TITLE": "خالی تندیر بݨاؤ", 89 | "LISTS_CREATE_WITH_CONTAINER_TITLE_ADD": "فہرست", 90 | "LISTS_ISEMPTY_TITLE": "%1 خالی ہے", 91 | "LISTS_INLIST": "فہرست وچ", 92 | "LISTS_GET_INDEX_GET": "گھنو", 93 | "LISTS_GET_INDEX_GET_REMOVE": "گھنو تے ہٹاؤ", 94 | "LISTS_GET_INDEX_REMOVE": "ہٹاؤ", 95 | "LISTS_GET_INDEX_FROM_END": "# چھیکڑ کنوں", 96 | "LISTS_GET_INDEX_FIRST": "پہلا", 97 | "LISTS_GET_INDEX_LAST": "چھیکڑی", 98 | "LISTS_GET_INDEX_RANDOM": "پُٹھے سِدھے", 99 | "LISTS_SET_INDEX_SET": "سیٹ", 100 | "LISTS_SET_INDEX_INSERT": "تے درج کرو", 101 | "LISTS_SET_INDEX_INPUT_TO": "بطور", 102 | "LISTS_SORT_TITLE": "سارٹ کرو%1%2%3", 103 | "LISTS_SORT_ORDER_ASCENDING": "چڑھدا ہویا", 104 | "LISTS_SORT_ORDER_DESCENDING": "لہندا ہویا", 105 | "LISTS_SORT_TYPE_NUMERIC": "عددی", 106 | "LISTS_SORT_TYPE_TEXT": "الف بے دی", 107 | "PROCEDURES_DEFNORETURN_TITLE": "کوں", 108 | "PROCEDURES_BEFORE_PARAMS": "نال:", 109 | "PROCEDURES_CALL_BEFORE_PARAMS": "نال:", 110 | "PROCEDURES_DEFRETURN_RETURN": "واپس آ ونڄو", 111 | "PROCEDURES_MUTATORARG_TITLE": "ان پُٹ ناں:" 112 | } 113 | -------------------------------------------------------------------------------- /web/msg/json/synonyms.json: -------------------------------------------------------------------------------- 1 | {"PROCEDURES_DEFRETURN_TITLE": "PROCEDURES_DEFNORETURN_TITLE", "CONTROLS_IF_IF_TITLE_IF": "CONTROLS_IF_MSG_IF", "CONTROLS_WHILEUNTIL_INPUT_DO": "CONTROLS_REPEAT_INPUT_DO", "CONTROLS_IF_MSG_THEN": "CONTROLS_REPEAT_INPUT_DO", "LISTS_GET_SUBLIST_INPUT_IN_LIST": "LISTS_INLIST", "CONTROLS_IF_ELSE_TITLE_ELSE": "CONTROLS_IF_MSG_ELSE", "PROCEDURES_DEFRETURN_PROCEDURE": "PROCEDURES_DEFNORETURN_PROCEDURE", "TEXT_CREATE_JOIN_ITEM_TITLE_ITEM": "VARIABLES_DEFAULT_NAME", "LISTS_GET_INDEX_INPUT_IN_LIST": "LISTS_INLIST", "PROCEDURES_DEFRETURN_COMMENT": "PROCEDURES_DEFNORETURN_COMMENT", "CONTROLS_IF_ELSEIF_TITLE_ELSEIF": "CONTROLS_IF_MSG_ELSEIF", "PROCEDURES_DEFRETURN_DO": "PROCEDURES_DEFNORETURN_DO", "CONTROLS_FOR_INPUT_DO": "CONTROLS_REPEAT_INPUT_DO", "LISTS_GET_INDEX_HELPURL": "LISTS_INDEX_OF_HELPURL", "LISTS_INDEX_OF_INPUT_IN_LIST": "LISTS_INLIST", "CONTROLS_FOREACH_INPUT_DO": "CONTROLS_REPEAT_INPUT_DO", "LISTS_CREATE_WITH_ITEM_TITLE": "VARIABLES_DEFAULT_NAME", "TEXT_APPEND_VARIABLE": "VARIABLES_DEFAULT_NAME", "MATH_CHANGE_TITLE_ITEM": "VARIABLES_DEFAULT_NAME", "LISTS_SET_INDEX_INPUT_IN_LIST": "LISTS_INLIST"} -------------------------------------------------------------------------------- /web/msg/json/xmf.json: -------------------------------------------------------------------------------- 1 | { 2 | "@metadata": { 3 | "authors": [ 4 | "Silovan" 5 | ] 6 | }, 7 | "VARIABLES_DEFAULT_NAME": "ელემენტი", 8 | "TODAY": "ამდღა", 9 | "DUPLICATE_BLOCK": "კოპირაფა", 10 | "ADD_COMMENT": "კომენტარიშ გეძინა", 11 | "REMOVE_COMMENT": "კომენტარიშ გოუქვაფა", 12 | "EXTERNAL_INPUTS": "გალეშე დინოხუნაფა", 13 | "INLINE_INPUTS": "დინოხოლე დინოხუნაფა", 14 | "DELETE_BLOCK": "ბლოკიშ ლასუა", 15 | "DELETE_X_BLOCKS": "%1 ბლოკიშ ლასუა", 16 | "DELETE_ALL_BLOCKS": "არძა (%1) ბლოკი ბლასათო?", 17 | "CLEAN_UP": "ბლოკეფიშ გოუქვაფა", 18 | "COLLAPSE_BLOCK": "ბლოკიშ ტყობინაფა", 19 | "COLLAPSE_ALL": "ბლოკეფიშ ინოკიჩუა", 20 | "EXPAND_BLOCK": "ბლოკიშ გჷმოფაჩუა", 21 | "EXPAND_ALL": "ბლოკეფიშ გჷმოფაჩუა", 22 | "DISABLE_BLOCK": "ბლოკიშ თიშუა", 23 | "ENABLE_BLOCK": "ბლოკიშ ჩართება", 24 | "HELP": "მოხვარა", 25 | "UNDO": "გოუქვაფა", 26 | "REDO": "ოშხონაფა", 27 | "CHANGE_VALUE_TITLE": "შანულობაშ თირუა:", 28 | "RENAME_VARIABLE": "ჯოხოშ თირუა მათირეფონი…", 29 | "RENAME_VARIABLE_TITLE": "არძა მათირეფონი '%1' ჯოხოშ თირუა -შა:", 30 | "NEW_VARIABLE": "აკოქიმინი მათირეფონი...", 31 | "NEW_VARIABLE_TITLE": "ახალი მათირეფონიშ ჯოხო:", 32 | "VARIABLE_ALREADY_EXISTS": "მათირეფონი ჯოხოთი '%1' უკვე არსენებს.", 33 | "DELETE_VARIABLE_CONFIRMATION": "'%2' მათირეფონიშ გჷმორინაფა %1 ბლასათო?", 34 | "DELETE_VARIABLE": "'%1' მათირეფონიშ ლასუა", 35 | "COLOUR_PICKER_HELPURL": "https://xmf.wikipedia.org/wiki/ფერი", 36 | "COLOUR_PICKER_TOOLTIP": "გეგშაგორით ფერი პალიტრაშე.", 37 | "COLOUR_RANDOM_TITLE": "შემთხვევითი ფერი", 38 | "COLOUR_RANDOM_TOOLTIP": "ფერიშ შემთხვევითო გიშაგორუა.", 39 | "COLOUR_RGB_TITLE": "ფერიː", 40 | "COLOUR_RGB_RED": "ჭითა", 41 | "COLOUR_RGB_GREEN": "წვანე", 42 | "COLOUR_RGB_BLUE": "ლენი", 43 | "COLOUR_RGB_TOOLTIP": "აკოქიმინით ფერი მოჩამილი ჭითა, წვანე დო ლენი ფერეფიშ პროპორციეფით. არძა შანულობა 0 დო 100 შქას ოკო რდას.", 44 | "COLOUR_BLEND_TITLE": "ესვარუა", 45 | "COLOUR_BLEND_COLOUR1": "ფერი 1", 46 | "COLOUR_BLEND_COLOUR2": "ფერი 2", 47 | "COLOUR_BLEND_RATIO": "ფერი 1-შ წილი", 48 | "COLOUR_BLEND_TOOLTIP": "ჟირ ფერს ართიანს უწყორუანს მოჩამილი ზჷმათ (0.0 - 1.0).", 49 | "CONTROLS_REPEAT_HELPURL": "https://ru.wikipedia.org/wiki/ციკლი_(პროგრამირაფა)", 50 | "CONTROLS_REPEAT_TITLE": "%1 შა გომაჟირაფა", 51 | "CONTROLS_REPEAT_INPUT_DO": "რსულება", 52 | "CONTROLS_REPEAT_TOOLTIP": "მუსხირენ ზოჯუაშ მუსხირენშა რსულება.", 53 | "CONTROLS_WHILEUNTIL_OPERATOR_WHILE": "გომაჟირაფა, სოიშახ", 54 | "CONTROLS_WHILEUNTIL_OPERATOR_UNTIL": "გომაჟირაფა, სოიშახ ვა", 55 | "CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "სოიშახ შანულობა ნანდული რე, ზოჯუეფიშ რსულება.", 56 | "CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "სოიშახ შანულობა ტყურა რე, ზოჯუეფიშ რსულება", 57 | "CONTROLS_FOR_TOOLTIP": "მათირეფონი '%1'-ის მითმურჩქინანს შანულობას მოჩამილი ბიჯგეფით დუდშე ბოლოშა დო მეწურაფილ ზოჯუეფს არსულენს.", 58 | "CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "ციკლშე გიშულა", 59 | "CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE": "ციკლიშ გეჸვენჯი ბიჯგშა გინულა", 60 | "CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK": "თე ციკლიშ მეჭყორიდუა.", 61 | "CONTROLS_FLOW_STATEMENTS_WARNING": "ხვილაფა: თე ბლოკიშ გჷმორინაფა ხვალე ციკლიშ დინოხოლე შილებე.", 62 | "CONTROLS_IF_TOOLTIP_1": "პიჯალეფი ნანდული ქორე-და, ზოჯუეფს არსულენს.", 63 | "CONTROLS_IF_MSG_IF": "თუ", 64 | "CONTROLS_IF_MSG_ELSEIF": "შხვანერო თუ", 65 | "CONTROLS_IF_MSG_ELSE": "შხვანერო", 66 | "IOS_OK": "OK", 67 | "IOS_CANCEL": "გოუქვაფა", 68 | "IOS_ERROR": "ჩილათა", 69 | "IOS_PROCEDURES_INPUTS": "მიშულა", 70 | "IOS_VARIABLES_ADD_BUTTON": "გეძინა", 71 | "IOS_VARIABLES_RENAME_BUTTON": "ჯოხოშ თირუა", 72 | "IOS_VARIABLES_DELETE_BUTTON": "ლასუა", 73 | "LOGIC_OPERATION_AND": "დო", 74 | "LOGIC_OPERATION_OR": "ვარდა", 75 | "LOGIC_BOOLEAN_TRUE": "ნანდული", 76 | "LOGIC_BOOLEAN_FALSE": "ტყურა", 77 | "LOGIC_NULL": "მუთუნ ვარი", 78 | "LOGIC_NULL_TOOLTIP": "დჷთმართინუანს მუთუნ ვარს.", 79 | "MATH_NUMBER_HELPURL": "https://xmf.wikipedia.org/wiki/რიცხუ", 80 | "MATH_NUMBER_TOOLTIP": "რიცხუ.", 81 | "MATH_ARITHMETIC_HELPURL": "https://xmf.wikipedia.org/wiki/არითმეტიკა", 82 | "MATH_SINGLE_OP_ROOT": "კვადრატული ჯინჯი", 83 | "MATH_SINGLE_OP_ABSOLUTE": "მოდული", 84 | "MATH_IS_EVEN": "ჭკობა რე", 85 | "MATH_IS_ODD": "ცანდი რე", 86 | "MATH_IS_PRIME": "უკაჭული რე", 87 | "MATH_IS_WHOLE": "ნთელი რე", 88 | "MATH_IS_POSITIVE": "დადებითი რე", 89 | "MATH_IS_NEGATIVE": "უარყოფითი რე", 90 | "LISTS_ISEMPTY_TITLE": "%1 ცარიელი რე" 91 | } 92 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blockly", 3 | "version": "3.20200625.1", 4 | "description": "Blockly is a library for building visual programming editors.", 5 | "keywords": [ 6 | "blockly" 7 | ], 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/google/blockly.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/google/blockly/issues" 14 | }, 15 | "homepage": "https://developers.google.com/blockly/", 16 | "author": { 17 | "name": "Neil Fraser" 18 | }, 19 | "scripts": { 20 | "build": "gulp build", 21 | "build:blocks": "gulp buildBlocks", 22 | "build:compressed": "gulp buildCompressed", 23 | "build:core": "gulp buildCore", 24 | "build:debug": "gulp buildCompressed --verbose --strict", 25 | "build:debug:log": "npm run build:debug > build-debug.log 2>&1 && tail -3 build-debug.log", 26 | "build:generators": "gulp buildGenerators", 27 | "build:langfiles": "gulp buildLangfiles", 28 | "build:uncompressed": "gulp buildUncompressed", 29 | "bump": "npm --no-git-tag-version version 3.$(date +'%Y%m%d').0", 30 | "license": "gulp checkLicenses", 31 | "lint": "eslint .", 32 | "package": "gulp package", 33 | "prepare": "npm run package", 34 | "recompile": "gulp gitPreCompile && npm run bump && gulp gitPostCompile", 35 | "release": "gulp gitCreateRC", 36 | "test": "concurrently 'npm run test:prepare' 'sleep 5 && npm run test:run'", 37 | "test:prepare": "npm run test:setupselenium && npm run test:startselenium", 38 | "test:run": "tests/run_all_tests.sh", 39 | "test:setupselenium": "selenium-standalone install --config=./tests/scripts/selenium-config.js", 40 | "test:startselenium": "selenium-standalone start --config=./tests/scripts/selenium-config.js", 41 | "typings": "gulp typings", 42 | "updateGithubPages": "gulp gitUpdateGithubPages" 43 | }, 44 | "main": "./index.js", 45 | "umd": "./blockly.min.js", 46 | "unpkg": "./blockly.min.js", 47 | "types": "./index.d.ts", 48 | "browser": { 49 | "./node.js": "./browser.js", 50 | "./core.js": "./core-browser.js", 51 | "./blockly-node.js": "./blockly.js" 52 | }, 53 | "license": "Apache-2.0", 54 | "devDependencies": { 55 | "chai": "^4.2.0", 56 | "concurrently": "^4.1.2", 57 | "eslint": "^5.13.0", 58 | "eslint-plugin-es5": "^1.5.0", 59 | "google-closure-compiler": "^20200101.0.0", 60 | "google-closure-deps": "^20200101.0.0", 61 | "gulp": "^4.0.2", 62 | "gulp-concat": "^2.6.1", 63 | "gulp-insert": "^0.5.0", 64 | "gulp-rename": "^1.4.0", 65 | "gulp-replace": "^1.0.0", 66 | "gulp-series": "^1.0.2", 67 | "gulp-shell": "^0.7.1", 68 | "gulp-sourcemaps": "^2.6.5", 69 | "gulp-umd": "^2.0.0", 70 | "js-green-licenses": "^1.1.0", 71 | "jshint": "^2.11.0", 72 | "mocha": "^6.2.3", 73 | "pixelmatch": "^4.0.2", 74 | "pngjs": "^3.4.0", 75 | "rimraf": "^2.6.3", 76 | "selenium-standalone": "^6.17.0", 77 | "through2": "^3.0.1", 78 | "typescript-closure-tools": "^0.0.7", 79 | "webdriverio": "^5.22.4", 80 | "yargs": "^14.2.3" 81 | }, 82 | "jshintConfig": { 83 | "globalstrict": true, 84 | "predef": [ 85 | "Blockly", 86 | "goog", 87 | "window", 88 | "document", 89 | "soy", 90 | "XMLHttpRequest" 91 | ], 92 | "sub": true, 93 | "undef": true, 94 | "unused": true 95 | }, 96 | "dependencies": { 97 | "jsdom": "^15.2.1" 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /web/package/README.md: -------------------------------------------------------------------------------- 1 | # Blockly 2 | 3 | Google's Blockly is a web-based, visual programming editor. Users can drag 4 | blocks together to build programs. All code is free and open source. 5 | 6 | The source for this module is in the [Blockly repo](http://github.com/google/blockly). 7 | 8 | ## Installation 9 | 10 | You can install this package either via ``npm`` or ``unpkg``. 11 | 12 | ### npm 13 | ```bash 14 | npm install blockly 15 | ``` 16 | 17 | ### unpkg 18 | ```html 19 | 20 | ``` 21 | 22 | ## Example Usage 23 | 24 | ```js 25 | import Blockly from 'blockly'; 26 | Blockly.inject('blocklyDiv', { 27 | ... 28 | }) 29 | ``` 30 | 31 | ## Samples 32 | 33 | For samples on how to integrate Blockly into your project, view the list of samples at [blockly-samples](https://github.com/google/blockly-samples). 34 | 35 | 36 | ### Importing Blockly 37 | 38 | When you import Blockly with ``import * as Blockly from 'blockly';`` you'll get the default modules: 39 | Blockly core, Blockly built-in blocks, the JavaScript generator and the English lang files. 40 | 41 | If you need more flexibility, you'll want to define your imports more carefully: 42 | 43 | #### Blockly Core 44 | 45 | ```js 46 | import * as Blockly from 'blockly/core'; 47 | ``` 48 | 49 | #### Blockly built in blocks 50 | 51 | ```js 52 | import 'blockly/blocks'; 53 | ``` 54 | 55 | #### Blockly Generators 56 | If your application needs to generate code from the Blockly blocks, you'll want to include a generator. 57 | 58 | ```js 59 | import 'blockly/python'; 60 | ``` 61 | to include the Python generator, you can also import ``blockly/javascript``, ``blockly/php``, ``blockly/dart`` and ``blockly/lua``. 62 | 63 | #### Blockly Languages 64 | 65 | ```js 66 | import * as Fr from 'blockly/msg/fr'; 67 | Blockly.setLocale(Fr); 68 | ``` 69 | 70 | To import the French lang files. Once you've imported the specific lang module, you'll also want to set the locale in Blockly. 71 | 72 | For a full list of supported Blockly locales, see: [https://github.com/google/blockly/tree/master/msg/js](https://github.com/google/blockly/tree/master/msg/js) 73 | 74 | 75 | ## License 76 | 77 | Apache 2.0 78 | -------------------------------------------------------------------------------- /web/package/blockly.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Blockly module. 9 | */ 10 | 11 | /* eslint-disable */ 12 | 'use strict'; 13 | -------------------------------------------------------------------------------- /web/package/blocks.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Blockly Blocks module. 9 | */ 10 | 11 | /* eslint-disable */ 12 | 'use strict'; 13 | 14 | Blockly.Blocks = {}; 15 | -------------------------------------------------------------------------------- /web/package/browser/core.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Blockly core module for the browser. It includes blockly.js 9 | * and adds a helper method for setting the locale. 10 | */ 11 | 12 | /* eslint-disable */ 13 | 'use strict'; 14 | 15 | // Add a helper method to set the Blockly locale. 16 | Blockly.setLocale = function (locale) { 17 | Blockly.Msg = Blockly.Msg || {}; 18 | Object.keys(locale).forEach(function (k) { 19 | Blockly.Msg[k] = locale[k]; 20 | }); 21 | }; 22 | -------------------------------------------------------------------------------- /web/package/browser/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Blockly module for the browser. This includes Blockly core 9 | * and built in blocks, the JavaScript code generator and the English block 10 | * localization files. 11 | */ 12 | 13 | /* eslint-disable */ 14 | 'use strict'; 15 | 16 | // Include the EN Locale by default. 17 | Blockly.setLocale(En); 18 | 19 | Blockly.Blocks = Blockly.Blocks || {}; 20 | Object.keys(BlocklyBlocks).forEach(function (k) { 21 | Blockly.Blocks[k] = BlocklyBlocks[k]; 22 | }); 23 | 24 | Blockly.JavaScript = BlocklyJS; -------------------------------------------------------------------------------- /web/package/dart.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Dart Generator module. 9 | */ 10 | 11 | /* eslint-disable */ 12 | 'use strict'; 13 | 14 | Blockly.Dart = BlocklyDart; 15 | -------------------------------------------------------------------------------- /web/package/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Blockly module. 9 | */ 10 | 11 | /* eslint-disable */ 12 | 'use strict'; -------------------------------------------------------------------------------- /web/package/javascript.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview JavaScript Generator module. 9 | */ 10 | 11 | /* eslint-disable */ 12 | 'use strict'; 13 | 14 | Blockly.JavaScript = BlocklyJavaScript; 15 | -------------------------------------------------------------------------------- /web/package/lua.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Lua Generator module. 9 | */ 10 | 11 | /* eslint-disable */ 12 | 'use strict'; 13 | 14 | Blockly.Lua = BlocklyLua; 15 | -------------------------------------------------------------------------------- /web/package/node/core.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Blockly core module for Node. It includes blockly-node.js 9 | * and adds a helper method for setting the locale. 10 | */ 11 | 12 | /* eslint-disable */ 13 | 'use strict'; 14 | 15 | // Add a helper method to set the Blockly locale. 16 | Blockly.setLocale = function (locale) { 17 | Blockly.Msg = Blockly.Msg || {}; 18 | Object.keys(locale).forEach(function (k) { 19 | Blockly.Msg[k] = locale[k]; 20 | }); 21 | }; 22 | 23 | // Override textToDomDocument and provide Node.js alternatives to DOMParser and 24 | // XMLSerializer. 25 | if (typeof Blockly.utils.global.document !== 'object') { 26 | Blockly.utils.global.DOMParser = require("jsdom/lib/jsdom/living").DOMParser; 27 | Blockly.utils.global.XMLSerializer = require("jsdom/lib/jsdom/living").XMLSerializer; 28 | var doc = Blockly.utils.xml.textToDomDocument( 29 | ''); 30 | Blockly.utils.xml.document = function() { 31 | return doc; 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /web/package/node/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Blockly module for Node. It includes Blockly core, 9 | * built-in blocks, all the generators and the English locale. 10 | */ 11 | 12 | /* eslint-disable */ 13 | 'use strict'; 14 | 15 | // Include the EN Locale by default. 16 | Blockly.setLocale(En); 17 | 18 | Blockly.Blocks = Blockly.Blocks || {}; 19 | Object.keys(BlocklyBlocks).forEach(function (k) { 20 | Blockly.Blocks[k] = BlocklyBlocks[k]; 21 | }); 22 | 23 | Blockly.JavaScript = BlocklyJS; 24 | 25 | Blockly.Python = BlocklyPython; 26 | 27 | Blockly.Lua = BlocklyLua; 28 | 29 | Blockly.PHP = BlocklyPHP; 30 | 31 | Blockly.Dart = BlocklyDart; -------------------------------------------------------------------------------- /web/package/php.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview PHP Generator module. 9 | */ 10 | 11 | /* eslint-disable */ 12 | 'use strict'; 13 | 14 | Blockly.PHP = BlocklyPHP; 15 | -------------------------------------------------------------------------------- /web/package/python.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2020 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * @fileoverview Python Generator module. 9 | */ 10 | 11 | /* eslint-disable */ 12 | 'use strict'; 13 | 14 | Blockly.Python = BlocklyPython; 15 | -------------------------------------------------------------------------------- /web/package/templates/node.template: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | (function (<%= param %>){ 3 | <%= contents %> 4 | module.exports = <%= exports %>; 5 | })(<%= cjs %>); 6 | -------------------------------------------------------------------------------- /web/package/templates/umd.template: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | ;(function(root, factory) { 3 | if (typeof define === 'function' && define.amd) { // AMD 4 | define(<%= amd %>, factory); 5 | } else if (typeof exports === 'object') { // Node.js 6 | module.exports = factory(<%= cjs %>); 7 | } else { // Browser 8 | root.<%= namespace %> = factory(<%= global %>); 9 | } 10 | }(this, function(<%= param %>) { 11 | <%= contents %> 12 | return <%= exports %>; 13 | })); 14 | -------------------------------------------------------------------------------- /web/theme_scripts/blockStyles_example.json: -------------------------------------------------------------------------------- 1 | { 2 | "colour":"#A5745B", 3 | "lists":"260", 4 | "logic":"210", 5 | "loops":"120", 6 | "math":"230", 7 | "procedure":"290", 8 | "text":"160", 9 | "variables":"310", 10 | "variables_dynamic":"310" 11 | } 12 | -------------------------------------------------------------------------------- /web/vote1/10_weather_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/10_weather_01.png -------------------------------------------------------------------------------- /web/vote1/10_weather_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/10_weather_02.png -------------------------------------------------------------------------------- /web/vote1/11_rollinit.cbs: -------------------------------------------------------------------------------- 1 | rollmessageTextrollinitiativeroll120messageText@ rolled a roll!EQroll1messageTextmessageText Critical failure! D:EQroll20messageTextmessageText Critical success! :DmessageText -------------------------------------------------------------------------------- /web/vote1/11_rollinit_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/11_rollinit_01.png -------------------------------------------------------------------------------- /web/vote1/12_passwordfinder_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/12_passwordfinder_01.png -------------------------------------------------------------------------------- /web/vote1/13_fishing_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/13_fishing_01.png -------------------------------------------------------------------------------- /web/vote1/13_fishing_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/13_fishing_02.png -------------------------------------------------------------------------------- /web/vote1/13_fishing_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/13_fishing_03.png -------------------------------------------------------------------------------- /web/vote1/13_fishing_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/13_fishing_04.png -------------------------------------------------------------------------------- /web/vote1/13_fishing_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/13_fishing_05.png -------------------------------------------------------------------------------- /web/vote1/1_superhero_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/1_superhero_01.png -------------------------------------------------------------------------------- /web/vote1/1_superhero_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/1_superhero_02.png -------------------------------------------------------------------------------- /web/vote1/2_fluffyfacts.cbs: -------------------------------------------------------------------------------- 1 | fluffyfactHey did you know... facthttps://catfact.ninja/factgeneralfluffHey did you know... texthttps://uselessfacts.jsph.pl/random.json?language=en -------------------------------------------------------------------------------- /web/vote1/2_fluffyfacts_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/2_fluffyfacts_01.png -------------------------------------------------------------------------------- /web/vote1/3_subhandler_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/3_subhandler_01.png -------------------------------------------------------------------------------- /web/vote1/4_speciesspotlight_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/4_speciesspotlight_01.png -------------------------------------------------------------------------------- /web/vote1/5_inspireme.cbs: -------------------------------------------------------------------------------- 1 | quoteDataquotequoteAuthorquoteTextinspireme1quoteDatahttps://type.fit/api/quotesquoteGETFIRSTquoteDataquoteGETRANDOMquotequotequoteAuthorauthorquotequoteTexttextquote"quoteText" -quoteAuthor -------------------------------------------------------------------------------- /web/vote1/5_inspireme_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/5_inspireme_01.png -------------------------------------------------------------------------------- /web/vote1/6_trackthor_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/6_trackthor_01.png -------------------------------------------------------------------------------- /web/vote1/6_trackthor_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/6_trackthor_02.png -------------------------------------------------------------------------------- /web/vote1/6_trackthor_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/6_trackthor_03.png -------------------------------------------------------------------------------- /web/vote1/7_localdroptracker_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/7_localdroptracker_01.png -------------------------------------------------------------------------------- /web/vote1/8_gilokk0_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/8_gilokk0_01.png -------------------------------------------------------------------------------- /web/vote1/9_smile.cbs: -------------------------------------------------------------------------------- 1 | complimentThis is a chat command for !hellosmile1 You are GETRANDOMcomplimentcomplimentSPLITbeautiful,wonderful,clever,smart,funny,witty,intelligent,amazing,courageous,a shining star,priceless,a smart cookie,stylish,a beautiful rainbow unicorn,a great listener, -------------------------------------------------------------------------------- /web/vote1/9_smile_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote1/9_smile_01.jpg -------------------------------------------------------------------------------- /web/vote2/1_quest_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/1_quest_01.png -------------------------------------------------------------------------------- /web/vote2/2_mathlete_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/2_mathlete_01.png -------------------------------------------------------------------------------- /web/vote2/2_mathlete_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/2_mathlete_02.png -------------------------------------------------------------------------------- /web/vote2/3_windwaker_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/3_windwaker_01.png -------------------------------------------------------------------------------- /web/vote2/4_cleanbot_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/4_cleanbot_01.jpg -------------------------------------------------------------------------------- /web/vote2/4_cleanbot_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/4_cleanbot_02.jpg -------------------------------------------------------------------------------- /web/vote2/5_funtranslations_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/5_funtranslations_01.png -------------------------------------------------------------------------------- /web/vote2/6_counter.cbs: -------------------------------------------------------------------------------- 1 | counturlcounterMon repositorycounturlInsert URL for a JSON bin here. I used npoint.io 2 | If you've never used npoint.io do not log in when you make your storage bin or it won't work! 3 | InformaTheMusic helped me figure that out! :) 4 | It should look like this: https://api.npoint.io/stringoflettersandnumbers 5 | The original counter was made for EveryDayGamerM!countercounturlcounter0.5ADD1countercounter1countercounterCounter message here! countercountercounturlcounter -------------------------------------------------------------------------------- /web/vote2/6_counter_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/6_counter_01.png -------------------------------------------------------------------------------- /web/vote2/6_counter_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/6_counter_02.png -------------------------------------------------------------------------------- /web/vote2/7_fishing_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/7_fishing_01.png -------------------------------------------------------------------------------- /web/vote2/8_eventtts_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/8_eventtts_01.png -------------------------------------------------------------------------------- /web/vote2/9_cbwinodds_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote2/9_cbwinodds_01.png -------------------------------------------------------------------------------- /web/vote3/1_pokeball_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/1_pokeball_01.png -------------------------------------------------------------------------------- /web/vote3/1_pokeball_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/1_pokeball_02.png -------------------------------------------------------------------------------- /web/vote3/2_bean_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/2_bean_01.jpg -------------------------------------------------------------------------------- /web/vote3/3_cooldown_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/3_cooldown_01.png -------------------------------------------------------------------------------- /web/vote3/3_cooldown_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/3_cooldown_02.png -------------------------------------------------------------------------------- /web/vote3/4_questions.cbs: -------------------------------------------------------------------------------- 1 | list900GETRANDOMlistlistSPLITWhat do you like daydreaming about?;What have your friends been up to?;What's a memory that makes you happy?;What do you look forward to when you wake up?;You're at the beach. What's the first thing you do?;How do you show people you care?;If you could give $100 to a charity, which would you choose?;How would you design a treehouse?;If you wrote a book, what would it be about?;If you designed clothes, what would they look like?;How do you best like helping others?;What makes you feel thankful?;If you made a cave in the woods, what would be inside it?;What makes you feel energized?;If you were in a play, what would your character be like?;What makes you so awesome?;If you had friends all over the world, how would you keep in touch?;If you joined the circus, what would your circus act be?;If you were a teacher and could teach your students anything at all, what would you teach them?; -------------------------------------------------------------------------------- /web/vote3/4_questions_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/4_questions_01.png -------------------------------------------------------------------------------- /web/vote3/4_questions_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/4_questions_02.jpg -------------------------------------------------------------------------------- /web/vote3/5_sketch_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/5_sketch_01.png -------------------------------------------------------------------------------- /web/vote3/6_username_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/6_username_01.png -------------------------------------------------------------------------------- /web/vote3/7_wiki_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/7_wiki_01.png -------------------------------------------------------------------------------- /web/vote3/8_stretch.cbs: -------------------------------------------------------------------------------- 1 | Put your time here! 3600= one hour, 1800 = half an hour, etc.360080Insert a URL to a sound of your choice here. If you hold the copyright to the sound you can use Vocaroo. The link will look like: https://media1.vocaroo.com/mp3/[lettersandnumbers]Time to stretch! Get up! Take a break! -------------------------------------------------------------------------------- /web/vote3/8_stretch_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/8_stretch_01.png -------------------------------------------------------------------------------- /web/vote3/8_stretch_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instafluff/ChatBlocks/f01623c13f8e37c3678cdbeb549fedd9b57b3fd8/web/vote3/8_stretch_02.png --------------------------------------------------------------------------------