a4eefac1 by guyan

init; finish basic css for field_icon_drop_down

1 parent 92f1bd6e
Showing 326 changed files with 4931 additions and 0 deletions
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
*_compressed*.js
*_uncompressed*.js
/msg/*
/core/css.js
/i18n/*
/tests/jsunit/*
/tests/workspace_svg/*
/tests/blocks/*
/demos/*
/accessible/*
/appengine/*
/shim/*
/dist/*
/gh-pages/*
/webpack.config.js
/build/*
{
"rules": {
"curly": ["error", "multi-line"],
"eol-last": ["error"],
"indent": [
"error", 2, # Blockly/Google use 2-space indents
# Blockly/Google uses +4 space indents for line continuations.
{
"SwitchCase": 1,
"MemberExpression": 2,
"ObjectExpression": 1,
"FunctionDeclaration": {
"body": 1,
"parameters": 2
},
"FunctionExpression": {
"body": 1,
"parameters": 2
},
"CallExpression": {
"arguments": 2
},
# Ignore default rules for ternary expressions.
"ignoredNodes": ["ConditionalExpression"]
}
],
"linebreak-style": ["error", "unix"],
"max-len": ["error", 120, 4],
"no-trailing-spaces": ["error", { "skipBlankLines": true }],
"no-unused-vars": [
"error",
{
"args": "after-used",
# Ignore vars starting with an underscore.
"varsIgnorePattern": "^_",
# Ignore arguments starting with an underscore.
"argsIgnorePattern": "^_"
}
],
"no-use-before-define": ["error"],
"quotes": ["off"], # Blockly mixes single and double quotes
"semi": ["error", "always"],
"space-before-function-paren": ["error", "never"], # Blockly doesn't have space before function paren
"space-infix-ops": ["error"],
"strict": ["off"], # Blockly uses 'use strict' in files
"no-cond-assign": ["off"], # Blockly often uses cond-assignment in loops
"no-redeclare": ["off"], # Closure style allows redeclarations
"valid-jsdoc": ["error", {"requireReturn": false}],
"no-console": ["off"],
"no-constant-condition": ["off"]
},
"env": {
"browser": true
},
"globals": {
"Blockly": true, # Blockly global
"goog": true, # goog closure libraries/includes
},
"extends": "eslint:recommended"
}
## Contributing
The development of Scratch is an ongoing process, and we love to have people in the Scratch and open source communities help us along the way.
### Ways to Help
* **Documenting bugs**
* If you've identified a bug in Scratch you should first check to see if it's been filed as an issue, if not you can file one. Make sure you follow the issue template.
* It's important that we can consistently reproduce issues. When writing an issue, be sure to follow our [reproduction step guidelines](https://github.com/LLK/scratch-gui/wiki/Writing-good-repro-steps).
* Some issues are marked "Needs Repro". Adding a comment with good reproduction steps to those issues is a great way to help.
* If you don't have an issue in mind already, you can look through the [Bugs & Glitches forum.](https://scratch.mit.edu/discuss/3/) Look for users reporting problems, reproduce the problem yourself, and file new issues following our guidelines.
* **Fixing bugs**
* You can request to fix a bug in a comment on the issue if you at mention the repo coordinator, who for this repo is @ericrosenbaum.
* If the issue is marked "Help Wanted" you can go ahead and start working on it!
* **We will only accept Pull Requests for bugs that have an issue filed that has a priority label**
* If you're interested in fixing a bug with no issue, file the issue first and wait for it to have a priority added to it.
* We are not looking for Pull Requests ("PR") for every issue and may deny a PR if it doesn't fit our criteria.
* We are far more likely to accept a PR if it is for an issue marked with Help Wanted.
* We will not accept PRs for issues marked with "Needs Discussion" or "Needs Design."
* Wait until the Repo Coordinator assigns the issue to you before you begin work or submit a PR.
### Learning Git and Github
If you want to work on fixing issues, you should be familiar with Git and Github.
* [Learn Git branching](https://learngitbranching.js.org/) includes an introduction to basic git commands and useful branching features.
* Here's a general introduction to [contributing to an open source project](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github).
**Important:** we follow the [Github Flow process](https://guides.github.com/introduction/flow/) as our development process.
### How to Fix Bugs
1. Identify which Github issue you are working on. Leave a comment on the issue to let us (and other contributors) know you're working on it.
2. Make sure you have a fork of this repo (see [Github's forking a repo](https://help.github.com/en/github/getting-started-with-github/fork-a-repo) for details)
3. Switch to the `develop` branch, and pull down the latest changes from upstream
4. Run the code, and reproduce the problem
5. Create your branch from the `develop` branch
6. Make code changes to fix the problem
7. Run `npm test` to make sure that your changes pass our tests
8. Commit your changes
9. Push your branch to your fork
10. Create your pull request
1. Make sure to follow the template in the PR description
1. Remember to check the “[Allow edits from maintainers](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork)” box
When submitting pull requests keep in mind:
* please be patient -- it can take a while to find time to review them
* try to change the least amount of code necessary to fix the bug
* the code can't be radically changed without significant coordination with the Scratch Team, so these types of changes should be avoided
* if you find yourself changing a substantial amount of code or considering radical changes, please ask for clarification -- we may have envisioned a different approach, or underestimated the amount of effort
### Suggestions
![Block sketch](https://user-images.githubusercontent.com/3431616/77192550-1dcebe00-6ab3-11ea-9606-8ecd8500c958.png)
Please note: **_we are unlikely to accept PRs with new features that haven't been thought through and discussed as a group_**.
Why? Because we have a strong belief in the value of keeping things simple for new users. It's been said that the Scratch Team spends about one hour of design discussion for every pixel in Scratch. To learn more about our design philosophy, see [the Scratch Developers page](https://scratch.mit.edu/developers), or [this paper](http://web.media.mit.edu/~mres/papers/Scratch-CACM-final.pdf).
We welcome suggestions! If you want to suggest a feature, please post in our [suggestions forum](https://scratch.mit.edu/discuss/1/). Your suggestion will be helped if you include a mockup design; this can be simple, even hand-drawn.
### Other resources
Beyond this repo, there are also some other resources that you might want to take a look at:
* [Community Guidelines](https://github.com/LLK/scratch-www/wiki/Community-Guidelines) (we find it important to maintain a constructive and welcoming community, just like on Scratch)
* [Open Source forum](https://scratch.mit.edu/discuss/49/) on Scratch
* [Suggestions forum](https://scratch.mit.edu/discuss/1/) on Scratch
* [Bugs & Glitches forum](https://scratch.mit.edu/discuss/3/) on Scratch
### Expected Behavior
_Please describe what should happen_
### Actual Behavior
_Describe what actually happens_
### Steps to Reproduce
_Explain what someone needs to do in order to see what's described in *Actual behavior* above_
### Operating System and Browser
_e.g. Mac OS 10.11.6 Safari 10.0_
### Resolves
_What Github issue does this resolve (please include link)?_
### Proposed Changes
_Describe what this Pull Request does_
### Reason for Changes
_Explain why these changes should be made_
### Test Coverage
_Please show how you have added tests to cover your changes_
name: Publish Npm Package
on:
push:
branches: [ main ]
paths-ignore:
- 'README.md'
- '.github/*'
jobs:
check:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Set up Python 2.7
run: |
sudo apt-get update
sudo apt-get install -y \
python2.7 python2.7-dev python2-pip-whl
sudo ln -sf python2.7 /usr/bin/python
export PYTHONPATH=`echo /usr/share/python-wheels/pip-*py2*.whl`
sudo --preserve-env=PYTHONPATH python -m pip install --upgrade pip setuptools wheel
sudo chown -R $USER /usr/local/lib/python2.7
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- run: npm ci
- name: Set test env
run: |
CHROME_VERSION=$(google-chrome --version | grep -oP '\d+\.\d+\.\d+')
CHROME_MAJOR_VERSION=$(echo $CHROME_VERSION | cut -d '.' -f 1)
npm install --save-dev chromedriver@$CHROME_MAJOR_VERSION
export DISPLAY=:99.0
tests/scripts/setup_linux_env.sh
sleep 2
- run: npm test
publish:
needs: check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14.x'
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Set up Python 2.7
run: |
sudo apt-get update
sudo apt-get install -y \
python2.7 python2.7-dev python2-pip-whl
sudo ln -sf python2.7 /usr/bin/python
export PYTHONPATH=`echo /usr/share/python-wheels/pip-*py2*.whl`
sudo --preserve-env=PYTHONPATH python -m pip install --upgrade pip setuptools wheel
sudo chown -R $USER /usr/local/lib/python2.7
- run: npm ci
- name: Update openblock-l10n
run: npm i --save openblock-l10n@latest
# Don't push translations to TX, just pull, The push step will be run by the distro repository.
# - name: Sync translations
# run: |
# export TX_TOKEN=${{ secrets.TX_TOKEN }}
# npm run translate
# npm run translate:update
- name: Pull translations
run: |
export TX_TOKEN=${{ secrets.TX_TOKEN }}
npm run translate
npm run translate:sync:translations
- name: Set test env
run: |
CHROME_VERSION=$(google-chrome --version | grep -oP '\d+\.\d+\.\d+')
CHROME_MAJOR_VERSION=$(echo $CHROME_VERSION | cut -d '.' -f 1)
npm install --save-dev chromedriver@$CHROME_MAJOR_VERSION
export DISPLAY=:99.0
tests/scripts/setup_linux_env.sh
sleep 2
- run: npm test
- name: Check for modified files
id: git-check
# Check if there are any files update, but ignore the case where only package-lock.json is updated.
run: |
echo ::set-output name=modified::$(if [ -n "$(git status --porcelain)" ] && [ "$(git status --porcelain)" != " M package-lock.json" ]; then echo "true"; else echo "false"; fi)
- name: Commit translations
if: ${{ steps.git-check.outputs.modified == 'true' }}
run: |
git config --global user.name github-actions
git config --global user.email github-actions@github.com
git add .
git commit -m '[skip ci] Update translations from transifex'
git remote add origin-translation https://x-access-token:${{ secrets.GH_TOKEN }}@github.com/$GITHUB_REPOSITORY
git push --set-upstream origin-translation main
- name: Get package main version
id: package-version
uses: martinbeentjes/npm-get-version-action@v1.1.0
- name: Generate release version
run: |
echo "RELEASE_VERSION=${{ steps.package-version.outputs.current-version }}-prerelease.$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
- name: Set package version
run: npm --no-git-tag-version version $RELEASE_VERSION
- name: Tag release
run: |
git tag $RELEASE_VERSION
git push https://x-access-token:${{ secrets.GH_TOKEN }}@github.com/$GITHUB_REPOSITORY $RELEASE_VERSION
- name: Deploy with gh-pages
run: |
git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
git apply gh-pages/patch
npm run prepublish
npm run deploy -- -u "github-actions-bot <support+actions@github.com>"
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
- uses: JS-DevTools/npm-publish@v1
with:
token: ${{ secrets.NPM_TOKEN }}
name: Pull Request Check
on:
pull_request:
branches: [ main ]
paths-ignore:
- 'README.md'
jobs:
check:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Set up Python 2.7
run: |
sudo apt-get update
sudo apt-get install -y \
python2.7 python2.7-dev python2-pip-whl
sudo ln -sf python2.7 /usr/bin/python
export PYTHONPATH=`echo /usr/share/python-wheels/pip-*py2*.whl`
sudo --preserve-env=PYTHONPATH python -m pip install --upgrade pip setuptools wheel
sudo chown -R $USER /usr/local/lib/python2.7
- name: Set test env
run: |
CHROME_VERSION=$(google-chrome --version | grep -oP '\d+\.\d+\.\d+')
CHROME_MAJOR_VERSION=$(echo $CHROME_VERSION | cut -d '.' -f 1)
npm install --save-dev chromedriver@$CHROME_MAJOR_VERSION
export DISPLAY=:99.0
tests/scripts/setup_linux_env.sh
sleep 2
- run: npm ci
- run: npm test
name: Weekly Update Translations
on:
schedule:
- cron: '0 1 * * 1,4' # Runs at 01:00 UTC on Monday and Thursday
jobs:
weekly-update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14.x'
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Set up Python 2.7
run: |
sudo apt-get update
sudo apt-get install -y \
python2.7 python2.7-dev python2-pip-whl
sudo ln -sf python2.7 /usr/bin/python
export PYTHONPATH=`echo /usr/share/python-wheels/pip-*py2*.whl`
sudo --preserve-env=PYTHONPATH python -m pip install --upgrade pip setuptools wheel
sudo chown -R $USER /usr/local/lib/python2.7
- run: npm ci
- name: Update openblock-l10n
run: npm i --save openblock-l10n@latest
# Don't push translations to TX, just pull, The push step will be run by the enterprise edition repository.
# - name: Sync translations
# run: |
# export TX_TOKEN=${{ secrets.TX_TOKEN }}
# npm run translate
# npm run translate:update
- name: Pull translations
run: |
export TX_TOKEN=${{ secrets.TX_TOKEN }}
npm run translate
npm run translate:sync:translations
- name: Check for modified files
id: git-check
# Check if there are any files update, but ignore the case where only package-lock.json is updated.
run: |
echo ::set-output name=modified::$(if [ -n "$(git status --porcelain)" ] && [ "$(git status --porcelain)" != " M package-lock.json" ]; then echo "true"; else echo "false"; fi)
- name: Set test env
if: ${{ steps.git-check.outputs.modified == 'true' }}
run: |
CHROME_VERSION=$(google-chrome --version | grep -oP '\d+\.\d+\.\d+')
CHROME_MAJOR_VERSION=$(echo $CHROME_VERSION | cut -d '.' -f 1)
npm install --save-dev chromedriver@$CHROME_MAJOR_VERSION
export DISPLAY=:99.0
tests/scripts/setup_linux_env.sh
sleep 2
- run: npm test
if: ${{ steps.git-check.outputs.modified == 'true' }}
- name: Update translations changes in GitHub repository
if: ${{ steps.git-check.outputs.modified == 'true' }}
id: git-push
run: |
git config --global user.name github-actions
git config --global user.email github-actions@github.com
git add .
git commit -m '[skip ci] Update translations from transifex'
git remote add origin-translation https://x-access-token:${{ secrets.GH_TOKEN }}@github.com/$GITHUB_REPOSITORY
git push --set-upstream origin-translation main
- name: Get package main version
if: ${{ steps.git-check.outputs.modified == 'true' }}
id: package-version
uses: martinbeentjes/npm-get-version-action@v1.1.0
- name: Generate release version
if: ${{ steps.git-check.outputs.modified == 'true' }}
run: |
echo "RELEASE_VERSION=${{ steps.package-version.outputs.current-version }}-prerelease.$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
- name: Set package version
if: ${{ steps.git-check.outputs.modified == 'true' }}
run: npm --no-git-tag-version version $RELEASE_VERSION
- name: Tag release
if: ${{ steps.git-check.outputs.modified == 'true' }}
run: |
git tag $RELEASE_VERSION
git push https://x-access-token:${{ secrets.GH_TOKEN }}@github.com/$GITHUB_REPOSITORY $RELEASE_VERSION
- uses: JS-DevTools/npm-publish@v1
if: ${{ steps.git-check.outputs.modified == 'true' }}
with:
token: ${{ secrets.NPM_TOKEN }}
# OSX
.DS_Store
# NPM
/node_modules
npm-*
# Localization / I18N
common.pyc
.settings
.project
*.pyc
*.komodoproject
/nbproject/private/
# Unused by openblock-blocks
arduino_compressed.js
dart_compressed.js
javascript_compressed.js
lua_compressed.js
php_compressed.js
python_compressed.js
# Editor
.vscode
# Chromedriver
LICENSE.chromedriver
/accessible/*
/dist
/msg/js/*
!/msg/js/en.js
/msg/json/*
!/msg/json/en.json
/blockly_compressed_horizontal.js
/blockly_compressed_vertical.js
/blockly_uncompressed_horizontal.js
/blockly_uncompressed_vertical.js
/blocks_compressed_horizontal.js
/blocks_compressed_vertical.js
/blocks_compressed.js
/gh-pages/main.js
/gh-pages/playgrounds
/gh-pages/Gemfile.lock
/gh-pages/closure-library
/gh-pages/_site
/*compiler*.jar
/local_blockly_compressed_vertical.js
/chromedriver
# Development files
.eslintrc
/.editorconfig
/.eslintignore
/.gitattributes
/.github
/.travis.yml
/.tx
/tests
/webpack.config.js
# Localization / I18N
common.pyc
.settings
.project
*.pyc
*.komodoproject
/nbproject/private/
/accessible/*
# Build created files
/gh-pages
# Chromedriver
/LICENSE.chromedriver
# Exclude already built packages from testing with npm pack
/openblock-blocks-*.{tar,tgz}
registry=https://registry.npmjs.org/
[main]
host = https://www.transifex.com
lang_map = zh_CN:zh-cn, zh_TW:zh-tw, pt_BR:pt-br, es_419:es-419
[openblock-editor.blocks]
file_filter = msg/json/<lang>.json
source_file = msg/json/en.json
source_lang = en
type = KEYVALUEJSON
Apache License
Version 2.0, January 2011
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
The Scratch trademarks, including the Scratch name, logo, the Scratch Cat, Gobo, Pico, Nano, Tera and Giga graphics (the "Marks"), are property of the Massachusetts Institute of Technology (MIT). Marks may not be used to endorse or promote products derived from this software without specific prior written permission.
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Colour blocks for Blockly.
* @author fraser@google.com (Neil Fraser)
*/
'use strict';
goog.provide('Blockly.Blocks.colour');
goog.require('Blockly.Blocks');
goog.require('Blockly.constants');
/**
* Pick a random colour.
* @return {string} #RRGGBB for random colour.
*/
function randomColour() {
var num = Math.floor(Math.random() * Math.pow(2, 24));
return '#' + ('00000' + num.toString(16)).substr(-6);
}
Blockly.Blocks['colour_picker'] = {
/**
* Block for colour picker.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_colour_slider",
"name": "COLOUR",
"colour": randomColour()
}
],
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"output": "Colour"
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Math blocks for Blockly.
* @author q.neutron@gmail.com (Quynh Neutron)
*/
'use strict';
goog.provide('Blockly.Blocks.math');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
goog.require('Blockly.constants');
Blockly.Blocks['math_number'] = {
/**
* Block for generic numeric value.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_number",
"name": "NUM",
"value": "0"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_integer'] = {
/**
* Block for integer value (no decimal, + or -).
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_number",
"name": "NUM",
"precision": 1
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_whole_number'] = {
/**
* Block for whole number value, no negatives or decimals.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_number",
"name": "NUM",
"min": 0,
"precision": 1
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_positive_number'] = {
/**
* Block for positive number value, with decimal.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_number",
"name": "NUM",
"min": 0
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_angle'] = {
/**
* Block for angle picker.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_angle",
"name": "NUM",
"value": 90
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Matrix blocks for Blockly.
* @author khanning@gmail.com (Kreg Hanning)
*/
'use strict';
goog.provide('Blockly.Blocks.matrix');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
goog.require('Blockly.constants');
Blockly.Blocks['matrix'] = {
/**
* Block for matrix value.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_matrix",
"name": "MATRIX",
"width": 5,
"height": 5
}
],
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"output": "Number",
"extensions": ["colours_pen"]
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Note block.
* @author ericr@media.mit.edu (Eric Rosenbaum)
*/
'use strict';
goog.provide('Blockly.Blocks.note');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
goog.require('Blockly.constants');
Blockly.Blocks['note'] = {
/**
* Block for musical note value.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_note",
"name": "NOTE",
"value": 60
}
],
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"output": "Number",
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Text blocks for Blockly.
* @author fraser@google.com (Neil Fraser)
*/
'use strict';
goog.provide('Blockly.Blocks.texts');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
goog.require('Blockly.constants');
Blockly.Blocks['text'] = {
/**
* Block for text value.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_input",
"name": "TEXT"
}
],
"output": "String",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
--compilation_level SIMPLE build\\gen_blocks.js blocks_vertical\\control.js blocks_vertical\\data.js blocks_vertical\\default_toolbox.js blocks_vertical\\device.js blocks_vertical\\event.js blocks_vertical\\extensions.js blocks_vertical\\looks.js blocks_vertical\\motion.js blocks_vertical\\operators.js blocks_vertical\\procedures.js blocks_vertical\\sensing.js blocks_vertical\\sound.js blocks_vertical\\stdint.js blocks_vertical\\vertical_extensions.js core\\colours.js core\\constants.js
\ No newline at end of file
/**
* @license
* Visual Blocks Editor
*
* Copyright 2016 Massachusetts Institute of Technology
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Control blocks for Scratch (Horizontal)
* @author ascii@media.mit.edu <Andrew Sliwinski>
*/
'use strict';
goog.provide('Blockly.Blocks.control');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
Blockly.Blocks['control_repeat'] = {
/**
* Block for repeat n times (external number).
* https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#so57n9
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "control_repeat",
"message0": "%1 %2 %3",
"args0": [
{
"type": "input_statement",
"name": "SUBSTACK"
},
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_repeat.svg",
"width": 40,
"height": 40,
"alt": "*",
"flip_rtl": true
},
{
"type": "input_value",
"name": "TIMES",
"check": "Number"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"category": Blockly.Categories.control,
"colour": Blockly.Colours.control.primary,
"colourSecondary": Blockly.Colours.control.secondary,
"colourTertiary": Blockly.Colours.control.tertiary
});
}
};
Blockly.Blocks['control_forever'] = {
/**
* Block for repeat n times (external number).
* https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#5eke39
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "control_forever",
"message0": "%1 %2",
"args0": [
{
"type": "input_statement",
"name": "SUBSTACK"
},
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_forever.svg",
"width": 40,
"height": 40,
"alt": "*",
"flip_rtl": true
}
],
"inputsInline": true,
"previousStatement": null,
"category": Blockly.Categories.control,
"colour": Blockly.Colours.control.primary,
"colourSecondary": Blockly.Colours.control.secondary,
"colourTertiary": Blockly.Colours.control.tertiary
});
}
};
Blockly.Blocks['control_repeat'] = {
/**
* Block for repeat n times (external number).
* https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#so57n9
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "control_repeat",
"message0": "%1 %2 %3",
"args0": [
{
"type": "input_statement",
"name": "SUBSTACK"
},
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_repeat.svg",
"width": 40,
"height": 40,
"alt": "*",
"flip_rtl": true
},
{
"type": "input_value",
"name": "TIMES",
"check": "Number"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"category": Blockly.Categories.control,
"colour": Blockly.Colours.control.primary,
"colourSecondary": Blockly.Colours.control.secondary,
"colourTertiary": Blockly.Colours.control.tertiary
});
}
};
Blockly.Blocks['control_stop'] = {
/**
* Block for stop all scripts.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "control_stop",
"message0": "%1",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_stop.svg",
"width": 40,
"height": 40,
"alt": "Stop"
}
],
"inputsInline": true,
"previousStatement": null,
"category": Blockly.Categories.control,
"colour": Blockly.Colours.control.primary,
"colourSecondary": Blockly.Colours.control.secondary,
"colourTertiary": Blockly.Colours.control.tertiary
});
}
};
Blockly.Blocks['control_wait'] = {
/**
* Block to wait (pause) stack.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "control_wait",
"message0": "%1 %2",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "icons/control_wait.svg",
"width": 40,
"height": 40,
"alt": "Wait"
},
{
"type": "input_value",
"name": "DURATION",
"check": "Number"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"category": Blockly.Categories.control,
"colour": Blockly.Colours.control.primary,
"colourSecondary": Blockly.Colours.control.secondary,
"colourTertiary": Blockly.Colours.control.tertiary
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2016 Massachusetts Institute of Technology
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
goog.provide('Blockly.Blocks.defaultToolbox');
goog.require('Blockly.Blocks');
/**
* @fileoverview Provide a default toolbox XML.
*/
Blockly.Blocks.defaultToolbox = '<xml id="toolbox-categories" style="display: none">' +
'<category name="Events">' +
'<block type="event_whenflagclicked"></block>' +
'<block type="event_whenbroadcastreceived">' +
'<value name="CHOICE">' +
'<shadow type="dropdown_whenbroadcast">' +
'<field name="CHOICE">blue</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="event_broadcast">' +
'<value name="CHOICE">' +
'<shadow type="dropdown_broadcast">' +
'<field name="CHOICE">blue</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'</category>' +
'<category name="Control">' +
'<block type="control_forever"></block>' +
'<block type="control_repeat">' +
'<value name="TIMES">' +
'<shadow type="math_whole_number">' +
'<field name="NUM">4</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="control_stop"></block>' +
'<block type="control_wait">' +
'<value name="DURATION">' +
'<shadow type="math_positive_number">' +
'<field name="NUM">1</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'</category>' +
'<category name="Wedo">' +
'<block type="wedo_setcolor">' +
'<value name="CHOICE">' +
'<shadow type="dropdown_wedo_setcolor">' +
'<field name="CHOICE">mystery</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="wedo_motorclockwise">' +
'<value name="DURATION">' +
'<shadow type="math_positive_number">' +
'<field name="NUM">1</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="wedo_motorcounterclockwise">' +
'<value name="DURATION">' +
'<shadow type="math_positive_number">' +
'<field name="NUM">1</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="wedo_motorspeed">' +
'<value name="CHOICE">' +
'<shadow type="dropdown_wedo_motorspeed">' +
'<field name="CHOICE">fast</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="wedo_whentilt">' +
'<value name="CHOICE">' +
'<shadow type="dropdown_wedo_whentilt">' +
'<field name="CHOICE">forward</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="wedo_whendistanceclose"></block>' +
'</category>' +
'</xml>';
Blockly.Blocks.defaultToolboxSimple = '<xml id="toolbox-simple" style="display: none">' +
'<block type="event_whenflagclicked"></block>' +
'<block type="event_whenbroadcastreceived">' +
'<value name="CHOICE">' +
'<shadow type="dropdown_whenbroadcast">' +
'<field name="CHOICE">blue</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="event_broadcast">' +
'<value name="CHOICE">' +
'<shadow type="dropdown_broadcast">' +
'<field name="CHOICE">blue</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="control_forever"></block>' +
'<block type="control_repeat">' +
'<value name="TIMES">' +
'<shadow type="math_whole_number">' +
'<field name="NUM">4</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'<block type="control_stop"></block>' +
'<block type="control_wait">' +
'<value name="DURATION">' +
'<shadow type="math_positive_number">' +
'<field name="NUM">1</field>' +
'</shadow>' +
'</value>' +
'</block>' +
'</xml>';
/**
* @license
* Visual Blocks Editor
*
* Copyright 2016 Massachusetts Institute of Technology
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Control blocks for Scratch (Horizontal)
* @author ascii@media.mit.edu <Andrew Sliwinski>
*/
'use strict';
goog.provide('Blockly.Blocks.event');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
Blockly.Blocks['event_whenflagclicked'] = {
/**
* Block for when flag clicked.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenflagclicked",
"message0": "%1",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "icons/event_whenflagclicked.svg",
"width": 40,
"height": 40,
"alt": "When green flag clicked",
"flip_rtl": true
}
],
"inputsInline": true,
"nextStatement": null,
"category": Blockly.Categories.event,
"colour": Blockly.Colours.event.primary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary
});
}
};
Blockly.Blocks['dropdown_whenbroadcast'] = {
/**
* Block for when broadcast dropdown (used for shadow).
* @this Blockly.Block
*/
init: function() {
this.appendDummyInput()
.appendField(new Blockly.FieldIconMenu(
[
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_blue.svg',
value: 'blue', width: 48, height: 48, alt: 'Blue'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_green.svg',
value: 'green', width: 48, height: 48, alt: 'Green'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_coral.svg',
value: 'coral', width: 48, height: 48, alt: 'Coral'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_magenta.svg',
value: 'magenta', width: 48, height: 48, alt: 'Magenta'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_orange.svg',
value: 'orange', width: 48, height: 48, alt: 'Orange'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_when-broadcast-received_purple.svg',
value: 'purple', width: 48, height: 48, alt: 'Purple'}
]), 'CHOICE');
this.setOutput(true);
this.setColour(Blockly.Colours.event.primary,
Blockly.Colours.event.secondary,
Blockly.Colours.event.tertiary
);
}
};
Blockly.Blocks['event_whenbroadcastreceived'] = {
/**
* Block for when broadcast received.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenbroadcastreceived",
"message0": "%1 %2",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "icons/event_when-broadcast-received_blue.svg",
"width": 40,
"height": 40,
"alt": "Broadcast received"
},
{
"type": "input_value",
"name": "CHOICE"
}
],
"inputsInline": true,
"nextStatement": null,
"category": Blockly.Categories.event,
"colour": Blockly.Colours.event.primary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary
});
}
};
Blockly.Blocks['dropdown_broadcast'] = {
/**
* Block for broadcast dropdown (used for shadow).
* @this Blockly.Block
*/
init: function() {
this.appendDummyInput()
.appendField(new Blockly.FieldIconMenu(
[
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_blue.svg',
value: 'blue', width: 48, height: 48, alt: 'Blue'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_green.svg',
value: 'green', width: 48, height: 48, alt: 'Green'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_coral.svg',
value: 'coral', width: 48, height: 48, alt: 'Coral'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_magenta.svg',
value: 'magenta', width: 48, height: 48, alt: 'Magenta'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_orange.svg',
value: 'orange', width: 48, height: 48, alt: 'Orange'},
{src: Blockly.mainWorkspace.options.pathToMedia + 'icons/event_broadcast_purple.svg',
value: 'purple', width: 48, height: 48, alt: 'Purple'}
]), 'CHOICE');
this.setOutput(true);
this.setColour(Blockly.Colours.event.primary,
Blockly.Colours.event.secondary,
Blockly.Colours.event.tertiary
);
}
};
Blockly.Blocks['event_broadcast'] = {
/**
* Block to send a broadcast.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_broadcast",
"message0": "%1 %2",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "icons/event_broadcast_blue.svg",
"width": 40,
"height": 40,
"alt": "Broadcast"
},
{
"type": "input_value",
"name": "CHOICE"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"category": Blockly.Categories.event,
"colour": Blockly.Colours.event.primary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2020 openblock.cc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
goog.provide('Blockly.Blocks.device');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
Blockly.Blocks['event_whenarduinobegin'] = {
/**
* Block for when arduino begin.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenarduinobegin",
"message0": Blockly.Msg.EVENT_WHENARDUINOBEGIN,
"nextStatement": null,
"category": Blockly.Categories.event,
"colour": Blockly.Colours.event.primary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary
});
}
};
Blockly.Blocks['event_whenmicropythonbegin'] = {
/**
* Block for when arduino begin.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenmicropythonbegin",
"message0": Blockly.Msg.EVENT_WHENMICROPYTHONBEGIN,
"nextStatement": null,
"category": Blockly.Categories.event,
"colour": Blockly.Colours.event.primary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary
});
}
};
Blockly.Blocks['event_whenmicrobitbegin'] = {
/**
* Block for when microbit begin.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenmicrobitbegin",
"message0": Blockly.Msg.EVENT_WHENMICROBITBEGIN,
"nextStatement": null,
"category": Blockly.Categories.event,
"colour": Blockly.Colours.event.primary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary
});
}
};
Blockly.Blocks['event_whenmicrobitbuttonpressed'] = {
/**
* Block for when microbit button pressed.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenmicrobitbuttonpressed",
"message0": Blockly.Msg.EVENT_WHENMICROBITBUTTONPRESSED,
"args0": [
{
"type": "field_dropdown",
"name": "KEY_OPTION",
"options": [
['A', 'a'],
['B', 'b'],
['A+B', 'ab']
]
}
],
"nextStatement": null,
"category": Blockly.Categories.event,
"colour": Blockly.Colours.event.primary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary
});
}
};
Blockly.Blocks['event_whenmicrobitpinbeingtouched'] = {
/**
* Block for when microbit pin was touched.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenmicrobitpinbeingtouched",
"message0": Blockly.Msg.EVENT_WHENMICROBITPINBEINGTOUCHED,
"args0": [
{
"type": "field_dropdown",
"name": "PIN_OPTION",
"options": [
['0', '0'],
['1', '1'],
['2', '2']
]
}
],
"nextStatement": null,
"category": Blockly.Categories.event,
"colour": Blockly.Colours.event.primary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary
});
}
};
Blockly.Blocks['event_whenmicrobitgesture'] = {
/**
* Block for when microbit gesture is XXX.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenmicrobitgesture",
"message0": Blockly.Msg.EVENT_WHENMICROBITGESTURE,
"args0": [
{
"type": "field_dropdown",
"name": "GESTURE_OPTION",
"options": [
[Blockly.Msg.EVENT_WHENMICROBITGESTURE_SHAKEN, 'shake'],
[Blockly.Msg.EVENT_WHENMICROBITGESTURE_TILTEDUPWARD, 'up'],
[Blockly.Msg.EVENT_WHENMICROBITGESTURE_TILTEDDOWNWARD, 'down'],
[Blockly.Msg.EVENT_WHENMICROBITGESTURE_TILTEDDLEFTWARD, 'left'],
[Blockly.Msg.EVENT_WHENMICROBITGESTURE_TILTEDDRIGHTWARD, 'right'],
[Blockly.Msg.EVENT_WHENMICROBITGESTURE_FACEUP, 'face up'],
[Blockly.Msg.EVENT_WHENMICROBITGESTURE_FACEDOWN, 'face down'],
[Blockly.Msg.EVENT_WHENMICROBITGESTURE_FREEFALL, 'freefall'],
['3g', '3g'],
['6g', '6g'],
['8g', '8g']
]
}
],
"nextStatement": null,
"category": Blockly.Categories.event,
"colour": Blockly.Colours.event.primary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2016 Massachusetts Institute of Technology
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
goog.provide('Blockly.Blocks.event');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
goog.require('Blockly.constants');
goog.require('Blockly.ScratchBlocks.VerticalExtensions');
Blockly.Blocks['event_whentouchingobject'] = {
/**
* Block for when a sprite is touching an object.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.EVENT_WHENTOUCHINGOBJECT,
"args0": [
{
"type": "input_value",
"name": "TOUCHINGOBJECTMENU"
}
],
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_hat"]
});
}
};
Blockly.Blocks['event_touchingobjectmenu'] = {
/**
* "Touching [Object]" Block Menu.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_dropdown",
"name": "TOUCHINGOBJECTMENU",
"options": [
[Blockly.Msg.SENSING_TOUCHINGOBJECT_POINTER, '_mouse_'],
[Blockly.Msg.SENSING_TOUCHINGOBJECT_EDGE, '_edge_']
]
}
],
"extensions": ["colours_event", "output_string"]
});
}
};
Blockly.Blocks['event_whenflagclicked'] = {
/**
* Block for when flag clicked.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenflagclicked",
"message0": Blockly.Msg.EVENT_WHENFLAGCLICKED,
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "green-flag.svg",
"width": 24,
"height": 24,
"alt": "flag"
}
],
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_hat"]
});
}
};
Blockly.Blocks['event_whenthisspriteclicked'] = {
/**
* Block for when this sprite clicked.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.EVENT_WHENTHISSPRITECLICKED,
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_hat"]
});
}
};
Blockly.Blocks['event_whenstageclicked'] = {
/**
* Block for when the stage is clicked.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.EVENT_WHENSTAGECLICKED,
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_hat"]
});
}
};
Blockly.Blocks['event_whenbroadcastreceived'] = {
/**
* Block for when broadcast received.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenbroadcastreceived",
"message0": Blockly.Msg.EVENT_WHENBROADCASTRECEIVED,
"args0": [
{
"type": "field_variable",
"name": "BROADCAST_OPTION",
"variableTypes": [Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE],
"variable": Blockly.Msg.DEFAULT_BROADCAST_MESSAGE_NAME
}
],
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_hat"]
});
}
};
Blockly.Blocks['event_whenbackdropswitchesto'] = {
/**
* Block for when the current backdrop switched to a selected backdrop.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.EVENT_WHENBACKDROPSWITCHESTO,
"args0": [
{
"type": "field_dropdown",
"name": "BACKDROP",
"options": [
['backdrop1', 'BACKDROP1']
]
}
],
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_hat"]
});
}
};
Blockly.Blocks['event_whengreaterthan'] = {
/**
* Block for when loudness/timer/video motion is greater than the value.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.EVENT_WHENGREATERTHAN,
"args0": [
{
"type": "field_dropdown",
"name": "WHENGREATERTHANMENU",
"options": [
[Blockly.Msg.EVENT_WHENGREATERTHAN_LOUDNESS, 'LOUDNESS'],
[Blockly.Msg.EVENT_WHENGREATERTHAN_TIMER, 'TIMER']
]
},
{
"type": "input_value",
"name": "VALUE"
}
],
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_hat"]
});
}
};
Blockly.Blocks['event_broadcast_menu'] = {
/**
* Broadcast drop-down menu.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_variable",
"name": "BROADCAST_OPTION",
"variableTypes":[Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE],
"variable": Blockly.Msg.DEFAULT_BROADCAST_MESSAGE_NAME
}
],
"colour": Blockly.Colours.event.secondary,
"colourSecondary": Blockly.Colours.event.secondary,
"colourTertiary": Blockly.Colours.event.tertiary,
"extensions": ["output_string"]
});
}
};
Blockly.Blocks['event_broadcast'] = {
/**
* Block to send a broadcast.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_broadcast",
"message0": Blockly.Msg.EVENT_BROADCAST,
"args0": [
{
"type": "input_value",
"name": "BROADCAST_INPUT"
}
],
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_statement"]
});
}
};
Blockly.Blocks['event_broadcastandwait'] = {
/**
* Block to send a broadcast.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.EVENT_BROADCASTANDWAIT,
"args0": [
{
"type":"input_value",
"name":"BROADCAST_INPUT"
}
],
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_statement"]
});
}
};
Blockly.Blocks['event_whenkeypressed'] = {
/**
* Block to send a broadcast.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"id": "event_whenkeypressed",
"message0": Blockly.Msg.EVENT_WHENKEYPRESSED,
"args0": [
{
"type": "field_dropdown",
"name": "KEY_OPTION",
"options": [
[Blockly.Msg.EVENT_WHENKEYPRESSED_SPACE, 'space'],
[Blockly.Msg.EVENT_WHENKEYPRESSED_UP, 'up arrow'],
[Blockly.Msg.EVENT_WHENKEYPRESSED_DOWN, 'down arrow'],
[Blockly.Msg.EVENT_WHENKEYPRESSED_RIGHT, 'right arrow'],
[Blockly.Msg.EVENT_WHENKEYPRESSED_LEFT, 'left arrow'],
[Blockly.Msg.EVENT_WHENKEYPRESSED_ANY, 'any'],
['a', 'a'],
['b', 'b'],
['c', 'c'],
['d', 'd'],
['e', 'e'],
['f', 'f'],
['g', 'g'],
['h', 'h'],
['i', 'i'],
['j', 'j'],
['k', 'k'],
['l', 'l'],
['m', 'm'],
['n', 'n'],
['o', 'o'],
['p', 'p'],
['q', 'q'],
['r', 'r'],
['s', 's'],
['t', 't'],
['u', 'u'],
['v', 'v'],
['w', 'w'],
['x', 'x'],
['y', 'y'],
['z', 'z'],
['0', '0'],
['1', '1'],
['2', '2'],
['3', '3'],
['4', '4'],
['5', '5'],
['6', '6'],
['7', '7'],
['8', '8'],
['9', '9']
]
}
],
"category": Blockly.Categories.event,
"extensions": ["colours_event", "shape_hat"]
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2016 Massachusetts Institute of Technology
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
goog.provide('Blockly.Blocks.extensions');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
goog.require('Blockly.constants');
goog.require('Blockly.ScratchBlocks.VerticalExtensions');
Blockly.Blocks['extension_pen_down'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1 %2 pen down",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "extensions/pen-block-icon.svg",
"width": 40,
"height": 40
},
{
"type": "field_vertical_separator"
}
],
"category": Blockly.Categories.more,
"extensions": ["colours_more", "shape_statement", "scratch_extension"]
});
}
};
Blockly.Blocks['extension_music_drum'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1 %2 play drum %3",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "extensions/music-block-icon.svg",
"width": 40,
"height": 40
},
{
"type": "field_vertical_separator"
},
{
"type": "input_value",
"name": "NUMBER"
}
],
"category": Blockly.Categories.more,
"extensions": ["colours_more", "shape_statement", "scratch_extension"]
});
}
};
Blockly.Blocks['extension_wedo_motor'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1 %2 turn a motor %3",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "extensions/wedo2-block-icon.svg",
"width": 40,
"height": 40
},
{
"type": "field_vertical_separator"
},
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "rotate-right.svg",
"width": 24,
"height": 24
}
],
"category": Blockly.Categories.more,
"extensions": ["colours_more", "shape_statement", "scratch_extension"]
});
}
};
Blockly.Blocks['extension_wedo_hat'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1 %2 when I am wearing a hat",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "extensions/wedo2-block-icon.svg",
"width": 40,
"height": 40
},
{
"type": "field_vertical_separator"
}
],
"category": Blockly.Categories.more,
"extensions": ["colours_more", "shape_hat", "scratch_extension"]
});
}
};
Blockly.Blocks['extension_wedo_boolean'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1 %2 O RLY?",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "extensions/wedo2-block-icon.svg",
"width": 40,
"height": 40
},
{
"type": "field_vertical_separator"
}
],
"category": Blockly.Categories.more,
"extensions": ["colours_more", "output_boolean", "scratch_extension"]
});
}
};
Blockly.Blocks['extension_wedo_tilt_reporter'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1 %2 tilt angle %3",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "extensions/wedo2-block-icon.svg",
"width": 40,
"height": 40
},
{
"type": "field_vertical_separator"
},
{
"type": "input_value",
"name": "TILT"
}
],
"category": Blockly.Categories.more,
"extensions": ["colours_more", "output_number", "scratch_extension"]
});
}
};
Blockly.Blocks['extension_wedo_tilt_menu'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_dropdown",
"name": "TILT",
"options": [
['Any', 'Any'],
['Whirl', 'Whirl'],
['South', 'South'],
['Back in time', 'Back in time']
]
}
],
"extensions": ["colours_more", "output_string"]
});
}
};
Blockly.Blocks['extension_music_reporter'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1 %2 hey now, you're an all-star",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "extensions/music-block-icon.svg",
"width": 40,
"height": 40
},
{
"type": "field_vertical_separator"
}
],
"category": Blockly.Categories.more,
"extensions": ["colours_more", "output_number", "scratch_extension"]
});
}
};
Blockly.Blocks['extension_microbit_display'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1 %2 display %3",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "extensions/microbit-block-icon.svg",
"width": 40,
"height": 40
},
{
"type": "field_vertical_separator"
},
{
"type": "input_value",
"name": "MATRIX"
},
],
"category": Blockly.Categories.pen,
"extensions": ["colours_pen", "shape_statement", "scratch_extension"]
});
}
};
Blockly.Blocks['extension_music_play_note'] = {
/**
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1 %2 play note %3 for %4 beats",
"args0": [
{
"type": "field_image",
"src": Blockly.mainWorkspace.options.pathToMedia + "extensions/music-block-icon.svg",
"width": 40,
"height": 40
},
{
"type": "field_vertical_separator"
},
{
"type": "input_value",
"name": "NOTE"
},
{
"type": "input_value",
"name": "BEATS"
}
],
"category": Blockly.Categories.pen,
"extensions": ["colours_pen", "shape_statement", "scratch_extension"]
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2016 Massachusetts Institute of Technology
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
goog.provide('Blockly.Blocks.sound');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
goog.require('Blockly.constants');
goog.require('Blockly.ScratchBlocks.VerticalExtensions');
Blockly.Blocks['sound_sounds_menu'] = {
/**
* Sound effects drop-down menu.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_dropdown",
"name": "SOUND_MENU",
"options": [
['1', '0'],
['2', '1'],
['3', '2'],
['4', '3'],
['5', '4'],
['6', '5'],
['7', '6'],
['8', '7'],
['9', '8'],
['10', '9'],
['call a function', function() {
window.alert('function called!');}
]
]
}
],
"colour": Blockly.Colours.sounds.secondary,
"colourSecondary": Blockly.Colours.sounds.secondary,
"colourTertiary": Blockly.Colours.sounds.tertiary,
"extensions": ["output_string"]
});
}
};
Blockly.Blocks['sound_play'] = {
/**
* Block to play sound.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.SOUND_PLAY,
"args0": [
{
"type": "input_value",
"name": "SOUND_MENU"
}
],
"category": Blockly.Categories.sound,
"extensions": ["colours_sounds", "shape_statement"]
});
}
};
Blockly.Blocks['sound_playuntildone'] = {
/**
* Block to play sound until done.
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.SOUND_PLAYUNTILDONE,
"args0": [
{
"type": "input_value",
"name": "SOUND_MENU"
}
],
"category": Blockly.Categories.sound,
"extensions": ["colours_sounds", "shape_statement"]
});
}
};
Blockly.Blocks['sound_stopallsounds'] = {
/**
* Block to stop all sounds
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.SOUND_STOPALLSOUNDS,
"category": Blockly.Categories.sound,
"extensions": ["colours_sounds", "shape_statement"]
});
}
};
Blockly.Blocks['sound_seteffectto'] = {
/**
* Block to set the audio effect
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.SOUND_SETEFFECTO,
"args0": [
{
"type": "field_dropdown",
"name": "EFFECT",
"options": [
[Blockly.Msg.SOUND_EFFECTS_PITCH, 'PITCH'],
[Blockly.Msg.SOUND_EFFECTS_PAN, 'PAN']
]
},
{
"type": "input_value",
"name": "VALUE"
}
],
"category": Blockly.Categories.sound,
"extensions": ["colours_sounds", "shape_statement"]
});
}
};
Blockly.Blocks['sound_changeeffectby'] = {
/**
* Block to change the audio effect
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.SOUND_CHANGEEFFECTBY,
"args0": [
{
"type": "field_dropdown",
"name": "EFFECT",
"options": [
[Blockly.Msg.SOUND_EFFECTS_PITCH, 'PITCH'],
[Blockly.Msg.SOUND_EFFECTS_PAN, 'PAN']
]
},
{
"type": "input_value",
"name": "VALUE"
}
],
"category": Blockly.Categories.sound,
"extensions": ["colours_sounds", "shape_statement"]
});
}
};
Blockly.Blocks['sound_cleareffects'] = {
/**
* Block to clear audio effects
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.SOUND_CLEAREFFECTS,
"category": Blockly.Categories.sound,
"extensions": ["colours_sounds", "shape_statement"]
});
}
};
Blockly.Blocks['sound_changevolumeby'] = {
/**
* Block to change the sprite's volume by a certain value
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.SOUND_CHANGEVOLUMEBY,
"args0": [
{
"type": "input_value",
"name": "VOLUME"
}
],
"category": Blockly.Categories.sound,
"extensions": ["colours_sounds", "shape_statement"]
});
}
};
Blockly.Blocks['sound_setvolumeto'] = {
/**
* Block to set the sprite's volume to a certain percent
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.SOUND_SETVOLUMETO,
"args0": [
{
"type": "input_value",
"name": "VOLUME"
}
],
"category": Blockly.Categories.sound,
"extensions": ["colours_sounds", "shape_statement"]
});
}
};
Blockly.Blocks['sound_volume'] = {
/**
* Block to report volume
* @this Blockly.Block
*/
init: function() {
this.jsonInit({
"message0": Blockly.Msg.SOUND_VOLUME,
"category": Blockly.Categories.sound,
"checkboxInFlyout": true,
"extensions": ["colours_sounds", "output_number"]
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2020 openblock.cc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
goog.provide('Blockly.Blocks.stdint');
goog.require('Blockly.Blocks');
goog.require('Blockly.Colours');
Blockly.Blocks['math_int8_number'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"precision": 1,
"min": "-127",
"max": "127"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_uint8_number'] = {
init: function() {
this.jsonInit({
message0: "%1",
args0: [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"precision": 1,
"min": "0",
"max": "255"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_int9_number'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"precision": 1,
"min": "-255",
"max": "255"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_uint10_number'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"precision": 1,
"min": "0",
"max": "1023"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_int11_number'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"precision": 1,
"min": "-1023",
"max": "1023"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_uint16_number'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"precision": 1,
"min": "0",
"max": "65535"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_int0to100_number'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"precision": 1,
"min": "0",
"max": "100"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_0to100_number'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"min": "0",
"max": "100"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_intn100to100_number'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"precision": 1,
"min": "-100",
"max": "100"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_n100to100_number'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_slider",
"name": "NUM",
"value": "0",
"min": "-100",
"max": "100"
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
Blockly.Blocks['math_half_angle'] = {
init: function() {
this.jsonInit({
"message0": "%1",
"args0": [
{
"type": "field_angle",
"name": "NUM",
"value": 90,
"max": 180
}
],
"output": "Number",
"outputShape": Blockly.OUTPUT_SHAPE_ROUND,
"colour": Blockly.Colours.textField,
"colourSecondary": Blockly.Colours.textField,
"colourTertiary": Blockly.Colours.textField
});
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2017 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Extensions for vertical blocks in scratch-blocks.
* The following extensions can be used to describe a block in Scratch terms.
* For instance, a block in the operators colour scheme with a number output
* would have the "colours_operators" and "output_number" extensions.
* @author fenichel@google.com (Rachel Fenichel)
*/
'use strict';
goog.provide('Blockly.ScratchBlocks.VerticalExtensions');
goog.require('Blockly.Colours');
goog.require('Blockly.constants');
/**
* Helper function that generates an extension based on a category name.
* The generated function will set primary, secondary, and tertiary colours
* based on the category name.
* @param {String} category The name of the category to set colours for.
* @return {function} An extension function that sets colours based on the given
* category.
*/
Blockly.ScratchBlocks.VerticalExtensions.colourHelper = function(category) {
var colours = Blockly.Colours[category];
if (!(colours && colours.primary && colours.secondary && colours.tertiary)) {
throw new Error('Could not find colours for category "' + category + '"');
}
/**
* Set the primary, secondary, and tertiary colours on this block for the
* given category.
* @this {Blockly.Block}
*/
return function() {
this.setColourFromRawValues_(colours.primary, colours.secondary,
colours.tertiary);
};
};
/**
* Extension to set the colours of a text field, which are all the same.
*/
Blockly.ScratchBlocks.VerticalExtensions.COLOUR_TEXTFIELD = function() {
this.setColourFromRawValues_(Blockly.Colours.textField,
Blockly.Colours.textField, Blockly.Colours.textField);
};
/**
* Extension to make a block fit into a stack of statements, regardless of its
* inputs. That means the block should have a previous connection and a next
* connection and have inline inputs.
* @this {Blockly.Block}
* @readonly
*/
Blockly.ScratchBlocks.VerticalExtensions.SHAPE_STATEMENT = function() {
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
};
/**
* Extension to make a block be shaped as a hat block, regardless of its
* inputs. That means the block should have a next connection and have inline
* inputs, but have no previous connection.
* @this {Blockly.Block}
* @readonly
*/
Blockly.ScratchBlocks.VerticalExtensions.SHAPE_HAT = function() {
this.setInputsInline(true);
this.setNextStatement(true, null);
};
/**
* Extension to make a block be shaped as an end block, regardless of its
* inputs. That means the block should have a previous connection and have
* inline inputs, but have no next connection.
* @this {Blockly.Block}
* @readonly
*/
Blockly.ScratchBlocks.VerticalExtensions.SHAPE_END = function() {
this.setInputsInline(true);
this.setPreviousStatement(true, null);
};
/**
* Extension to make represent a number reporter in Scratch-Blocks.
* That means the block has inline inputs, a round output shape, and a 'Number'
* output type.
* @this {Blockly.Block}
* @readonly
*/
Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_NUMBER = function() {
this.setInputsInline(true);
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
this.setOutput(true, 'Number');
};
/**
* Extension to make represent a string reporter in Scratch-Blocks.
* That means the block has inline inputs, a round output shape, and a 'String'
* output type.
* @this {Blockly.Block}
* @readonly
*/
Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_STRING = function() {
this.setInputsInline(true);
this.setOutputShape(Blockly.OUTPUT_SHAPE_ROUND);
this.setOutput(true, 'String');
};
/**
* Extension to make represent a boolean reporter in Scratch-Blocks.
* That means the block has inline inputs, a round output shape, and a 'Boolean'
* output type.
* @this {Blockly.Block}
* @readonly
*/
Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_BOOLEAN = function() {
this.setInputsInline(true);
this.setOutputShape(Blockly.OUTPUT_SHAPE_HEXAGONAL);
this.setOutput(true, 'Boolean');
};
/**
* Mixin to add a context menu for a procedure definition block.
* It adds the "edit" option and removes the "duplicate" option.
* @mixin
* @augments Blockly.Block
* @package
* @readonly
*/
Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU = {
/**
* Add the "edit" option and removes the "duplicate" option from the context
* menu.
* @param {!Array.<!Object>} menuOptions List of menu options to edit.
* @this Blockly.Block
*/
customContextMenu: function(menuOptions) {
// Add the edit option at the end.
menuOptions.push(Blockly.Procedures.makeEditOption(this));
// Find the delete option and update its callback to be specific to
// functions.
for (var i = 0, option; option = menuOptions[i]; i++) {
if (option.text == Blockly.Msg.DELETE_BLOCK) {
var input = this.getInput('custom_block');
// this is the root block, not the shadow block.
if (input && input.connection && input.connection.targetBlock()) {
var procCode = input.connection.targetBlock().getProcCode();
} else {
return;
}
var rootBlock = this;
option.callback = function() {
var didDelete = Blockly.Procedures.deleteProcedureDefCallback(
procCode, rootBlock);
if (!didDelete) {
alert(Blockly.Msg.PROCEDURE_USED);
}
};
}
}
// Find and remove the duplicate option
for (var i = 0, option; option = menuOptions[i]; i++) {
if (option.text == Blockly.Msg.DUPLICATE) {
menuOptions.splice(i, 1);
break;
}
}
}
};
/**
* Mixin to add a context menu for a procedure call block.
* It adds the "edit" option and the "define" option.
* @mixin
* @augments Blockly.Block
* @package
* @readonly
*/
Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU = {
/**
* Add the "edit" option to the context menu.
* @todo Add "go to definition" option once implemented.
* @param {!Array.<!Object>} menuOptions List of menu options to edit.
* @this Blockly.Block
*/
customContextMenu: function(menuOptions) {
menuOptions.push(Blockly.Procedures.makeEditOption(this));
}
};
Blockly.ScratchBlocks.VerticalExtensions.SCRATCH_EXTENSION = function() {
this.isScratchExtension = true;
};
/**
* Register all extensions for scratch-blocks.
* @package
*/
Blockly.ScratchBlocks.VerticalExtensions.registerAll = function() {
var categoryNames =
['control', 'data', 'data_lists', 'sounds', 'motion', 'looks', 'event',
'sensing', 'pen', 'operators', 'more'];
// Register functions for all category colours.
for (var i = 0; i < categoryNames.length; i++) {
var name = categoryNames[i];
Blockly.Extensions.register('colours_' + name,
Blockly.ScratchBlocks.VerticalExtensions.colourHelper(name));
}
// Text fields transcend categories.
Blockly.Extensions.register('colours_textfield',
Blockly.ScratchBlocks.VerticalExtensions.COLOUR_TEXTFIELD);
// Register extensions for common block shapes.
Blockly.Extensions.register('shape_statement',
Blockly.ScratchBlocks.VerticalExtensions.SHAPE_STATEMENT);
Blockly.Extensions.register('shape_hat',
Blockly.ScratchBlocks.VerticalExtensions.SHAPE_HAT);
Blockly.Extensions.register('shape_end',
Blockly.ScratchBlocks.VerticalExtensions.SHAPE_END);
// Output shapes and types are related.
Blockly.Extensions.register('output_number',
Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_NUMBER);
Blockly.Extensions.register('output_string',
Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_STRING);
Blockly.Extensions.register('output_boolean',
Blockly.ScratchBlocks.VerticalExtensions.OUTPUT_BOOLEAN);
// Custom procedures have interesting context menus.
Blockly.Extensions.registerMixin('procedure_def_contextmenu',
Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_DEF_CONTEXTMENU);
Blockly.Extensions.registerMixin('procedure_call_contextmenu',
Blockly.ScratchBlocks.VerticalExtensions.PROCEDURE_CALL_CONTEXTMENU);
// Extension blocks have slightly different block rendering.
Blockly.Extensions.register('scratch_extension',
Blockly.ScratchBlocks.VerticalExtensions.SCRATCH_EXTENSION);
};
Blockly.ScratchBlocks.VerticalExtensions.registerAll();
This diff is collapsed. Click to expand it.
goog.provide('Blockly.Blocks');
goog.provide('Blockly.Generator');
\ No newline at end of file
var Blockly={Blocks:{}};
goog.provide('Blockly.Blocks');
#!/bin/bash
# Script for cleaning up blockly-specific files when merging blockly into scratch-blocks
# Removes files and directories that scratch-blocks doesn't want.
# Rachel Fenichel (fenichel@google.com)
# Note: 'ours' is scratch-blocks, 'theirs' is blockly.
# Formatting helpers.
indent() { sed 's/^/ /'; }
indent_more() { sed 's/^/\t/'; }
empty_lines() { printf '\n\n'; }
empty_lines
echo Cleaning up a merge from Blockly to Scratch-Blocks...
# Get rid of Blockly's internationalization/messages. This is not usually worth
# scrolling up to look at.
empty_lines
echo Cleaning up Blockly message files...
# Turn on more powerful globbing
shopt -s extglob
# Having trouble with directories. Let's just go there.
cd msg/json
git rm -f !(en.json|synonyms.json) | indent_more
cd ../..
# Having trouble with directories. Let's just go there.
cd msg/js
git rm -f !(en.js) | indent_more
cd ../..
# Turn powerful globbing off again
shopt -u extglob
# Whole directories that we want to get rid of.
empty_lines
echo Removing blockly-specific directories...
dirslist="accessible demos tests/generators appengine blocks local_build"
for directory in $dirslist
do
echo 'Cleaning up' $directory | indent
git rm -rf $directory | indent_more
done
# Scratch-blocks does not use generators
empty_lines
echo Removing generators...
generated_langs="dart javascript lua php python"
for lang in $generated_langs
do
echo 'Cleaning up' $lang | indent
# Directories containing block generators.
git rm -rf generators/${lang} | indent_more
done
# Built stuff that we should get rid of.
empty_lines
echo Removing built files...
built_files="blockly_compressed.js \
blockly_uncompressed.js \
blockly_accessible_compressed.js \
blockly_accessible_uncompressed.js \
blocks_compressed.js \
arduino_compressed.js\
dart_compressed.js \
php_compressed.js \
python_compressed.js \
javascript_compressed.js \
lua_compressed.js"
for filename in $built_files
do
git rm $filename | indent_more
done
empty_lines
echo Miscellaneous cleanup...
# Use ours.
keep_ours=".github/ISSUE_TEMPLATE.md \
.github/PULL_REQUEST_TEMPLATE.md \
.gitignore \
.travis.yml \
core/block_animations.js \
msg/messages.js \
msg/js/en.js \
msg/json/en.json"
for filename in $keep_ours
do
git checkout --ours $filename && git add $filename | indent_more
done
# Scratch-blocks has separate vertical and horizontal playgrounds and block
# rendering.
git rm -f tests/playground.html core/block_render_svg.js | indent_more
empty_lines
echo Done with cleanup.
/**
* @license
* Visual Blocks Editor
*
* Copyright 2018 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Methods animating a block on connection and disconnection.
* @author fenichel@google.com (Rachel Fenichel)
*/
'use strict';
goog.provide('Blockly.BlockAnimations');
/**
* Play some UI effects (sound, animation) when disposing of a block.
* @param {!Blockly.BlockSvg} block The block being disposed of.
* @package
*/
Blockly.BlockAnimations.disposeUiEffect = function(block) {
var workspace = block.workspace;
var svgGroup = block.getSvgRoot();
workspace.getAudioManager().play('delete');
var xy = workspace.getSvgXY(svgGroup);
// Deeply clone the current block.
var clone = svgGroup.cloneNode(true);
clone.translateX_ = xy.x;
clone.translateY_ = xy.y;
clone.setAttribute('transform', 'translate(' + xy.x + ',' + xy.y + ')');
workspace.getParentSvg().appendChild(clone);
clone.bBox_ = clone.getBBox();
// Start the animation.
Blockly.BlockAnimations.disposeUiStep_(clone, workspace.RTL, new Date,
workspace.scale);
};
/**
* Animate a cloned block and eventually dispose of it.
* This is a class method, not an instance method since the original block has
* been destroyed and is no longer accessible.
* @param {!Element} clone SVG element to animate and dispose of.
* @param {boolean} rtl True if RTL, false if LTR.
* @param {!Date} start Date of animation's start.
* @param {number} workspaceScale Scale of workspace.
* @private
*/
Blockly.BlockAnimations.disposeUiStep_ = function(clone, rtl, start,
workspaceScale) {
var ms = new Date - start;
var percent = ms / 150;
if (percent > 1) {
goog.dom.removeNode(clone);
} else {
var x = clone.translateX_ +
(rtl ? -1 : 1) * clone.bBox_.width * workspaceScale / 2 * percent;
var y = clone.translateY_ + clone.bBox_.height * workspaceScale * percent;
var scale = (1 - percent) * workspaceScale;
clone.setAttribute('transform', 'translate(' + x + ',' + y + ')' +
' scale(' + scale + ')');
setTimeout(Blockly.BlockAnimations.disposeUiStep_, 10, clone, rtl, start,
workspaceScale);
}
};
/**
* Play some UI effects (sound, ripple) after a connection has been established.
* @param {!Blockly.BlockSvg} block The block being connected.
* @package
*/
Blockly.BlockAnimations.connectionUiEffect = function(block) {
block.workspace.getAudioManager().play('click');
};
/**
* Play some UI effects (sound, animation) when disconnecting a block.
* No-op in scratch-blocks, which has no disconnect animation.
* @param {!Blockly.BlockSvg} _block The block being disconnected.
* @package
*/
Blockly.BlockAnimations.disconnectUiEffect = function(
/* eslint-disable no-unused-vars */ _block
/* eslint-enable no-unused-vars */) {
};
/**
* Stop the disconnect UI animation immediately.
* No-op in scratch-blocks, which has no disconnect animation.
* @package
*/
Blockly.BlockAnimations.disconnectUiStop = function() {
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2013 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview A mapping of block type names to block prototype objects.
* @author spertus@google.com (Ellen Spertus)
*/
'use strict';
/**
* A mapping of block type names to block prototype objects.
* @name Blockly.Blocks
*/
goog.provide('Blockly.Blocks');
/*
* A mapping of block type names to block prototype objects.
* @type {!Object.<string,Object>}
*/
Blockly.Blocks = new Object(null);
/**
* @license
* Visual Blocks Editor
*
* Copyright 2018 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Methods for dragging a bubble visually.
* @author fenichel@google.com (Rachel Fenichel)
*/
'use strict';
goog.provide('Blockly.BubbleDragger');
goog.require('Blockly.Bubble');
goog.require('Blockly.Events.CommentMove');
goog.require('Blockly.WorkspaceCommentSvg');
goog.require('goog.math.Coordinate');
goog.require('goog.asserts');
/**
* Class for a bubble dragger. It moves things on the bubble canvas around the
* workspace when they are being dragged by a mouse or touch. These can be
* block comments, mutators, warnings, or workspace comments.
* @param {!Blockly.Bubble|!Blockly.WorkspaceCommentSvg} bubble The item on the
* bubble canvas to drag.
* @param {!Blockly.WorkspaceSvg} workspace The workspace to drag on.
* @constructor
*/
Blockly.BubbleDragger = function(bubble, workspace) {
/**
* The item on the bubble canvas that is being dragged.
* @type {!Blockly.Bubble|!Blockly.WorkspaceCommentSvg}
* @private
*/
this.draggingBubble_ = bubble;
/**
* The workspace on which the bubble is being dragged.
* @type {!Blockly.WorkspaceSvg}
* @private
*/
this.workspace_ = workspace;
/**
* Which delete area the mouse pointer is over, if any.
* One of {@link Blockly.DELETE_AREA_TRASH},
* {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}.
* @type {?number}
* @private
*/
this.deleteArea_ = null;
/**
* Whether the bubble would be deleted if dropped immediately.
* @type {boolean}
* @private
*/
this.wouldDeleteBubble_ = false;
/**
* The location of the top left corner of the dragging bubble's body at the
* beginning of the drag, in workspace coordinates.
* @type {!goog.math.Coordinate}
* @private
*/
this.startXY_ = this.draggingBubble_.getRelativeToSurfaceXY();
/**
* The drag surface to move bubbles to during a drag, or null if none should
* be used. Block dragging and bubble dragging use the same surface.
* @type {?Blockly.BlockDragSurfaceSvg}
* @private
*/
this.dragSurface_ =
Blockly.utils.is3dSupported() && !!workspace.getBlockDragSurface() ?
workspace.getBlockDragSurface() : null;
};
/**
* Sever all links from this object.
* @package
*/
Blockly.BubbleDragger.prototype.dispose = function() {
this.draggingBubble_ = null;
this.workspace_ = null;
this.dragSurface_ = null;
};
/**
* Start dragging a bubble. This includes moving it to the drag surface.
* @package
*/
Blockly.BubbleDragger.prototype.startBubbleDrag = function() {
if (!Blockly.Events.getGroup()) {
Blockly.Events.setGroup(true);
}
this.workspace_.setResizesEnabled(false);
this.draggingBubble_.setAutoLayout(false);
if (this.dragSurface_) {
this.moveToDragSurface_();
}
this.draggingBubble_.setDragging && this.draggingBubble_.setDragging(true);
var toolbox = this.workspace_.getToolbox();
if (toolbox) {
var style = this.draggingBubble_.isDeletable() ? 'blocklyToolboxDelete' :
'blocklyToolboxGrab';
toolbox.addStyle(style);
}
};
/**
* Execute a step of bubble dragging, based on the given event. Update the
* display accordingly.
* @param {!Event} e The most recent move event.
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
* moved from the position at the start of the drag, in pixel units.
* @package
*/
Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) {
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
this.draggingBubble_.moveDuringDrag(this.dragSurface_, newLoc);
if (this.draggingBubble_.isDeletable()) {
this.deleteArea_ = this.workspace_.isDeleteArea(e);
this.updateCursorDuringBubbleDrag_();
}
};
/**
* Shut the trash can and, if necessary, delete the dragging bubble.
* Should be called at the end of a bubble drag.
* @return {boolean} whether the bubble was deleted.
* @private
*/
Blockly.BubbleDragger.prototype.maybeDeleteBubble_ = function() {
var trashcan = this.workspace_.trashcan;
if (this.wouldDeleteBubble_) {
if (trashcan) {
setTimeout(trashcan.close.bind(trashcan), 100);
}
// Fire a move event, so we know where to go back to for an undo.
this.fireMoveEvent_();
this.draggingBubble_.dispose(false, true);
} else if (trashcan) {
// Make sure the trash can is closed.
trashcan.close();
}
return this.wouldDeleteBubble_;
};
/**
* Update the cursor (and possibly the trash can lid) to reflect whether the
* dragging bubble would be deleted if released immediately.
* @private
*/
Blockly.BubbleDragger.prototype.updateCursorDuringBubbleDrag_ = function() {
this.wouldDeleteBubble_ = this.deleteArea_ != Blockly.DELETE_AREA_NONE;
var trashcan = this.workspace_.trashcan;
if (this.wouldDeleteBubble_) {
this.draggingBubble_.setDeleteStyle(true);
if (this.deleteArea_ == Blockly.DELETE_AREA_TRASH && trashcan) {
trashcan.setOpen_(true);
}
} else {
this.draggingBubble_.setDeleteStyle(false);
if (trashcan) {
trashcan.setOpen_(false);
}
}
};
/**
* Finish a bubble drag and put the bubble back on the workspace.
* @param {!Event} e The mouseup/touchend event.
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
* moved from the position at the start of the drag, in pixel units.
* @package
*/
Blockly.BubbleDragger.prototype.endBubbleDrag = function(
e, currentDragDeltaXY) {
// Make sure internal state is fresh.
this.dragBubble(e, currentDragDeltaXY);
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
// Move the bubble to its final location.
this.draggingBubble_.moveTo(newLoc.x, newLoc.y);
var deleted = this.maybeDeleteBubble_();
if (!deleted) {
// Put everything back onto the bubble canvas.
if (this.dragSurface_) {
this.dragSurface_.clearAndHide(this.workspace_.getBubbleCanvas());
}
this.draggingBubble_.setDragging && this.draggingBubble_.setDragging(false);
this.fireMoveEvent_();
}
this.workspace_.setResizesEnabled(true);
if (this.workspace_.toolbox_) {
var style = this.draggingBubble_.isDeletable() ? 'blocklyToolboxDelete' :
'blocklyToolboxGrab';
this.workspace_.toolbox_.removeStyle(style);
}
Blockly.Events.setGroup(false);
};
/**
* Fire a move event at the end of a bubble drag.
* @private
*/
Blockly.BubbleDragger.prototype.fireMoveEvent_ = function() {
var event = null;
if (this.draggingBubble_.isComment) {
event = new Blockly.Events.CommentMove(this.draggingBubble_);
} else if (this.draggingBubble_ instanceof Blockly.ScratchBubble) {
event = new Blockly.Events.CommentMove(this.draggingBubble_.comment);
} else {
return;
}
event.setOldCoordinate(this.startXY_);
event.recordNew();
Blockly.Events.fire(event);
};
/**
* Convert a coordinate object from pixels to workspace units, including a
* correction for mutator workspaces.
* This function does not consider differing origins. It simply scales the
* input's x and y values.
* @param {!goog.math.Coordinate} pixelCoord A coordinate with x and y values
* in css pixel units.
* @return {!goog.math.Coordinate} The input coordinate divided by the workspace
* scale.
* @private
*/
Blockly.BubbleDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
var result = new goog.math.Coordinate(pixelCoord.x / this.workspace_.scale,
pixelCoord.y / this.workspace_.scale);
if (this.workspace_.isMutator) {
// If we're in a mutator, its scale is always 1, purely because of some
// oddities in our rendering optimizations. The actual scale is the same as
// the scale on the parent workspace.
// Fix that for dragging.
var mainScale = this.workspace_.options.parentWorkspace.scale;
result = result.scale(1 / mainScale);
}
return result;
};
/**
* Move the bubble onto the drag surface at the beginning of a drag. Move the
* drag surface to preserve the apparent location of the bubble.
* @private
*/
Blockly.BubbleDragger.prototype.moveToDragSurface_ = function() {
this.draggingBubble_.moveTo(0, 0);
this.dragSurface_.translateSurface(this.startXY_.x, this.startXY_.y);
// Execute the move on the top-level SVG component.
this.dragSurface_.setBlocksAndShow(this.draggingBubble_.getSvgRoot());
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2016 Massachusetts Institute of Technology
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
goog.provide('Blockly.Colours');
Blockly.Colours = {
// SVG colours: these must be specificed in #RRGGBB style
// To add an opacity, this must be specified as a separate property (for SVG fill-opacity)
"motion": {
"primary": "#4C97FF",
"secondary": "#4280D7",
"tertiary": "#3373CC"
},
"looks": {
"primary": "#9966FF",
"secondary": "#855CD6",
"tertiary": "#774DCB"
},
"sounds": {
"primary": "#CF63CF",
"secondary": "#C94FC9",
"tertiary": "#BD42BD"
},
"control": {
"primary": "#FFAB19",
"secondary": "#EC9C13",
"tertiary": "#CF8B17"
},
"event": {
"primary": "#FFBF00",
"secondary": "#E6AC00",
"tertiary": "#CC9900"
},
"sensing": {
"primary": "#5CB1D6",
"secondary": "#47A8D1",
"tertiary": "#2E8EB8"
},
"pen": {
"primary": "#0fBD8C",
"secondary": "#0DA57A",
"tertiary": "#0B8E69"
},
"operators": {
"primary": "#59C059",
"secondary": "#46B946",
"tertiary": "#389438"
},
"data": {
"primary": "#FF8C1A",
"secondary": "#FF8000",
"tertiary": "#DB6E00"
},
// This is not a new category, but rather for differentiation
// between lists and scalar variables.
"data_lists": {
"primary": "#FF661A",
"secondary": "#FF5500",
"tertiary": "#E64D00"
},
"more": {
"primary": "#FF6680",
"secondary": "#FF4D6A",
"tertiary": "#FF3355"
},
"text": "#575E75",
"workspace": "#F9F9F9",
"toolboxHover": "#4C97FF",
"toolboxSelected": "#e9eef2",
"toolboxText": "#575E75",
"toolbox": "#FFFFFF",
"flyout": "#F9F9F9",
"scrollbar": "#CECDCE",
"scrollbarHover": '#CECDCE',
"textField": "#FFFFFF",
"insertionMarker": "#000000",
"insertionMarkerOpacity": 0.2,
"dragShadowOpacity": 0.3,
"stackGlow": "#FFF200",
"stackGlowSize": 4,
"stackGlowOpacity": 1,
"replacementGlow": "#FFFFFF",
"replacementGlowSize": 2,
"replacementGlowOpacity": 1,
"colourPickerStroke": "#FFFFFF",
// CSS colours: support RGBA
"fieldShadow": "rgba(0,0,0,0.1)",
"dropDownShadow": "rgba(0, 0, 0, .3)",
"numPadBackground": "#547AB2",
"numPadBorder": "#435F91",
"numPadActiveBackground": "#435F91",
"numPadText": "white", // Do not use hex here, it cannot be inlined with data-uri SVG
"valueReportBackground": "#FFFFFF",
"valueReportBorder": "#AAAAAA"
};
/**
* Override the colours in Blockly.Colours with new values basded on the
* given dictionary.
* @param {!Object} colours Dictionary of colour properties and new values.
* @package
*/
Blockly.Colours.overrideColours = function(colours) {
// Colour overrides provided by the injection
if (colours) {
for (var colourProperty in colours) {
if (colours.hasOwnProperty(colourProperty) &&
Blockly.Colours.hasOwnProperty(colourProperty)) {
// If a property is in both colours option and Blockly.Colours,
// set the Blockly.Colours value to the override.
// Override Blockly category color object properties with those
// provided.
var colourPropertyValue = colours[colourProperty];
if (goog.isObject(colourPropertyValue)) {
for (var colourSequence in colourPropertyValue) {
if (colourPropertyValue.hasOwnProperty(colourSequence) &&
Blockly.Colours[colourProperty].hasOwnProperty(colourSequence)) {
Blockly.Colours[colourProperty][colourSequence] =
colourPropertyValue[colourSequence];
}
}
} else {
Blockly.Colours[colourProperty] = colourPropertyValue;
}
}
}
}
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2011 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Object representing a code comment.
* @author fraser@google.com (Neil Fraser)
*/
'use strict';
goog.provide('Blockly.Comment');
goog.require('Blockly.Bubble');
goog.require('Blockly.Events.BlockChange');
goog.require('Blockly.Events.Ui');
goog.require('Blockly.Icon');
goog.require('goog.userAgent');
/**
* Class for a comment.
* @param {!Blockly.Block} block The block associated with this comment.
* @extends {Blockly.Icon}
* @constructor
*/
Blockly.Comment = function(block) {
Blockly.Comment.superClass_.constructor.call(this, block);
this.createIcon();
};
goog.inherits(Blockly.Comment, Blockly.Icon);
/**
* Comment text (if bubble is not visible).
* @private
*/
Blockly.Comment.prototype.text_ = '';
/**
* Width of bubble.
* @private
*/
Blockly.Comment.prototype.width_ = 160;
/**
* Height of bubble.
* @private
*/
Blockly.Comment.prototype.height_ = 80;
/**
* Draw the comment icon.
* @param {!Element} group The icon group.
* @private
*/
Blockly.Comment.prototype.drawIcon_ = function(group) {
// Circle.
Blockly.utils.createSvgElement('circle',
{'class': 'blocklyIconShape', 'r': '8', 'cx': '8', 'cy': '8'},
group);
// Can't use a real '?' text character since different browsers and operating
// systems render it differently.
// Body of question mark.
Blockly.utils.createSvgElement('path',
{
'class': 'blocklyIconSymbol',
'd': 'm6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405' +
'0.607,-5.534 -3.765,-3.874v1.7c3.12,-1.657 3.698,0.118 2.336,1.25' +
'-1.201,0.998 -1.201,1.528 -1.204,2.19z'
},
group);
// Dot of question mark.
Blockly.utils.createSvgElement('rect',
{
'class': 'blocklyIconSymbol',
'x': '6.8',
'y': '10.78',
'height': '2',
'width': '2'
},
group);
};
/**
* Create the editor for the comment's bubble.
* @return {!Element} The top-level node of the editor.
* @private
*/
Blockly.Comment.prototype.createEditor_ = function() {
/* Create the editor. Here's the markup that will be generated:
<foreignObject x="8" y="8" width="164" height="164">
<body xmlns="http://www.w3.org/1999/xhtml" class="blocklyMinimalBody">
<textarea xmlns="http://www.w3.org/1999/xhtml"
class="blocklyCommentTextarea"
style="height: 164px; width: 164px;"></textarea>
</body>
</foreignObject>
*/
this.foreignObject_ = Blockly.utils.createSvgElement('foreignObject',
{'x': Blockly.Bubble.BORDER_WIDTH, 'y': Blockly.Bubble.BORDER_WIDTH},
null);
var body = document.createElementNS(Blockly.HTML_NS, 'body');
body.setAttribute('xmlns', Blockly.HTML_NS);
body.className = 'blocklyMinimalBody';
var textarea = document.createElementNS(Blockly.HTML_NS, 'textarea');
textarea.className = 'blocklyCommentTextarea';
textarea.setAttribute('dir', this.block_.RTL ? 'RTL' : 'LTR');
body.appendChild(textarea);
this.textarea_ = textarea;
this.foreignObject_.appendChild(body);
Blockly.bindEventWithChecks_(textarea, 'mouseup', this, this.textareaFocus_);
// Don't zoom with mousewheel.
Blockly.bindEventWithChecks_(textarea, 'wheel', this, function(e) {
e.stopPropagation();
});
Blockly.bindEventWithChecks_(textarea, 'change', this, function(_e) {
if (this.text_ != textarea.value) {
Blockly.Events.fire(new Blockly.Events.BlockChange(
this.block_, 'comment', null, this.text_, textarea.value));
this.text_ = textarea.value;
}
});
setTimeout(function() {
textarea.focus();
}, 0);
return this.foreignObject_;
};
/**
* Add or remove editability of the comment.
* @override
*/
Blockly.Comment.prototype.updateEditable = function() {
if (this.isVisible()) {
// Toggling visibility will force a rerendering.
this.setVisible(false);
this.setVisible(true);
}
// Allow the icon to update.
Blockly.Icon.prototype.updateEditable.call(this);
};
/**
* Callback function triggered when the bubble has resized.
* Resize the text area accordingly.
* @private
*/
Blockly.Comment.prototype.resizeBubble_ = function() {
if (this.isVisible()) {
var size = this.bubble_.getBubbleSize();
var doubleBorderWidth = 2 * Blockly.Bubble.BORDER_WIDTH;
this.foreignObject_.setAttribute('width', size.width - doubleBorderWidth);
this.foreignObject_.setAttribute('height', size.height - doubleBorderWidth);
this.textarea_.style.width = (size.width - doubleBorderWidth - 4) + 'px';
this.textarea_.style.height = (size.height - doubleBorderWidth - 4) + 'px';
}
};
/**
* Show or hide the comment bubble.
* @param {boolean} visible True if the bubble should be visible.
*/
Blockly.Comment.prototype.setVisible = function(visible) {
if (visible == this.isVisible()) {
// No change.
return;
}
Blockly.Events.fire(
new Blockly.Events.Ui(this.block_, 'commentOpen', !visible, visible));
if ((!this.block_.isEditable() && !this.textarea_) || goog.userAgent.IE) {
// Steal the code from warnings to make an uneditable text bubble.
// MSIE does not support foreignobject; textareas are impossible.
// http://msdn.microsoft.com/en-us/library/hh834675%28v=vs.85%29.aspx
// Always treat comments in IE as uneditable.
Blockly.Warning.prototype.setVisible.call(this, visible);
return;
}
// Save the bubble stats before the visibility switch.
var text = this.getText();
var size = this.getBubbleSize();
if (visible) {
// Create the bubble.
this.bubble_ = new Blockly.Bubble(
/** @type {!Blockly.WorkspaceSvg} */ (this.block_.workspace),
this.createEditor_(), this.block_.svgPath_,
this.iconXY_, this.width_, this.height_);
// Expose this comment's block's ID on its top-level SVG group.
this.bubble_.setSvgId(this.block_.id);
this.bubble_.registerResizeEvent(this.resizeBubble_.bind(this));
this.updateColour();
} else {
// Dispose of the bubble.
this.bubble_.dispose();
this.bubble_ = null;
this.textarea_ = null;
this.foreignObject_ = null;
}
// Restore the bubble stats after the visibility switch.
this.setText(text);
this.setBubbleSize(size.width, size.height);
};
/**
* Bring the comment to the top of the stack when clicked on.
* @param {!Event} _e Mouse up event.
* @private
*/
Blockly.Comment.prototype.textareaFocus_ = function(_e) {
// Ideally this would be hooked to the focus event for the comment.
// This is tied to mousedown, however doing so in Firefox swallows the cursor
// for unknown reasons.
// See https://github.com/LLK/scratch-blocks/issues/1631 for more history.
if (this.bubble_.promote_()) {
// Since the act of moving this node within the DOM causes a loss of focus,
// we need to reapply the focus.
this.textarea_.focus();
}
};
/**
* Get the dimensions of this comment's bubble.
* @return {!Object} Object with width and height properties.
*/
Blockly.Comment.prototype.getBubbleSize = function() {
if (this.isVisible()) {
return this.bubble_.getBubbleSize();
} else {
return {width: this.width_, height: this.height_};
}
};
/**
* Size this comment's bubble.
* @param {number} width Width of the bubble.
* @param {number} height Height of the bubble.
*/
Blockly.Comment.prototype.setBubbleSize = function(width, height) {
if (this.textarea_) {
this.bubble_.setBubbleSize(width, height);
} else {
this.width_ = width;
this.height_ = height;
}
};
/**
* Returns this comment's text.
* @return {string} Comment text.
*/
Blockly.Comment.prototype.getText = function() {
return this.textarea_ ? this.textarea_.value : this.text_;
};
/**
* Set this comment's text.
* @param {string} text Comment text.
*/
Blockly.Comment.prototype.setText = function(text) {
if (this.text_ != text) {
Blockly.Events.fire(new Blockly.Events.BlockChange(
this.block_, 'comment', null, this.text_, text));
this.text_ = text;
}
if (this.textarea_) {
this.textarea_.value = text;
}
};
/**
* Dispose of this comment.
*/
Blockly.Comment.prototype.dispose = function() {
if (Blockly.Events.isEnabled()) {
this.setText(''); // Fire event to delete comment.
}
this.block_.comment = null;
Blockly.Icon.prototype.dispose.call(this);
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2011 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Components for managing connections between blocks.
* @author fraser@google.com (Neil Fraser)
*/
'use strict';
goog.provide('Blockly.ConnectionDB');
goog.require('Blockly.Connection');
/**
* Database of connections.
* Connections are stored in order of their vertical component. This way
* connections in an area may be looked up quickly using a binary search.
* @constructor
*/
Blockly.ConnectionDB = function() {
/**
* Array of connections sorted by y coordinate.
* @type {!Array.<!Blockly.Connection>}
* @private
*/
this.connections_ = [];
};
/**
* Add a connection to the database. Must not already exist in DB.
* @param {!Blockly.Connection} connection The connection to be added.
*/
Blockly.ConnectionDB.prototype.addConnection = function(connection) {
if (connection.inDB_) {
throw Error('Connection already in database.');
}
if (connection.getSourceBlock().isInFlyout) {
// Don't bother maintaining a database of connections in a flyout.
return;
}
var position = this.findPositionForConnection_(connection);
this.connections_.splice(position, 0, connection);
connection.inDB_ = true;
};
/**
* Find the given connection.
* Starts by doing a binary search to find the approximate location, then
* linearly searches nearby for the exact connection.
* @param {!Blockly.Connection} conn The connection to find.
* @return {number} The index of the connection, or -1 if the connection was
* not found.
*/
Blockly.ConnectionDB.prototype.findConnection = function(conn) {
if (!this.connections_.length) {
return -1;
}
var bestGuess = this.findPositionForConnection_(conn);
if (bestGuess >= this.connections_.length) {
// Not in list
return -1;
}
var yPos = conn.y_;
// Walk forward and back on the y axis looking for the connection.
var pointerMin = bestGuess;
var pointerMax = bestGuess;
while (pointerMin >= 0 && this.connections_[pointerMin].y_ == yPos) {
if (this.connections_[pointerMin] == conn) {
return pointerMin;
}
pointerMin--;
}
while (pointerMax < this.connections_.length &&
this.connections_[pointerMax].y_ == yPos) {
if (this.connections_[pointerMax] == conn) {
return pointerMax;
}
pointerMax++;
}
return -1;
};
/**
* Finds a candidate position for inserting this connection into the list.
* This will be in the correct y order but makes no guarantees about ordering in
* the x axis.
* @param {!Blockly.Connection} connection The connection to insert.
* @return {number} The candidate index.
* @private
*/
Blockly.ConnectionDB.prototype.findPositionForConnection_ = function(
connection) {
if (!this.connections_.length) {
return 0;
}
var pointerMin = 0;
var pointerMax = this.connections_.length;
while (pointerMin < pointerMax) {
var pointerMid = Math.floor((pointerMin + pointerMax) / 2);
if (this.connections_[pointerMid].y_ < connection.y_) {
pointerMin = pointerMid + 1;
} else if (this.connections_[pointerMid].y_ > connection.y_) {
pointerMax = pointerMid;
} else {
pointerMin = pointerMid;
break;
}
}
return pointerMin;
};
/**
* Remove a connection from the database. Must already exist in DB.
* @param {!Blockly.Connection} connection The connection to be removed.
* @private
*/
Blockly.ConnectionDB.prototype.removeConnection_ = function(connection) {
if (!connection.inDB_) {
throw Error('Connection not in database.');
}
var removalIndex = this.findConnection(connection);
if (removalIndex == -1) {
throw Error('Unable to find connection in connectionDB.');
}
connection.inDB_ = false;
this.connections_.splice(removalIndex, 1);
};
/**
* Find all nearby connections to the given connection.
* Type checking does not apply, since this function is used for bumping.
* @param {!Blockly.Connection} connection The connection whose neighbours
* should be returned.
* @param {number} maxRadius The maximum radius to another connection.
* @return {!Array.<Blockly.Connection>} List of connections.
*/
Blockly.ConnectionDB.prototype.getNeighbours = function(connection, maxRadius) {
var db = this.connections_;
var currentX = connection.x_;
var currentY = connection.y_;
// Binary search to find the closest y location.
var pointerMin = 0;
var pointerMax = db.length - 2;
var pointerMid = pointerMax;
while (pointerMin < pointerMid) {
if (db[pointerMid].y_ < currentY) {
pointerMin = pointerMid;
} else {
pointerMax = pointerMid;
}
pointerMid = Math.floor((pointerMin + pointerMax) / 2);
}
var neighbours = [];
/**
* Computes if the current connection is within the allowed radius of another
* connection.
* This function is a closure and has access to outside variables.
* @param {number} yIndex The other connection's index in the database.
* @return {boolean} True if the current connection's vertical distance from
* the other connection is less than the allowed radius.
*/
function checkConnection_(yIndex) {
var dx = currentX - db[yIndex].x_;
var dy = currentY - db[yIndex].y_;
var r = Math.sqrt(dx * dx + dy * dy);
if (r <= maxRadius) {
neighbours.push(db[yIndex]);
}
return dy < maxRadius;
}
// Walk forward and back on the y axis looking for the closest x,y point.
pointerMin = pointerMid;
pointerMax = pointerMid;
if (db.length) {
while (pointerMin >= 0 && checkConnection_(pointerMin)) {
pointerMin--;
}
do {
pointerMax++;
} while (pointerMax < db.length && checkConnection_(pointerMax));
}
return neighbours;
};
/**
* Is the candidate connection close to the reference connection.
* Extremely fast; only looks at Y distance.
* @param {number} index Index in database of candidate connection.
* @param {number} baseY Reference connection's Y value.
* @param {number} maxRadius The maximum radius to another connection.
* @return {boolean} True if connection is in range.
* @private
*/
Blockly.ConnectionDB.prototype.isInYRange_ = function(index, baseY, maxRadius) {
return (Math.abs(this.connections_[index].y_ - baseY) <= maxRadius);
};
/**
* Find the closest compatible connection to this connection.
* @param {!Blockly.Connection} conn The connection searching for a compatible
* mate.
* @param {number} maxRadius The maximum radius to another connection.
* @param {!goog.math.Coordinate} dxy Offset between this connection's location
* in the database and the current location (as a result of dragging).
* @return {!{connection: ?Blockly.Connection, radius: number}} Contains two
* properties:' connection' which is either another connection or null,
* and 'radius' which is the distance.
*/
Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius,
dxy) {
// Don't bother.
if (!this.connections_.length) {
return {connection: null, radius: maxRadius};
}
// Stash the values of x and y from before the drag.
var baseY = conn.y_;
var baseX = conn.x_;
conn.x_ = baseX + dxy.x;
conn.y_ = baseY + dxy.y;
// findPositionForConnection finds an index for insertion, which is always
// after any block with the same y index. We want to search both forward
// and back, so search on both sides of the index.
var closestIndex = this.findPositionForConnection_(conn);
var bestConnection = null;
var bestRadius = maxRadius;
var temp;
// Walk forward and back on the y axis looking for the closest x,y point.
var pointerMin = closestIndex - 1;
while (pointerMin >= 0 && this.isInYRange_(pointerMin, conn.y_, maxRadius)) {
temp = this.connections_[pointerMin];
if (conn.isConnectionAllowed(temp, bestRadius)) {
bestConnection = temp;
bestRadius = temp.distanceFrom(conn);
}
pointerMin--;
}
var pointerMax = closestIndex;
while (pointerMax < this.connections_.length &&
this.isInYRange_(pointerMax, conn.y_, maxRadius)) {
temp = this.connections_[pointerMax];
if (conn.isConnectionAllowed(temp, bestRadius)) {
bestConnection = temp;
bestRadius = temp.distanceFrom(conn);
}
pointerMax++;
}
// Reset the values of x and y.
conn.x_ = baseX;
conn.y_ = baseY;
// If there were no valid connections, bestConnection will be null.
return {connection: bestConnection, radius: bestRadius};
};
/**
* Initialize a set of connection DBs for a specified workspace.
* @param {!Blockly.Workspace} workspace The workspace this DB is for.
*/
Blockly.ConnectionDB.init = function(workspace) {
// Create four databases, one for each connection type.
var dbList = [];
dbList[Blockly.INPUT_VALUE] = new Blockly.ConnectionDB();
dbList[Blockly.OUTPUT_VALUE] = new Blockly.ConnectionDB();
dbList[Blockly.NEXT_STATEMENT] = new Blockly.ConnectionDB();
dbList[Blockly.PREVIOUS_STATEMENT] = new Blockly.ConnectionDB();
workspace.connectionDBList = dbList;
};
/**
* @license
* Visual Blocks Editor
*
* Copyright 2016 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Blockly constants.
* @author fenichel@google.com (Rachel Fenichel)
*/
'use strict';
goog.provide('Blockly.constants');
/**
* Number of pixels the mouse must move before a drag starts.
*/
Blockly.DRAG_RADIUS = 3;
/**
* Number of pixels the mouse must move before a drag/scroll starts from the
* flyout. Because the drag-intention is determined when this is reached, it is
* larger than Blockly.DRAG_RADIUS so that the drag-direction is clearer.
*/
Blockly.FLYOUT_DRAG_RADIUS = 10;
/**
* Maximum misalignment between connections for them to snap together.
*/
Blockly.SNAP_RADIUS = 48;
/**
* Maximum misalignment between connections for them to snap together,
* when a connection is already highlighted.
*/
Blockly.CONNECTING_SNAP_RADIUS = 68;
/**
* How much to prefer staying connected to the current connection over moving to
* a new connection. The current previewed connection is considered to be this
* much closer to the matching connection on the block than it actually is.
*/
Blockly.CURRENT_CONNECTION_PREFERENCE = 20;
/**
* Delay in ms between trigger and bumping unconnected block out of alignment.
*/
Blockly.BUMP_DELAY = 0;
/**
* Number of characters to truncate a collapsed block to.
*/
Blockly.COLLAPSE_CHARS = 30;
/**
* Length in ms for a touch to become a long press.
*/
Blockly.LONGPRESS = 750;
/**
* Distance to scroll when a mouse wheel event is received and its delta mode
* is line (0x1) instead of pixel (0x0). In these cases, a single "scroll" has
* a delta of 1, which makes the workspace scroll very slowly (just one pixel).
* To compensate, that delta is multiplied by this value.
* @const
* @package
*/
Blockly.LINE_SCROLL_MULTIPLIER = 15;
/**
* Prevent a sound from playing if another sound preceded it within this many
* milliseconds.
*/
Blockly.SOUND_LIMIT = 100;
/**
* When dragging a block out of a stack, split the stack in two (true), or drag
* out the block healing the stack (false).
*/
Blockly.DRAG_STACK = true;
/**
* The richness of block colours, regardless of the hue.
* Must be in the range of 0 (inclusive) to 1 (exclusive).
*/
Blockly.HSV_SATURATION = 0.45;
/**
* The intensity of block colours, regardless of the hue.
* Must be in the range of 0 (inclusive) to 1 (exclusive).
*/
Blockly.HSV_VALUE = 0.65;
/**
* Sprited icons and images.
*/
Blockly.SPRITE = {
width: 96,
height: 124,
url: 'sprites.png'
};
// Constants below this point are not intended to be changed.
/**
* Required name space for SVG elements.
* @const
*/
Blockly.SVG_NS = 'http://www.w3.org/2000/svg';
/**
* Required name space for HTML elements.
* @const
*/
Blockly.HTML_NS = 'http://www.w3.org/1999/xhtml';
/**
* ENUM for a right-facing value input. E.g. 'set item to' or 'return'.
* @const
*/
Blockly.INPUT_VALUE = 1;
/**
* ENUM for a left-facing value output. E.g. 'random fraction'.
* @const
*/
Blockly.OUTPUT_VALUE = 2;
/**
* ENUM for a down-facing block stack. E.g. 'if-do' or 'else'.
* @const
*/
Blockly.NEXT_STATEMENT = 3;
/**
* ENUM for an up-facing block stack. E.g. 'break out of loop'.
* @const
*/
Blockly.PREVIOUS_STATEMENT = 4;
/**
* ENUM for an dummy input. Used to add field(s) with no input.
* @const
*/
Blockly.DUMMY_INPUT = 5;
/**
* ENUM for left alignment.
* @const
*/
Blockly.ALIGN_LEFT = -1;
/**
* ENUM for centre alignment.
* @const
*/
Blockly.ALIGN_CENTRE = 0;
/**
* ENUM for right alignment.
* @const
*/
Blockly.ALIGN_RIGHT = 1;
/**
* ENUM for no drag operation.
* @const
*/
Blockly.DRAG_NONE = 0;
/**
* ENUM for inside the sticky DRAG_RADIUS.
* @const
*/
Blockly.DRAG_STICKY = 1;
/**
* ENUM for inside the non-sticky DRAG_RADIUS, for differentiating between
* clicks and drags.
* @const
*/
Blockly.DRAG_BEGIN = 1;
/**
* ENUM for freely draggable (outside the DRAG_RADIUS, if one applies).
* @const
*/
Blockly.DRAG_FREE = 2;
/**
* Lookup table for determining the opposite type of a connection.
* @const
*/
Blockly.OPPOSITE_TYPE = [];
Blockly.OPPOSITE_TYPE[Blockly.INPUT_VALUE] = Blockly.OUTPUT_VALUE;
Blockly.OPPOSITE_TYPE[Blockly.OUTPUT_VALUE] = Blockly.INPUT_VALUE;
Blockly.OPPOSITE_TYPE[Blockly.NEXT_STATEMENT] = Blockly.PREVIOUS_STATEMENT;
Blockly.OPPOSITE_TYPE[Blockly.PREVIOUS_STATEMENT] = Blockly.NEXT_STATEMENT;
/**
* ENUM for toolbox and flyout at top of screen.
* @const
*/
Blockly.TOOLBOX_AT_TOP = 0;
/**
* ENUM for toolbox and flyout at bottom of screen.
* @const
*/
Blockly.TOOLBOX_AT_BOTTOM = 1;
/**
* ENUM for toolbox and flyout at left of screen.
* @const
*/
Blockly.TOOLBOX_AT_LEFT = 2;
/**
* ENUM for toolbox and flyout at right of screen.
* @const
*/
Blockly.TOOLBOX_AT_RIGHT = 3;
/**
* ENUM for output shape: hexagonal (booleans/predicates).
* @const
*/
Blockly.OUTPUT_SHAPE_HEXAGONAL = 1;
/**
* ENUM for output shape: rounded (numbers).
* @const
*/
Blockly.OUTPUT_SHAPE_ROUND = 2;
/**
* ENUM for output shape: squared (any/all values; strings).
* @const
*/
Blockly.OUTPUT_SHAPE_SQUARE = 3;
/**
* ENUM for categories.
* @const
*/
Blockly.Categories = {
"motion": "motion",
"looks": "looks",
"sound": "sounds",
"pen": "pen",
"data": "data",
"dataLists": "data-lists",
"event": "events",
"control": "control",
"sensing": "sensing",
"operators": "operators",
"more": "more"
};
/**
* ENUM representing that an event is not in any delete areas.
* Null for backwards compatibility reasons.
* @const
*/
Blockly.DELETE_AREA_NONE = null;
/**
* ENUM representing that an event is in the delete area of the trash can.
* @const
*/
Blockly.DELETE_AREA_TRASH = 1;
/**
* ENUM representing that an event is in the delete area of the toolbox or
* flyout.
* @const
*/
Blockly.DELETE_AREA_TOOLBOX = 2;
/**
* String for use in the "custom" attribute of a category in toolbox xml.
* This string indicates that the category should be dynamically populated with
* variable blocks.
* @const {string}
*/
Blockly.VARIABLE_CATEGORY_NAME = 'VARIABLE';
/**
* String for use in the "custom" attribute of a category in toolbox xml.
* This string indicates that the category should be dynamically populated with
* procedure blocks.
* @const {string}
*/
Blockly.PROCEDURE_CATEGORY_NAME = 'PROCEDURE';
/**
* String for use in the dropdown created in field_variable.
* This string indicates that this option in the dropdown is 'Rename
* variable...' and if selected, should trigger the prompt to rename a variable.
* @const {string}
*/
Blockly.RENAME_VARIABLE_ID = 'RENAME_VARIABLE_ID';
/**
* String for use in the dropdown created in field_variable.
* This string indicates that this option in the dropdown is 'Delete the "%1"
* variable' and if selected, should trigger the prompt to delete a variable.
* @const {string}
*/
Blockly.DELETE_VARIABLE_ID = 'DELETE_VARIABLE_ID';
/**
* String for use in the dropdown created in field_variable,
* specifically for broadcast messages.
* This string indicates that this option in the dropdown is 'New message...'
* and if selected, should trigger the prompt to create a new message.
* @const {string}
*/
Blockly.NEW_BROADCAST_MESSAGE_ID = 'NEW_BROADCAST_MESSAGE_ID';
/**
* String representing the variable type of broadcast message blocks.
* This string, for use in differentiating between types of variables,
* indicates that the current variable is a broadcast message.
* @const {string}
*/
Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE = 'broadcast_msg';
/**
* String representing the variable type of list blocks.
* This string, for use in differentiating between types of variables,
* indicates that the current variable is a list.
* @const {string}
*/
Blockly.LIST_VARIABLE_TYPE = 'list';
// TODO (#1251) Replace '' below with 'scalar', and start using this constant
// everywhere.
/**
* String representing the variable type of scalar variables.
* This string, for use in differentiating between types of variables,
* indicates that the current variable is a scalar variable.
* @const {string}
*/
Blockly.SCALAR_VARIABLE_TYPE = '';
/**
* The type of all procedure definition blocks.
* @const {string}
*/
Blockly.PROCEDURES_DEFINITION_BLOCK_TYPE = 'procedures_definition';
/**
* The type of all procedure prototype blocks.
* @const {string}
*/
Blockly.PROCEDURES_PROTOTYPE_BLOCK_TYPE = 'procedures_prototype';
/**
* The type of all procedure call blocks.
* @const {string}
*/
Blockly.PROCEDURES_CALL_BLOCK_TYPE = 'procedures_call';
/**
* ENUM for flyout status button states.
* @const
*/
Blockly.StatusButtonState = {
"READY": "ready",
"NOT_READY": "not ready",
};
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
media/1x1.gif

43 Bytes

No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!