mirror of
https://github.com/google/blockly.git
synced 2026-06-17 00:25:14 +02:00
Merge branch 'develop' into rc/nov_2017
This commit is contained in:
+5
-1
@@ -2,9 +2,13 @@
|
||||
*_uncompressed*.js
|
||||
/msg/*
|
||||
/core/css.js
|
||||
/tests/blocks/*
|
||||
/tests/compile/*
|
||||
/tests/jsunit/*
|
||||
/tests/generators/*
|
||||
/tests/workspace_svg/*
|
||||
/generators/*
|
||||
/demos/*
|
||||
/accessible/*
|
||||
/appengine/*
|
||||
/appengine/*
|
||||
/externs/svg-externs.js
|
||||
|
||||
+48
-32
@@ -1,57 +1,73 @@
|
||||
Thanks for opening an issue for us! Before you open an issue, please check if a similar issue exists or has been closed before.
|
||||
|
||||
If you're asking a question about how to use Blockly in your application, please ask questions on the [mailing list](https://groups.google.com/forum/#!forum/blockly) instead of filing issues.
|
||||
|
||||
_Please delete the above section and the instructions in the sections below before submitting. If a section is not applicable, type "N/A" in that section._
|
||||
<!--
|
||||
- Thanks for opening an issue for us! Before you open an issue,
|
||||
- please check if a similar issue exists or has been closed before.
|
||||
-
|
||||
- If you're asking a question about how to use Blockly in your application,
|
||||
- please ask questions on the mailing list, instead of filing issues:
|
||||
- https://groups.google.com/forum/#!forum/blockly
|
||||
-->
|
||||
|
||||
### Problem statement
|
||||
|
||||
_Remove this hint: these checkboxes can be checked like this: [x]_
|
||||
|
||||
- [ ] Bug report
|
||||
- [ ] Feature request
|
||||
|
||||
_What were you trying to do when you hit this bug? Or, what do you want to do with Blockly that your proposed feature would enable?_
|
||||
<!-- TODO: Please describe the problem.
|
||||
- Is it a bug report (something didn't work the way you expected),
|
||||
- or a feature request (something new you think would improve Blockly)?
|
||||
-->
|
||||
|
||||
### Expected Behavior
|
||||
|
||||
_Please describe what should happen. Include screenshots if applicable._
|
||||
<!-- TODO: Please describe what should happen.
|
||||
- Include screenshots if applicable.
|
||||
-->
|
||||
|
||||
### Actual Behavior
|
||||
|
||||
_Describe what actually happens. Include screenshots if applicable._
|
||||
<!-- TODO: Describe what actually happens.
|
||||
- Include screenshots if applicable.
|
||||
-->
|
||||
|
||||
### Steps to Reproduce
|
||||
|
||||
_Explain what someone needs to do in order to see what's described in *Actual behavior* above_
|
||||
<!-- TODO: Explain what someone needs to do in order to see
|
||||
- what's described in *Actual behavior* above
|
||||
-->
|
||||
|
||||
1. Start by..
|
||||
2. Next, do..
|
||||
|
||||
### Stack Traces
|
||||
|
||||
```
|
||||
Please open up the console. If you see any Blockly-related errors, paste them here.
|
||||
<!-- TODO: Please open up the console. If you see any Blockly-related errors,
|
||||
- paste them between the quotes below.
|
||||
-
|
||||
- Ignore any instances of...
|
||||
- "Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()."
|
||||
-->
|
||||
|
||||
Ignore any instances of "Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause()."
|
||||
```
|
||||
Replace with error stack trace.
|
||||
```
|
||||
|
||||
### Operating System and Browser
|
||||
|
||||
_Remove this hint: these checkboxes can be checked like this: [x]_
|
||||
<!-- TODO: If this issue is browser specific, uncomment the systems you have tested. -->
|
||||
|
||||
- [ ] Desktop:
|
||||
- [ ] Chrome
|
||||
- [ ] Firefox
|
||||
- [ ] Safari
|
||||
- [ ] Opera
|
||||
- [ ] IE 10+
|
||||
- [ ] IE 11
|
||||
- [ ] EDGE
|
||||
<!-- * Desktop Chrome -->
|
||||
<!-- * Desktop Firefox -->
|
||||
<!-- * Desktop Safari -->
|
||||
<!-- * Desktop Opera -->
|
||||
<!-- * Windows Internet Explorer 10 -->
|
||||
<!-- * Windows Internet Explorer 11 -->
|
||||
<!-- * Windows Edge -->
|
||||
|
||||
- [ ] Smartphone/Tablet/Chromebook (please complete the following information):
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
<!--
|
||||
* Smartphone/Tablet/Chromebook (please complete the following information):
|
||||
* Device: [e.g. iPhone6]
|
||||
* OS: [e.g. iOS8.1]
|
||||
* Browser [e.g. stock browser, safari]
|
||||
* Version [e.g. 22]
|
||||
-->
|
||||
|
||||
### Additional Information
|
||||
|
||||
_Anything else we should know?_
|
||||
<!-- Anything else we should know? -->
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
Thanks for submitting code to Blockly! Please fill out the following as part of your pull request so we can review your code more easily.
|
||||
<!--
|
||||
- Thanks for submitting code to Blockly! Please fill out the following as part of
|
||||
- your pull request so we can review your code more easily.
|
||||
-->
|
||||
|
||||
## The basics
|
||||
|
||||
<!-- TODO: Verify the following, checking each box with an 'x' between the brackets: [x] -->
|
||||
|
||||
- [ ] I branched from develop
|
||||
- [ ] My pull request is against develop
|
||||
- [ ] My code follows the [style guide](https://developers.google.com/blockly/guides/modify/web/style-guide)
|
||||
@@ -9,37 +14,40 @@ Thanks for submitting code to Blockly! Please fill out the following as part of
|
||||
## The details
|
||||
### Resolves
|
||||
|
||||
_What Github issue does this resolve (please include link)?_
|
||||
<!-- TODO: What Github issue does this resolve? Please include a link. -->
|
||||
|
||||
### Proposed Changes
|
||||
|
||||
_Describe what this Pull Request does. Include screenshots if applicable._
|
||||
<!-- TODO: Describe what this Pull Request does. Include screenshots if applicable. -->
|
||||
|
||||
### Reason for Changes
|
||||
|
||||
_Explain why these changes should be made. Include screenshots if applicable._
|
||||
<!--TODO: Explain why these changes should be made. Include screenshots if applicable. -->
|
||||
|
||||
### Test Coverage
|
||||
|
||||
_Please show how you have added tests to cover your changes, or tell us how you tested it and on which platforms. If it's plaform-agnostic you can delete these checkboxes._
|
||||
<!-- TODO: Please show how you have added tests to cover your changes,
|
||||
- or tell us how you tested it. For each systems you tested,
|
||||
- uncomment the systems in the list below.
|
||||
-->
|
||||
|
||||
Tested on:
|
||||
_Remove this hint: these checkboxes can be checked like this: [x]_
|
||||
- [ ] Desktop:
|
||||
- [ ] Chrome
|
||||
- [ ] Firefox
|
||||
- [ ] Safari
|
||||
- [ ] Opera
|
||||
- [ ] IE 10+
|
||||
- [ ] IE 11
|
||||
- [ ] EDGE
|
||||
<!-- * Desktop Chrome -->
|
||||
<!-- * Desktop Firefox -->
|
||||
<!-- * Desktop Safari -->
|
||||
<!-- * Desktop Opera -->
|
||||
<!-- * Windows Internet Explorer 10 -->
|
||||
<!-- * Windows Internet Explorer 11 -->
|
||||
<!-- * Windows Edge -->
|
||||
|
||||
<!--
|
||||
* Smartphone/Tablet/Chromebook (please complete the following information):
|
||||
* Device: [e.g. iPhone6]
|
||||
* OS: [e.g. iOS8.1]
|
||||
* Browser [e.g. stock browser, safari]
|
||||
* Version [e.g. 22]
|
||||
-->
|
||||
|
||||
- [ ] Smartphone/Tablet/Chromebook (please complete the following information):
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
### Additional Information
|
||||
|
||||
_Anything else we should know?_
|
||||
<!-- Anything else we should know? -->
|
||||
|
||||
@@ -6,3 +6,6 @@ npm-debug.log
|
||||
*.pyc
|
||||
*.komodoproject
|
||||
/nbproject/private/
|
||||
|
||||
tests/compile/main_compressed.js
|
||||
tests/compile/*compiler*.jar
|
||||
|
||||
+5
-2
@@ -15,16 +15,19 @@ matrix:
|
||||
|
||||
before_install:
|
||||
- npm install google-closure-library
|
||||
- npm install google-closure-compiler
|
||||
- npm install webdriverio
|
||||
# Symlink closure library
|
||||
- ln -s $(npm root)/google-closure-library ../closure-library
|
||||
|
||||
before_script:
|
||||
- export DISPLAY=:99.0
|
||||
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then ( scripts/setup_linux_env.sh ) fi
|
||||
- if [ "${TRAVIS_OS_NAME}" == "osx" ]; then ( scripts/setup_osx_env.sh ) fi
|
||||
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then ( tests/scripts/setup_linux_env.sh ) fi
|
||||
- if [ "${TRAVIS_OS_NAME}" == "osx" ]; then ( tests/scripts/setup_osx_env.sh ) fi
|
||||
- sleep 2
|
||||
|
||||
script:
|
||||
- set -x
|
||||
- npm run lint
|
||||
- npm test
|
||||
- cd tests/compile; compile.sh; cd ..
|
||||
|
||||
@@ -1390,7 +1390,7 @@ Blockly.Events.VarRename=function(a,b){a&&(Blockly.Events.VarRename.superClass_.
|
||||
Blockly.Events.VarRename.prototype.fromJson=function(a){Blockly.Events.VarRename.superClass_.fromJson.call(this,a);this.oldName=a.oldName;this.newName=a.newName};Blockly.Events.VarRename.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.renameVariableById(this.varId,this.newName):b.renameVariableById(this.varId,this.oldName)};
|
||||
Blockly.Events.disableOrphans=function(a){if(a.type==Blockly.Events.MOVE||a.type==Blockly.Events.CREATE){Blockly.Events.disable();var b=Blockly.Workspace.getById(a.workspaceId);if(a=b.getBlockById(a.blockId))if(a.getParent()&&!a.getParent().disabled){b=a.getDescendants();a=0;for(var c;c=b[a];a++)c.setDisabled(!1)}else if((a.outputConnection||a.previousConnection)&&!b.isDragging()){do a.setDisabled(!0),a=a.getNextBlock();while(a)}Blockly.Events.enable()}};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.htmlInput_=null;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)};
|
||||
Blockly.FieldTextInput.prototype.setValue=function(a){if(null!==a){if(this.sourceBlock_){var b=this.callValidator(a);null!==b&&(a=b)}Blockly.Field.prototype.setValue.call(this,a)}};Blockly.FieldTextInput.prototype.setText=function(a){null!==a&&(a=String(a),a!==this.text_&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.text_,a)),Blockly.Field.prototype.setText.call(this,a)))};
|
||||
Blockly.FieldTextInput.prototype.setSpellcheck=function(a){this.spellcheck_=a};Blockly.FieldTextInput.prototype.showEditor_=function(a){this.workspace_=this.sourceBlock_.workspace;a=a||!1;!a&&(goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD)?this.showPromptEditor_():this.showInlineEditor_(a)};Blockly.FieldTextInput.prototype.showPromptEditor_=function(){var a=this;Blockly.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_,function(b){a.sourceBlock_&&(b=a.callValidator(b));a.setValue(b)})};
|
||||
Blockly.FieldTextInput.prototype.setSpellcheck=function(a){this.spellcheck_=a};Blockly.FieldTextInput.prototype.showEditor_=function(a){this.workspace_=this.sourceBlock_.workspace;a=a||!1;!a&&(goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD)?this.showPromptEditor_():this.showInlineEditor_(a)};Blockly.FieldTextInput.showPromptEditor_=function(){var a=this;Blockly.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_,function(b){a.sourceBlock_&&(b=a.callValidator(b));a.setValue(b)})};
|
||||
Blockly.FieldTextInput.prototype.showInlineEditor_=function(a){Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,this.widgetDispose_());var b=Blockly.WidgetDiv.DIV,c=goog.dom.createDom("INPUT","blocklyHtmlInput");c.setAttribute("spellcheck",this.spellcheck_);var d=Blockly.FieldTextInput.FONTSIZE*this.workspace_.scale+"pt";b.style.fontSize=d;c.style.fontSize=d;Blockly.FieldTextInput.htmlInput_=c;b.appendChild(c);c.value=c.defaultValue=this.text_;c.oldValue_=null;this.validate_();this.resizeEditor_();
|
||||
a||(c.focus(),c.select());this.bindEvents_(c)};Blockly.FieldTextInput.prototype.bindEvents_=function(a){a.onKeyDownWrapper_=Blockly.bindEventWithChecks_(a,"keydown",this,this.onHtmlInputKeyDown_);a.onKeyUpWrapper_=Blockly.bindEventWithChecks_(a,"keyup",this,this.onHtmlInputChange_);a.onKeyPressWrapper_=Blockly.bindEventWithChecks_(a,"keypress",this,this.onHtmlInputChange_);a.onWorkspaceChangeWrapper_=this.resizeEditor_.bind(this);this.workspace_.addChangeListener(a.onWorkspaceChangeWrapper_)};
|
||||
Blockly.FieldTextInput.prototype.unbindEvents_=function(a){Blockly.unbindEvent_(a.onKeyDownWrapper_);Blockly.unbindEvent_(a.onKeyUpWrapper_);Blockly.unbindEvent_(a.onKeyPressWrapper_);this.workspace_.removeChangeListener(a.onWorkspaceChangeWrapper_)};
|
||||
@@ -1553,8 +1553,8 @@ Blockly.Css.CONTENT=[".blocklySvg {","background-color: #fff;","outline: none;",
|
||||
"opacity: 0;","}",".blocklyMainWorkspaceScrollbar {","z-index: 20;","}",".blocklyFlyoutScrollbar {","z-index: 30;","}",".blocklyScrollbarHorizontal, .blocklyScrollbarVertical {","position: absolute;","outline: none;","}",".blocklyScrollbarBackground {","opacity: 0;","}",".blocklyScrollbarHandle {","fill: #ccc;","}",".blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyScrollbarHandle:hover {","fill: #bbb;","}",".blocklyZoom>image {","opacity: .4;","}",".blocklyZoom>image:hover {",
|
||||
"opacity: .6;","}",".blocklyZoom>image:active {","opacity: .8;","}",".blocklyFlyout .blocklyScrollbarHandle {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyFlyout .blocklyScrollbarHandle:hover {","fill: #aaa;","}",".blocklyInvalidInput {","background: #faa;","}",".blocklyAngleCircle {","stroke: #444;","stroke-width: 1;","fill: #ddd;","fill-opacity: .8;","}",".blocklyAngleMarks {","stroke: #444;","stroke-width: 1;","}",".blocklyAngleGauge {",
|
||||
"fill: #f88;","fill-opacity: .8;","}",".blocklyAngleLine {","stroke: #f00;","stroke-width: 2;","stroke-linecap: round;","pointer-events: none;","}",".blocklyContextMenu {","border-radius: 4px;","}",".blocklyDropdownMenu {","padding: 0 !important;","}",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {","background: url(<<<PATH>>>/sprites.png) no-repeat -48px -16px !important;","}",".blocklyToolboxDiv {","background-color: #ddd;",
|
||||
"overflow-x: visible;","overflow-y: auto;","position: absolute;","z-index: 70;","-webkit-tap-highlight-color: transparent;","}",".blocklyTreeRoot {","padding: 4px 0;","}",".blocklyTreeRoot:focus {","outline: none;","}",".blocklyTreeRow {","height: 22px;","line-height: 22px;","margin-bottom: 3px;","padding-right: 8px;","white-space: nowrap;","}",".blocklyHorizontalTree {","float: left;","margin: 1px 5px 8px 0;","}",".blocklyHorizontalTreeRtl {","float: right;","margin: 1px 0 8px 5px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',
|
||||
"margin-left: 8px;","}",".blocklyTreeRow:not(.blocklyTreeSelected):hover {","background-color: #e4e4e4;","}",".blocklyTreeSeparator {","border-bottom: solid #e5e5e5 1px;","height: 0;","margin: 5px 0;","}",".blocklyTreeSeparatorHorizontal {","border-right: solid #e5e5e5 1px;","width: 0;","padding: 5px 0;","margin: 0 5px;","}",".blocklyTreeIcon {","background-image: url(<<<PATH>>>/sprites.png);","height: 16px;","vertical-align: middle;","width: 16px;","}",".blocklyTreeIconClosedLtr {","background-position: -32px -1px;",
|
||||
"overflow-x: visible;","overflow-y: auto;","position: absolute;","z-index: 70;","}",".blocklyTreeRoot {","padding: 4px 0;","}",".blocklyTreeRoot:focus {","outline: none;","}",".blocklyTreeRow {","height: 22px;","line-height: 22px;","margin-bottom: 3px;","padding-right: 8px;","white-space: nowrap;","}",".blocklyHorizontalTree {","float: left;","margin: 1px 5px 8px 0;","}",".blocklyHorizontalTreeRtl {","float: right;","margin: 1px 0 8px 5px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',"margin-left: 8px;",
|
||||
"}",".blocklyTreeRow:not(.blocklyTreeSelected):hover {","background-color: #e4e4e4;","}",".blocklyTreeSeparator {","border-bottom: solid #e5e5e5 1px;","height: 0;","margin: 5px 0;","}",".blocklyTreeSeparatorHorizontal {","border-right: solid #e5e5e5 1px;","width: 0;","padding: 5px 0;","margin: 0 5px;","}",".blocklyTreeIcon {","background-image: url(<<<PATH>>>/sprites.png);","height: 16px;","vertical-align: middle;","width: 16px;","}",".blocklyTreeIconClosedLtr {","background-position: -32px -1px;",
|
||||
"}",".blocklyTreeIconClosedRtl {","background-position: 0px -1px;","}",".blocklyTreeIconOpen {","background-position: -16px -1px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedLtr {","background-position: -32px -17px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedRtl {","background-position: 0px -17px;","}",".blocklyTreeSelected>.blocklyTreeIconOpen {","background-position: -16px -17px;","}",".blocklyTreeIconNone,",".blocklyTreeSelected>.blocklyTreeIconNone {","background-position: -48px -1px;",
|
||||
"}",".blocklyTreeLabel {","cursor: default;","font-family: sans-serif;","font-size: 16px;","padding: 0 3px;","vertical-align: middle;","}",".blocklyToolboxDelete .blocklyTreeLabel {",'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',"}",".blocklyTreeSelected .blocklyTreeLabel {","color: #fff;","}",".blocklyWidgetDiv .goog-palette {","outline: none;","cursor: default;","}",".blocklyWidgetDiv .goog-palette-table {","border: 1px solid #666;","border-collapse: collapse;","}",".blocklyWidgetDiv .goog-palette-cell {",
|
||||
"height: 13px;","width: 15px;","margin: 0;","border: 0;","text-align: center;","vertical-align: middle;","border-right: 1px solid #666;","font-size: 1px;","}",".blocklyWidgetDiv .goog-palette-colorswatch {","position: relative;","height: 13px;","width: 15px;","border: 1px solid #666;","}",".blocklyWidgetDiv .goog-palette-cell-hover .goog-palette-colorswatch {","border: 1px solid #FFF;","}",".blocklyWidgetDiv .goog-palette-cell-selected .goog-palette-colorswatch {","border: 1px solid #000;","color: #fff;",
|
||||
|
||||
+102
-119
File diff suppressed because one or more lines are too long
@@ -1399,7 +1399,7 @@ Blockly.Events.VarRename=function(a,b){a&&(Blockly.Events.VarRename.superClass_.
|
||||
Blockly.Events.VarRename.prototype.fromJson=function(a){Blockly.Events.VarRename.superClass_.fromJson.call(this,a);this.oldName=a.oldName;this.newName=a.newName};Blockly.Events.VarRename.prototype.run=function(a){var b=this.getEventWorkspace_();a?b.renameVariableById(this.varId,this.newName):b.renameVariableById(this.varId,this.oldName)};
|
||||
Blockly.Events.disableOrphans=function(a){if(a.type==Blockly.Events.MOVE||a.type==Blockly.Events.CREATE){Blockly.Events.disable();var b=Blockly.Workspace.getById(a.workspaceId);if(a=b.getBlockById(a.blockId))if(a.getParent()&&!a.getParent().disabled){b=a.getDescendants();a=0;for(var c;c=b[a];a++)c.setDisabled(!1)}else if((a.outputConnection||a.previousConnection)&&!b.isDragging()){do a.setDisabled(!0),a=a.getNextBlock();while(a)}Blockly.Events.enable()}};Blockly.Msg={};goog.getMsgOrig=goog.getMsg;goog.getMsg=function(a,b){var c=goog.getMsg.blocklyMsgMap[a];c&&(a=Blockly.Msg[c]);return goog.getMsgOrig(a,b)};goog.getMsg.blocklyMsgMap={Today:"TODAY"};Blockly.FieldTextInput=function(a,b){Blockly.FieldTextInput.superClass_.constructor.call(this,a,b)};goog.inherits(Blockly.FieldTextInput,Blockly.Field);Blockly.FieldTextInput.FONTSIZE=11;Blockly.FieldTextInput.htmlInput_=null;Blockly.FieldTextInput.prototype.CURSOR="text";Blockly.FieldTextInput.prototype.spellcheck_=!0;Blockly.FieldTextInput.prototype.dispose=function(){Blockly.WidgetDiv.hideIfOwner(this);Blockly.FieldTextInput.superClass_.dispose.call(this)};
|
||||
Blockly.FieldTextInput.prototype.setValue=function(a){if(null!==a){if(this.sourceBlock_){var b=this.callValidator(a);null!==b&&(a=b)}Blockly.Field.prototype.setValue.call(this,a)}};Blockly.FieldTextInput.prototype.setText=function(a){null!==a&&(a=String(a),a!==this.text_&&(this.sourceBlock_&&Blockly.Events.isEnabled()&&Blockly.Events.fire(new Blockly.Events.BlockChange(this.sourceBlock_,"field",this.name,this.text_,a)),Blockly.Field.prototype.setText.call(this,a)))};
|
||||
Blockly.FieldTextInput.prototype.setSpellcheck=function(a){this.spellcheck_=a};Blockly.FieldTextInput.prototype.showEditor_=function(a){this.workspace_=this.sourceBlock_.workspace;a=a||!1;!a&&(goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD)?this.showPromptEditor_():this.showInlineEditor_(a)};Blockly.FieldTextInput.prototype.showPromptEditor_=function(){var a=this;Blockly.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_,function(b){a.sourceBlock_&&(b=a.callValidator(b));a.setValue(b)})};
|
||||
Blockly.FieldTextInput.prototype.setSpellcheck=function(a){this.spellcheck_=a};Blockly.FieldTextInput.prototype.showEditor_=function(a){this.workspace_=this.sourceBlock_.workspace;a=a||!1;!a&&(goog.userAgent.MOBILE||goog.userAgent.ANDROID||goog.userAgent.IPAD)?this.showPromptEditor_():this.showInlineEditor_(a)};Blockly.FieldTextInput.showPromptEditor_=function(){var a=this;Blockly.prompt(Blockly.Msg.CHANGE_VALUE_TITLE,this.text_,function(b){a.sourceBlock_&&(b=a.callValidator(b));a.setValue(b)})};
|
||||
Blockly.FieldTextInput.prototype.showInlineEditor_=function(a){Blockly.WidgetDiv.show(this,this.sourceBlock_.RTL,this.widgetDispose_());var b=Blockly.WidgetDiv.DIV,c=goog.dom.createDom("INPUT","blocklyHtmlInput");c.setAttribute("spellcheck",this.spellcheck_);var d=Blockly.FieldTextInput.FONTSIZE*this.workspace_.scale+"pt";b.style.fontSize=d;c.style.fontSize=d;Blockly.FieldTextInput.htmlInput_=c;b.appendChild(c);c.value=c.defaultValue=this.text_;c.oldValue_=null;this.validate_();this.resizeEditor_();
|
||||
a||(c.focus(),c.select());this.bindEvents_(c)};Blockly.FieldTextInput.prototype.bindEvents_=function(a){a.onKeyDownWrapper_=Blockly.bindEventWithChecks_(a,"keydown",this,this.onHtmlInputKeyDown_);a.onKeyUpWrapper_=Blockly.bindEventWithChecks_(a,"keyup",this,this.onHtmlInputChange_);a.onKeyPressWrapper_=Blockly.bindEventWithChecks_(a,"keypress",this,this.onHtmlInputChange_);a.onWorkspaceChangeWrapper_=this.resizeEditor_.bind(this);this.workspace_.addChangeListener(a.onWorkspaceChangeWrapper_)};
|
||||
Blockly.FieldTextInput.prototype.unbindEvents_=function(a){Blockly.unbindEvent_(a.onKeyDownWrapper_);Blockly.unbindEvent_(a.onKeyUpWrapper_);Blockly.unbindEvent_(a.onKeyPressWrapper_);this.workspace_.removeChangeListener(a.onWorkspaceChangeWrapper_)};
|
||||
@@ -1562,8 +1562,8 @@ Blockly.Css.CONTENT=[".blocklySvg {","background-color: #fff;","outline: none;",
|
||||
"opacity: 0;","}",".blocklyMainWorkspaceScrollbar {","z-index: 20;","}",".blocklyFlyoutScrollbar {","z-index: 30;","}",".blocklyScrollbarHorizontal, .blocklyScrollbarVertical {","position: absolute;","outline: none;","}",".blocklyScrollbarBackground {","opacity: 0;","}",".blocklyScrollbarHandle {","fill: #ccc;","}",".blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyScrollbarHandle:hover {","fill: #bbb;","}",".blocklyZoom>image {","opacity: .4;","}",".blocklyZoom>image:hover {",
|
||||
"opacity: .6;","}",".blocklyZoom>image:active {","opacity: .8;","}",".blocklyFlyout .blocklyScrollbarHandle {","fill: #bbb;","}",".blocklyFlyout .blocklyScrollbarBackground:hover+.blocklyScrollbarHandle,",".blocklyFlyout .blocklyScrollbarHandle:hover {","fill: #aaa;","}",".blocklyInvalidInput {","background: #faa;","}",".blocklyAngleCircle {","stroke: #444;","stroke-width: 1;","fill: #ddd;","fill-opacity: .8;","}",".blocklyAngleMarks {","stroke: #444;","stroke-width: 1;","}",".blocklyAngleGauge {",
|
||||
"fill: #f88;","fill-opacity: .8;","}",".blocklyAngleLine {","stroke: #f00;","stroke-width: 2;","stroke-linecap: round;","pointer-events: none;","}",".blocklyContextMenu {","border-radius: 4px;","}",".blocklyDropdownMenu {","padding: 0 !important;","}",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,",".blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {","background: url(<<<PATH>>>/sprites.png) no-repeat -48px -16px !important;","}",".blocklyToolboxDiv {","background-color: #ddd;",
|
||||
"overflow-x: visible;","overflow-y: auto;","position: absolute;","z-index: 70;","-webkit-tap-highlight-color: transparent;","}",".blocklyTreeRoot {","padding: 4px 0;","}",".blocklyTreeRoot:focus {","outline: none;","}",".blocklyTreeRow {","height: 22px;","line-height: 22px;","margin-bottom: 3px;","padding-right: 8px;","white-space: nowrap;","}",".blocklyHorizontalTree {","float: left;","margin: 1px 5px 8px 0;","}",".blocklyHorizontalTreeRtl {","float: right;","margin: 1px 0 8px 5px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',
|
||||
"margin-left: 8px;","}",".blocklyTreeRow:not(.blocklyTreeSelected):hover {","background-color: #e4e4e4;","}",".blocklyTreeSeparator {","border-bottom: solid #e5e5e5 1px;","height: 0;","margin: 5px 0;","}",".blocklyTreeSeparatorHorizontal {","border-right: solid #e5e5e5 1px;","width: 0;","padding: 5px 0;","margin: 0 5px;","}",".blocklyTreeIcon {","background-image: url(<<<PATH>>>/sprites.png);","height: 16px;","vertical-align: middle;","width: 16px;","}",".blocklyTreeIconClosedLtr {","background-position: -32px -1px;",
|
||||
"overflow-x: visible;","overflow-y: auto;","position: absolute;","z-index: 70;","}",".blocklyTreeRoot {","padding: 4px 0;","}",".blocklyTreeRoot:focus {","outline: none;","}",".blocklyTreeRow {","height: 22px;","line-height: 22px;","margin-bottom: 3px;","padding-right: 8px;","white-space: nowrap;","}",".blocklyHorizontalTree {","float: left;","margin: 1px 5px 8px 0;","}",".blocklyHorizontalTreeRtl {","float: right;","margin: 1px 0 8px 5px;","}",'.blocklyToolboxDiv[dir="RTL"] .blocklyTreeRow {',"margin-left: 8px;",
|
||||
"}",".blocklyTreeRow:not(.blocklyTreeSelected):hover {","background-color: #e4e4e4;","}",".blocklyTreeSeparator {","border-bottom: solid #e5e5e5 1px;","height: 0;","margin: 5px 0;","}",".blocklyTreeSeparatorHorizontal {","border-right: solid #e5e5e5 1px;","width: 0;","padding: 5px 0;","margin: 0 5px;","}",".blocklyTreeIcon {","background-image: url(<<<PATH>>>/sprites.png);","height: 16px;","vertical-align: middle;","width: 16px;","}",".blocklyTreeIconClosedLtr {","background-position: -32px -1px;",
|
||||
"}",".blocklyTreeIconClosedRtl {","background-position: 0px -1px;","}",".blocklyTreeIconOpen {","background-position: -16px -1px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedLtr {","background-position: -32px -17px;","}",".blocklyTreeSelected>.blocklyTreeIconClosedRtl {","background-position: 0px -17px;","}",".blocklyTreeSelected>.blocklyTreeIconOpen {","background-position: -16px -17px;","}",".blocklyTreeIconNone,",".blocklyTreeSelected>.blocklyTreeIconNone {","background-position: -48px -1px;",
|
||||
"}",".blocklyTreeLabel {","cursor: default;","font-family: sans-serif;","font-size: 16px;","padding: 0 3px;","vertical-align: middle;","}",".blocklyToolboxDelete .blocklyTreeLabel {",'cursor: url("<<<PATH>>>/handdelete.cur"), auto;',"}",".blocklyTreeSelected .blocklyTreeLabel {","color: #fff;","}",".blocklyWidgetDiv .goog-palette {","outline: none;","cursor: default;","}",".blocklyWidgetDiv .goog-palette-table {","border: 1px solid #666;","border-collapse: collapse;","}",".blocklyWidgetDiv .goog-palette-cell {",
|
||||
"height: 13px;","width: 15px;","margin: 0;","border: 0;","text-align: center;","vertical-align: middle;","border-right: 1px solid #666;","font-size: 1px;","}",".blocklyWidgetDiv .goog-palette-colorswatch {","position: relative;","height: 13px;","width: 15px;","border: 1px solid #666;","}",".blocklyWidgetDiv .goog-palette-cell-hover .goog-palette-colorswatch {","border: 1px solid #FFF;","}",".blocklyWidgetDiv .goog-palette-cell-selected .goog-palette-colorswatch {","border: 1px solid #000;","color: #fff;",
|
||||
|
||||
+102
-119
File diff suppressed because one or more lines are too long
+2
-1
@@ -107,7 +107,8 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
|
||||
// Block for blending two colours together.
|
||||
{
|
||||
"type": "colour_blend",
|
||||
"message0": "%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} %1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3",
|
||||
"message0": "%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} " +
|
||||
"%1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
|
||||
+5
-5
@@ -295,8 +295,8 @@ Blockly.Constants.Logic.TOOLTIPS_BY_OP = {
|
||||
};
|
||||
|
||||
Blockly.Extensions.register('logic_op_tooltip',
|
||||
Blockly.Extensions.buildTooltipForDropdown(
|
||||
'OP', Blockly.Constants.Logic.TOOLTIPS_BY_OP));
|
||||
Blockly.Extensions.buildTooltipForDropdown(
|
||||
'OP', Blockly.Constants.Logic.TOOLTIPS_BY_OP));
|
||||
|
||||
/**
|
||||
* Mutator methods added to controls_if blocks.
|
||||
@@ -486,7 +486,7 @@ Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION = function() {
|
||||
};
|
||||
|
||||
Blockly.Extensions.register('controls_if_tooltip',
|
||||
Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION);
|
||||
Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION);
|
||||
|
||||
/**
|
||||
* Corrects the logic_compare dropdown label with respect to language direction.
|
||||
@@ -574,7 +574,7 @@ Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION = function() {
|
||||
};
|
||||
|
||||
Blockly.Extensions.register('logic_compare',
|
||||
Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION);
|
||||
Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION);
|
||||
|
||||
/**
|
||||
* Adds type coordination between inputs and output.
|
||||
@@ -619,4 +619,4 @@ Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN = {
|
||||
};
|
||||
|
||||
Blockly.Extensions.registerMixin('logic_ternary',
|
||||
Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN);
|
||||
Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN);
|
||||
|
||||
+11
-11
@@ -227,8 +227,8 @@ Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS = {
|
||||
};
|
||||
|
||||
Blockly.Extensions.register('controls_whileUntil_tooltip',
|
||||
Blockly.Extensions.buildTooltipForDropdown(
|
||||
'MODE', Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));
|
||||
Blockly.Extensions.buildTooltipForDropdown(
|
||||
'MODE', Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));
|
||||
|
||||
/**
|
||||
* Tooltips for the 'controls_flow_statements' block, keyed by FLOW value.
|
||||
@@ -242,8 +242,8 @@ Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS = {
|
||||
};
|
||||
|
||||
Blockly.Extensions.register('controls_flow_tooltip',
|
||||
Blockly.Extensions.buildTooltipForDropdown(
|
||||
'FLOW', Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
|
||||
Blockly.Extensions.buildTooltipForDropdown(
|
||||
'FLOW', Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
|
||||
|
||||
/**
|
||||
* Mixin to add a context menu item to create a 'variables_get' block.
|
||||
@@ -277,15 +277,15 @@ Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN = {
|
||||
};
|
||||
|
||||
Blockly.Extensions.registerMixin('contextMenu_newGetVariableBlock',
|
||||
Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);
|
||||
Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);
|
||||
|
||||
Blockly.Extensions.register('controls_for_tooltip',
|
||||
Blockly.Extensions.buildTooltipWithFieldValue(
|
||||
Blockly.Msg.CONTROLS_FOR_TOOLTIP, 'VAR'));
|
||||
Blockly.Extensions.buildTooltipWithFieldValue(
|
||||
'%{BKY_CONTROLS_FOR_TOOLTIP}', 'VAR'));
|
||||
|
||||
Blockly.Extensions.register('controls_forEach_tooltip',
|
||||
Blockly.Extensions.buildTooltipWithFieldValue(
|
||||
Blockly.Msg.CONTROLS_FOREACH_TOOLTIP, 'VAR'));
|
||||
Blockly.Extensions.buildTooltipWithFieldValue(
|
||||
'%{BKY_CONTROLS_FOREACH_TOOLTIP}', 'VAR'));
|
||||
|
||||
/**
|
||||
* This mixin adds a check to make sure the 'controls_flow_statements' block
|
||||
@@ -295,7 +295,7 @@ Blockly.Extensions.register('controls_forEach_tooltip',
|
||||
* @package
|
||||
* @readonly
|
||||
*/
|
||||
Blockly.Constants.Loops.CONTROL_FLOW_CHECK_IN_LOOP_MIXIN = {
|
||||
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = {
|
||||
/**
|
||||
* List of block types that are loops and thus do not need warnings.
|
||||
* To add a new loop type add this to your code:
|
||||
@@ -339,4 +339,4 @@ Blockly.Constants.Loops.CONTROL_FLOW_CHECK_IN_LOOP_MIXIN = {
|
||||
};
|
||||
|
||||
Blockly.Extensions.registerMixin('controls_flow_in_loop_check',
|
||||
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);
|
||||
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);
|
||||
|
||||
+8
-8
@@ -422,8 +422,8 @@ Blockly.Constants.Math.TOOLTIPS_BY_OP = {
|
||||
};
|
||||
|
||||
Blockly.Extensions.register('math_op_tooltip',
|
||||
Blockly.Extensions.buildTooltipForDropdown(
|
||||
'OP', Blockly.Constants.Math.TOOLTIPS_BY_OP));
|
||||
Blockly.Extensions.buildTooltipForDropdown(
|
||||
'OP', Blockly.Constants.Math.TOOLTIPS_BY_OP));
|
||||
|
||||
|
||||
/**
|
||||
@@ -489,8 +489,8 @@ Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION = function() {
|
||||
};
|
||||
|
||||
Blockly.Extensions.registerMutator('math_is_divisibleby_mutator',
|
||||
Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,
|
||||
Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);
|
||||
Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,
|
||||
Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);
|
||||
|
||||
/**
|
||||
* Update the tooltip of 'math_change' block to reference the variable.
|
||||
@@ -505,8 +505,8 @@ Blockly.Constants.Math.CHANGE_TOOLTIP_EXTENSION = function() {
|
||||
};
|
||||
|
||||
Blockly.Extensions.register('math_change_tooltip',
|
||||
Blockly.Extensions.buildTooltipWithFieldValue(
|
||||
Blockly.Msg.MATH_CHANGE_TOOLTIP, 'VAR'));
|
||||
Blockly.Extensions.buildTooltipWithFieldValue(
|
||||
'%{BKY_MATH_CHANGE_TOOLTIP}', 'VAR'));
|
||||
|
||||
/**
|
||||
* Mixin with mutator methods to support alternate output based if the
|
||||
@@ -563,5 +563,5 @@ Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION = function() {
|
||||
};
|
||||
|
||||
Blockly.Extensions.registerMutator('math_modes_of_list_mutator',
|
||||
Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN,
|
||||
Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION);
|
||||
Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN,
|
||||
Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION);
|
||||
|
||||
+61
-54
@@ -188,8 +188,13 @@ Blockly.defineBlocksWithJsonArray([ // BEGIN JSON EXTRACT
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "input_dummy",
|
||||
"name": "AT"
|
||||
"type": "field_dropdown",
|
||||
"name": "WHERE",
|
||||
"options": [["%{BKY_TEXT_CHARAT_FROM_START}", "FROM_START"],
|
||||
["%{BKY_TEXT_CHARAT_FROM_END}", "FROM_END"],
|
||||
["%{BKY_TEXT_CHARAT_FIRST}", "FIRST"],
|
||||
["%{BKY_TEXT_CHARAT_LAST}", "LAST"],
|
||||
["%{BKY_TEXT_CHARAT_RANDOM}", "RANDOM"]]
|
||||
}
|
||||
],
|
||||
"output": "String",
|
||||
@@ -562,17 +567,25 @@ Blockly.Blocks['text_reverse'] = {
|
||||
*/
|
||||
Blockly.Constants.Text.QUOTE_IMAGE_MIXIN = {
|
||||
/**
|
||||
* Image data URI of an LTR opening double quote (same as RTL closing couble quote).
|
||||
* Image data URI of an LTR opening double quote (same as RTL closing double quote).
|
||||
* @readonly
|
||||
*/
|
||||
QUOTE_IMAGE_LEFT_DATAURI:
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC',
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAA' +
|
||||
'n0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY' +
|
||||
'1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1' +
|
||||
'HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMf' +
|
||||
'z9AylsaRRgGzvZAAAAAElFTkSuQmCC',
|
||||
/**
|
||||
* Image data URI of an LTR closing double quote (same as RTL opening couble quote).
|
||||
* Image data URI of an LTR closing double quote (same as RTL opening double quote).
|
||||
* @readonly
|
||||
*/
|
||||
QUOTE_IMAGE_RIGHT_DATAURI:
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==',
|
||||
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAA' +
|
||||
'qUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhg' +
|
||||
'gONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvB' +
|
||||
'O3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5Aos' +
|
||||
'lLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==',
|
||||
/**
|
||||
* Pixel width of QUOTE_IMAGE_LEFT_DATAURI and QUOTE_IMAGE_RIGHT_DATAURI.
|
||||
* @readonly
|
||||
@@ -587,6 +600,7 @@ Blockly.Constants.Text.QUOTE_IMAGE_MIXIN = {
|
||||
/**
|
||||
* Inserts appropriate quote images before and after the named field.
|
||||
* @param {string} fieldName The name of the field to wrap with quotes.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
quoteField_: function(fieldName) {
|
||||
for (var i = 0, input; input = this.inputList[i]; i++) {
|
||||
@@ -607,6 +621,7 @@ Blockly.Constants.Text.QUOTE_IMAGE_MIXIN = {
|
||||
* @param {boolean} open If the image should be open quote (“ in LTR).
|
||||
* Otherwise, a closing quote is used (” in LTR).
|
||||
* @returns {!Blockly.FieldImage} The new field.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
newQuote_: function(open) {
|
||||
var isLeft = this.RTL? !open : open;
|
||||
@@ -749,10 +764,10 @@ Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN = {
|
||||
Blockly.Constants.Text.TEXT_JOIN_EXTENSION = function() {
|
||||
// Add the quote mixin for the itemCount_ = 0 case.
|
||||
this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);
|
||||
// initialize the mutator values
|
||||
// Initialize the mutator values.
|
||||
this.itemCount_ = 2;
|
||||
this.updateShape_();
|
||||
// Configure the mutator ui
|
||||
// Configure the mutator UI.
|
||||
this.setMutator(new Blockly.Mutator(['text_create_join_item']));
|
||||
};
|
||||
|
||||
@@ -814,7 +829,7 @@ Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN = {
|
||||
*/
|
||||
updateAt_: function(isAt) {
|
||||
// Destroy old 'AT' and 'ORDINAL' inputs.
|
||||
this.removeInput('AT');
|
||||
this.removeInput('AT', true);
|
||||
this.removeInput('ORDINAL', true);
|
||||
// Create either a value 'AT' input or a dummy input.
|
||||
if (isAt) {
|
||||
@@ -823,71 +838,63 @@ Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN = {
|
||||
this.appendDummyInput('ORDINAL')
|
||||
.appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX);
|
||||
}
|
||||
} else {
|
||||
this.appendDummyInput('AT');
|
||||
}
|
||||
if (Blockly.Msg.TEXT_CHARAT_TAIL) {
|
||||
this.removeInput('TAIL', true);
|
||||
this.appendDummyInput('TAIL')
|
||||
.appendField(Blockly.Msg.TEXT_CHARAT_TAIL);
|
||||
}
|
||||
var menu = new Blockly.FieldDropdown(this.WHERE_OPTIONS, function(value) {
|
||||
var newAt = (value == 'FROM_START') || (value == 'FROM_END');
|
||||
// The 'isAt' variable is available due to this function being a closure.
|
||||
if (newAt != isAt) {
|
||||
var block = this.sourceBlock_;
|
||||
block.updateAt_(newAt);
|
||||
// This menu has been destroyed and replaced. Update the replacement.
|
||||
block.setFieldValue(value, 'WHERE');
|
||||
return null;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
this.getInput('AT').appendField(menu, 'WHERE');
|
||||
|
||||
this.isAt_ = isAt;
|
||||
}
|
||||
};
|
||||
|
||||
// Does the initial mutator update of text_charAt and adds the tooltip
|
||||
Blockly.Constants.Text.TEXT_CHARAT_EXTENSION = function() {
|
||||
this.WHERE_OPTIONS = [
|
||||
[Blockly.Msg.TEXT_CHARAT_FROM_START, 'FROM_START'],
|
||||
[Blockly.Msg.TEXT_CHARAT_FROM_END, 'FROM_END'],
|
||||
[Blockly.Msg.TEXT_CHARAT_FIRST, 'FIRST'],
|
||||
[Blockly.Msg.TEXT_CHARAT_LAST, 'LAST'],
|
||||
[Blockly.Msg.TEXT_CHARAT_RANDOM, 'RANDOM']
|
||||
];
|
||||
this.updateAt_(true);
|
||||
// Assign 'this' to a variable for use in the tooltip closure below.
|
||||
var thisBlock = this;
|
||||
this.setTooltip(function() {
|
||||
var where = thisBlock.getFieldValue('WHERE');
|
||||
var tooltip = Blockly.Msg.TEXT_CHARAT_TOOLTIP;
|
||||
if (where == 'FROM_START' || where == 'FROM_END') {
|
||||
var msg = (where == 'FROM_START') ?
|
||||
Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP :
|
||||
Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP;
|
||||
if (msg) {
|
||||
tooltip += ' ' + msg.replace('%1',
|
||||
thisBlock.workspace.options.oneBasedIndex ? '#1' : '#0');
|
||||
}
|
||||
var dropdown = this.getField('WHERE');
|
||||
dropdown.setValidator(function(value) {
|
||||
var newAt = (value == 'FROM_START') || (value == 'FROM_END');
|
||||
if (newAt != this.isAt_) {
|
||||
var block = this.sourceBlock_;
|
||||
block.updateAt_(newAt);
|
||||
// This menu has been destroyed and replaced. Update the replacement.
|
||||
block.setFieldValue(value, 'WHERE');
|
||||
return null;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
this.updateAt_(true);
|
||||
// Assign 'this' to a variable for use in the tooltip closure below.
|
||||
var thisBlock = this;
|
||||
this.setTooltip(function() {
|
||||
var where = thisBlock.getFieldValue('WHERE');
|
||||
var tooltip = Blockly.Msg.TEXT_CHARAT_TOOLTIP;
|
||||
if (where == 'FROM_START' || where == 'FROM_END') {
|
||||
var msg = (where == 'FROM_START') ?
|
||||
Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP :
|
||||
Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP;
|
||||
if (msg) {
|
||||
tooltip += ' ' + msg.replace('%1',
|
||||
thisBlock.workspace.options.oneBasedIndex ? '#1' : '#0');
|
||||
}
|
||||
return tooltip;
|
||||
});
|
||||
}
|
||||
return tooltip;
|
||||
});
|
||||
};
|
||||
|
||||
Blockly.Extensions.register('text_indexOf_tooltip',
|
||||
Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION);
|
||||
Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION);
|
||||
|
||||
Blockly.Extensions.register('text_quotes',
|
||||
Blockly.Constants.Text.TEXT_QUOTES_EXTENSION);
|
||||
Blockly.Constants.Text.TEXT_QUOTES_EXTENSION);
|
||||
|
||||
Blockly.Extensions.register('text_append_tooltip',
|
||||
Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION);
|
||||
Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION);
|
||||
|
||||
Blockly.Extensions.registerMutator('text_join_mutator',
|
||||
Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN,
|
||||
Blockly.Constants.Text.TEXT_JOIN_EXTENSION);
|
||||
Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN,
|
||||
Blockly.Constants.Text.TEXT_JOIN_EXTENSION);
|
||||
|
||||
Blockly.Extensions.registerMutator('text_charAt_mutator',
|
||||
Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN,
|
||||
Blockly.Constants.Text.TEXT_CHARAT_EXTENSION);
|
||||
Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN,
|
||||
Blockly.Constants.Text.TEXT_CHARAT_EXTENSION);
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
# The uncompressed file is a script that loads in each of Blockly's core files
|
||||
# one by one. This takes much longer for a browser to load, but is useful
|
||||
# when debugging code since line numbers are meaningful and variables haven't
|
||||
# been renamed. The uncompressed file also allows for a faster developement
|
||||
# been renamed. The uncompressed file also allows for a faster development
|
||||
# cycle since there is no need to rebuild or recompile, just reload.
|
||||
#
|
||||
# The second pair are:
|
||||
@@ -45,10 +45,11 @@
|
||||
#
|
||||
# This script also generates:
|
||||
# blocks_compressed.js: The compressed Blockly language blocks.
|
||||
# javascript_compressed.js: The compressed Javascript generator.
|
||||
# javascript_compressed.js: The compressed JavaScript generator.
|
||||
# python_compressed.js: The compressed Python generator.
|
||||
# dart_compressed.js: The compressed Dart generator.
|
||||
# php_compressed.js: The compressed PHP generator.
|
||||
# lua_compressed.js: The compressed Lua generator.
|
||||
# dart_compressed.js: The compressed Dart generator.
|
||||
# msg/js/<LANG>.js for every language <LANG> defined in msg/js/<LANG>.json.
|
||||
|
||||
import sys
|
||||
@@ -60,10 +61,9 @@ for arg in sys.argv[1:len(sys.argv)]:
|
||||
if (arg != 'core' and
|
||||
arg != 'accessible' and
|
||||
arg != 'generators' and
|
||||
arg != 'langfiles' and
|
||||
arg != 'demo'):
|
||||
raise Exception("Invalid argument: \"" + arg + "\". Usage: build.py <0 or more of accessible," +
|
||||
" core, generators, langfiles, demo>")
|
||||
arg != 'langfiles'):
|
||||
raise Exception("Invalid argument: \"" + arg + "\". Usage: build.py "
|
||||
"<0 or more of accessible, core, generators, langfiles>")
|
||||
|
||||
import errno, glob, httplib, json, os, re, subprocess, threading, urllib
|
||||
|
||||
@@ -212,49 +212,8 @@ class Gen_compressed(threading.Thread):
|
||||
self.gen_generator("javascript")
|
||||
self.gen_generator("python")
|
||||
self.gen_generator("php")
|
||||
self.gen_generator("dart")
|
||||
self.gen_generator("lua")
|
||||
|
||||
if ('demo' in self.bundles):
|
||||
self.gen_together()
|
||||
|
||||
def gen_together(self):
|
||||
target_filename = os.path.join("demos", "fixed-advanced", "main_compressed.js")
|
||||
# Define the parameters for the POST request.
|
||||
params = [
|
||||
("compilation_level", "ADVANCED_OPTIMIZATIONS"),
|
||||
("use_closure_library", "true"),
|
||||
("generate_exports", "true"),
|
||||
("output_format", "json"),
|
||||
("output_info", "compiled_code"),
|
||||
("output_info", "warnings"),
|
||||
("output_info", "errors"),
|
||||
("output_info", "statistics"),
|
||||
# debug options (to make the uglified code readable)
|
||||
# ("formatting", "pretty_print"),
|
||||
# ("formatting", "print_input_delimiter"),
|
||||
# ("debug", "true"),
|
||||
]
|
||||
|
||||
# Read in all the source files.
|
||||
filenames = calcdeps.CalculateDependencies(self.search_paths,
|
||||
[os.path.join("demos", "fixed-advanced", "main.js")])
|
||||
filenames.sort() # Deterministic build.
|
||||
for filename in filenames:
|
||||
# Filter out the Closure files (the compiler will add them).
|
||||
if filename.startswith(os.pardir + os.sep): # '../'
|
||||
continue
|
||||
f = open(filename)
|
||||
params.append(("js_code", "".join(f.readlines())))
|
||||
f.close()
|
||||
|
||||
externs = [os.path.join("externs", "svg-externs.js")]
|
||||
for filename in externs:
|
||||
f = open(filename)
|
||||
params.append(("js_externs", "".join(f.readlines())))
|
||||
f.close()
|
||||
|
||||
self.do_compile(params, target_filename, filenames, "")
|
||||
self.gen_generator("dart")
|
||||
|
||||
def gen_core(self):
|
||||
target_filename = "blockly_compressed.js"
|
||||
@@ -403,7 +362,12 @@ class Gen_compressed(threading.Thread):
|
||||
conn.close()
|
||||
|
||||
# Parse the JSON response.
|
||||
json_data = json.loads(json_str)
|
||||
try:
|
||||
json_data = json.loads(json_str)
|
||||
except ValueError:
|
||||
print("ERROR: Could not parse JSON for %s. Raw data:" % target_filename)
|
||||
print(json_str)
|
||||
return
|
||||
|
||||
def file_lookup(name):
|
||||
if not name.startswith("Input_"):
|
||||
@@ -610,16 +574,8 @@ developers.google.com/blockly/guides/modify/web/closure""")
|
||||
if ('accessible' in args):
|
||||
Gen_uncompressed(full_search_paths, 'blockly_accessible_uncompressed.js').start()
|
||||
|
||||
if ('demo' in args):
|
||||
all_search_paths = calcdeps.ExpandDirectories(
|
||||
["accessible", "core", "blocks", os.path.join("demos", "fixed-advanced"), os.path.join("msg", "js"), os.path.join(os.path.pardir, "closure-library")])
|
||||
all_search_paths.sort() # Deterministic build.
|
||||
print("Compressing " + str(len(all_search_paths)) + " files...")
|
||||
Gen_compressed(all_search_paths, args).start()
|
||||
|
||||
else:
|
||||
# Compressed is limited by network and server speed.
|
||||
Gen_compressed(full_search_paths, args).start()
|
||||
# Compressed is limited by network and server speed.
|
||||
Gen_compressed(full_search_paths, args).start()
|
||||
|
||||
# This is run locally in a separate thread
|
||||
# defaultlangfiles checks for changes in the msg files, while manually asking
|
||||
|
||||
+20
-11
@@ -48,7 +48,7 @@ goog.require('goog.string');
|
||||
* @param {?string} prototypeName Name of the language object containing
|
||||
* type-specific functions for this block.
|
||||
* @param {string=} opt_id Optional ID. Use this ID if provided, otherwise
|
||||
* create a new id.
|
||||
* create a new ID.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Block = function(workspace, prototypeName, opt_id) {
|
||||
@@ -261,7 +261,7 @@ Blockly.Block.prototype.dispose = function(healStack) {
|
||||
/**
|
||||
* Unplug this block from its superior block. If this block is a statement,
|
||||
* optionally reconnect the block underneath with the block on top.
|
||||
* @param {boolean} opt_healStack Disconnect child statement and reconnect
|
||||
* @param {boolean=} opt_healStack Disconnect child statement and reconnect
|
||||
* stack. Defaults to false.
|
||||
*/
|
||||
Blockly.Block.prototype.unplug = function(opt_healStack) {
|
||||
@@ -293,10 +293,13 @@ Blockly.Block.prototype.unplug = function(opt_healStack) {
|
||||
|
||||
/**
|
||||
* Returns all connections originating from this block.
|
||||
* @param {boolean} all If true, return all connections even hidden ones.
|
||||
* @return {!Array.<!Blockly.Connection>} Array of connections.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Block.prototype.getConnections_ = function() {
|
||||
Blockly.Block.prototype.getConnections_ = function(
|
||||
/* eslint-disable no-unused-vars */ all
|
||||
/* eslint-enable no-unused-vars */) {
|
||||
var myConnections = [];
|
||||
if (this.outputConnection) {
|
||||
myConnections.push(this.outputConnection);
|
||||
@@ -608,7 +611,7 @@ Blockly.Block.prototype.getColour = function() {
|
||||
*/
|
||||
Blockly.Block.prototype.getHue = function() {
|
||||
return this.hue_;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Change the colour of a block.
|
||||
@@ -619,9 +622,9 @@ Blockly.Block.prototype.setColour = function(colour) {
|
||||
if (!isNaN(hue) && 0 <= hue && hue <= 360) {
|
||||
this.hue_ = hue;
|
||||
this.colour_ = Blockly.hueToRgb(hue);
|
||||
} else if (goog.isString(colour) && colour.match(/^#[0-9a-fA-F]{6}$/)) {
|
||||
} else if (goog.isString(colour) && /^#[0-9a-fA-F]{6}$/.test(colour)) {
|
||||
this.colour_ = colour;
|
||||
// Only store hue if colour is set as a hue
|
||||
// Only store hue if colour is set as a hue.
|
||||
this.hue_ = null;
|
||||
} else {
|
||||
throw 'Invalid colour: ' + colour;
|
||||
@@ -727,7 +730,7 @@ Blockly.Block.prototype.setFieldValue = function(newValue, name) {
|
||||
/**
|
||||
* Set whether this block can chain onto the bottom of another block.
|
||||
* @param {boolean} newBoolean True if there can be a previous statement.
|
||||
* @param {string|Array.<string>|null|undefined} opt_check Statement type or
|
||||
* @param {(string|Array.<string>|null)=} opt_check Statement type or
|
||||
* list of statement types. Null/undefined if any type could be connected.
|
||||
*/
|
||||
Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) {
|
||||
@@ -755,7 +758,7 @@ Blockly.Block.prototype.setPreviousStatement = function(newBoolean, opt_check) {
|
||||
/**
|
||||
* Set whether another block can chain onto the bottom of this block.
|
||||
* @param {boolean} newBoolean True if there can be a next statement.
|
||||
* @param {string|Array.<string>|null|undefined} opt_check Statement type or
|
||||
* @param {(string|Array.<string>|null)=} opt_check Statement type or
|
||||
* list of statement types. Null/undefined if any type could be connected.
|
||||
*/
|
||||
Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) {
|
||||
@@ -780,7 +783,7 @@ Blockly.Block.prototype.setNextStatement = function(newBoolean, opt_check) {
|
||||
/**
|
||||
* Set whether this block returns a value.
|
||||
* @param {boolean} newBoolean True if there is an output.
|
||||
* @param {string|Array.<string>|null|undefined} opt_check Returned type or list
|
||||
* @param {(string|Array.<string>|null)=} opt_check Returned type or list
|
||||
* of returned types. Null or undefined if any type could be returned
|
||||
* (e.g. variable get).
|
||||
*/
|
||||
@@ -1423,8 +1426,12 @@ Blockly.Block.prototype.setCommentText = function(text) {
|
||||
/**
|
||||
* Set this block's warning text.
|
||||
* @param {?string} text The text, or null to delete.
|
||||
* @param {string=} opt_id An optional ID for the warning text to be able to
|
||||
* maintain multiple warnings.
|
||||
*/
|
||||
Blockly.Block.prototype.setWarningText = function(/* text */) {
|
||||
Blockly.Block.prototype.setWarningText = function(text,
|
||||
/* eslint-disable no-unused-vars */ opt_id
|
||||
/* eslint-enable no-unused-vars */) {
|
||||
// NOP.
|
||||
};
|
||||
|
||||
@@ -1432,7 +1439,9 @@ Blockly.Block.prototype.setWarningText = function(/* text */) {
|
||||
* Give this block a mutator dialog.
|
||||
* @param {Blockly.Mutator} mutator A mutator dialog instance or null to remove.
|
||||
*/
|
||||
Blockly.Block.prototype.setMutator = function(/* mutator */) {
|
||||
Blockly.Block.prototype.setMutator = function(
|
||||
/* eslint-disable no-unused-vars */ mutator
|
||||
/* eslint-enable no-unused-vars */) {
|
||||
// NOP.
|
||||
};
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
|
||||
/**
|
||||
* @fileoverview A class that manages a surface for dragging blocks. When a
|
||||
* block drag is started, we move the block (and children) to a separate dom
|
||||
* block drag is started, we move the block (and children) to a separate DOM
|
||||
* element that we move around using translate3d. At the end of the drag, the
|
||||
* blocks are put back in into the svg they came from. This helps performance by
|
||||
* avoiding repainting the entire svg on every mouse move while dragging blocks.
|
||||
* blocks are put back in into the SVG they came from. This helps performance by
|
||||
* avoiding repainting the entire SVG on every mouse move while dragging blocks.
|
||||
* @author picklesrus
|
||||
*/
|
||||
|
||||
@@ -202,7 +202,7 @@ Blockly.BlockDragSurfaceSvg.prototype.getCurrentBlock = function() {
|
||||
* element.
|
||||
* If the block is being deleted it doesn't need to go back to the original
|
||||
* surface, since it would be removed immediately during dispose.
|
||||
* @param {Element} opt_newSurface Surface the dragging blocks should be moved
|
||||
* @param {Element=} opt_newSurface Surface the dragging blocks should be moved
|
||||
* to, or null if the blocks should be removed from this surface without
|
||||
* being moved to a different surface.
|
||||
*/
|
||||
|
||||
@@ -326,9 +326,8 @@ Blockly.BlockSvg.prototype.render = function(opt_bubble) {
|
||||
* @return {number} X-coordinate of the end of the field row (plus a gap).
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.renderFields_ =
|
||||
function(fieldList, cursorX, cursorY) {
|
||||
/* eslint-disable indent */
|
||||
Blockly.BlockSvg.prototype.renderFields_ = function(fieldList,
|
||||
cursorX, cursorY) {
|
||||
cursorY += Blockly.BlockSvg.INLINE_PADDING_Y;
|
||||
if (this.RTL) {
|
||||
cursorX = -cursorX;
|
||||
@@ -356,7 +355,7 @@ Blockly.BlockSvg.prototype.renderFields_ =
|
||||
}
|
||||
}
|
||||
return this.RTL ? -cursorX : cursorX;
|
||||
}; /* eslint-enable indent */
|
||||
};
|
||||
|
||||
/**
|
||||
* Computes the height and widths for each row and field.
|
||||
@@ -614,9 +613,8 @@ Blockly.BlockSvg.prototype.renderMoveConnections_ = function() {
|
||||
* @param {number} rightEdge Minimum width of block.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.renderDrawTop_ =
|
||||
function(steps, highlightSteps, rightEdge) {
|
||||
/* eslint-disable indent */
|
||||
Blockly.BlockSvg.prototype.renderDrawTop_ = function(steps,
|
||||
highlightSteps, rightEdge) {
|
||||
// Position the cursor at the top-left starting point.
|
||||
if (this.squareTopLeftCorner_) {
|
||||
steps.push('m 0,0');
|
||||
@@ -651,7 +649,7 @@ Blockly.BlockSvg.prototype.renderDrawTop_ =
|
||||
steps.push('H', rightEdge);
|
||||
highlightSteps.push('H', rightEdge - 0.5);
|
||||
this.width = rightEdge;
|
||||
}; /* eslint-enable indent */
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the right edge of the block.
|
||||
@@ -916,9 +914,8 @@ Blockly.BlockSvg.prototype.renderDrawRight_ = function(steps, highlightSteps,
|
||||
* @param {number} cursorY Height of block.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.renderDrawBottom_ =
|
||||
function(steps, highlightSteps, cursorY) {
|
||||
/* eslint-disable indent */
|
||||
Blockly.BlockSvg.prototype.renderDrawBottom_ = function(steps,
|
||||
highlightSteps, cursorY) {
|
||||
this.height += cursorY + 1; // Add one for the shadow.
|
||||
if (this.nextConnection) {
|
||||
steps.push('H', (Blockly.BlockSvg.NOTCH_WIDTH + (this.RTL ? 0.5 : - 0.5)) +
|
||||
@@ -954,7 +951,7 @@ Blockly.BlockSvg.prototype.renderDrawBottom_ =
|
||||
'0.5,' + (cursorY - Blockly.BlockSvg.CORNER_RADIUS));
|
||||
}
|
||||
}
|
||||
}; /* eslint-enable indent */
|
||||
};
|
||||
|
||||
/**
|
||||
* Render the left edge of the block.
|
||||
|
||||
+44
-79
@@ -47,7 +47,7 @@ goog.require('goog.userAgent');
|
||||
* @param {?string} prototypeName Name of the language object containing
|
||||
* type-specific functions for this block.
|
||||
* @param {string=} opt_id Optional ID. Use this ID if provided, otherwise
|
||||
* create a new id.
|
||||
* create a new ID.
|
||||
* @extends {Blockly.Block}
|
||||
* @constructor
|
||||
*/
|
||||
@@ -118,6 +118,14 @@ Blockly.BlockSvg.prototype.width = 0;
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.dragStartXY_ = null;
|
||||
|
||||
/**
|
||||
* Map from IDs for warnings text to PIDs of functions to apply them.
|
||||
* Used to be able to maintain multiple warnings.
|
||||
* @type {Object.<string, number>}
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.warningTextDb_ = null;
|
||||
|
||||
/**
|
||||
* Constant for identifying rows that are to be rendered inline.
|
||||
* Don't collide with Blockly.INPUT_VALUE and friends.
|
||||
@@ -244,7 +252,7 @@ Blockly.BlockSvg.prototype.setParent = function(newParent) {
|
||||
// Move this block up the DOM. Keep track of x/y translations.
|
||||
var xy = this.getRelativeToSurfaceXY();
|
||||
this.workspace.getCanvas().appendChild(svgRoot);
|
||||
svgRoot.setAttribute('transform', 'translate(' + xy.x + ',' + xy.y + ')');
|
||||
svgRoot.setAttribute('transform', 'translate' + xy);
|
||||
}
|
||||
|
||||
Blockly.Field.startCache();
|
||||
@@ -375,7 +383,7 @@ Blockly.BlockSvg.prototype.moveDuringDrag = function(newLoc) {
|
||||
if (this.useDragSurface_) {
|
||||
this.workspace.blockDragSurface_.translateSurface(newLoc.x, newLoc.y);
|
||||
} else {
|
||||
this.svgGroup_.translate_ = 'translate(' + newLoc.x + ',' + newLoc.y + ')';
|
||||
this.svgGroup_.translate_ = 'translate' + newLoc;
|
||||
this.svgGroup_.setAttribute('transform',
|
||||
this.svgGroup_.translate_ + this.svgGroup_.skew_);
|
||||
}
|
||||
@@ -526,7 +534,7 @@ Blockly.BlockSvg.prototype.tab = function(start, forward) {
|
||||
|
||||
/**
|
||||
* Create an ordered list of all text fields and connected inputs.
|
||||
* @return {!Array<!Blockly.FieldTextInput|!Blockly.Input>} The ordered list.
|
||||
* @return {!Array.<!Blockly.FieldTextInput|!Blockly.Input>} The ordered list.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.createTabList_ = function() {
|
||||
@@ -586,35 +594,10 @@ Blockly.BlockSvg.prototype.showContextMenu_ = function(e) {
|
||||
var menuOptions = [];
|
||||
|
||||
if (this.isDeletable() && this.isMovable() && !block.isInFlyout) {
|
||||
// Option to duplicate this block.
|
||||
var duplicateOption = {
|
||||
text: Blockly.Msg.DUPLICATE_BLOCK,
|
||||
enabled: true,
|
||||
callback: function() {
|
||||
Blockly.duplicate_(block);
|
||||
}
|
||||
};
|
||||
if (this.getDescendants().length > this.workspace.remainingCapacity()) {
|
||||
duplicateOption.enabled = false;
|
||||
}
|
||||
menuOptions.push(duplicateOption);
|
||||
|
||||
menuOptions.push(Blockly.ContextMenu.blockDuplicateOption(block));
|
||||
if (this.isEditable() && !this.collapsed_ &&
|
||||
this.workspace.options.comments) {
|
||||
// Option to add/remove a comment.
|
||||
var commentOption = {enabled: !goog.userAgent.IE};
|
||||
if (this.comment) {
|
||||
commentOption.text = Blockly.Msg.REMOVE_COMMENT;
|
||||
commentOption.callback = function() {
|
||||
block.setCommentText(null);
|
||||
};
|
||||
} else {
|
||||
commentOption.text = Blockly.Msg.ADD_COMMENT;
|
||||
commentOption.callback = function() {
|
||||
block.setCommentText('');
|
||||
};
|
||||
}
|
||||
menuOptions.push(commentOption);
|
||||
menuOptions.push(Blockly.ContextMenu.blockCommentOption(block));
|
||||
}
|
||||
|
||||
// Option to make block inline.
|
||||
@@ -669,35 +652,10 @@ Blockly.BlockSvg.prototype.showContextMenu_ = function(e) {
|
||||
menuOptions.push(disableOption);
|
||||
}
|
||||
|
||||
// Option to delete this block.
|
||||
// Count the number of blocks that are nested in this block.
|
||||
var descendantCount = this.getDescendants().length;
|
||||
var nextBlock = this.getNextBlock();
|
||||
if (nextBlock) {
|
||||
// Blocks in the current stack would survive this block's deletion.
|
||||
descendantCount -= nextBlock.getDescendants().length;
|
||||
}
|
||||
var deleteOption = {
|
||||
text: descendantCount == 1 ? Blockly.Msg.DELETE_BLOCK :
|
||||
Blockly.Msg.DELETE_X_BLOCKS.replace('%1', String(descendantCount)),
|
||||
enabled: true,
|
||||
callback: function() {
|
||||
Blockly.Events.setGroup(true);
|
||||
block.dispose(true, true);
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
};
|
||||
menuOptions.push(deleteOption);
|
||||
menuOptions.push(Blockly.ContextMenu.blockDeleteOption(block));
|
||||
}
|
||||
|
||||
// Option to get help.
|
||||
var url = goog.isFunction(this.helpUrl) ? this.helpUrl() : this.helpUrl;
|
||||
var helpOption = {enabled: !!url};
|
||||
helpOption.text = Blockly.Msg.HELP;
|
||||
helpOption.callback = function() {
|
||||
block.showHelp_();
|
||||
};
|
||||
menuOptions.push(helpOption);
|
||||
menuOptions.push(Blockly.ContextMenu.blockHelpOption(block));
|
||||
|
||||
// Allow the block to add or modify menuOptions.
|
||||
if (this.customContextMenu) {
|
||||
@@ -848,6 +806,14 @@ Blockly.BlockSvg.prototype.dispose = function(healStack, animate) {
|
||||
// Stop rerendering.
|
||||
this.rendered = false;
|
||||
|
||||
// Clear pending warnings.
|
||||
if (this.warningTextDb_) {
|
||||
for (var n in this.warningTextDb_) {
|
||||
clearTimeout(this.warningTextDb_[n]);
|
||||
}
|
||||
this.warningTextDb_ = null;
|
||||
}
|
||||
|
||||
Blockly.Events.disable();
|
||||
try {
|
||||
var icons = this.getIcons();
|
||||
@@ -1140,30 +1106,30 @@ Blockly.BlockSvg.prototype.setCommentText = function(text) {
|
||||
* maintain multiple warnings.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setWarningText = function(text, opt_id) {
|
||||
if (!this.setWarningText.pid_) {
|
||||
if (!this.warningTextDb_) {
|
||||
// Create a database of warning PIDs.
|
||||
// Only runs once per block (and only those with warnings).
|
||||
this.setWarningText.pid_ = Object.create(null);
|
||||
this.warningTextDb_ = Object.create(null);
|
||||
}
|
||||
var id = opt_id || '';
|
||||
if (!id) {
|
||||
// Kill all previous pending processes, this edit supersedes them all.
|
||||
for (var n in this.setWarningText.pid_) {
|
||||
clearTimeout(this.setWarningText.pid_[n]);
|
||||
delete this.setWarningText.pid_[n];
|
||||
for (var n in this.warningTextDb_) {
|
||||
clearTimeout(this.warningTextDb_[n]);
|
||||
delete this.warningTextDb_[n];
|
||||
}
|
||||
} else if (this.setWarningText.pid_[id]) {
|
||||
} else if (this.warningTextDb_[id]) {
|
||||
// Only queue up the latest change. Kill any earlier pending process.
|
||||
clearTimeout(this.setWarningText.pid_[id]);
|
||||
delete this.setWarningText.pid_[id];
|
||||
clearTimeout(this.warningTextDb_[id]);
|
||||
delete this.warningTextDb_[id];
|
||||
}
|
||||
if (this.workspace.isDragging()) {
|
||||
// Don't change the warning text during a drag.
|
||||
// Wait until the drag finishes.
|
||||
var thisBlock = this;
|
||||
this.setWarningText.pid_[id] = setTimeout(function() {
|
||||
this.warningTextDb_[id] = setTimeout(function() {
|
||||
if (thisBlock.workspace) { // Check block wasn't deleted.
|
||||
delete thisBlock.setWarningText.pid_[id];
|
||||
delete thisBlock.warningTextDb_[id];
|
||||
thisBlock.setWarningText(text, id);
|
||||
}
|
||||
}, 100);
|
||||
@@ -1194,7 +1160,7 @@ Blockly.BlockSvg.prototype.setWarningText = function(text, opt_id) {
|
||||
}
|
||||
this.warning.setText(/** @type {string} */ (text), id);
|
||||
} else {
|
||||
// Dispose all warnings if no id is given.
|
||||
// Dispose all warnings if no ID is given.
|
||||
if (this.warning && !id) {
|
||||
this.warning.dispose();
|
||||
changedState = true;
|
||||
@@ -1311,8 +1277,8 @@ Blockly.BlockSvg.prototype.setColour = function(colour) {
|
||||
|
||||
/**
|
||||
* Move this block to the front of the visible workspace.
|
||||
* <g> tags do not respect z-index so svg renders them in the
|
||||
* order that they are in the dom. By placing this block first within the
|
||||
* <g> tags do not respect z-index so SVG renders them in the
|
||||
* order that they are in the DOM. By placing this block first within the
|
||||
* block group's <g>, it will render on top of any other blocks.
|
||||
* @package
|
||||
*/
|
||||
@@ -1328,12 +1294,11 @@ Blockly.BlockSvg.prototype.bringToFront = function() {
|
||||
/**
|
||||
* Set whether this block can chain onto the bottom of another block.
|
||||
* @param {boolean} newBoolean True if there can be a previous statement.
|
||||
* @param {string|Array.<string>|null|undefined} opt_check Statement type or
|
||||
* @param {(string|Array.<string>|null)=} opt_check Statement type or
|
||||
* list of statement types. Null/undefined if any type could be connected.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setPreviousStatement =
|
||||
function(newBoolean, opt_check) {
|
||||
/* eslint-disable indent */
|
||||
Blockly.BlockSvg.prototype.setPreviousStatement = function(newBoolean,
|
||||
opt_check) {
|
||||
Blockly.BlockSvg.superClass_.setPreviousStatement.call(this, newBoolean,
|
||||
opt_check);
|
||||
|
||||
@@ -1341,12 +1306,12 @@ Blockly.BlockSvg.prototype.setPreviousStatement =
|
||||
this.render();
|
||||
this.bumpNeighbours_();
|
||||
}
|
||||
}; /* eslint-enable indent */
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether another block can chain onto the bottom of this block.
|
||||
* @param {boolean} newBoolean True if there can be a next statement.
|
||||
* @param {string|Array.<string>|null|undefined} opt_check Statement type or
|
||||
* @param {(string|Array.<string>|null)=} opt_check Statement type or
|
||||
* list of statement types. Null/undefined if any type could be connected.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setNextStatement = function(newBoolean, opt_check) {
|
||||
@@ -1362,7 +1327,7 @@ Blockly.BlockSvg.prototype.setNextStatement = function(newBoolean, opt_check) {
|
||||
/**
|
||||
* Set whether this block returns a value.
|
||||
* @param {boolean} newBoolean True if there is an output.
|
||||
* @param {string|Array.<string>|null|undefined} opt_check Returned type or list
|
||||
* @param {(string|Array.<string>|null)=} opt_check Returned type or list
|
||||
* of returned types. Null or undefined if any type could be returned
|
||||
* (e.g. variable get).
|
||||
*/
|
||||
@@ -1492,7 +1457,7 @@ Blockly.BlockSvg.prototype.bumpNeighbours_ = function() {
|
||||
if (!this.workspace) {
|
||||
return; // Deleted block.
|
||||
}
|
||||
if (Blockly.dragMode_ != Blockly.DRAG_NONE) {
|
||||
if (this.workspace.isDragging()) {
|
||||
return; // Don't bump blocks during a drag.
|
||||
}
|
||||
var rootBlock = this.getRootBlock();
|
||||
|
||||
+8
-5
@@ -58,7 +58,10 @@ goog.require('goog.userAgent');
|
||||
|
||||
|
||||
// Turn off debugging when compiled.
|
||||
// Unused within the Blockly library, but used in Closure.
|
||||
/* eslint-disable no-unused-vars */
|
||||
var CLOSURE_DEFINES = {'goog.DEBUG': false};
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
/**
|
||||
* The main workspace most recently used.
|
||||
@@ -395,14 +398,14 @@ Blockly.defineBlocksWithJsonArray = function(jsonArray) {
|
||||
* Bind an event to a function call. When calling the function, verifies that
|
||||
* it belongs to the touch stream that is currently being processed, and splits
|
||||
* multitouch events into multiple events as needed.
|
||||
* @param {!Node} node Node upon which to listen.
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
* @param {boolean} opt_noCaptureIdentifier True if triggering on this event
|
||||
* @param {boolean=} opt_noCaptureIdentifier True if triggering on this event
|
||||
* should not block execution of other event handlers on this touch or other
|
||||
* simultaneous touches.
|
||||
* @param {boolean} opt_noPreventDefault True if triggering on this event
|
||||
* @param {boolean=} opt_noPreventDefault True if triggering on this event
|
||||
* should prevent the default handler. False by default. If
|
||||
* opt_noPreventDefault is provided, opt_noCaptureIdentifier must also be
|
||||
* provided.
|
||||
@@ -461,7 +464,7 @@ Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
|
||||
* simultaneous event processing.
|
||||
* @deprecated in favor of bindEventWithChecks_, but preserved for external
|
||||
* users.
|
||||
* @param {!Node} node Node upon which to listen.
|
||||
* @param {!EventTarget} node Node upon which to listen.
|
||||
* @param {string} name Event name to listen to (e.g. 'mousedown').
|
||||
* @param {Object} thisObject The value of 'this' in the function.
|
||||
* @param {!Function} func Function to call when event is triggered.
|
||||
@@ -528,7 +531,7 @@ Blockly.unbindEvent_ = function(bindData) {
|
||||
* @return {boolean} True if number, false otherwise.
|
||||
*/
|
||||
Blockly.isNumber = function(str) {
|
||||
return !!str.match(/^\s*-?\d+(\.\d+)?\s*$/);
|
||||
return /^\s*-?\d+(\.\d+)?\s*$/.test(str);
|
||||
};
|
||||
|
||||
// IE9 does not have a console. Create a stub to stop errors.
|
||||
|
||||
+1
-1
@@ -32,6 +32,6 @@ goog.provide('Blockly.Blocks');
|
||||
|
||||
/*
|
||||
* A mapping of block type names to block prototype objects.
|
||||
* @type {!Object<string,Object>}
|
||||
* @type {!Object.<string,Object>}
|
||||
*/
|
||||
Blockly.Blocks = new Object(null);
|
||||
|
||||
+12
-7
@@ -70,19 +70,21 @@ Blockly.Comment.prototype.drawIcon_ = function(group) {
|
||||
// Circle.
|
||||
Blockly.utils.createSvgElement('circle',
|
||||
{'class': 'blocklyIconShape', 'r': '8', 'cx': '8', 'cy': '8'},
|
||||
group);
|
||||
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);
|
||||
'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);
|
||||
'x': '6.8', 'y': '10.78', 'height': '2', 'width': '2'},
|
||||
group);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -117,7 +119,9 @@ Blockly.Comment.prototype.createEditor_ = function() {
|
||||
Blockly.bindEventWithChecks_(textarea, 'wheel', this, function(e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
Blockly.bindEventWithChecks_(textarea, 'change', this, function(e) {
|
||||
Blockly.bindEventWithChecks_(textarea, 'change', this, function(
|
||||
/* eslint-disable no-unused-vars */ e
|
||||
/* eslint-enable no-unused-vars */) {
|
||||
if (this.text_ != textarea.value) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.block_, 'comment', null, this.text_, textarea.value));
|
||||
@@ -207,7 +211,8 @@ Blockly.Comment.prototype.setVisible = function(visible) {
|
||||
* @param {!Event} e Mouse up event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Comment.prototype.textareaFocus_ = function(e) {
|
||||
Blockly.Comment.prototype.textareaFocus_ = function(
|
||||
/* eslint-disable no-unused-vars */ e /* eslint-enable no-unused-vars */) {
|
||||
// Ideally this would be hooked to the focus event for the comment.
|
||||
// However doing so in Firefox swallows the cursor for unknown reasons.
|
||||
// So this is hooked to mouseup instead. No big deal.
|
||||
|
||||
@@ -201,3 +201,99 @@ Blockly.ContextMenu.callbackFactory = function(block, xml) {
|
||||
newBlock.select();
|
||||
};
|
||||
};
|
||||
|
||||
// Helper functions for creating context menu options.
|
||||
|
||||
/**
|
||||
* Make a context menu option for deleting the current block.
|
||||
* @param {!Blockly.BlockSvg} block The block where the right-click originated.
|
||||
* @return {!Object} A menu option, containing text, enabled, and a callback.
|
||||
* @package
|
||||
*/
|
||||
Blockly.ContextMenu.blockDeleteOption = function(block) {
|
||||
// Option to delete this block but not blocks lower in the stack.
|
||||
// Count the number of blocks that are nested in this block.
|
||||
var descendantCount = block.getDescendants(true).length;
|
||||
var nextBlock = block.getNextBlock();
|
||||
if (nextBlock) {
|
||||
// Blocks in the current stack would survive this block's deletion.
|
||||
descendantCount -= nextBlock.getDescendants(true).length;
|
||||
}
|
||||
var deleteOption = {
|
||||
text: descendantCount == 1 ? Blockly.Msg.DELETE_BLOCK :
|
||||
Blockly.Msg.DELETE_X_BLOCKS.replace('%1', String(descendantCount)),
|
||||
enabled: true,
|
||||
callback: function() {
|
||||
Blockly.Events.setGroup(true);
|
||||
block.dispose(true, true);
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
};
|
||||
return deleteOption;
|
||||
};
|
||||
|
||||
/**
|
||||
* Make a context menu option for showing help for the current block.
|
||||
* @param {!Blockly.BlockSvg} block The block where the right-click originated.
|
||||
* @return {!Object} A menu option, containing text, enabled, and a callback.
|
||||
* @package
|
||||
*/
|
||||
Blockly.ContextMenu.blockHelpOption = function(block) {
|
||||
var url = goog.isFunction(block.helpUrl) ? block.helpUrl() : block.helpUrl;
|
||||
var helpOption = {
|
||||
enabled: !!url,
|
||||
text: Blockly.Msg.HELP,
|
||||
callback: function() {
|
||||
block.showHelp_();
|
||||
}
|
||||
};
|
||||
return helpOption;
|
||||
};
|
||||
|
||||
/**
|
||||
* Make a context menu option for duplicating the current block.
|
||||
* @param {!Blockly.BlockSvg} block The block where the right-click originated.
|
||||
* @return {!Object} A menu option, containing text, enabled, and a callback.
|
||||
* @package
|
||||
*/
|
||||
Blockly.ContextMenu.blockDuplicateOption = function(block) {
|
||||
var enabled = true;
|
||||
if (block.getDescendants().length > block.workspace.remainingCapacity()) {
|
||||
enabled = false;
|
||||
}
|
||||
var duplicateOption = {
|
||||
text: Blockly.Msg.DUPLICATE_BLOCK,
|
||||
enabled: enabled,
|
||||
callback: function() {
|
||||
Blockly.duplicate_(block);
|
||||
}
|
||||
};
|
||||
return duplicateOption;
|
||||
};
|
||||
|
||||
/**
|
||||
* Make a context menu option for adding or removing comments on the current
|
||||
* block.
|
||||
* @param {!Blockly.BlockSvg} block The block where the right-click originated.
|
||||
* @return {!Object} A menu option, containing text, enabled, and a callback.
|
||||
* @package
|
||||
*/
|
||||
Blockly.ContextMenu.blockCommentOption = function(block) {
|
||||
var commentOption = {
|
||||
enabled: !goog.userAgent.IE
|
||||
};
|
||||
// If there's already a comment, add an option to delete it.
|
||||
if (block.comment) {
|
||||
commentOption.text = Blockly.Msg.REMOVE_COMMENT;
|
||||
commentOption.callback = function() {
|
||||
block.setCommentText(null);
|
||||
};
|
||||
} else {
|
||||
// If there's no comment, add an option to create a comment.
|
||||
commentOption.text = Blockly.Msg.ADD_COMMENT;
|
||||
commentOption.callback = function() {
|
||||
block.setCommentText('');
|
||||
};
|
||||
}
|
||||
return commentOption;
|
||||
};
|
||||
|
||||
@@ -171,6 +171,12 @@ Blockly.DraggedConnectionManager.prototype.update = function(dxy, deleteArea) {
|
||||
this.topBlock_.isDeletable();
|
||||
this.wouldDeleteBlock_ = wouldDelete && !wouldConnect;
|
||||
|
||||
// Get rid of highlighting so we don't sent mixed messages.
|
||||
if (wouldDelete && this.closestConnection_) {
|
||||
this.closestConnection_.unhighlight();
|
||||
this.closestConnection_ = null;
|
||||
}
|
||||
|
||||
if (!this.wouldDeleteBlock_ && closestConnectionChanged &&
|
||||
this.closestConnection_) {
|
||||
this.addHighlighting_();
|
||||
|
||||
+60
-20
@@ -42,7 +42,7 @@ goog.require('goog.math.Coordinate');
|
||||
Blockly.Events.group_ = '';
|
||||
|
||||
/**
|
||||
* Sets whether events should be added to the undo stack.
|
||||
* Sets whether the next event should be added to the undo stack.
|
||||
* @type {boolean}
|
||||
*/
|
||||
Blockly.Events.recordUndo = true;
|
||||
@@ -201,10 +201,15 @@ Blockly.Events.filter = function(queueIn, forward) {
|
||||
lastEvent.element == 'warningOpen')) {
|
||||
// Merge click events.
|
||||
lastEvent.newValue = event.newValue;
|
||||
} else {
|
||||
// Collision: newer events should merge into this event to maintain order
|
||||
hash[key] = event;
|
||||
mergedQueue.push(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
queue = mergedQueue;
|
||||
// Filter out any events that have become null due to merging.
|
||||
queue = mergedQueue.filter(function(e) { return !e.isNull(); });
|
||||
if (!forward) {
|
||||
// Restore undo order.
|
||||
queue.reverse();
|
||||
@@ -305,7 +310,7 @@ Blockly.Events.fromJson = function(json, workspace) {
|
||||
event = new Blockly.Events.Delete(null);
|
||||
break;
|
||||
case Blockly.Events.CHANGE:
|
||||
event = new Blockly.Events.Change(null);
|
||||
event = new Blockly.Events.Change(null, '', '', '', '');
|
||||
break;
|
||||
case Blockly.Events.MOVE:
|
||||
event = new Blockly.Events.Move(null);
|
||||
@@ -317,7 +322,7 @@ Blockly.Events.fromJson = function(json, workspace) {
|
||||
event = new Blockly.Events.VarDelete(null);
|
||||
break;
|
||||
case Blockly.Events.VAR_RENAME:
|
||||
event = new Blockly.Events.VarRename(null);
|
||||
event = new Blockly.Events.VarRename(null, '');
|
||||
break;
|
||||
case Blockly.Events.UI:
|
||||
event = new Blockly.Events.Ui(null);
|
||||
@@ -336,11 +341,44 @@ Blockly.Events.fromJson = function(json, workspace) {
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Events.Abstract = function(elem) {
|
||||
/**
|
||||
* The block id for the block this event pertains to, if appropriate for the
|
||||
* event type.
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.blockId = undefined;
|
||||
|
||||
/**
|
||||
* The variable id for the variable this event pertains to. Only set in
|
||||
* VarCreate, VarDelete, and VarRename events.
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.varId = undefined;
|
||||
|
||||
/**
|
||||
* The workspace identifier for this event.
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.workspaceId = undefined;
|
||||
|
||||
/**
|
||||
* The event group id for the group this event belongs to. Groups define
|
||||
* events that should be treated as an single action from the user's
|
||||
* perspective, and should be undone together.
|
||||
* @type {string}
|
||||
*/
|
||||
this.group = undefined;
|
||||
|
||||
/**
|
||||
* Sets whether the event should be added to the undo stack.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.recordUndo = undefined;
|
||||
|
||||
if (elem instanceof Blockly.Block) {
|
||||
this.blockId = elem.id;
|
||||
this.workspaceId = elem.workspace.id;
|
||||
}
|
||||
else if (elem instanceof Blockly.VariableModel){
|
||||
} else if (elem instanceof Blockly.VariableModel) {
|
||||
this.workspaceId = elem.workspace.id;
|
||||
this.varId = elem.getId();
|
||||
}
|
||||
@@ -390,7 +428,9 @@ Blockly.Events.Abstract.prototype.isNull = function() {
|
||||
* Run an event.
|
||||
* @param {boolean} forward True if run forward, false if run backward (undo).
|
||||
*/
|
||||
Blockly.Events.Abstract.prototype.run = function(forward) {
|
||||
Blockly.Events.Abstract.prototype.run = function(
|
||||
/* eslint-disable no-unused-vars */ forward
|
||||
/* eslint-enable no-unused-vars */) {
|
||||
// Defined by subclasses.
|
||||
};
|
||||
|
||||
@@ -482,7 +522,7 @@ Blockly.Events.Create.prototype.run = function(forward) {
|
||||
block.dispose(false, false);
|
||||
} else if (id == this.blockId) {
|
||||
// Only complain about root-level block.
|
||||
console.warn("Can't uncreate non-existant block: " + id);
|
||||
console.warn("Can't uncreate non-existent block: " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -558,7 +598,7 @@ Blockly.Events.Delete.prototype.run = function(forward) {
|
||||
block.dispose(false, false);
|
||||
} else if (id == this.blockId) {
|
||||
// Only complain about root-level block.
|
||||
console.warn("Can't delete non-existant block: " + id);
|
||||
console.warn("Can't delete non-existent block: " + id);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -573,8 +613,8 @@ Blockly.Events.Delete.prototype.run = function(forward) {
|
||||
* @param {Blockly.Block} block The changed block. Null for a blank event.
|
||||
* @param {string} element One of 'field', 'comment', 'disabled', etc.
|
||||
* @param {?string} name Name of input or field affected, or null.
|
||||
* @param {string} oldValue Previous value of element.
|
||||
* @param {string} newValue New value of element.
|
||||
* @param {*} oldValue Previous value of element.
|
||||
* @param {*} newValue New value of element.
|
||||
* @extends {Blockly.Events.Abstract}
|
||||
* @constructor
|
||||
*/
|
||||
@@ -595,8 +635,8 @@ goog.inherits(Blockly.Events.Change, Blockly.Events.Abstract);
|
||||
* @param {Blockly.Block} block The changed block. Null for a blank event.
|
||||
* @param {string} element One of 'field', 'comment', 'disabled', etc.
|
||||
* @param {?string} name Name of input or field affected, or null.
|
||||
* @param {string} oldValue Previous value of element.
|
||||
* @param {string} newValue New value of element.
|
||||
* @param {*} oldValue Previous value of element.
|
||||
* @param {*} newValue New value of element.
|
||||
* @extends {Blockly.Events.Abstract}
|
||||
* @constructor
|
||||
*/
|
||||
@@ -649,7 +689,7 @@ Blockly.Events.Change.prototype.run = function(forward) {
|
||||
var workspace = this.getEventWorkspace_();
|
||||
var block = workspace.getBlockById(this.blockId);
|
||||
if (!block) {
|
||||
console.warn("Can't change non-existant block: " + this.blockId);
|
||||
console.warn("Can't change non-existent block: " + this.blockId);
|
||||
return;
|
||||
}
|
||||
if (block.mutator) {
|
||||
@@ -666,7 +706,7 @@ Blockly.Events.Change.prototype.run = function(forward) {
|
||||
field.callValidator(value);
|
||||
field.setValue(value);
|
||||
} else {
|
||||
console.warn("Can't set non-existant field: " + this.name);
|
||||
console.warn("Can't set non-existent field: " + this.name);
|
||||
}
|
||||
break;
|
||||
case 'comment':
|
||||
@@ -818,7 +858,7 @@ Blockly.Events.Move.prototype.run = function(forward) {
|
||||
var workspace = this.getEventWorkspace_();
|
||||
var block = workspace.getBlockById(this.blockId);
|
||||
if (!block) {
|
||||
console.warn("Can't move non-existant block: " + this.blockId);
|
||||
console.warn("Can't move non-existent block: " + this.blockId);
|
||||
return;
|
||||
}
|
||||
var parentId = forward ? this.newParentId : this.oldParentId;
|
||||
@@ -828,7 +868,7 @@ Blockly.Events.Move.prototype.run = function(forward) {
|
||||
if (parentId) {
|
||||
parentBlock = workspace.getBlockById(parentId);
|
||||
if (!parentBlock) {
|
||||
console.warn("Can't connect to non-existant block: " + parentId);
|
||||
console.warn("Can't connect to non-existent block: " + parentId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -852,7 +892,7 @@ Blockly.Events.Move.prototype.run = function(forward) {
|
||||
if (parentConnection) {
|
||||
blockConnection.connect(parentConnection);
|
||||
} else {
|
||||
console.warn("Can't connect to non-existant input: " + inputName);
|
||||
console.warn("Can't connect to non-existent input: " + inputName);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -861,8 +901,8 @@ Blockly.Events.Move.prototype.run = function(forward) {
|
||||
* Class for a UI event.
|
||||
* @param {Blockly.Block} block The affected block.
|
||||
* @param {string} element One of 'selected', 'comment', 'mutator', etc.
|
||||
* @param {string} oldValue Previous value of element.
|
||||
* @param {string} newValue New value of element.
|
||||
* @param {*} oldValue Previous value of element.
|
||||
* @param {*} newValue New value of element.
|
||||
* @extends {Blockly.Events.Abstract}
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
+67
-69
@@ -83,8 +83,8 @@ Blockly.Extensions.registerMixin = function(name, mixinObj) {
|
||||
* decompose are defined on the mixin.
|
||||
* @param {string} name The name of this mutator extension.
|
||||
* @param {!Object} mixinObj The values to mix in.
|
||||
* @param {(function())=} opt_helperFn An optional function to apply after mixing
|
||||
* in the object.
|
||||
* @param {(function())=} opt_helperFn An optional function to apply after
|
||||
* mixing in the object.
|
||||
* @param {Array.<string>=} opt_blockList A list of blocks to appear in the
|
||||
* flyout of the mutator dialog.
|
||||
* @throws {Error} if the mutation is invalid or can't be applied to the block.
|
||||
@@ -99,8 +99,8 @@ Blockly.Extensions.registerMutator = function(name, mixinObj, opt_helperFn,
|
||||
Blockly.Extensions.checkHasFunction_(errorPrefix, mixinObj.mutationToDom,
|
||||
'mutationToDom');
|
||||
|
||||
var hasMutatorDialog = Blockly.Extensions.checkMutatorDialog_(mixinObj,
|
||||
errorPrefix);
|
||||
var hasMutatorDialog =
|
||||
Blockly.Extensions.checkMutatorDialog_(mixinObj, errorPrefix);
|
||||
|
||||
if (opt_helperFn && !goog.isFunction(opt_helperFn)) {
|
||||
throw new Error('Extension "' + name + '" is not a function');
|
||||
@@ -148,8 +148,8 @@ Blockly.Extensions.apply = function(name, block, isMutator) {
|
||||
Blockly.Extensions.checkBlockHasMutatorProperties_(errorPrefix, block);
|
||||
} else {
|
||||
if (!Blockly.Extensions.mutatorPropertiesMatch_(mutatorProperties, block)) {
|
||||
throw new Error('Error when applying extension "' + name +
|
||||
'": mutation properties changed when applying a non-mutator extension.');
|
||||
throw new Error('Error when applying extension "' + name + '": ' +
|
||||
'mutation properties changed when applying a non-mutator extension.');
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -169,7 +169,7 @@ Blockly.Extensions.checkHasFunction_ = function(errorPrefix, func,
|
||||
'missing required property "' + propertyName + '"');
|
||||
} else if (typeof func != 'function') {
|
||||
throw new Error(errorPrefix +
|
||||
'" required property "' + propertyName + '" must be a function');
|
||||
'" required property "' + propertyName + '" must be a function');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -209,9 +209,9 @@ Blockly.Extensions.checkMutatorDialog_ = function(object, errorPrefix) {
|
||||
var hasDecompose = object.decompose !== undefined;
|
||||
|
||||
if (hasCompose && hasDecompose) {
|
||||
if (typeof object.compose !== 'function') {
|
||||
if (typeof object.compose != 'function') {
|
||||
throw new Error(errorPrefix + 'compose must be a function.');
|
||||
} else if (typeof object.decompose !== 'function') {
|
||||
} else if (typeof object.decompose != 'function') {
|
||||
throw new Error(errorPrefix + 'decompose must be a function.');
|
||||
}
|
||||
return true;
|
||||
@@ -232,11 +232,13 @@ Blockly.Extensions.checkMutatorDialog_ = function(object, errorPrefix) {
|
||||
*/
|
||||
Blockly.Extensions.checkBlockHasMutatorProperties_ = function(errorPrefix,
|
||||
block) {
|
||||
if (typeof block.domToMutation !== 'function') {
|
||||
throw new Error(errorPrefix + 'Applying a mutator didn\'t add "domToMutation"');
|
||||
if (typeof block.domToMutation != 'function') {
|
||||
throw new Error(errorPrefix +
|
||||
'Applying a mutator didn\'t add "domToMutation"');
|
||||
}
|
||||
if (typeof block.mutationToDom !== 'function') {
|
||||
throw new Error(errorPrefix + 'Applying a mutator didn\'t add "mutationToDom"');
|
||||
if (typeof block.mutationToDom != 'function') {
|
||||
throw new Error(errorPrefix +
|
||||
'Applying a mutator didn\'t add "mutationToDom"');
|
||||
}
|
||||
|
||||
// A block with a mutator isn't required to have a mutation dialog, but
|
||||
@@ -280,19 +282,16 @@ Blockly.Extensions.getMutatorProperties_ = function(block) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.Extensions.mutatorPropertiesMatch_ = function(oldProperties, block) {
|
||||
var match = true;
|
||||
var newProperties = Blockly.Extensions.getMutatorProperties_(block);
|
||||
if (newProperties.length != oldProperties.length) {
|
||||
match = false;
|
||||
} else {
|
||||
for (var i = 0; i < newProperties.length; i++) {
|
||||
if (oldProperties[i] != newProperties[i]) {
|
||||
match = false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < newProperties.length; i++) {
|
||||
if (oldProperties[i] != newProperties[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -310,11 +309,12 @@ Blockly.Extensions.mutatorPropertiesMatch_ = function(oldProperties, block) {
|
||||
* reported as warnings in the console, and are never fatal.
|
||||
* @param {string} dropdownName The name of the field whose value is the key
|
||||
* to the lookup table.
|
||||
* @param {!Object<string, string>} lookupTable The table of field values to
|
||||
* @param {!Object.<string, string>} lookupTable The table of field values to
|
||||
* tooltip text.
|
||||
* @return {Function} The extension function.
|
||||
*/
|
||||
Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, lookupTable) {
|
||||
Blockly.Extensions.buildTooltipForDropdown = function(dropdownName,
|
||||
lookupTable) {
|
||||
// List of block types already validated, to minimize duplicate warnings.
|
||||
var blockTypesChecked = [];
|
||||
|
||||
@@ -322,10 +322,10 @@ Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, lookupTable)
|
||||
// Wait for load, in case Blockly.Msg is not yet populated.
|
||||
// runAfterPageLoad() does not run in a Node.js environment due to lack of
|
||||
// document object, in which case skip the validation.
|
||||
if (document) { // Relies on document.readyState
|
||||
if (document) { // Relies on document.readyState
|
||||
Blockly.utils.runAfterPageLoad(function() {
|
||||
for (var key in lookupTable) {
|
||||
// Will print warnings is reference is missing.
|
||||
// Will print warnings if reference is missing.
|
||||
Blockly.utils.checkMessageReferences(lookupTable[key]);
|
||||
}
|
||||
});
|
||||
@@ -338,7 +338,7 @@ Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, lookupTable)
|
||||
var extensionFn = function() {
|
||||
if (this.type && blockTypesChecked.indexOf(this.type) === -1) {
|
||||
Blockly.Extensions.checkDropdownOptionsInTable_(
|
||||
this, dropdownName, lookupTable);
|
||||
this, dropdownName, lookupTable);
|
||||
blockTypesChecked.push(this.type);
|
||||
}
|
||||
|
||||
@@ -347,7 +347,7 @@ Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, lookupTable)
|
||||
var tooltip = lookupTable[value];
|
||||
if (tooltip == null) {
|
||||
if (blockTypesChecked.indexOf(this.type) === -1) {
|
||||
// Warn for missing values on generated tooltips
|
||||
// Warn for missing values on generated tooltips.
|
||||
var warning = 'No tooltip mapping for value ' + value +
|
||||
' of field ' + dropdownName;
|
||||
if (this.type != null) {
|
||||
@@ -369,24 +369,24 @@ Blockly.Extensions.buildTooltipForDropdown = function(dropdownName, lookupTable)
|
||||
* Emits console warnings when they are not.
|
||||
* @param {!Blockly.Block} block The block containing the dropdown
|
||||
* @param {string} dropdownName The name of the dropdown
|
||||
* @param {!Object<string, string>} lookupTable The string lookup table
|
||||
* @param {!Object.<string, string>} lookupTable The string lookup table
|
||||
* @private
|
||||
*/
|
||||
Blockly.Extensions.checkDropdownOptionsInTable_ =
|
||||
function(block, dropdownName, lookupTable) {
|
||||
// Validate all dropdown options have values.
|
||||
var dropdown = block.getField(dropdownName);
|
||||
if (!dropdown.isOptionListDynamic()) {
|
||||
var options = dropdown.getOptions();
|
||||
for (var i = 0; i < options.length; ++i) {
|
||||
var optionKey = options[i][1]; // label, then value
|
||||
if (lookupTable[optionKey] == null) {
|
||||
console.warn('No tooltip mapping for value ' + optionKey +
|
||||
' of field ' + dropdownName + ' of block type ' + block.type);
|
||||
}
|
||||
Blockly.Extensions.checkDropdownOptionsInTable_ = function(block, dropdownName,
|
||||
lookupTable) {
|
||||
// Validate all dropdown options have values.
|
||||
var dropdown = block.getField(dropdownName);
|
||||
if (!dropdown.isOptionListDynamic()) {
|
||||
var options = dropdown.getOptions();
|
||||
for (var i = 0; i < options.length; ++i) {
|
||||
var optionKey = options[i][1]; // label, then value
|
||||
if (lookupTable[optionKey] == null) {
|
||||
console.warn('No tooltip mapping for value ' + optionKey +
|
||||
' of field ' + dropdownName + ' of block type ' + block.type);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds an extension function that will install a dynamic tooltip. The
|
||||
@@ -397,31 +397,31 @@ Blockly.Extensions.checkDropdownOptionsInTable_ =
|
||||
* @param {string} fieldName The field with the replacement value.
|
||||
* @returns {Function} The extension function.
|
||||
*/
|
||||
Blockly.Extensions.buildTooltipWithFieldValue =
|
||||
function(msgTemplate, fieldName) {
|
||||
// Check the tooltip string messages for invalid references.
|
||||
// Wait for load, in case Blockly.Msg is not yet populated.
|
||||
// runAfterPageLoad() does not run in a Node.js environment due to lack of
|
||||
// document object, in which case skip the validation.
|
||||
if (document) { // Relies on document.readyState
|
||||
Blockly.utils.runAfterPageLoad(function() {
|
||||
// Will print warnings is reference is missing.
|
||||
Blockly.utils.checkMessageReferences(msgTemplate);
|
||||
});
|
||||
}
|
||||
Blockly.Extensions.buildTooltipWithFieldValue = function(msgTemplate,
|
||||
fieldName) {
|
||||
// Check the tooltip string messages for invalid references.
|
||||
// Wait for load, in case Blockly.Msg is not yet populated.
|
||||
// runAfterPageLoad() does not run in a Node.js environment due to lack of
|
||||
// document object, in which case skip the validation.
|
||||
if (document) { // Relies on document.readyState
|
||||
Blockly.utils.runAfterPageLoad(function() {
|
||||
// Will print warnings if reference is missing.
|
||||
Blockly.utils.checkMessageReferences(msgTemplate);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual extension.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
var extensionFn = function() {
|
||||
this.setTooltip(function() {
|
||||
return Blockly.utils.replaceMessageReferences(msgTemplate)
|
||||
.replace('%1', this.getFieldValue(fieldName));
|
||||
}.bind(this));
|
||||
};
|
||||
return extensionFn;
|
||||
/**
|
||||
* The actual extension.
|
||||
* @this {Blockly.Block}
|
||||
*/
|
||||
var extensionFn = function() {
|
||||
this.setTooltip(function() {
|
||||
return Blockly.utils.replaceMessageReferences(msgTemplate)
|
||||
.replace('%1', this.getFieldValue(fieldName));
|
||||
}.bind(this));
|
||||
};
|
||||
return extensionFn;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configures the tooltip to mimic the parent block when connected. Otherwise,
|
||||
@@ -435,10 +435,8 @@ Blockly.Extensions.extensionParentTooltip_ = function() {
|
||||
this.tooltipWhenNotConnected_ = this.tooltip;
|
||||
this.setTooltip(function() {
|
||||
var parent = this.getParent();
|
||||
return (parent &&
|
||||
parent.getInputsInline() &&
|
||||
parent.tooltip) ||
|
||||
this.tooltipWhenNotConnected_;
|
||||
return (parent && parent.getInputsInline() && parent.tooltip) ||
|
||||
this.tooltipWhenNotConnected_;
|
||||
}.bind(this));
|
||||
};
|
||||
Blockly.Extensions.register('parent_tooltip_when_inline',
|
||||
|
||||
+6
-4
@@ -146,7 +146,7 @@ Blockly.Field.prototype.init = function() {
|
||||
'ry': 4,
|
||||
'x': -Blockly.BlockSvg.SEP_SPACE_X / 2,
|
||||
'y': 0,
|
||||
'height': 16}, this.fieldGroup_, this.sourceBlock_.workspace);
|
||||
'height': 16}, this.fieldGroup_);
|
||||
/** @type {!Element} */
|
||||
this.textElement_ = Blockly.utils.createSvgElement('text',
|
||||
{'class': 'blocklyText', 'y': this.size_.height - 12.5},
|
||||
@@ -527,7 +527,8 @@ Blockly.Field.prototype.setValue = function(newValue) {
|
||||
* @param {!Event} e Mouse down event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Field.prototype.onMouseDown_ = function(e) {
|
||||
Blockly.Field.prototype.onMouseDown_ = function(
|
||||
/* eslint-disable no-unused-vars */ e /* eslint-enable no-unused-vars */) {
|
||||
if (!this.sourceBlock_ || !this.sourceBlock_.workspace) {
|
||||
return;
|
||||
}
|
||||
@@ -537,13 +538,14 @@ Blockly.Field.prototype.onMouseDown_ = function(e) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Change the tooltip text for this field.
|
||||
* @param {string|!Element} newTip Text for tooltip or a parent element to
|
||||
* link to for its tooltip.
|
||||
*/
|
||||
Blockly.Field.prototype.setTooltip = function(newTip) {
|
||||
Blockly.Field.prototype.setTooltip = function(
|
||||
/* eslint-disable no-unused-vars */ newTip
|
||||
/* eslint-enable no-unused-vars */) {
|
||||
// Non-abstract sub-classes may wish to implement this. See FieldLabel.
|
||||
};
|
||||
|
||||
|
||||
+11
-11
@@ -112,13 +112,13 @@ Blockly.FieldAngle.prototype.render_ = function() {
|
||||
|
||||
// Update textElement.
|
||||
this.textElement_.textContent = this.getDisplayText_();
|
||||
|
||||
|
||||
// Insert degree symbol.
|
||||
if (this.sourceBlock_.RTL) {
|
||||
this.textElement_.insertBefore(this.symbol_, this.textElement_.firstChild);
|
||||
} else {
|
||||
this.textElement_.appendChild(this.symbol_);
|
||||
}
|
||||
this.textElement_.insertBefore(this.symbol_, this.textElement_.firstChild);
|
||||
} else {
|
||||
this.textElement_.appendChild(this.symbol_);
|
||||
}
|
||||
this.updateWidth();
|
||||
};
|
||||
|
||||
@@ -174,11 +174,11 @@ Blockly.FieldAngle.prototype.showEditor_ = function() {
|
||||
}, svg);
|
||||
this.gauge_ = Blockly.utils.createSvgElement('path',
|
||||
{'class': 'blocklyAngleGauge'}, svg);
|
||||
this.line_ = Blockly.utils.createSvgElement('line',{
|
||||
'x1': Blockly.FieldAngle.HALF,
|
||||
'y1': Blockly.FieldAngle.HALF,
|
||||
'class': 'blocklyAngleLine',
|
||||
}, svg);
|
||||
this.line_ = Blockly.utils.createSvgElement('line', {
|
||||
'x1': Blockly.FieldAngle.HALF,
|
||||
'y1': Blockly.FieldAngle.HALF,
|
||||
'class': 'blocklyAngleLine'
|
||||
}, svg);
|
||||
// Draw markers around the edge.
|
||||
for (var angle = 0; angle < 360; angle += 15) {
|
||||
Blockly.utils.createSvgElement('line', {
|
||||
@@ -317,4 +317,4 @@ Blockly.FieldAngle.prototype.classValidator = function(text) {
|
||||
n -= 360;
|
||||
}
|
||||
return String(n);
|
||||
};
|
||||
};
|
||||
|
||||
+2
-2
@@ -54,7 +54,7 @@ Blockly.FieldImage = function(src, width, height, opt_alt, opt_onClick) {
|
||||
this.text_ = opt_alt || '';
|
||||
this.setValue(src);
|
||||
|
||||
if (typeof opt_onClick === "function") {
|
||||
if (typeof opt_onClick == 'function') {
|
||||
this.clickHandler_ = opt_onClick;
|
||||
}
|
||||
};
|
||||
@@ -188,7 +188,7 @@ Blockly.FieldImage.prototype.updateWidth = function() {
|
||||
* call the handler.
|
||||
*/
|
||||
Blockly.FieldImage.prototype.showEditor_ = function() {
|
||||
if (this.clickHandler_){
|
||||
if (this.clickHandler_) {
|
||||
this.clickHandler_(this);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -29,6 +29,7 @@ goog.provide('Blockly.FieldNumber');
|
||||
goog.require('Blockly.FieldTextInput');
|
||||
goog.require('goog.math');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an editable number field.
|
||||
* @param {(string|number)=} opt_value The initial content of the field. The value
|
||||
|
||||
+9
-10
@@ -258,7 +258,8 @@ Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_ = function(e) {
|
||||
* @param {!Event} e Keyboard event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.onHtmlInputChange_ = function(e) {
|
||||
Blockly.FieldTextInput.prototype.onHtmlInputChange_ = function(
|
||||
/* eslint-disable no-unused-vars */ e /* eslint-enable no-unused-vars */) {
|
||||
var htmlInput = Blockly.FieldTextInput.htmlInput_;
|
||||
// Update source block.
|
||||
var text = htmlInput.value;
|
||||
@@ -300,17 +301,15 @@ Blockly.FieldTextInput.prototype.validate_ = function() {
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.resizeEditor_ = function() {
|
||||
var div = Blockly.WidgetDiv.DIV;
|
||||
var bBox = this.fieldGroup_.getBBox();
|
||||
div.style.width = bBox.width * this.workspace_.scale + 'px';
|
||||
div.style.height = bBox.height * this.workspace_.scale + 'px';
|
||||
var xy = this.getAbsoluteXY_();
|
||||
var bBox = this.getScaledBBox_();
|
||||
div.style.width = bBox.right - bBox.left + 'px';
|
||||
div.style.height = bBox.bottom - bBox.top + 'px';
|
||||
|
||||
// In RTL mode block fields and LTR input fields the left edge moves,
|
||||
// whereas the right edge is fixed. Reposition the editor.
|
||||
if (this.sourceBlock_.RTL) {
|
||||
var borderBBox = this.getScaledBBox_();
|
||||
xy.x += borderBBox.width;
|
||||
xy.x -= div.offsetWidth;
|
||||
}
|
||||
var x = this.sourceBlock_.RTL ? bBox.right - div.offsetWidth : bBox.left;
|
||||
var xy = new goog.math.Coordinate(x, bBox.top);
|
||||
|
||||
// Shift by a few pixels to line up exactly.
|
||||
xy.y += 1;
|
||||
if (goog.userAgent.GECKO && Blockly.WidgetDiv.DIV.style.top) {
|
||||
|
||||
@@ -41,8 +41,8 @@ goog.require('goog.string');
|
||||
* a unique variable name will be generated.
|
||||
* @param {Function=} opt_validator A function that is executed when a new
|
||||
* option is selected. Its sole argument is the new option value.
|
||||
* @param {Array.<string>} opt_variableTypes A list of the types of variables to
|
||||
* include in the dropdown.
|
||||
* @param {Array.<string>=} opt_variableTypes A list of the types of variables
|
||||
* to include in the dropdown.
|
||||
* @extends {Blockly.FieldDropdown}
|
||||
* @constructor
|
||||
*/
|
||||
@@ -118,7 +118,7 @@ Blockly.FieldVariable.prototype.setValue = function(value) {
|
||||
newText = variable.name;
|
||||
}
|
||||
// TODO(marisaleung): Remove name lookup after converting all Field Variable
|
||||
// instances to use id instead of name.
|
||||
// instances to use ID instead of name.
|
||||
else if (variable = this.sourceBlock_.workspace.getVariable(value)) {
|
||||
newValue = variable.getId();
|
||||
}
|
||||
@@ -181,7 +181,7 @@ Blockly.FieldVariable.dropdownCreate = function() {
|
||||
var variables = workspace.getVariablesOfType(variableType);
|
||||
variableModelList = variableModelList.concat(variables);
|
||||
}
|
||||
for (var i = 0; i < variableModelList.length; i++){
|
||||
for (var i = 0; i < variableModelList.length; i++) {
|
||||
if (createSelectedVariable &&
|
||||
goog.string.caseInsensitiveEquals(variableModelList[i].name, name)) {
|
||||
createSelectedVariable = false;
|
||||
@@ -197,13 +197,13 @@ Blockly.FieldVariable.dropdownCreate = function() {
|
||||
variableModelList.sort(Blockly.VariableModel.compareByName);
|
||||
var options = [];
|
||||
for (var i = 0; i < variableModelList.length; i++) {
|
||||
// Set the uuid as the internal representation of the variable.
|
||||
// Set the UUID as the internal representation of the variable.
|
||||
options[i] = [variableModelList[i].name, variableModelList[i].getId()];
|
||||
}
|
||||
options.push([Blockly.Msg.RENAME_VARIABLE, Blockly.RENAME_VARIABLE_ID]);
|
||||
if (Blockly.Msg.DELETE_VARIABLE) {
|
||||
options.push([Blockly.Msg.DELETE_VARIABLE.replace('%1', name),
|
||||
Blockly.DELETE_VARIABLE_ID]);
|
||||
Blockly.DELETE_VARIABLE_ID]);
|
||||
}
|
||||
return options;
|
||||
};
|
||||
@@ -217,7 +217,7 @@ Blockly.FieldVariable.dropdownCreate = function() {
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.onItemSelected = function(menu, menuItem) {
|
||||
var id = menuItem.getValue();
|
||||
// TODO(marisaleung): change setValue() to take in an id as the parameter.
|
||||
// TODO(marisaleung): change setValue() to take in an ID as the parameter.
|
||||
// Then remove itemText.
|
||||
var itemText;
|
||||
if (this.sourceBlock_ && this.sourceBlock_.workspace) {
|
||||
@@ -226,8 +226,7 @@ Blockly.FieldVariable.prototype.onItemSelected = function(menu, menuItem) {
|
||||
// If the item selected is a variable, set itemText to the variable name.
|
||||
if (variable) {
|
||||
itemText = variable.name;
|
||||
}
|
||||
else if (id == Blockly.RENAME_VARIABLE_ID) {
|
||||
} else if (id == Blockly.RENAME_VARIABLE_ID) {
|
||||
// Rename variable.
|
||||
var currentName = this.getText();
|
||||
variable = workspace.getVariable(currentName);
|
||||
|
||||
+17
-16
@@ -75,12 +75,12 @@ Blockly.Flyout = function(workspaceOptions) {
|
||||
this.eventWrappers_ = [];
|
||||
|
||||
/**
|
||||
* List of background buttons that lurk behind each block to catch clicks
|
||||
* List of background mats that lurk behind each block to catch clicks
|
||||
* landing in the blocks' lakes and bays.
|
||||
* @type {!Array.<!Element>}
|
||||
* @private
|
||||
*/
|
||||
this.backgroundButtons_ = [];
|
||||
this.mats_ = [];
|
||||
|
||||
/**
|
||||
* List of visible buttons.
|
||||
@@ -518,7 +518,7 @@ Blockly.Flyout.prototype.show = function(xmlList) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete blocks and background buttons from a previous showing of the flyout.
|
||||
* Delete blocks, mats and buttons from a previous showing of the flyout.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Flyout.prototype.clearOldBlocks_ = function() {
|
||||
@@ -529,13 +529,15 @@ Blockly.Flyout.prototype.clearOldBlocks_ = function() {
|
||||
block.dispose(false, false);
|
||||
}
|
||||
}
|
||||
// Delete any background buttons from a previous showing.
|
||||
for (var j = 0; j < this.backgroundButtons_.length; j++) {
|
||||
var rect = this.backgroundButtons_[j];
|
||||
if (rect) goog.dom.removeNode(rect);
|
||||
// Delete any mats from a previous showing.
|
||||
for (var j = 0; j < this.mats_.length; j++) {
|
||||
var rect = this.mats_[j];
|
||||
if (rect) {
|
||||
goog.dom.removeNode(rect);
|
||||
}
|
||||
}
|
||||
this.backgroundButtons_.length = 0;
|
||||
|
||||
this.mats_.length = 0;
|
||||
// Delete any buttons from a previous showing.
|
||||
for (var i = 0, button; button = this.buttons_[i]; i++) {
|
||||
button.dispose();
|
||||
}
|
||||
@@ -547,7 +549,7 @@ Blockly.Flyout.prototype.clearOldBlocks_ = function() {
|
||||
* @param {!Element} root The root node of the SVG group the block is in.
|
||||
* @param {!Blockly.Block} block The block to add listeners for.
|
||||
* @param {!Element} rect The invisible rectangle under the block that acts as
|
||||
* a button for that block.
|
||||
* a mat for that block.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Flyout.prototype.addBlockListeners_ = function(root, block, rect) {
|
||||
@@ -652,8 +654,8 @@ Blockly.Flyout.prototype.initFlyoutButton_ = function(button, x, y) {
|
||||
* @param {number} y The y position of the cursor during this layout pass.
|
||||
* @param {!{height: number, width: number}} blockHW The height and width of the
|
||||
* block.
|
||||
* @param {number} index The index into the background buttons list where this
|
||||
* rect should be placed.
|
||||
* @param {number} index The index into the mats list where this rect should be
|
||||
* placed.
|
||||
* @return {!SVGElement} Newly created SVG element for the rectangle behind the
|
||||
* block.
|
||||
* @private
|
||||
@@ -675,7 +677,7 @@ Blockly.Flyout.prototype.createRect_ = function(block, x, y, blockHW, index) {
|
||||
this.workspace_.getCanvas().insertBefore(rect, block.getSvgRoot());
|
||||
|
||||
block.flyoutRect_ = rect;
|
||||
this.backgroundButtons_[index] = rect;
|
||||
this.mats_[index] = rect;
|
||||
return rect;
|
||||
};
|
||||
|
||||
@@ -725,14 +727,13 @@ Blockly.Flyout.prototype.filterForCapacity_ = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Reflow blocks and their buttons.
|
||||
* Reflow blocks and their mats.
|
||||
*/
|
||||
Blockly.Flyout.prototype.reflow = function() {
|
||||
if (this.reflowWrapper_) {
|
||||
this.workspace_.removeChangeListener(this.reflowWrapper_);
|
||||
}
|
||||
var blocks = this.workspace_.getTopBlocks(false);
|
||||
this.reflowInternal_(blocks);
|
||||
this.reflowInternal_();
|
||||
if (this.reflowWrapper_) {
|
||||
this.workspace_.addChangeListener(this.reflowWrapper_);
|
||||
}
|
||||
|
||||
+15
-7
@@ -145,17 +145,17 @@ Blockly.FlyoutButton.prototype.createDom = function() {
|
||||
// Background rectangle.
|
||||
var rect = Blockly.utils.createSvgElement('rect',
|
||||
{'class': this.isLabel_ ?
|
||||
'blocklyFlyoutLabelBackground' : 'blocklyFlyoutButtonBackground',
|
||||
'rx': 4, 'ry': 4},
|
||||
'blocklyFlyoutLabelBackground' : 'blocklyFlyoutButtonBackground',
|
||||
'rx': 4, 'ry': 4},
|
||||
this.svgGroup_);
|
||||
|
||||
var svgText = Blockly.utils.createSvgElement('text',
|
||||
{'class': this.isLabel_ ? 'blocklyFlyoutLabelText' : 'blocklyText',
|
||||
'x': 0, 'y': 0, 'text-anchor': 'middle'},
|
||||
'x': 0, 'y': 0, 'text-anchor': 'middle'},
|
||||
this.svgGroup_);
|
||||
svgText.textContent = this.text_;
|
||||
|
||||
this.width = svgText.getComputedTextLength();
|
||||
this.width = Blockly.Field.getCachedWidth(svgText);
|
||||
this.height = 20; // Can't compute it :(
|
||||
|
||||
if (!this.isLabel_) {
|
||||
@@ -185,12 +185,11 @@ Blockly.FlyoutButton.prototype.show = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Update svg attributes to match internal state.
|
||||
* Update SVG attributes to match internal state.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FlyoutButton.prototype.updateTransform_ = function() {
|
||||
this.svgGroup_.setAttribute('transform',
|
||||
'translate(' + this.position_.x + ',' + this.position_.y + ')');
|
||||
this.svgGroup_.setAttribute('transform', 'translate' + this.position_);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -204,6 +203,15 @@ Blockly.FlyoutButton.prototype.moveTo = function(x, y) {
|
||||
this.updateTransform_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Location of the button.
|
||||
* @return {!goog.math.Coordinate} x, y coordinates.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FlyoutButton.prototype.getPosition = function() {
|
||||
return this.position_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the button's target workspace.
|
||||
* @return {!Blockly.WorkspaceSvg} The target workspace of the flyout where this
|
||||
|
||||
@@ -351,14 +351,14 @@ Blockly.HorizontalFlyout.prototype.getClientRect = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute height of flyout. Position button under each block.
|
||||
* Compute height of flyout. Position mat under each block.
|
||||
* For RTL: Lay out the blocks right-aligned.
|
||||
* @param {!Array<!Blockly.Block>} blocks The blocks to reflow.
|
||||
* @private
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.reflowInternal_ = function(blocks) {
|
||||
Blockly.HorizontalFlyout.prototype.reflowInternal_ = function() {
|
||||
this.workspace_.scale = this.targetWorkspace_.scale;
|
||||
var flyoutHeight = 0;
|
||||
var blocks = this.workspace_.getTopBlocks(false);
|
||||
for (var i = 0, block; block = blocks[i]; i++) {
|
||||
flyoutHeight = Math.max(flyoutHeight, block.getHeightWidth().height);
|
||||
}
|
||||
|
||||
+16
-7
@@ -188,7 +188,7 @@ Blockly.VerticalFlyout.prototype.setBackgroundPath_ = function(width, height) {
|
||||
atRight ? this.CORNER_RADIUS : -this.CORNER_RADIUS,
|
||||
this.CORNER_RADIUS);
|
||||
// Bottom.
|
||||
path.push('h', atRight ? width : -width);
|
||||
path.push('h', atRight ? width : -width);
|
||||
path.push('z');
|
||||
this.svgBackground_.setAttribute('d', path.join(' '));
|
||||
};
|
||||
@@ -326,14 +326,14 @@ Blockly.VerticalFlyout.prototype.getClientRect = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute width of flyout. Position button under each block.
|
||||
* For RTL: Lay out the blocks right-aligned.
|
||||
* @param {!Array<!Blockly.Block>} blocks The blocks to reflow.
|
||||
* Compute width of flyout. Position mat under each block.
|
||||
* For RTL: Lay out the blocks and buttons to be right-aligned.
|
||||
* @private
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.reflowInternal_ = function(blocks) {
|
||||
Blockly.VerticalFlyout.prototype.reflowInternal_ = function() {
|
||||
this.workspace_.scale = this.targetWorkspace_.scale;
|
||||
var flyoutWidth = 0;
|
||||
var blocks = this.workspace_.getTopBlocks(false);
|
||||
for (var i = 0, block; block = blocks[i]; i++) {
|
||||
var width = block.getHeightWidth().width;
|
||||
if (block.outputConnection) {
|
||||
@@ -353,14 +353,23 @@ Blockly.VerticalFlyout.prototype.reflowInternal_ = function(blocks) {
|
||||
if (this.RTL) {
|
||||
// With the flyoutWidth known, right-align the blocks.
|
||||
var oldX = block.getRelativeToSurfaceXY().x;
|
||||
var newX = flyoutWidth / this.workspace_.scale - this.MARGIN;
|
||||
newX -= Blockly.BlockSvg.TAB_WIDTH;
|
||||
var newX = flyoutWidth / this.workspace_.scale - this.MARGIN -
|
||||
Blockly.BlockSvg.TAB_WIDTH;
|
||||
block.moveBy(newX - oldX, 0);
|
||||
}
|
||||
if (block.flyoutRect_) {
|
||||
this.moveRectToBlock_(block.flyoutRect_, block);
|
||||
}
|
||||
}
|
||||
if (this.RTL) {
|
||||
// With the flyoutWidth known, right-align the buttons.
|
||||
for (var i = 0, button; button = this.buttons_[i]; i++) {
|
||||
var y = button.getPosition().y;
|
||||
var x = flyoutWidth - button.width - this.MARGIN -
|
||||
Blockly.BlockSvg.TAB_WIDTH;
|
||||
button.moveTo(x, y);
|
||||
}
|
||||
}
|
||||
// Record the width for .getMetrics_ and .position.
|
||||
this.width_ = flyoutWidth;
|
||||
// Call this since it is possible the trash and zoom buttons need
|
||||
|
||||
+1
-1
@@ -366,7 +366,7 @@ Blockly.Generator.prototype.provideFunction_ = function(desiredName, code) {
|
||||
var oldCodeText;
|
||||
while (oldCodeText != codeText) {
|
||||
oldCodeText = codeText;
|
||||
codeText = codeText.replace(/^(( )*) /gm, '$1\0');
|
||||
codeText = codeText.replace(/^(( {2})*) {2}/gm, '$1\0');
|
||||
}
|
||||
codeText = codeText.replace(/\0/g, this.INDENT);
|
||||
this.definitions_[desiredName] = codeText;
|
||||
|
||||
+2
-2
@@ -246,7 +246,7 @@ Blockly.Gesture.prototype.updateFromEvent_ = function(e) {
|
||||
var currentXY = new goog.math.Coordinate(e.clientX, e.clientY);
|
||||
var changed = this.updateDragDelta_(currentXY);
|
||||
// Exceeded the drag radius for the first time.
|
||||
if (changed){
|
||||
if (changed) {
|
||||
this.updateIsDragging_();
|
||||
Blockly.longStop_();
|
||||
}
|
||||
@@ -328,7 +328,7 @@ Blockly.Gesture.prototype.updateIsDraggingBlock_ = function() {
|
||||
|
||||
if (this.flyout_) {
|
||||
this.isDraggingBlock_ = this.updateIsDraggingFromFlyout_();
|
||||
} else if (this.targetBlock_.isMovable()){
|
||||
} else if (this.targetBlock_.isMovable()) {
|
||||
this.isDraggingBlock_ = true;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ Blockly.Grid.prototype.getSpacing = function() {
|
||||
/**
|
||||
* Get the id of the pattern element, which should be randomized to avoid
|
||||
* conflicts with other Blockly instances on the page.
|
||||
* @return {string} The pattern id.
|
||||
* @return {string} The pattern ID.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Grid.prototype.getPatternId = function() {
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ Blockly.inject = function(container, opt_options) {
|
||||
throw 'Error: container is not in current document.';
|
||||
}
|
||||
var options = new Blockly.Options(opt_options || {});
|
||||
var subContainer = goog.dom.createDom('div', 'injectionDiv');
|
||||
var subContainer = goog.dom.createDom(goog.dom.TagName.DIV, 'injectionDiv');
|
||||
container.appendChild(subContainer);
|
||||
var svg = Blockly.createDom_(subContainer, options);
|
||||
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ Blockly.Input.prototype.insertFieldAt = function(index, field, opt_name) {
|
||||
|
||||
// Empty string, Null or undefined generates no field, unless field is named.
|
||||
if (!field && !opt_name) {
|
||||
return this;
|
||||
return index;
|
||||
}
|
||||
// Generate a FieldLabel when given a plain text field.
|
||||
if (goog.isString(field)) {
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ goog.getMsgOrig = goog.getMsg;
|
||||
* Overrides the default Closure function to check for a Blockly.Msg first.
|
||||
* Used infrequently, only known case is TODAY button in date picker.
|
||||
* @param {string} str Translatable string, places holders in the form {$foo}.
|
||||
* @param {Object<string, string>=} opt_values Maps place holder name to value.
|
||||
* @param {Object.<string, string>=} opt_values Maps place holder name to value.
|
||||
* @return {string} message with placeholders filled.
|
||||
* @suppress {duplicate}
|
||||
*/
|
||||
|
||||
+7
-1
@@ -73,7 +73,13 @@ Blockly.Mutator.prototype.drawIcon_ = function(group) {
|
||||
// Gear teeth.
|
||||
Blockly.utils.createSvgElement('path',
|
||||
{'class': 'blocklyIconSymbol',
|
||||
'd': 'm4.203,7.296 0,1.368 -0.92,0.677 -0.11,0.41 0.9,1.559 0.41,0.11 1.043,-0.457 1.187,0.683 0.127,1.134 0.3,0.3 1.8,0 0.3,-0.299 0.127,-1.138 1.185,-0.682 1.046,0.458 0.409,-0.11 0.9,-1.559 -0.11,-0.41 -0.92,-0.677 0,-1.366 0.92,-0.677 0.11,-0.41 -0.9,-1.559 -0.409,-0.109 -1.046,0.458 -1.185,-0.682 -0.127,-1.138 -0.3,-0.299 -1.8,0 -0.3,0.3 -0.126,1.135 -1.187,0.682 -1.043,-0.457 -0.41,0.11 -0.899,1.559 0.108,0.409z'},
|
||||
'd': 'm4.203,7.296 0,1.368 -0.92,0.677 -0.11,0.41 0.9,1.559 0.41,' +
|
||||
'0.11 1.043,-0.457 1.187,0.683 0.127,1.134 0.3,0.3 1.8,0 0.3,' +
|
||||
'-0.299 0.127,-1.138 1.185,-0.682 1.046,0.458 0.409,-0.11 0.9,' +
|
||||
'-1.559 -0.11,-0.41 -0.92,-0.677 0,-1.366 0.92,-0.677 0.11,' +
|
||||
'-0.41 -0.9,-1.559 -0.409,-0.109 -1.046,0.458 -1.185,-0.682 ' +
|
||||
'-0.127,-1.138 -0.3,-0.299 -1.8,0 -0.3,0.3 -0.126,1.135 -1.187,' +
|
||||
'0.682 -1.043,-0.457 -0.41,0.11 -0.899,1.559 0.108,0.409z'},
|
||||
group);
|
||||
// Axle hole.
|
||||
Blockly.utils.createSvgElement('circle',
|
||||
|
||||
+6
-5
@@ -30,6 +30,7 @@ goog.provide('Blockly.ScrollbarPair');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.events');
|
||||
|
||||
|
||||
/**
|
||||
* A note on units: most of the numbers that are in CSS pixels are scaled if the
|
||||
* scrollbar is in a mutator.
|
||||
@@ -189,7 +190,7 @@ Blockly.ScrollbarPair.prototype.getRatio_ = function(handlePosition, viewSize) {
|
||||
* @param {!Blockly.Workspace} workspace Workspace to bind the scrollbar to.
|
||||
* @param {boolean} horizontal True if horizontal, false if vertical.
|
||||
* @param {boolean=} opt_pair True if scrollbar is part of a horiz/vert pair.
|
||||
* @param {string} opt_class A class to be applied to this scrollbar.
|
||||
* @param {string=} opt_class A class to be applied to this scrollbar.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Scrollbar = function(workspace, horizontal, opt_pair, opt_class) {
|
||||
@@ -201,7 +202,7 @@ Blockly.Scrollbar = function(workspace, horizontal, opt_pair, opt_class) {
|
||||
this.createDom_(opt_class);
|
||||
|
||||
/**
|
||||
* The upper left corner of the scrollbar's svg group in CSS pixels relative
|
||||
* The upper left corner of the scrollbar's SVG group in CSS pixels relative
|
||||
* to the scrollbar's origin. This is usually relative to the injection div
|
||||
* origin.
|
||||
* @type {goog.math.Coordinate}
|
||||
@@ -394,7 +395,7 @@ Blockly.ScrollbarPair.prototype.setContainerVisible = function(visible) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the position of the scrollbar's svg group in CSS pixels relative to the
|
||||
* Set the position of the scrollbar's SVG group in CSS pixels relative to the
|
||||
* scrollbar's origin. This sets the scrollbar's location within the workspace.
|
||||
* @param {number} x The new x coordinate.
|
||||
* @param {number} y The new y coordinate.
|
||||
@@ -591,7 +592,7 @@ Blockly.Scrollbar.prototype.resizeContentVertical = function(hostMetrics) {
|
||||
/**
|
||||
* Create all the DOM elements required for a scrollbar.
|
||||
* The resulting widget is not sized.
|
||||
* @param {string} opt_class A class to be applied to this scrollbar.
|
||||
* @param {string=} opt_class A class to be applied to this scrollbar.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Scrollbar.prototype.createDom_ = function(opt_class) {
|
||||
@@ -667,7 +668,7 @@ Blockly.Scrollbar.prototype.setVisible = function(visible) {
|
||||
* Update visibility of scrollbar based on whether it thinks it should
|
||||
* be visible and whether its containing workspace is visible.
|
||||
* We cannot rely on the containing workspace being hidden to hide us
|
||||
* because it is not necessarily our parent in the dom.
|
||||
* because it is not necessarily our parent in the DOM.
|
||||
*/
|
||||
Blockly.Scrollbar.prototype.updateDisplay_ = function() {
|
||||
var show = true;
|
||||
|
||||
+14
-10
@@ -296,8 +296,9 @@ Blockly.Toolbox.prototype.populate_ = function(newTree) {
|
||||
/**
|
||||
* Sync trees of the toolbox.
|
||||
* @param {!Node} treeIn DOM tree of blocks.
|
||||
* @param {!Blockly.Toolbox.TreeControl} treeOut
|
||||
* @param {string} pathToMedia
|
||||
* @param {!Blockly.Toolbox.TreeControl} treeOut The TreeContorol object built
|
||||
* from treeIn.
|
||||
* @param {string} pathToMedia The path to the Blockly media directory.
|
||||
* @return {Node} Tree node to open at startup (or null).
|
||||
* @private
|
||||
*/
|
||||
@@ -331,12 +332,12 @@ Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) {
|
||||
// Decode the colour for any potential message references
|
||||
// (eg. `%{BKY_MATH_HUE}`).
|
||||
var colour = Blockly.utils.replaceMessageReferences(
|
||||
childIn.getAttribute('colour'));
|
||||
childIn.getAttribute('colour'));
|
||||
if (goog.isString(colour)) {
|
||||
if (colour.match(/^#[0-9a-fA-F]{6}$/)) {
|
||||
if (/^#[0-9a-fA-F]{6}$/.test(colour)) {
|
||||
childOut.hexColour = colour;
|
||||
} else {
|
||||
childOut.hexColour = Blockly.hueToRgb(colour);
|
||||
childOut.hexColour = Blockly.hueToRgb(Number(colour));
|
||||
}
|
||||
this.hasColours_ = true;
|
||||
} else {
|
||||
@@ -388,7 +389,7 @@ Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) {
|
||||
|
||||
/**
|
||||
* Recursively add colours to this toolbox.
|
||||
* @param {Blockly.Toolbox.TreeNode} opt_tree Starting point of tree.
|
||||
* @param {Blockly.Toolbox.TreeNode=} opt_tree Starting point of tree.
|
||||
* Defaults to the root node.
|
||||
* @private
|
||||
*/
|
||||
@@ -629,7 +630,8 @@ Blockly.Toolbox.TreeNode.prototype.getExpandIconSafeHtml = function() {
|
||||
* @param {!goog.events.BrowserEvent} e The browser event.
|
||||
* @override
|
||||
*/
|
||||
Blockly.Toolbox.TreeNode.prototype.onClick_ = function(e) {
|
||||
Blockly.Toolbox.TreeNode.prototype.onClick_ = function(
|
||||
/* eslint-disable no-unused-vars */ e /* eslint-disable no-unused-vars */) {
|
||||
// Expand icon.
|
||||
if (this.hasChildren() && this.isUserCollapsible_) {
|
||||
this.toggle();
|
||||
@@ -648,7 +650,8 @@ Blockly.Toolbox.TreeNode.prototype.onClick_ = function(e) {
|
||||
* @override
|
||||
* @private
|
||||
*/
|
||||
Blockly.Toolbox.TreeNode.prototype.onMouseDown = function(e) {
|
||||
Blockly.Toolbox.TreeNode.prototype.onMouseDown = function(
|
||||
/* eslint-disable no-unused-vars */ e /* eslint-disable no-unused-vars */) {
|
||||
// NOPE.
|
||||
};
|
||||
|
||||
@@ -658,7 +661,8 @@ Blockly.Toolbox.TreeNode.prototype.onMouseDown = function(e) {
|
||||
* @override
|
||||
* @private
|
||||
*/
|
||||
Blockly.Toolbox.TreeNode.prototype.onDoubleClick_ = function(e) {
|
||||
Blockly.Toolbox.TreeNode.prototype.onDoubleClick_ = function(
|
||||
/* eslint-disable no-unused-vars */ e /* eslint-disable no-unused-vars */) {
|
||||
// NOP.
|
||||
};
|
||||
|
||||
@@ -695,6 +699,6 @@ Blockly.Toolbox.TreeNode.prototype.onKeyDown = function(e) {
|
||||
* @extends {Blockly.Toolbox.TreeNode}
|
||||
*/
|
||||
Blockly.Toolbox.TreeSeparator = function(config) {
|
||||
Blockly.Toolbox.TreeNode.call(this, null, '', config);
|
||||
Blockly.Toolbox.TreeNode.call(this, null, goog.html.SafeHtml.EMPTY, config);
|
||||
};
|
||||
goog.inherits(Blockly.Toolbox.TreeSeparator, Blockly.Toolbox.TreeNode);
|
||||
|
||||
+5
-2
@@ -184,7 +184,8 @@ Blockly.Tooltip.onMouseOver_ = function(e) {
|
||||
* @param {!Event} e Mouse event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Tooltip.onMouseOut_ = function(e) {
|
||||
Blockly.Tooltip.onMouseOut_ = function(/* eslint-disable no-unused-vars */e
|
||||
/* eslint-enable no-unused-vars */) {
|
||||
if (Blockly.Tooltip.blocked_) {
|
||||
// Someone doesn't want us to show tooltips.
|
||||
return;
|
||||
@@ -248,7 +249,9 @@ Blockly.Tooltip.hide = function() {
|
||||
Blockly.Tooltip.DIV.style.display = 'none';
|
||||
}
|
||||
}
|
||||
clearTimeout(Blockly.Tooltip.showPid_);
|
||||
if (Blockly.Tooltip.showPid_) {
|
||||
clearTimeout(Blockly.Tooltip.showPid_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+4
-3
@@ -34,9 +34,10 @@ goog.require('goog.events');
|
||||
goog.require('goog.events.BrowserFeature');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* Which touch events are we currently paying attention to?
|
||||
* @type {DOMString}
|
||||
* @type {?string}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Touch.touchIdentifier_ = null;
|
||||
@@ -63,7 +64,7 @@ Blockly.longPid_ = 0;
|
||||
|
||||
/**
|
||||
* Context menus on touch devices are activated using a long-press.
|
||||
* Unfortunately the contextmenu touch event is currently (2015) only suported
|
||||
* Unfortunately the contextmenu touch event is currently (2015) only supported
|
||||
* by Chrome. This function is fired on any touchstart event, queues a task,
|
||||
* which after about a second opens the context menu. The tasks is killed
|
||||
* if the touch event terminates early.
|
||||
@@ -154,7 +155,7 @@ Blockly.Touch.getTouchIdentifierFromEvent = function(e) {
|
||||
Blockly.Touch.checkTouchIdentifier = function(e) {
|
||||
var identifier = Blockly.Touch.getTouchIdentifierFromEvent(e);
|
||||
|
||||
// if (Blockly.touchIdentifier_ )is insufficient because android touch
|
||||
// if (Blockly.touchIdentifier_ )is insufficient because Android touch
|
||||
// identifiers may be zero.
|
||||
if (Blockly.Touch.touchIdentifier_ != undefined &&
|
||||
Blockly.Touch.touchIdentifier_ != null) {
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
**/
|
||||
goog.provide('Blockly.utils.uiMenu');
|
||||
|
||||
|
||||
/**
|
||||
* Get the size of a rendered goog.ui.Menu.
|
||||
* @param {!goog.ui.Menu} menu The menu to measure.
|
||||
|
||||
+29
-24
@@ -44,8 +44,8 @@ goog.require('goog.userAgent');
|
||||
* is not possible. To access the exported Blockly.Msg.Something it needs to be
|
||||
* accessed through the exact name that was exported. Note, that all the exports
|
||||
* are happening as the last thing in the generated js files, so they won't be
|
||||
* accessible before javascript loads!
|
||||
* @return {!Object<string, string>}
|
||||
* accessible before JavaScript loads!
|
||||
* @return {!Object.<string, string>} The message array.
|
||||
* @private
|
||||
*/
|
||||
Blockly.utils.getMessageArray_ = function() {
|
||||
@@ -208,10 +208,9 @@ Blockly.utils.getRelativeXY = function(element) {
|
||||
Blockly.utils.getInjectionDivXY_ = function(element) {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var scale = 1;
|
||||
while (element) {
|
||||
var xy = Blockly.utils.getRelativeXY(element);
|
||||
scale = Blockly.utils.getScale_(element);
|
||||
var scale = Blockly.utils.getScale_(element);
|
||||
x = (x * scale) + xy.x;
|
||||
y = (y * scale) + xy.y;
|
||||
var classes = element.getAttribute('class') || '';
|
||||
@@ -286,11 +285,9 @@ Blockly.utils.getRelativeXY.XY_2D_REGEX_ =
|
||||
* @param {string} name Element's tag name.
|
||||
* @param {!Object} attrs Dictionary of attribute names and values.
|
||||
* @param {Element} parent Optional parent on which to append the element.
|
||||
* @param {Blockly.Workspace=} opt_workspace Optional workspace for access to
|
||||
* context (scale...).
|
||||
* @return {!SVGElement} Newly created SVG element.
|
||||
*/
|
||||
Blockly.utils.createSvgElement = function(name, attrs, parent /*, opt_workspace */) {
|
||||
Blockly.utils.createSvgElement = function(name, attrs, parent) {
|
||||
var e = /** @type {!SVGElement} */ (
|
||||
document.createElementNS(Blockly.SVG_NS, name));
|
||||
for (var key in attrs) {
|
||||
@@ -328,7 +325,7 @@ Blockly.utils.isRightButton = function(e) {
|
||||
* @param {!Event} e Mouse event.
|
||||
* @param {!Element} svg SVG element.
|
||||
* @param {SVGMatrix} matrix Inverted screen CTM to use.
|
||||
* @return {!Object} Object with .x and .y properties.
|
||||
* @return {!SVGPoint} Object with .x and .y properties.
|
||||
*/
|
||||
Blockly.utils.mouseToSvg = function(e, svg, matrix) {
|
||||
var svgPoint = svg.createSVGPoint();
|
||||
@@ -454,38 +451,45 @@ Blockly.utils.replaceMessageReferences = function(message) {
|
||||
var interpolatedResult = Blockly.utils.tokenizeInterpolation_(message, false);
|
||||
// When parseInterpolationTokens == false, interpolatedResult should be at
|
||||
// most length 1.
|
||||
return interpolatedResult.length ? interpolatedResult[0] : "";
|
||||
return interpolatedResult.length ? interpolatedResult[0] : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates that any %{BKY_...} references in the message refer to keys of
|
||||
* Validates that any %{MSG_KEY} references in the message refer to keys of
|
||||
* the Blockly.Msg string table.
|
||||
* @param {string} message Text which might contain string table references.
|
||||
* @return {boolean} True if all message references have matching values.
|
||||
* Otherwise, false.
|
||||
*/
|
||||
Blockly.utils.checkMessageReferences = function(message) {
|
||||
var isValid = true; // True until a bad reference is found
|
||||
var validSoFar = true;
|
||||
|
||||
var regex = /%{BKY_([a-zA-Z][a-zA-Z0-9_]*)}/g;
|
||||
var msgTable = Blockly.utils.getMessageArray_();
|
||||
|
||||
// TODO(#1169): Implement support for other string tables, prefixes other than BKY_.
|
||||
var regex = /%{(BKY_[A-Z][A-Z0-9_]*)}/gi;
|
||||
var match = regex.exec(message);
|
||||
while (match != null) {
|
||||
while (match) {
|
||||
var msgKey = match[1];
|
||||
if (Blockly.utils.getMessageArray_()[msgKey] == null) {
|
||||
console.log('WARNING: No message string for %{BKY_' + msgKey + '}.');
|
||||
isValid = false;
|
||||
msgKey = msgKey.toUpperCase();
|
||||
if (msgKey.substr(0, 4) != 'BKY_') {
|
||||
console.log('WARNING: Unsupported message table prefix in %{' + match[1] + '}.');
|
||||
validSoFar = false; // Continue to report other errors.
|
||||
} else if (msgTable[msgKey.substr(4)] == undefined) {
|
||||
console.log('WARNING: No message string for %{' + match[1] + '}.');
|
||||
validSoFar = false; // Continue to report other errors.
|
||||
}
|
||||
|
||||
// Re-run on remainder of sting.
|
||||
// Re-run on remainder of string.
|
||||
message = message.substring(match.index + msgKey.length + 1);
|
||||
match = regex.exec(message);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
return validSoFar;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal implemention of the message reference and interpolation token
|
||||
* Internal implementation of the message reference and interpolation token
|
||||
* parsing used by tokenizeInterpolation() and replaceMessageReferences().
|
||||
* @param {string} message Text which might contain string table references and
|
||||
* interpolation tokens.
|
||||
@@ -494,7 +498,8 @@ Blockly.utils.checkMessageReferences = function(message) {
|
||||
* @return {!Array.<string|number>} Array of strings and numbers.
|
||||
* @private
|
||||
*/
|
||||
Blockly.utils.tokenizeInterpolation_ = function(message, parseInterpolationTokens) {
|
||||
Blockly.utils.tokenizeInterpolation_ = function(message,
|
||||
parseInterpolationTokens) {
|
||||
var tokens = [];
|
||||
var chars = message.split('');
|
||||
chars.push(''); // End marker.
|
||||
@@ -502,7 +507,7 @@ Blockly.utils.tokenizeInterpolation_ = function(message, parseInterpolationToken
|
||||
// 0 - Base case.
|
||||
// 1 - % found.
|
||||
// 2 - Digit found.
|
||||
// 3 - Message ref found
|
||||
// 3 - Message ref found.
|
||||
var state = 0;
|
||||
var buffer = [];
|
||||
var number = null;
|
||||
@@ -569,7 +574,8 @@ Blockly.utils.tokenizeInterpolation_ = function(message, parseInterpolationToken
|
||||
if (goog.isString(rawValue)) {
|
||||
// Attempt to dereference substrings, too, appending to the end.
|
||||
Array.prototype.push.apply(tokens,
|
||||
Blockly.utils.tokenizeInterpolation(rawValue));
|
||||
Blockly.utils.tokenizeInterpolation_(
|
||||
rawValue, parseInterpolationTokens));
|
||||
} else if (parseInterpolationTokens) {
|
||||
// When parsing interpolation tokens, numbers are special
|
||||
// placeholders (%1, %2, etc). Make sure all other values are
|
||||
@@ -640,7 +646,7 @@ Blockly.utils.genUid = function() {
|
||||
* Legal characters for the unique ID. Should be all on a US keyboard.
|
||||
* No characters that conflict with XML or JSON. Requests to remove additional
|
||||
* 'problematic' characters from this soup will be denied. That's your failure
|
||||
* to properly escape in your own environment. Issues #251, #625, #682.
|
||||
* to properly escape in your own environment. Issues #251, #625, #682, #1304.
|
||||
* @private
|
||||
*/
|
||||
Blockly.utils.genUid.soup_ = '!#$%()*+,-./:;=?@[]^_`{|}~' +
|
||||
@@ -937,4 +943,3 @@ Blockly.utils.getViewportBBox = function() {
|
||||
left: scrollOffset.x
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
+23
-21
@@ -26,6 +26,7 @@
|
||||
|
||||
goog.provide('Blockly.VariableMap');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a variable map. This contains a dictionary data structure with
|
||||
* variable types as keys and lists of variables as values. The list of
|
||||
@@ -33,12 +34,12 @@ goog.provide('Blockly.VariableMap');
|
||||
* @param {!Blockly.Workspace} workspace The workspace this map belongs to.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.VariableMap = function(workspace) {
|
||||
Blockly.VariableMap = function(workspace) {
|
||||
/**
|
||||
* A map from variable type to list of variable names. The lists contain all
|
||||
* of the named variables in the workspace, including variables
|
||||
* that are not currently in use.
|
||||
* @type {!Object<string, !Array.<Blockly.VariableModel>>}
|
||||
* @type {!Object.<string, !Array.<Blockly.VariableModel>>}
|
||||
* @private
|
||||
*/
|
||||
this.variableMap_ = {};
|
||||
@@ -59,7 +60,7 @@ Blockly.VariableMap.prototype.clear = function() {
|
||||
|
||||
/**
|
||||
* Rename the given variable by updating its name in the variable map.
|
||||
* @param {?Blockly.VariableModel} variable Variable to rename.
|
||||
* @param {Blockly.VariableModel} variable Variable to rename.
|
||||
* @param {string} newName New variable name.
|
||||
*/
|
||||
Blockly.VariableMap.prototype.renameVariable = function(variable, newName) {
|
||||
@@ -75,7 +76,7 @@ Blockly.VariableMap.prototype.renameVariable = function(variable, newName) {
|
||||
if (variable) {
|
||||
variableIndex = variableList.indexOf(variable);
|
||||
}
|
||||
if (newVariable){ // see if I can get rid of newVariable dependency
|
||||
if (newVariable) { // see if I can get rid of newVariable dependency
|
||||
newVariableIndex = variableList.indexOf(newVariable);
|
||||
}
|
||||
|
||||
@@ -103,17 +104,18 @@ Blockly.VariableMap.prototype.renameVariable = function(variable, newName) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a variable with a given name, optional type, and optional id.
|
||||
* @param {!string} name The name of the variable. This must be unique across
|
||||
* Create a variable with a given name, optional type, and optional ID.
|
||||
* @param {string} name The name of the variable. This must be unique across
|
||||
* variables and procedures.
|
||||
* @param {?string} opt_type The type of the variable like 'int' or 'string'.
|
||||
* @param {string=} opt_type The type of the variable like 'int' or 'string'.
|
||||
* Does not need to be unique. Field_variable can filter variables based on
|
||||
* their type. This will default to '' which is a specific type.
|
||||
* @param {?string} opt_id The unique id of the variable. This will default to
|
||||
* @param {string=} opt_id The unique ID of the variable. This will default to
|
||||
* a UUID.
|
||||
* @return {?Blockly.VariableModel} The newly created variable.
|
||||
* @return {Blockly.VariableModel} The newly created variable.
|
||||
*/
|
||||
Blockly.VariableMap.prototype.createVariable = function(name, opt_type, opt_id) {
|
||||
Blockly.VariableMap.prototype.createVariable = function(name,
|
||||
opt_type, opt_id) {
|
||||
var variable = this.getVariable(name);
|
||||
if (variable) {
|
||||
if (opt_type && variable.type != opt_type) {
|
||||
@@ -122,11 +124,11 @@ Blockly.VariableMap.prototype.createVariable = function(name, opt_type, opt_id)
|
||||
'type, "' + opt_type + '".');
|
||||
}
|
||||
if (opt_id && variable.getId() != opt_id) {
|
||||
throw Error('Variable "' + name + '" is already in use and its id is "'
|
||||
+ variable.getId() + '" which conflicts with the passed in ' +
|
||||
throw Error('Variable "' + name + '" is already in use and its id is "' +
|
||||
variable.getId() + '" which conflicts with the passed in ' +
|
||||
'id, "' + opt_id + '".');
|
||||
}
|
||||
// The variable already exists and has the same id and type.
|
||||
// The variable already exists and has the same ID and type.
|
||||
return variable;
|
||||
}
|
||||
if (opt_id && this.getVariableById(opt_id)) {
|
||||
@@ -148,7 +150,7 @@ Blockly.VariableMap.prototype.createVariable = function(name, opt_type, opt_id)
|
||||
|
||||
/**
|
||||
* Delete a variable.
|
||||
* @param {Blockly.VariableModel} variable Variable to delete.
|
||||
* @param {!Blockly.VariableModel} variable Variable to delete.
|
||||
*/
|
||||
Blockly.VariableMap.prototype.deleteVariable = function(variable) {
|
||||
var variableList = this.variableMap_[variable.type];
|
||||
@@ -164,8 +166,8 @@ Blockly.VariableMap.prototype.deleteVariable = function(variable) {
|
||||
/**
|
||||
* Find the variable by the given name and return it. Return null if it is not
|
||||
* found.
|
||||
* @param {!string} name The name to check for.
|
||||
* @return {?Blockly.VariableModel} The variable with the given name, or null if
|
||||
* @param {string} name The name to check for.
|
||||
* @return {Blockly.VariableModel} The variable with the given name, or null if
|
||||
* it was not found.
|
||||
*/
|
||||
Blockly.VariableMap.prototype.getVariable = function(name) {
|
||||
@@ -182,10 +184,10 @@ Blockly.VariableMap.prototype.getVariable = function(name) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the variable by the given id and return it. Return null if it is not
|
||||
* Find the variable by the given ID and return it. Return null if it is not
|
||||
* found.
|
||||
* @param {!string} id The id to check for.
|
||||
* @return {?Blockly.VariableModel} The variable with the given id.
|
||||
* @param {string} id The ID to check for.
|
||||
* @return {Blockly.VariableModel} The variable with the given ID.
|
||||
*/
|
||||
Blockly.VariableMap.prototype.getVariableById = function(id) {
|
||||
var keys = Object.keys(this.variableMap_);
|
||||
@@ -204,7 +206,7 @@ Blockly.VariableMap.prototype.getVariableById = function(id) {
|
||||
* Get a list containing all of the variables of a specified type. If type is
|
||||
* null, return list of variables with empty string type.
|
||||
* @param {?string} type Type of the variables to find.
|
||||
* @return {Array.<Blockly.VariableModel>} The sought after variables of the
|
||||
* @return {!Array.<!Blockly.VariableModel>} The sought after variables of the
|
||||
* passed in type. An empty array if none are found.
|
||||
*/
|
||||
Blockly.VariableMap.prototype.getVariablesOfType = function(type) {
|
||||
@@ -226,7 +228,7 @@ Blockly.VariableMap.prototype.getVariableTypes = function() {
|
||||
|
||||
/**
|
||||
* Return all variables of all types.
|
||||
* @return {!Array.<Blockly.VariableModel>} List of variable models.
|
||||
* @return {!Array.<!Blockly.VariableModel>} List of variable models.
|
||||
*/
|
||||
Blockly.VariableMap.prototype.getAllVariables = function() {
|
||||
var all_variables = [];
|
||||
|
||||
@@ -31,14 +31,14 @@ goog.require('goog.string');
|
||||
|
||||
/**
|
||||
* Class for a variable model.
|
||||
* Holds information for the variable including name, id, and type.
|
||||
* Holds information for the variable including name, ID, and type.
|
||||
* @param {!Blockly.Workspace} workspace The variable's workspace.
|
||||
* @param {!string} name The name of the variable. This must be unique across
|
||||
* variables and procedures.
|
||||
* @param {?string} opt_type The type of the variable like 'int' or 'string'.
|
||||
* @param {string=} opt_type The type of the variable like 'int' or 'string'.
|
||||
* Does not need to be unique. Field_variable can filter variables based on
|
||||
* their type. This will default to '' which is a specific type.
|
||||
* @param {?string} opt_id The unique id of the variable. This will default to
|
||||
* @param {string=} opt_id The unique ID of the variable. This will default to
|
||||
* a UUID.
|
||||
* @see {Blockly.FieldVariable}
|
||||
* @constructor
|
||||
@@ -80,7 +80,7 @@ Blockly.VariableModel = function(workspace, name, opt_type, opt_id) {
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {!string} The id for the variable.
|
||||
* @return {!string} The ID for the variable.
|
||||
*/
|
||||
Blockly.VariableModel.prototype.getId = function() {
|
||||
return this.id_;
|
||||
|
||||
+8
-8
@@ -177,13 +177,13 @@ Blockly.Variables.flyoutCategoryBlocks = function(workspace) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a new variable name that is not yet being used. This will try to
|
||||
* generate single letter variable names in the range 'i' to 'z' to start with.
|
||||
* If no unique name is located it will try 'i' to 'z', 'a' to 'h',
|
||||
* then 'i2' to 'z2' etc. Skip 'l'.
|
||||
* Return a new variable name that is not yet being used. This will try to
|
||||
* generate single letter variable names in the range 'i' to 'z' to start with.
|
||||
* If no unique name is located it will try 'i' to 'z', 'a' to 'h',
|
||||
* then 'i2' to 'z2' etc. Skip 'l'.
|
||||
* @param {!Blockly.Workspace} workspace The workspace to be unique in.
|
||||
* @return {string} New variable name.
|
||||
*/
|
||||
* @return {string} New variable name.
|
||||
*/
|
||||
Blockly.Variables.generateUniqueName = function(workspace) {
|
||||
var variableList = workspace.getAllVariables();
|
||||
var newName = '';
|
||||
@@ -232,7 +232,7 @@ Blockly.Variables.generateUniqueName = function(workspace) {
|
||||
* @param {function(?string=)=} opt_callback A callback. It will
|
||||
* be passed an acceptable new variable name, or null if change is to be
|
||||
* aborted (cancel button), or undefined if an existing variable was chosen.
|
||||
* @param {?string} opt_type The type of the variable like 'int', 'string', or
|
||||
* @param {string=} opt_type The type of the variable like 'int', 'string', or
|
||||
* ''. This will default to '', which is a specific type.
|
||||
*/
|
||||
Blockly.Variables.createVariable = function(workspace, opt_callback, opt_type) {
|
||||
@@ -340,7 +340,7 @@ Blockly.Variables.generateVariableFieldXml_ = function(variableModel) {
|
||||
// to be escaped to create valid XML.
|
||||
var element = goog.dom.createDom('field');
|
||||
element.setAttribute('name', 'VAR');
|
||||
element.setAttribute('variableType', variableModel.type);
|
||||
element.setAttribute('variabletype', variableModel.type);
|
||||
element.setAttribute('id', variableModel.getId());
|
||||
element.textContent = variableModel.name;
|
||||
|
||||
|
||||
+3
-1
@@ -139,7 +139,9 @@ Blockly.Warning.prototype.setVisible = function(visible) {
|
||||
* @param {!Event} e Mouse up event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Warning.prototype.bodyFocus_ = function(e) {
|
||||
|
||||
Blockly.Warning.prototype.bodyFocus_ = function(
|
||||
/* eslint-disable no-unused-vars */ e /* eslint-enable no-unused-vars */) {
|
||||
this.bubble_.promote_();
|
||||
};
|
||||
|
||||
|
||||
+24
-21
@@ -34,7 +34,7 @@ goog.require('goog.math');
|
||||
/**
|
||||
* Class for a workspace. This is a data structure that contains blocks.
|
||||
* There is no UI, and can be created headlessly.
|
||||
* @param {Blockly.Options} opt_options Dictionary of options.
|
||||
* @param {!Blockly.Options=} opt_options Dictionary of options.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Workspace = function(opt_options) {
|
||||
@@ -217,8 +217,7 @@ Blockly.Workspace.prototype.updateVariableStore = function(clear) {
|
||||
if (tempVar) {
|
||||
varList.push({'name': tempVar.name, 'type': tempVar.type,
|
||||
'id': tempVar.getId()});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
varList.push({'name': name, 'type': null, 'id': null});
|
||||
// TODO(marisaleung): Use variable.type and variable.getId() once variable
|
||||
// instances are storing more than just name.
|
||||
@@ -241,7 +240,8 @@ Blockly.Workspace.prototype.updateVariableStore = function(clear) {
|
||||
* @param {?Blockly.VariableModel} variable Variable to rename.
|
||||
* @param {string} newName New variable name.
|
||||
*/
|
||||
Blockly.Workspace.prototype.renameVariableInternal_ = function(variable, newName) {
|
||||
Blockly.Workspace.prototype.renameVariableInternal_ = function(
|
||||
variable, newName) {
|
||||
var newVariable = this.getVariable(newName);
|
||||
var oldCase;
|
||||
|
||||
@@ -285,8 +285,8 @@ Blockly.Workspace.prototype.renameVariable = function(oldName, newName) {
|
||||
|
||||
/**
|
||||
* Rename a variable by updating its name in the variable map. Identify the
|
||||
* variable to rename with the given id.
|
||||
* @param {string} id Id of the variable to rename.
|
||||
* variable to rename with the given ID.
|
||||
* @param {string} id ID of the variable to rename.
|
||||
* @param {string} newName New variable name.
|
||||
*/
|
||||
Blockly.Workspace.prototype.renameVariableById = function(id, newName) {
|
||||
@@ -295,13 +295,13 @@ Blockly.Workspace.prototype.renameVariableById = function(id, newName) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a variable with a given name, optional type, and optional id.
|
||||
* Create a variable with a given name, optional type, and optional ID.
|
||||
* @param {!string} name The name of the variable. This must be unique across
|
||||
* variables and procedures.
|
||||
* @param {?string} opt_type The type of the variable like 'int' or 'string'.
|
||||
* @param {string=} opt_type The type of the variable like 'int' or 'string'.
|
||||
* Does not need to be unique. Field_variable can filter variables based on
|
||||
* their type. This will default to '' which is a specific type.
|
||||
* @param {?string} opt_id The unique id of the variable. This will default to
|
||||
* @param {string=} opt_id The unique ID of the variable. This will default to
|
||||
* a UUID.
|
||||
* @return {?Blockly.VariableModel} The newly created variable.
|
||||
*/
|
||||
@@ -358,7 +358,8 @@ Blockly.Workspace.prototype.deleteVariable = function(name) {
|
||||
if (uses.length > 1) {
|
||||
// Confirm before deleting multiple blocks.
|
||||
Blockly.confirm(
|
||||
Blockly.Msg.DELETE_VARIABLE_CONFIRMATION.replace('%1', uses.length).
|
||||
Blockly.Msg.DELETE_VARIABLE_CONFIRMATION.replace('%1',
|
||||
String(uses.length)).
|
||||
replace('%2', name),
|
||||
function(ok) {
|
||||
if (ok) {
|
||||
@@ -372,23 +373,23 @@ Blockly.Workspace.prototype.deleteVariable = function(name) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a variables by the passed in id and all of its uses from this
|
||||
* Delete a variables by the passed in ID and all of its uses from this
|
||||
* workspace. May prompt the user for confirmation.
|
||||
* @param {string} id Id of variable to delete.
|
||||
* @param {string} id ID of variable to delete.
|
||||
*/
|
||||
Blockly.Workspace.prototype.deleteVariableById = function(id) {
|
||||
var variable = this.getVariableById(id);
|
||||
if (variable) {
|
||||
this.deleteVariableInternal_(variable);
|
||||
} else {
|
||||
console.warn("Can't delete non-existant variable: " + id);
|
||||
console.warn("Can't delete non-existent variable: " + id);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a variable and all of its uses from this workspace without asking the
|
||||
* user for confirmation.
|
||||
* @param {Blockly.VariableModel} variable Variable to delete.
|
||||
* @param {!Blockly.VariableModel} variable Variable to delete.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Workspace.prototype.deleteVariableInternal_ = function(variable) {
|
||||
@@ -409,7 +410,10 @@ Blockly.Workspace.prototype.deleteVariableInternal_ = function(variable) {
|
||||
* not present.
|
||||
* @deprecated April 2017
|
||||
*/
|
||||
Blockly.Workspace.prototype.variableIndexOf = function(name) {
|
||||
|
||||
Blockly.Workspace.prototype.variableIndexOf = function(
|
||||
/* eslint-disable no-unused-vars */ name
|
||||
/* eslint-enable no-unused-vars */) {
|
||||
console.warn(
|
||||
'Deprecated call to Blockly.Workspace.prototype.variableIndexOf');
|
||||
return -1;
|
||||
@@ -426,10 +430,10 @@ Blockly.Workspace.prototype.getVariable = function(name) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the variable by the given id and return it. Return null if it is not
|
||||
* Find the variable by the given ID and return it. Return null if it is not
|
||||
* found.
|
||||
* @param {!string} id The id to check for.
|
||||
* @return {?Blockly.VariableModel} The variable with the given id.
|
||||
* @param {!string} id The ID to check for.
|
||||
* @return {?Blockly.VariableModel} The variable with the given ID.
|
||||
*/
|
||||
Blockly.Workspace.prototype.getVariableById = function(id) {
|
||||
return this.variableMap_.getVariableById(id);
|
||||
@@ -450,7 +454,7 @@ Blockly.Workspace.prototype.getWidth = function() {
|
||||
* @param {?string} prototypeName Name of the language object containing
|
||||
* type-specific functions for this block.
|
||||
* @param {string=} opt_id Optional ID. Use this ID if provided, otherwise
|
||||
* create a new id.
|
||||
* create a new ID.
|
||||
* @return {!Blockly.Block} The created block.
|
||||
*/
|
||||
Blockly.Workspace.prototype.newBlock = function(prototypeName, opt_id) {
|
||||
@@ -496,8 +500,7 @@ Blockly.Workspace.prototype.undo = function(redo) {
|
||||
for (var i = 0, event; event = events[i]; i++) {
|
||||
event.run(redo);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
Blockly.Events.recordUndo = true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -27,10 +27,12 @@
|
||||
|
||||
goog.provide('Blockly.WorkspaceAudio');
|
||||
|
||||
|
||||
/**
|
||||
* Class for loading, storing, and playing audio for a workspace.
|
||||
* @param {Blockly.WorkspaceSvg} parentWorkspace The parent of the workspace
|
||||
* this audio object belongs to, or null.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.WorkspaceAudio = function(parentWorkspace) {
|
||||
|
||||
@@ -72,7 +74,6 @@ Blockly.WorkspaceAudio.prototype.dispose = function() {
|
||||
* preference (i.e. increasing size). E.g. ['media/go.mp3', 'media/go.wav']
|
||||
* Filenames include path from Blockly's root. File extensions matter.
|
||||
* @param {string} name Name of sound.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceAudio.prototype.load = function(filenames, name) {
|
||||
if (!filenames.length) {
|
||||
@@ -107,7 +108,7 @@ Blockly.WorkspaceAudio.prototype.load = function(filenames, name) {
|
||||
Blockly.WorkspaceAudio.prototype.preload = function() {
|
||||
for (var name in this.SOUNDS_) {
|
||||
var sound = this.SOUNDS_[name];
|
||||
sound.volume = .01;
|
||||
sound.volume = 0.01;
|
||||
sound.play();
|
||||
sound.pause();
|
||||
// iOS can only process one sound at a time. Trying to load more than one
|
||||
|
||||
@@ -93,7 +93,7 @@ Blockly.WorkspaceDragSurfaceSvg.prototype.createDom = function() {
|
||||
'xmlns:html': Blockly.HTML_NS,
|
||||
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
|
||||
'version': '1.1',
|
||||
'class': 'blocklyWsDragSurface blocklyOverflowVisible',
|
||||
'class': 'blocklyWsDragSurface blocklyOverflowVisible'
|
||||
}, null);
|
||||
this.container_.appendChild(this.SVG_);
|
||||
};
|
||||
@@ -168,9 +168,9 @@ Blockly.WorkspaceDragSurfaceSvg.prototype.clearAndHide = function(newSurface) {
|
||||
* @param {!Element} blockCanvas The block canvas <g> element from the workspace.
|
||||
* @param {!Element} bubbleCanvas The <g> element that contains the bubbles.
|
||||
* @param {?Element} previousSibling The element to insert the block canvas &
|
||||
bubble canvas after when it goes back in the dom at the end of a drag.
|
||||
* @param {number} width The width of the workspace svg element.
|
||||
* @param {number} height The height of the workspace svg element.
|
||||
bubble canvas after when it goes back in the DOM at the end of a drag.
|
||||
* @param {number} width The width of the workspace SVG element.
|
||||
* @param {number} height The height of the workspace SVG element.
|
||||
* @param {number} scale The scale of the workspace being dragged.
|
||||
* @package
|
||||
*/
|
||||
|
||||
+21
-22
@@ -245,7 +245,7 @@ Blockly.WorkspaceSvg.prototype.lastRecordedPageScroll_ = null;
|
||||
/**
|
||||
* Map from function names to callbacks, for deciding what to do when a button
|
||||
* is clicked.
|
||||
* @type {!Object<string, function(!Blockly.FlyoutButton)>}
|
||||
* @type {!Object.<string, function(!Blockly.FlyoutButton)>}
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.flyoutButtonCallbacks_ = {};
|
||||
@@ -253,7 +253,7 @@ Blockly.WorkspaceSvg.prototype.flyoutButtonCallbacks_ = {};
|
||||
/**
|
||||
* Map from function names to callbacks, for deciding what to do when a custom
|
||||
* toolbox category is opened.
|
||||
* @type {!Object<string, function(!Blockly.Workspace):!Array<!Element>>}
|
||||
* @type {!Object.<string, function(!Blockly.Workspace):!Array.<!Element>>}
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.toolboxCategoryCallbacks_ = {};
|
||||
@@ -370,10 +370,10 @@ Blockly.WorkspaceSvg.prototype.createDom = function(opt_backgroundClass) {
|
||||
}
|
||||
/** @type {SVGElement} */
|
||||
this.svgBlockCanvas_ = Blockly.utils.createSvgElement('g',
|
||||
{'class': 'blocklyBlockCanvas'}, this.svgGroup_, this);
|
||||
{'class': 'blocklyBlockCanvas'}, this.svgGroup_);
|
||||
/** @type {SVGElement} */
|
||||
this.svgBubbleCanvas_ = Blockly.utils.createSvgElement('g',
|
||||
{'class': 'blocklyBubbleCanvas'}, this.svgGroup_, this);
|
||||
{'class': 'blocklyBubbleCanvas'}, this.svgGroup_);
|
||||
var bottom = Blockly.Scrollbar.scrollbarThickness;
|
||||
if (this.options.hasTrashcan) {
|
||||
bottom = this.addTrashcan_(bottom);
|
||||
@@ -516,7 +516,7 @@ Blockly.WorkspaceSvg.prototype.addZoomControls_ = function(bottom) {
|
||||
/**
|
||||
* Add a flyout element in an element with the given tag name.
|
||||
* @param {string} tagName What type of tag the flyout belongs in.
|
||||
* @return {!Element} The element containing the flyout dom.
|
||||
* @return {!Element} The element containing the flyout DOM.
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.addFlyout_ = function(tagName) {
|
||||
@@ -623,8 +623,8 @@ Blockly.WorkspaceSvg.prototype.resize = function() {
|
||||
* scroll position.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.updateScreenCalculationsIfScrolled
|
||||
= function() {
|
||||
Blockly.WorkspaceSvg.prototype.updateScreenCalculationsIfScrolled =
|
||||
function() {
|
||||
/* eslint-disable indent */
|
||||
var currScroll = goog.dom.getDocumentScroll();
|
||||
if (!goog.math.Coordinate.equals(this.lastRecordedPageScroll_,
|
||||
@@ -652,7 +652,7 @@ Blockly.WorkspaceSvg.prototype.getBubbleCanvas = function() {
|
||||
|
||||
/**
|
||||
* Get the SVG element that contains this workspace.
|
||||
* @return {!Element} SVG element.
|
||||
* @return {Element} SVG element.
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.getParentSvg = function() {
|
||||
if (this.cachedParentSvg_) {
|
||||
@@ -664,7 +664,7 @@ Blockly.WorkspaceSvg.prototype.getParentSvg = function() {
|
||||
this.cachedParentSvg_ = element;
|
||||
return element;
|
||||
}
|
||||
element = element.parentNode;
|
||||
element = element.parentElement;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
@@ -691,7 +691,7 @@ Blockly.WorkspaceSvg.prototype.translate = function(x, y) {
|
||||
|
||||
/**
|
||||
* Called at the end of a workspace drag to take the contents
|
||||
* out of the drag surface and put them back into the workspace svg.
|
||||
* out of the drag surface and put them back into the workspace SVG.
|
||||
* Does nothing if the workspace drag surface is not enabled.
|
||||
* @package
|
||||
*/
|
||||
@@ -705,8 +705,7 @@ Blockly.WorkspaceSvg.prototype.resetDragSurface = function() {
|
||||
|
||||
var trans = this.workspaceDragSurface_.getSurfaceTranslation();
|
||||
this.workspaceDragSurface_.clearAndHide(this.svgGroup_);
|
||||
var translation = 'translate(' + trans.x + ',' + trans.y + ') ' +
|
||||
'scale(' + this.scale + ')';
|
||||
var translation = 'translate' + trans + ' scale(' + this.scale + ')';
|
||||
this.svgBlockCanvas_.setAttribute('transform', translation);
|
||||
this.svgBubbleCanvas_.setAttribute('transform', translation);
|
||||
};
|
||||
@@ -737,8 +736,8 @@ Blockly.WorkspaceSvg.prototype.setupDragSurface = function() {
|
||||
// Figure out where we want to put the canvas back. The order
|
||||
// in the is important because things are layered.
|
||||
var previousElement = this.svgBlockCanvas_.previousSibling;
|
||||
var width = this.getParentSvg().getAttribute("width");
|
||||
var height = this.getParentSvg().getAttribute("height");
|
||||
var width = this.getParentSvg().getAttribute('width');
|
||||
var height = this.getParentSvg().getAttribute('height');
|
||||
var coord = Blockly.utils.getRelativeXY(this.svgBlockCanvas_);
|
||||
this.workspaceDragSurface_.setContentsAndShow(this.svgBlockCanvas_,
|
||||
this.svgBubbleCanvas_, previousElement, width, height, this.scale);
|
||||
@@ -933,7 +932,7 @@ Blockly.WorkspaceSvg.prototype.renameVariable = function(oldName, newName) {
|
||||
/**
|
||||
* Rename a variable by updating its name in the variable map. Update the
|
||||
* flyout to show the renamed variable immediately.
|
||||
* @param {string} id Id of the variable to rename.
|
||||
* @param {string} id ID of the variable to rename.
|
||||
* @param {string} newName New variable name.
|
||||
* @package
|
||||
*/
|
||||
@@ -954,9 +953,9 @@ Blockly.WorkspaceSvg.prototype.deleteVariable = function(name) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a variable by the passed in id. Update the flyout to show
|
||||
* Delete a variable by the passed in ID. Update the flyout to show
|
||||
* immediately that the variable is deleted.
|
||||
* @param {string} id Id of variable to delete.
|
||||
* @param {string} id ID of variable to delete.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.deleteVariableById = function(id) {
|
||||
@@ -971,7 +970,7 @@ Blockly.WorkspaceSvg.prototype.deleteVariableById = function(id) {
|
||||
* @param {string=} opt_type The type of the variable like 'int' or 'string'.
|
||||
* Does not need to be unique. Field_variable can filter variables based on
|
||||
* their type. This will default to '' which is a specific type.
|
||||
* @param {string=} opt_id The unique id of the variable. This will default to
|
||||
* @param {string=} opt_id The unique ID of the variable. This will default to
|
||||
* a UUID.
|
||||
* @return {?Blockly.VariableModel} The newly created variable.
|
||||
* @package
|
||||
@@ -1064,7 +1063,7 @@ Blockly.WorkspaceSvg.prototype.moveDrag = function(e) {
|
||||
* @return {boolean} True if currently dragging or scrolling.
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.isDragging = function() {
|
||||
return this.currentGesture_ && this.currentGesture_.isDragging();
|
||||
return this.currentGesture_ != null && this.currentGesture_.isDragging();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1357,7 +1356,7 @@ Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() {
|
||||
try {
|
||||
// Focus the workspace SVG - this is for Chrome and Firefox.
|
||||
this.getParentSvg().focus();
|
||||
} catch (e) {
|
||||
} catch (e) {
|
||||
// IE and Edge do not support focus on SVG elements. When that fails
|
||||
// above, get the injectionDiv (the workspace's parent) and focus that
|
||||
// instead. This doesn't work in Chrome.
|
||||
@@ -1785,7 +1784,7 @@ Blockly.WorkspaceSvg.prototype.removeButtonCallback = function(key) {
|
||||
* custom toolbox categories in this workspace. See the variable and procedure
|
||||
* categories as an example.
|
||||
* @param {string} key The name to use to look up this function.
|
||||
* @param {function(!Blockly.Workspace):!Array<!Element>} func The function to
|
||||
* @param {function(!Blockly.Workspace):!Array.<!Element>} func The function to
|
||||
* call when the given toolbox category is opened.
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.registerToolboxCategoryCallback = function(key,
|
||||
@@ -1799,7 +1798,7 @@ Blockly.WorkspaceSvg.prototype.registerToolboxCategoryCallback = function(key,
|
||||
* Get the callback function associated with a given key, for populating
|
||||
* custom toolbox categories in this workspace.
|
||||
* @param {string} key The name to use to look up the function.
|
||||
* @return {?function(!Blockly.Workspace):!Array<!Element>} The function
|
||||
* @return {?function(!Blockly.Workspace):!Array.<!Element>} The function
|
||||
* corresponding to the given key for this workspace, or null if no function
|
||||
* is registered.
|
||||
*/
|
||||
|
||||
+45
-49
@@ -37,7 +37,7 @@ goog.require('goog.dom');
|
||||
/**
|
||||
* Encode a block tree as XML.
|
||||
* @param {!Blockly.Workspace} workspace The workspace containing blocks.
|
||||
* @param {boolean} opt_noId True if the encoder should skip the block ids.
|
||||
* @param {boolean=} opt_noId True if the encoder should skip the block IDs.
|
||||
* @return {!Element} XML document.
|
||||
*/
|
||||
Blockly.Xml.workspaceToDom = function(workspace, opt_noId) {
|
||||
@@ -70,7 +70,7 @@ Blockly.Xml.variablesToDom = function(variableList) {
|
||||
/**
|
||||
* Encode a block subtree as XML with XY coordinates.
|
||||
* @param {!Blockly.Block} block The root block to encode.
|
||||
* @param {boolean} opt_noId True if the encoder should skip the block id.
|
||||
* @param {boolean=} opt_noId True if the encoder should skip the block ID.
|
||||
* @return {!Element} Tree of XML elements.
|
||||
*/
|
||||
Blockly.Xml.blockToDomWithXY = function(block, opt_noId) {
|
||||
@@ -89,7 +89,7 @@ Blockly.Xml.blockToDomWithXY = function(block, opt_noId) {
|
||||
/**
|
||||
* Encode a block subtree as XML.
|
||||
* @param {!Blockly.Block} block The root block to encode.
|
||||
* @param {boolean} opt_noId True if the encoder should skip the block id.
|
||||
* @param {boolean=} opt_noId True if the encoder should skip the block ID.
|
||||
* @return {!Element} Tree of XML elements.
|
||||
*/
|
||||
Blockly.Xml.blockToDom = function(block, opt_noId) {
|
||||
@@ -113,7 +113,7 @@ Blockly.Xml.blockToDom = function(block, opt_noId) {
|
||||
var variable = block.workspace.getVariable(field.getValue());
|
||||
if (variable) {
|
||||
container.setAttribute('id', variable.getId());
|
||||
container.setAttribute('variableType', variable.type);
|
||||
container.setAttribute('variabletype', variable.type);
|
||||
}
|
||||
}
|
||||
element.appendChild(container);
|
||||
@@ -303,7 +303,7 @@ Blockly.Xml.textToDom = function(text) {
|
||||
* Decode an XML DOM and create blocks on the workspace.
|
||||
* @param {!Element} xml XML DOM.
|
||||
* @param {!Blockly.Workspace} workspace The workspace.
|
||||
* @return {Array.<string>} An array containing new block ids.
|
||||
* @return {Array.<string>} An array containing new block IDs.
|
||||
*/
|
||||
Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
||||
if (xml instanceof Blockly.Workspace) {
|
||||
@@ -317,7 +317,7 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
||||
if (workspace.RTL) {
|
||||
width = workspace.getWidth();
|
||||
}
|
||||
var newBlockIds = []; // A list of block ids added by this call.
|
||||
var newBlockIds = []; // A list of block IDs added by this call.
|
||||
Blockly.Field.startCache();
|
||||
// Safari 7.1.3 is known to provide node lists with extra references to
|
||||
// children beyond the lists' length. Trust the length, do not use the
|
||||
@@ -353,11 +353,10 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
||||
} else if (name == 'shadow') {
|
||||
goog.asserts.fail('Shadow block cannot be a top-level block.');
|
||||
variablesFirst = false;
|
||||
} else if (name == 'variables') {
|
||||
} else if (name == 'variables') {
|
||||
if (variablesFirst) {
|
||||
Blockly.Xml.domToVariables(xmlChild, workspace);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
throw Error('\'variables\' tag must exist once before block and ' +
|
||||
'shadow tag elements in the workspace XML, but it was found in ' +
|
||||
'another location.');
|
||||
@@ -365,8 +364,7 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
||||
variablesFirst = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
if (!existingGroup) {
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
@@ -385,12 +383,12 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
||||
* blocks immediately below prior blocks, aligned by their starting edge.
|
||||
* @param {!Element} xml The XML DOM.
|
||||
* @param {!Blockly.Workspace} workspace The workspace to add to.
|
||||
* @return {Array.<string>} An array containing new block ids.
|
||||
* @return {Array.<string>} An array containing new block IDs.
|
||||
*/
|
||||
Blockly.Xml.appendDomToWorkspace = function(xml, workspace) {
|
||||
var bbox; //bounding box of the current blocks
|
||||
// first check if we have a workspaceSvg otherwise the block have no shape
|
||||
// and the position does not matter
|
||||
var bbox; // Bounding box of the current blocks.
|
||||
// First check if we have a workspaceSvg, otherwise the blocks have no shape
|
||||
// and the position does not matter.
|
||||
if (workspace.hasOwnProperty('scale')) {
|
||||
var savetab = Blockly.BlockSvg.TAB_WIDTH;
|
||||
try {
|
||||
@@ -400,22 +398,22 @@ Blockly.Xml.appendDomToWorkspace = function(xml, workspace) {
|
||||
Blockly.BlockSvg.TAB_WIDTH = savetab;
|
||||
}
|
||||
}
|
||||
// load the new blocks into the workspace and get the ids of the new blocks
|
||||
// Load the new blocks into the workspace and get the IDs of the new blocks.
|
||||
var newBlockIds = Blockly.Xml.domToWorkspace(xml,workspace);
|
||||
if (bbox && bbox.height) { // check if any previous block
|
||||
var offsetY = 0; // offset to add to y of the new block
|
||||
if (bbox && bbox.height) { // check if any previous block
|
||||
var offsetY = 0; // offset to add to y of the new block
|
||||
var offsetX = 0;
|
||||
var farY = bbox.y + bbox.height; //bottom position
|
||||
var topX = bbox.x; // x of bounding box
|
||||
// check position of the new blocks
|
||||
var newX = Infinity; // x of top corner
|
||||
var newY = Infinity; // y of top corner
|
||||
var farY = bbox.y + bbox.height; // bottom position
|
||||
var topX = bbox.x; // x of bounding box
|
||||
// Check position of the new blocks.
|
||||
var newX = Infinity; // x of top corner
|
||||
var newY = Infinity; // y of top corner
|
||||
for (var i = 0; i < newBlockIds.length; i++) {
|
||||
var blockXY = workspace.getBlockById(newBlockIds[i]).getRelativeToSurfaceXY();
|
||||
if (blockXY.y < newY) {
|
||||
newY = blockXY.y;
|
||||
}
|
||||
if (blockXY.x < newX) { //if we align also on x
|
||||
if (blockXY.x < newX) { // if we align also on x
|
||||
newX = blockXY.x;
|
||||
}
|
||||
}
|
||||
@@ -498,7 +496,7 @@ Blockly.Xml.domToVariables = function(xmlVariables, workspace) {
|
||||
var id = xmlChild.getAttribute('id');
|
||||
var name = xmlChild.textContent;
|
||||
|
||||
if (typeof(type) === undefined || type === null) {
|
||||
if (type == null) {
|
||||
throw Error('Variable with id, ' + id + ' is without a type');
|
||||
}
|
||||
workspace.createVariable(name, type, id);
|
||||
@@ -530,21 +528,21 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
||||
var input;
|
||||
|
||||
// Find any enclosed blocks or shadows in this tag.
|
||||
var childBlockNode = null;
|
||||
var childShadowNode = null;
|
||||
var childBlockElement = null;
|
||||
var childShadowElement = null;
|
||||
for (var j = 0, grandchildNode; grandchildNode = xmlChild.childNodes[j];
|
||||
j++) {
|
||||
if (grandchildNode.nodeType == 1) {
|
||||
if (grandchildNode.nodeName.toLowerCase() == 'block') {
|
||||
childBlockNode = grandchildNode;
|
||||
childBlockElement = /** @type {!Element} */ (grandchildNode);
|
||||
} else if (grandchildNode.nodeName.toLowerCase() == 'shadow') {
|
||||
childShadowNode = grandchildNode;
|
||||
childShadowElement = /** @type {!Element} */ (grandchildNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use the shadow block if there is no child block.
|
||||
if (!childBlockNode && childShadowNode) {
|
||||
childBlockNode = childShadowNode;
|
||||
if (!childBlockElement && childShadowElement) {
|
||||
childBlockElement = childShadowElement;
|
||||
}
|
||||
|
||||
var name = xmlChild.getAttribute('name');
|
||||
@@ -589,21 +587,19 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
||||
var text = xmlChild.textContent;
|
||||
if (field instanceof Blockly.FieldVariable) {
|
||||
// TODO (marisaleung): When we change setValue and getValue to
|
||||
// interact with id's instead of names, update this so that we get
|
||||
// the variable based on id instead of textContent.
|
||||
var type = xmlChild.getAttribute('variableType') || '';
|
||||
// interact with IDs instead of names, update this so that we get
|
||||
// the variable based on ID instead of textContent.
|
||||
var type = xmlChild.getAttribute('variabletype') || '';
|
||||
var variable = workspace.getVariable(text);
|
||||
if (!variable) {
|
||||
variable = workspace.createVariable(text, type,
|
||||
xmlChild.getAttribute(id));
|
||||
}
|
||||
if (typeof(type) !== undefined && type !== null) {
|
||||
if (type !== variable.type) {
|
||||
throw Error('Serialized variable type with id \'' +
|
||||
variable.getId() + '\' had type ' + variable.type + ', and ' +
|
||||
'does not match variable field that references it: ' +
|
||||
Blockly.Xml.domToText(xmlChild) + '.');
|
||||
}
|
||||
if (type != null && type !== variable.type) {
|
||||
throw Error('Serialized variable type with id \'' +
|
||||
variable.getId() + '\' had type ' + variable.type + ', and ' +
|
||||
'does not match variable field that references it: ' +
|
||||
Blockly.Xml.domToText(xmlChild) + '.');
|
||||
}
|
||||
}
|
||||
if (!field) {
|
||||
@@ -621,11 +617,11 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
||||
prototypeName);
|
||||
break;
|
||||
}
|
||||
if (childShadowNode) {
|
||||
input.connection.setShadowDom(childShadowNode);
|
||||
if (childShadowElement) {
|
||||
input.connection.setShadowDom(childShadowElement);
|
||||
}
|
||||
if (childBlockNode) {
|
||||
blockChild = Blockly.Xml.domToBlockHeadless_(childBlockNode,
|
||||
if (childBlockElement) {
|
||||
blockChild = Blockly.Xml.domToBlockHeadless_(childBlockElement,
|
||||
workspace);
|
||||
if (blockChild.outputConnection) {
|
||||
input.connection.connect(blockChild.outputConnection);
|
||||
@@ -638,16 +634,16 @@ Blockly.Xml.domToBlockHeadless_ = function(xmlBlock, workspace) {
|
||||
}
|
||||
break;
|
||||
case 'next':
|
||||
if (childShadowNode && block.nextConnection) {
|
||||
block.nextConnection.setShadowDom(childShadowNode);
|
||||
if (childShadowElement && block.nextConnection) {
|
||||
block.nextConnection.setShadowDom(childShadowElement);
|
||||
}
|
||||
if (childBlockNode) {
|
||||
if (childBlockElement) {
|
||||
goog.asserts.assert(block.nextConnection,
|
||||
'Next statement does not exist.');
|
||||
// If there is more than one XML 'next' tag.
|
||||
goog.asserts.assert(!block.nextConnection.isConnected(),
|
||||
'Next statement is already connected.');
|
||||
blockChild = Blockly.Xml.domToBlockHeadless_(childBlockNode,
|
||||
blockChild = Blockly.Xml.domToBlockHeadless_(childBlockElement,
|
||||
workspace);
|
||||
goog.asserts.assert(blockChild.previousConnection,
|
||||
'Next block does not have previous statement.');
|
||||
|
||||
@@ -37,9 +37,9 @@ goog.require('goog.dom.xml');
|
||||
|
||||
|
||||
/**
|
||||
* Block Exporter Tools Class
|
||||
* @constructor
|
||||
*/
|
||||
* Block Exporter Tools Class
|
||||
* @constructor
|
||||
*/
|
||||
BlockExporterTools = function() {
|
||||
// Create container for hidden workspace.
|
||||
this.container = goog.dom.createDom('div', {
|
||||
|
||||
+4
-2
@@ -387,13 +387,15 @@ Code.init = function() {
|
||||
// TODO: Clean up the message files so this is done explicitly instead of
|
||||
// through this for-loop.
|
||||
for (var messageKey in MSG) {
|
||||
if (goog.string.startsWith(messageKey, 'cat')) {
|
||||
if (messageKey.indexOf('cat') == 0) {
|
||||
Blockly.Msg[messageKey.toUpperCase()] = MSG[messageKey];
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the toolbox XML.
|
||||
// Construct the toolbox XML, replacing translated variable names.
|
||||
var toolboxText = document.getElementById('toolbox').outerHTML;
|
||||
toolboxText = toolboxText.replace(/(^|[^%]){(\w+)}/g,
|
||||
function(m, p1, p2) {return p1 + MSG[p2];});
|
||||
var toolboxXml = Blockly.Xml.textToDom(toolboxText);
|
||||
|
||||
Code.workspace = Blockly.inject('content_blocks',
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* @fileoverview Main file (entry point) for the advanced compilation demo.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Demo');
|
||||
|
||||
// messages (in some language)
|
||||
goog.require('Blockly.Msg.en');
|
||||
// core
|
||||
goog.require('Blockly');
|
||||
// blocks
|
||||
goog.require('Blockly.Constants.Colour');
|
||||
goog.require('Blockly.Constants.Lists');
|
||||
goog.require('Blockly.Constants.Logic');
|
||||
goog.require('Blockly.Constants.Loops');
|
||||
goog.require('Blockly.Constants.Math');
|
||||
goog.require('Blockly.Blocks.procedures');
|
||||
goog.require('Blockly.Constants.Text');
|
||||
goog.require('Blockly.Constants.Variables');
|
||||
|
||||
|
||||
Demo.init = function() {
|
||||
Blockly.inject('blocklyDiv', {
|
||||
'media': '../../media/',
|
||||
'toolbox': document.getElementById('toolbox')
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', Demo.init);
|
||||
|
||||
+27
-28
@@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Blockly Demo: Minimap </title>
|
||||
<title>Blockly Demo: Minimap</title>
|
||||
<script src="../../blockly_compressed.js"></script>
|
||||
<script src="../../blocks_compressed.js"></script>
|
||||
<script src="../../msg/js/en.js"></script>
|
||||
@@ -49,41 +49,40 @@
|
||||
</xml>
|
||||
|
||||
<script>
|
||||
// Inject master workspace.
|
||||
var masterWorkspace = Blockly.inject('masterDiv', {
|
||||
media: '../../media/',
|
||||
scrollbars: true,
|
||||
toolbox: document.getElementById('toolbox')
|
||||
});
|
||||
|
||||
// Inject master workspace.
|
||||
var masterWorkspace = Blockly.inject('masterDiv',{
|
||||
media: '../../media/',
|
||||
scrollbars: true,
|
||||
toolbox: document.getElementById('toolbox')
|
||||
});
|
||||
|
||||
// Inject workspace for minimap.
|
||||
var minimapWorkspace = Blockly.inject('mapDiv',
|
||||
{media: '../../media/',
|
||||
readOnly: true,
|
||||
zoom:
|
||||
{controls: false,
|
||||
wheel: true,
|
||||
startScale: 0.1, //you can change this accorting to your needs.
|
||||
maxScale: 0.1,
|
||||
minScale: 0.01
|
||||
}});
|
||||
|
||||
// Initilizing the minimap.
|
||||
Minimap.init(masterWorkspace,minimapWorkspace);
|
||||
// Inject workspace for minimap.
|
||||
var minimapWorkspace = Blockly.inject('mapDiv', {
|
||||
media: '../../media/',
|
||||
readOnly: true,
|
||||
zoom: {
|
||||
controls: false,
|
||||
wheel: true,
|
||||
startScale: 0.1, // Change this according to your needs.
|
||||
maxScale: 0.1,
|
||||
minScale: 0.01
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize the minimap.
|
||||
Minimap.init(masterWorkspace,minimapWorkspace);
|
||||
</script>
|
||||
<style>
|
||||
.minimap{
|
||||
position:absolute;
|
||||
position: absolute;
|
||||
}
|
||||
.mapDragger{
|
||||
cursor: move;
|
||||
fill:rgb(0,0,255);
|
||||
stroke-width:0.5;
|
||||
stroke:rgb(0,0,0);
|
||||
fill-opacity:0.1;
|
||||
}
|
||||
fill: rgb(0,0,255);
|
||||
stroke-width: .5;
|
||||
stroke: rgb(0,0,0);
|
||||
fill-opacity: .1;
|
||||
}
|
||||
</style>
|
||||
|
||||
</body>
|
||||
|
||||
+135
-127
@@ -1,46 +1,46 @@
|
||||
/**
|
||||
* Blockly Demos: Code
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
* Blockly Demos: Minimap
|
||||
*
|
||||
* 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 JavaScript for Blockly's Minimap demo.
|
||||
* @author karnpurohit@gmail.com (Karan Purohit)
|
||||
*/
|
||||
* @fileoverview JavaScript for Blockly's Minimap demo.
|
||||
* @author karnpurohit@gmail.com (Karan Purohit)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Creating a seperate namespace for minimap.
|
||||
*/
|
||||
* Creating a separate namespace for minimap.
|
||||
*/
|
||||
var Minimap = {};
|
||||
|
||||
/**
|
||||
* Initilize the workspace and minimap.
|
||||
* @param {Workspace} workspace The main workspace of the user.
|
||||
* @param {Workspace} minimap The workspace that will be used as a minimap.
|
||||
*/
|
||||
Minimap.init = function(workspace, minimap){
|
||||
* Initialize the workspace and minimap.
|
||||
* @param {!Workspace} workspace The main workspace of the user.
|
||||
* @param {!Workspace} minimap The workspace that will be used as a minimap.
|
||||
*/
|
||||
Minimap.init = function(workspace, minimap) {
|
||||
this.workspace = workspace;
|
||||
this.minimap = minimap;
|
||||
|
||||
//Adding scroll callback functionlity to vScroll and hScroll just for this demo.
|
||||
//IMPORTANT: This should be changed when there is proper UI event handling
|
||||
// api available and should be handled by workspace's event listeners.
|
||||
this.workspace.scrollbar.vScroll.setHandlePosition = function(newPosition){
|
||||
// Adding scroll callback functionality to vScroll and hScroll just for this demo.
|
||||
// IMPORTANT: This should be changed when there is proper UI event handling
|
||||
// API available and should be handled by workspace's event listeners.
|
||||
this.workspace.scrollbar.vScroll.setHandlePosition = function(newPosition) {
|
||||
this.handlePosition_ = newPosition;
|
||||
this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_);
|
||||
|
||||
@@ -55,7 +55,7 @@ Minimap.init = function(workspace, minimap){
|
||||
};
|
||||
|
||||
// Adding call back for horizontal scroll.
|
||||
this.workspace.scrollbar.hScroll.setHandlePosition = function(newPosition){
|
||||
this.workspace.scrollbar.hScroll.setHandlePosition = function(newPosition) {
|
||||
this.handlePosition_ = newPosition;
|
||||
this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_);
|
||||
|
||||
@@ -71,7 +71,7 @@ Minimap.init = function(workspace, minimap){
|
||||
|
||||
|
||||
// Required to stop a positive feedback loop when user clicks minimap
|
||||
// and the scroll changes, which inturn may change minimap.
|
||||
// and the scroll changes, which in turn may change minimap.
|
||||
this.disableScrollChange = false;
|
||||
|
||||
// Listen to events on the main workspace.
|
||||
@@ -95,9 +95,9 @@ Minimap.init = function(workspace, minimap){
|
||||
|
||||
// Creating a rectangle in the minimap that represents current view.
|
||||
Blockly.utils.createSvgElement('rect', {
|
||||
'width':100,
|
||||
'height':100,
|
||||
'class':'mapDragger'
|
||||
'width': 100,
|
||||
'height': 100,
|
||||
'class': 'mapDragger'
|
||||
}, this.svg);
|
||||
|
||||
// Rectangle in the minimap that represents current view.
|
||||
@@ -105,7 +105,7 @@ Minimap.init = function(workspace, minimap){
|
||||
|
||||
// Adding mouse events to the rectangle, to make it Draggable.
|
||||
// Using Blockly.bindEvent_ to attach mouse/touch listeners.
|
||||
Blockly.bindEvent_(this.mapDragger, "mousedown", null, Minimap.mousedown);
|
||||
Blockly.bindEvent_(this.mapDragger, 'mousedown', null, Minimap.mousedown);
|
||||
|
||||
//When the window change, we need to resize the minimap window.
|
||||
window.addEventListener('resize', Minimap.repositionMinimap);
|
||||
@@ -113,20 +113,22 @@ Minimap.init = function(workspace, minimap){
|
||||
// Mouse up event for the minimap.
|
||||
this.svg.addEventListener('mouseup', Minimap.updateMapDragger);
|
||||
|
||||
//Boolen to check whether I am dragging the surface or not.
|
||||
//Boolean to check whether I am dragging the surface or not.
|
||||
this.isDragging = false;
|
||||
};
|
||||
|
||||
Minimap.mousedown = function(e){
|
||||
Minimap.mousedown = function(e) {
|
||||
// Using Blockly.bindEvent_ to attach mouse/touch listeners.
|
||||
Minimap.mouseMoveBindData = Blockly.bindEvent_(document,"mousemove", null, Minimap.mousemove);
|
||||
Minimap.mouseUpBindData = Blockly.bindEvent_(document,"mouseup", null, Minimap.mouseup);
|
||||
Minimap.mouseMoveBindData =
|
||||
Blockly.bindEvent_(document, 'mousemove', null, Minimap.mousemove);
|
||||
Minimap.mouseUpBindData =
|
||||
Blockly.bindEvent_(document, 'mouseup', null, Minimap.mouseup);
|
||||
|
||||
Minimap.isDragging=true;
|
||||
Minimap.isDragging = true;
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
Minimap.mouseup = function(e){
|
||||
Minimap.mouseup = function(e) {
|
||||
Minimap.isDragging = false;
|
||||
// Removing listeners.
|
||||
Blockly.unbindEvent_(Minimap.mouseUpBindData);
|
||||
@@ -135,18 +137,18 @@ Minimap.mouseup = function(e){
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
Minimap.mousemove = function(e){
|
||||
if(Minimap.isDragging){
|
||||
Minimap.mousemove = function(e) {
|
||||
if (Minimap.isDragging) {
|
||||
Minimap.updateMapDragger(e);
|
||||
e.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initilize the workspace and minimap.
|
||||
* @param {Event} event Event that triggered in the main workspace.
|
||||
*/
|
||||
Minimap.mirrorEvent = function(event){
|
||||
* Run non-UI events from the main workspace on the minimap.
|
||||
* @param {!Event} event Event that triggered in the main workspace.
|
||||
*/
|
||||
Minimap.mirrorEvent = function(event) {
|
||||
if (event.type == Blockly.Events.UI) {
|
||||
return; // Don't mirror UI events.
|
||||
}
|
||||
@@ -161,146 +163,152 @@ Minimap.mirrorEvent = function(event){
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when window is resized. Repositions the minimap overlay.
|
||||
*/
|
||||
Minimap.repositionMinimap = function(){
|
||||
* Called when window is resized. Repositions the minimap overlay.
|
||||
*/
|
||||
Minimap.repositionMinimap = function() {
|
||||
Minimap.rect = document.getElementById('mapDiv').getBoundingClientRect();
|
||||
Minimap.svg.style.top = Minimap.rect.top + 'px';
|
||||
Minimap.svg.style.left = Minimap.rect.left + 'px';
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the rectangle's height .
|
||||
*/
|
||||
Minimap.setDraggerHeight = function(){
|
||||
* Updates the rectangle's height.
|
||||
*/
|
||||
Minimap.setDraggerHeight = function() {
|
||||
var workspaceMetrics = Minimap.workspace.getMetrics();
|
||||
var draggerHeight = (workspaceMetrics.viewHeight / Minimap.workspace.scale) * Minimap.minimap.scale;
|
||||
var draggerHeight = (workspaceMetrics.viewHeight / Minimap.workspace.scale) *
|
||||
Minimap.minimap.scale;
|
||||
// It's zero when first block is placed.
|
||||
if(draggerHeight == 0){
|
||||
if (draggerHeight == 0) {
|
||||
return;
|
||||
}
|
||||
Minimap.mapDragger.setAttribute("height", draggerHeight);
|
||||
Minimap.mapDragger.setAttribute('height', draggerHeight);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the rectangle's width.
|
||||
*/
|
||||
Minimap.setDraggerWidth = function(){
|
||||
* Updates the rectangle's width.
|
||||
*/
|
||||
Minimap.setDraggerWidth = function() {
|
||||
var workspaceMetrics = Minimap.workspace.getMetrics();
|
||||
var draggerWidth = (workspaceMetrics.viewWidth / Minimap.workspace.scale) * Minimap.minimap.scale;
|
||||
var draggerWidth = (workspaceMetrics.viewWidth / Minimap.workspace.scale) *
|
||||
Minimap.minimap.scale;
|
||||
// It's zero when first block is placed.
|
||||
if(draggerWidth == 0){
|
||||
if (draggerWidth == 0) {
|
||||
return;
|
||||
}
|
||||
Minimap.mapDragger.setAttribute("width", draggerWidth);
|
||||
Minimap.mapDragger.setAttribute('width', draggerWidth);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Updates the overall position of the viewport of the minimap by appropriately
|
||||
* using translate functions.
|
||||
*/
|
||||
Minimap.scaleMinimap = function(){
|
||||
* Updates the overall position of the viewport of the minimap by appropriately
|
||||
* using translate functions.
|
||||
*/
|
||||
Minimap.scaleMinimap = function() {
|
||||
var minimapBoundingBox = Minimap.minimap.getBlocksBoundingBox();
|
||||
var workspaceBoundingBox = Minimap.workspace.getBlocksBoundingBox();
|
||||
var workspaceMetrics = Minimap.workspace.getMetrics();
|
||||
var minimapMetrics = Minimap.minimap.getMetrics();
|
||||
|
||||
//Scaling the mimimap such that all the blocks can be seen in the viewport.
|
||||
//This padding is default because this is how to scrollbar(in main workspace) is implemented.
|
||||
var topPadding = (workspaceMetrics.viewHeight) * Minimap.minimap.scale / (2 * Minimap.workspace.scale);
|
||||
var sidePadding = (workspaceMetrics.viewWidth) * Minimap.minimap.scale / (2 * Minimap.workspace.scale);
|
||||
// Scaling the mimimap such that all the blocks can be seen in the viewport.
|
||||
// This padding is default because this is how to scrollbar(in main workspace)
|
||||
// is implemented.
|
||||
var topPadding = (workspaceMetrics.viewHeight) * Minimap.minimap.scale /
|
||||
(2 * Minimap.workspace.scale);
|
||||
var sidePadding = (workspaceMetrics.viewWidth) * Minimap.minimap.scale /
|
||||
(2 * Minimap.workspace.scale);
|
||||
|
||||
// If actual padding is more than half view ports height, change it to actual padding.
|
||||
if((workspaceBoundingBox.y * Minimap.workspace.scale - workspaceMetrics.contentTop)
|
||||
* Minimap.minimap.scale / Minimap.workspace.scale > topPadding){
|
||||
topPadding = (workspaceBoundingBox.y * Minimap.workspace.scale - workspaceMetrics.contentTop)
|
||||
* Minimap.minimap.scale / Minimap.workspace.scale;
|
||||
// If actual padding is more than half view ports height,
|
||||
// change it to actual padding.
|
||||
if ((workspaceBoundingBox.y * Minimap.workspace.scale -
|
||||
workspaceMetrics.contentTop) *
|
||||
Minimap.minimap.scale / Minimap.workspace.scale > topPadding) {
|
||||
topPadding = (workspaceBoundingBox.y * Minimap.workspace.scale -
|
||||
workspaceMetrics.contentTop) *
|
||||
Minimap.minimap.scale / Minimap.workspace.scale;
|
||||
}
|
||||
|
||||
// If actual padding is more than half view ports height, change it to actual padding.
|
||||
if((workspaceBoundingBox.x * Minimap.workspace.scale - workspaceMetrics.contentLeft)
|
||||
* Minimap.minimap.scale / Minimap.workspace.scale > sidePadding){
|
||||
sidePadding = (workspaceBoundingBox.x * Minimap.workspace.scale - workspaceMetrics.contentLeft)
|
||||
* Minimap.minimap.scale / Minimap.workspace.scale;
|
||||
// If actual padding is more than half view ports height,
|
||||
// change it to actual padding.
|
||||
if ((workspaceBoundingBox.x * Minimap.workspace.scale -
|
||||
workspaceMetrics.contentLeft) *
|
||||
Minimap.minimap.scale / Minimap.workspace.scale > sidePadding) {
|
||||
sidePadding = (workspaceBoundingBox.x * Minimap.workspace.scale -
|
||||
workspaceMetrics.contentLeft) *
|
||||
Minimap.minimap.scale / Minimap.workspace.scale;
|
||||
}
|
||||
|
||||
var scalex = (minimapMetrics.viewWidth - 2 * sidePadding) / minimapBoundingBox.width;
|
||||
var scaley = (minimapMetrics.viewHeight - 2 * topPadding) / minimapBoundingBox.height;
|
||||
var scalex = (minimapMetrics.viewWidth - 2 * sidePadding) /
|
||||
minimapBoundingBox.width;
|
||||
var scaley = (minimapMetrics.viewHeight - 2 * topPadding) /
|
||||
minimapBoundingBox.height;
|
||||
Minimap.minimap.setScale(Math.min(scalex, scaley));
|
||||
|
||||
// Translating the minimap.
|
||||
Minimap.minimap.translate( - minimapMetrics.contentLeft * Minimap.minimap.scale + sidePadding,
|
||||
- minimapMetrics.contentTop * Minimap.minimap.scale + topPadding);
|
||||
Minimap.minimap.translate(
|
||||
-minimapMetrics.contentLeft * Minimap.minimap.scale + sidePadding,
|
||||
-minimapMetrics.contentTop * Minimap.minimap.scale + topPadding);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the onclick event on the minimapBoundingBox. Changes mapDraggers position.
|
||||
* @param {Event} e Event from the mouse click.
|
||||
*/
|
||||
Minimap.updateMapDragger = function(e){
|
||||
* Handles the onclick event on the minimapBoundingBox.
|
||||
* Changes mapDraggers position.
|
||||
* @param {!Event} e Event from the mouse click.
|
||||
*/
|
||||
Minimap.updateMapDragger = function(e) {
|
||||
var y = e.clientY;
|
||||
var x = e.clientX;
|
||||
var draggerHeight = Minimap.mapDragger.getAttribute("height");
|
||||
var draggerWidth = Minimap.mapDragger.getAttribute("width");
|
||||
var draggerHeight = Minimap.mapDragger.getAttribute('height');
|
||||
var draggerWidth = Minimap.mapDragger.getAttribute('width');
|
||||
|
||||
var finalY = y - Minimap.rect.top - draggerHeight / 2;
|
||||
var finalX = x - Minimap.rect.left - draggerWidth / 2;
|
||||
|
||||
var maxValidY = (Minimap.workspace.getMetrics().contentHeight - Minimap.workspace.getMetrics().viewHeight)
|
||||
* Minimap.minimap.scale;
|
||||
var maxValidX = (Minimap.workspace.getMetrics().contentWidth - Minimap.workspace.getMetrics().viewWidth)
|
||||
* Minimap.minimap.scale;
|
||||
var maxValidY = (Minimap.workspace.getMetrics().contentHeight -
|
||||
Minimap.workspace.getMetrics().viewHeight) * Minimap.minimap.scale;
|
||||
var maxValidX = (Minimap.workspace.getMetrics().contentWidth -
|
||||
Minimap.workspace.getMetrics().viewWidth) * Minimap.minimap.scale;
|
||||
|
||||
if(y + draggerHeight / 2 > Minimap.rect.bottom){
|
||||
if (y + draggerHeight / 2 > Minimap.rect.bottom) {
|
||||
finalY = Minimap.rect.bottom - Minimap.rect.top - draggerHeight;
|
||||
}else if(y < Minimap.rect.top + draggerHeight / 2){
|
||||
} else if (y < Minimap.rect.top + draggerHeight / 2) {
|
||||
finalY = 0;
|
||||
}
|
||||
|
||||
if(x + draggerWidth / 2 > Minimap.rect.right){
|
||||
if (x + draggerWidth / 2 > Minimap.rect.right) {
|
||||
finalX = Minimap.rect.right - Minimap.rect.left - draggerWidth;
|
||||
}else if(x < Minimap.rect.left + draggerWidth / 2){
|
||||
} else if (x < Minimap.rect.left + draggerWidth / 2) {
|
||||
finalX = 0;
|
||||
}
|
||||
|
||||
// Do not go below lower bound of scrollbar.
|
||||
if(finalY > maxValidY){
|
||||
if (finalY > maxValidY) {
|
||||
finalY = maxValidY;
|
||||
}
|
||||
|
||||
if(finalX > maxValidX){
|
||||
if (finalX > maxValidX) {
|
||||
finalX = maxValidX;
|
||||
}
|
||||
Minimap.mapDragger.setAttribute("y", finalY);
|
||||
Minimap.mapDragger.setAttribute("x", finalX);
|
||||
Minimap.mapDragger.setAttribute('y', finalY);
|
||||
Minimap.mapDragger.setAttribute('x', finalX);
|
||||
// Required, otherwise creates a feedback loop.
|
||||
Minimap.disableScrollChange = true;
|
||||
Minimap.workspace.scrollbar.vScroll.set((finalY * Minimap.workspace.scale) / Minimap.minimap.scale);
|
||||
Minimap.workspace.scrollbar.hScroll.set((finalX * Minimap.workspace.scale) / Minimap.minimap.scale);
|
||||
Minimap.workspace.scrollbar.vScroll.set((finalY * Minimap.workspace.scale) /
|
||||
Minimap.minimap.scale);
|
||||
Minimap.workspace.scrollbar.hScroll.set((finalX * Minimap.workspace.scale) /
|
||||
Minimap.minimap.scale);
|
||||
Minimap.disableScrollChange = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the onclick event on the minimapBoundingBox, paramaters are passed by
|
||||
* the event handler.
|
||||
* @param {Float} position This is the absolute postion of the scrollbar.
|
||||
* @param {boolean} horizontal Informs if the change event if for horizontal(true)
|
||||
* scrollbar or vertical(false) scrollbar.
|
||||
*/
|
||||
Minimap.onScrollChange = function(position, horizontal){
|
||||
|
||||
if(Minimap.disableScrollChange){
|
||||
return;
|
||||
}
|
||||
|
||||
var newDraggerPosition = (position * Minimap.minimap.scale / Minimap.workspace.scale);
|
||||
if(horizontal){
|
||||
// Change the horizontal position of dragger.
|
||||
Minimap.mapDragger.setAttribute("x", newDraggerPosition);
|
||||
}
|
||||
else{
|
||||
// Change the vertical position of dragger.
|
||||
Minimap.mapDragger.setAttribute("y", newDraggerPosition);
|
||||
* Handles the onclick event on the minimapBoundingBox, parameters are passed by
|
||||
* the event handler.
|
||||
* @param {number} position This is the absolute position of the scrollbar.
|
||||
* @param {boolean} horizontal Informs if the change event if for
|
||||
* horizontal (true) or vertical (false) scrollbar.
|
||||
*/
|
||||
Minimap.onScrollChange = function(position, horizontal) {
|
||||
if (!Minimap.disableScrollChange) {
|
||||
Minimap.mapDragger.setAttribute(horizontal ? 'x' : 'y',
|
||||
position * Minimap.minimap.scale / Minimap.workspace.scale);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ Blockly.Dart['procedures_defreturn'] = function(block) {
|
||||
var returnValue = Blockly.Dart.valueToCode(block, 'RETURN',
|
||||
Blockly.Dart.ORDER_NONE) || '';
|
||||
if (returnValue) {
|
||||
returnValue = ' return ' + returnValue + ';\n';
|
||||
returnValue = Blockly.Dart.INDENT + 'return ' + returnValue + ';\n';
|
||||
}
|
||||
var returnType = returnValue ? 'dynamic' : 'void';
|
||||
var args = [];
|
||||
@@ -101,9 +101,9 @@ Blockly.Dart['procedures_ifreturn'] = function(block) {
|
||||
if (block.hasReturnValue_) {
|
||||
var value = Blockly.Dart.valueToCode(block, 'VALUE',
|
||||
Blockly.Dart.ORDER_NONE) || 'null';
|
||||
code += ' return ' + value + ';\n';
|
||||
code += Blockly.Dart.INDENT + 'return ' + value + ';\n';
|
||||
} else {
|
||||
code += ' return;\n';
|
||||
code += Blockly.Dart.INDENT + 'return;\n';
|
||||
}
|
||||
code += '}\n';
|
||||
return code;
|
||||
|
||||
@@ -47,7 +47,7 @@ Blockly.JavaScript['procedures_defreturn'] = function(block) {
|
||||
var returnValue = Blockly.JavaScript.valueToCode(block, 'RETURN',
|
||||
Blockly.JavaScript.ORDER_NONE) || '';
|
||||
if (returnValue) {
|
||||
returnValue = ' return ' + returnValue + ';\n';
|
||||
returnValue = Blockly.JavaScript.INDENT + 'return ' + returnValue + ';\n';
|
||||
}
|
||||
var args = [];
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
@@ -101,9 +101,9 @@ Blockly.JavaScript['procedures_ifreturn'] = function(block) {
|
||||
if (block.hasReturnValue_) {
|
||||
var value = Blockly.JavaScript.valueToCode(block, 'VALUE',
|
||||
Blockly.JavaScript.ORDER_NONE) || 'null';
|
||||
code += ' return ' + value + ';\n';
|
||||
code += Blockly.JavaScript.INDENT + 'return ' + value + ';\n';
|
||||
} else {
|
||||
code += ' return;\n';
|
||||
code += Blockly.JavaScript.INDENT + 'return;\n';
|
||||
}
|
||||
code += '}\n';
|
||||
return code;
|
||||
|
||||
@@ -47,7 +47,7 @@ Blockly.Lua['procedures_defreturn'] = function(block) {
|
||||
var returnValue = Blockly.Lua.valueToCode(block, 'RETURN',
|
||||
Blockly.Lua.ORDER_NONE) || '';
|
||||
if (returnValue) {
|
||||
returnValue = ' return ' + returnValue + '\n';
|
||||
returnValue = Blockly.Lua.INDENT + 'return ' + returnValue + '\n';
|
||||
} else if (!branch) {
|
||||
branch = '';
|
||||
}
|
||||
@@ -103,9 +103,9 @@ Blockly.Lua['procedures_ifreturn'] = function(block) {
|
||||
if (block.hasReturnValue_) {
|
||||
var value = Blockly.Lua.valueToCode(block, 'VALUE',
|
||||
Blockly.Lua.ORDER_NONE) || 'nil';
|
||||
code += ' return ' + value + '\n';
|
||||
code += Blockly.Lua.INDENT + 'return ' + value + '\n';
|
||||
} else {
|
||||
code += ' return\n';
|
||||
code += Blockly.Lua.INDENT + 'return\n';
|
||||
}
|
||||
code += 'end\n';
|
||||
return code;
|
||||
|
||||
@@ -43,7 +43,7 @@ Blockly.PHP['procedures_defreturn'] = function(block) {
|
||||
Blockly.Variables.NAME_TYPE));
|
||||
}
|
||||
}
|
||||
globals = globals.length ? ' global ' + globals.join(', ') + ';\n' : '';
|
||||
globals = globals.length ? Blockly.PHP.INDENT + 'global ' + globals.join(', ') + ';\n' : '';
|
||||
|
||||
var funcName = Blockly.PHP.variableDB_.getName(
|
||||
block.getFieldValue('NAME'), Blockly.Procedures.NAME_TYPE);
|
||||
@@ -61,7 +61,7 @@ Blockly.PHP['procedures_defreturn'] = function(block) {
|
||||
var returnValue = Blockly.PHP.valueToCode(block, 'RETURN',
|
||||
Blockly.PHP.ORDER_NONE) || '';
|
||||
if (returnValue) {
|
||||
returnValue = ' return ' + returnValue + ';\n';
|
||||
returnValue = Blockly.PHP.INDENT + 'return ' + returnValue + ';\n';
|
||||
}
|
||||
var args = [];
|
||||
for (var i = 0; i < block.arguments_.length; i++) {
|
||||
@@ -115,9 +115,9 @@ Blockly.PHP['procedures_ifreturn'] = function(block) {
|
||||
if (block.hasReturnValue_) {
|
||||
var value = Blockly.PHP.valueToCode(block, 'VALUE',
|
||||
Blockly.PHP.ORDER_NONE) || 'null';
|
||||
code += ' return ' + value + ';\n';
|
||||
code += Blockly.PHP.INDENT + 'return ' + value + ';\n';
|
||||
} else {
|
||||
code += ' return;\n';
|
||||
code += Blockly.PHP.INDENT + 'return;\n';
|
||||
}
|
||||
code += '}\n';
|
||||
return code;
|
||||
|
||||
@@ -44,7 +44,7 @@ Blockly.Python['procedures_defreturn'] = function(block) {
|
||||
Blockly.Variables.NAME_TYPE));
|
||||
}
|
||||
}
|
||||
globals = globals.length ? ' global ' + globals.join(', ') + '\n' : '';
|
||||
globals = globals.length ? Blockly.Python.INDENT + 'global ' + globals.join(', ') + '\n' : '';
|
||||
var funcName = Blockly.Python.variableDB_.getName(block.getFieldValue('NAME'),
|
||||
Blockly.Procedures.NAME_TYPE);
|
||||
var branch = Blockly.Python.statementToCode(block, 'STACK');
|
||||
@@ -61,7 +61,7 @@ Blockly.Python['procedures_defreturn'] = function(block) {
|
||||
var returnValue = Blockly.Python.valueToCode(block, 'RETURN',
|
||||
Blockly.Python.ORDER_NONE) || '';
|
||||
if (returnValue) {
|
||||
returnValue = ' return ' + returnValue + '\n';
|
||||
returnValue = Blockly.Python.INDENT + 'return ' + returnValue + '\n';
|
||||
} else if (!branch) {
|
||||
branch = Blockly.Python.PASS;
|
||||
}
|
||||
@@ -117,9 +117,9 @@ Blockly.Python['procedures_ifreturn'] = function(block) {
|
||||
if (block.hasReturnValue_) {
|
||||
var value = Blockly.Python.valueToCode(block, 'VALUE',
|
||||
Blockly.Python.ORDER_NONE) || 'None';
|
||||
code += ' return ' + value + '\n';
|
||||
code += Blockly.Python.INDENT + 'return ' + value + '\n';
|
||||
} else {
|
||||
code += ' return\n';
|
||||
code += Blockly.Python.INDENT + 'return\n';
|
||||
}
|
||||
return code;
|
||||
};
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ goog.require('Blockly.Msg');
|
||||
/** @export */ Blockly.Msg.LISTS_LENGTH_TITLE = "hirder %1";
|
||||
/** @export */ Blockly.Msg.LISTS_LENGTH_TOOLTIP = "Distreiñ hirder ul listenn.";
|
||||
/** @export */ Blockly.Msg.LISTS_REPEAT_HELPURL = "https://github.com/google/blockly/wiki/Lists#create-list-with"; // untranslated
|
||||
/** @export */ Blockly.Msg.LISTS_REPEAT_TITLE = "Krouiñ ul listenn gant an elfenn %1 arreet div wech";
|
||||
/** @export */ Blockly.Msg.LISTS_REPEAT_TITLE = "Krouiñ ul listenn gant an elfenn %1 arreet %2 div wech";
|
||||
/** @export */ Blockly.Msg.LISTS_REPEAT_TOOLTIP = "Krouiñ ul listenn a c'hoarvez eus an dalvoudenn roet arreet an niver a wech meneget";
|
||||
/** @export */ Blockly.Msg.LISTS_REVERSE_HELPURL = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
|
||||
/** @export */ Blockly.Msg.LISTS_REVERSE_MESSAGE0 = "eilpennañ %1";
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ goog.require('Blockly.Msg');
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOREACH_TITLE = "para cada item %1 na lista %2";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOREACH_TOOLTIP = "Para cada item numa lista, define a variável \"%1\" para o item e então faz algumas instruções.";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOR_HELPURL = "https://github.com/google/blockly/wiki/Loops#count-with"; // untranslated
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOR_TITLE = "contar com %1 de %2 até %3 de %3 em %4";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOR_TITLE = "contar com %1 de %2 até %3 por %4";
|
||||
/** @export */ Blockly.Msg.CONTROLS_FOR_TOOLTIP = "Faz com que a variável \"%1\" assuma os valores desde o número inicial até ao número final, contando de acordo com o intervalo especificado e executa os blocos especificados.";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP = "Acrescente uma condição ao bloco se.";
|
||||
/** @export */ Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP = "Acrescente uma condição de excepação final para o bloco se.";
|
||||
|
||||
+1
-1
@@ -247,7 +247,7 @@
|
||||
"LISTS_CREATE_WITH_CONTAINER_TOOLTIP": "Ouzhpennañ, lemel pe adurzhiañ ar rannoù evit kefluniañ ar bloc'h listenn-mañ.",
|
||||
"LISTS_CREATE_WITH_ITEM_TOOLTIP": "Ouzhpennañ un elfenn d'ar roll",
|
||||
"LISTS_REPEAT_TOOLTIP": "Krouiñ ul listenn a c'hoarvez eus an dalvoudenn roet arreet an niver a wech meneget",
|
||||
"LISTS_REPEAT_TITLE": "Krouiñ ul listenn gant an elfenn %1 arreet div wech",
|
||||
"LISTS_REPEAT_TITLE": "Krouiñ ul listenn gant an elfenn %1 arreet %2 div wech",
|
||||
"LISTS_LENGTH_TITLE": "hirder %1",
|
||||
"LISTS_LENGTH_TOOLTIP": "Distreiñ hirder ul listenn.",
|
||||
"LISTS_ISEMPTY_TITLE": "%1 zo goullo",
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@
|
||||
"CONTROLS_WHILEUNTIL_TOOLTIP_WHILE": "Enquanto um valor for verdadeiro, então faça algumas instruções.",
|
||||
"CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL": "Enquanto um valor for falso, então faça algumas instruções.",
|
||||
"CONTROLS_FOR_TOOLTIP": "Faz com que a variável \"%1\" assuma os valores desde o número inicial até ao número final, contando de acordo com o intervalo especificado e executa os blocos especificados.",
|
||||
"CONTROLS_FOR_TITLE": "contar com %1 de %2 até %3 de %3 em %4",
|
||||
"CONTROLS_FOR_TITLE": "contar com %1 de %2 até %3 por %4",
|
||||
"CONTROLS_FOREACH_TITLE": "para cada item %1 na lista %2",
|
||||
"CONTROLS_FOREACH_TOOLTIP": "Para cada item numa lista, define a variável \"%1\" para o item e então faz algumas instruções.",
|
||||
"CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK": "sair do ciclo",
|
||||
|
||||
+5
-2
@@ -17,8 +17,8 @@
|
||||
"name": "Neil Fraser"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "jshint .",
|
||||
"pretest": "scripts/test_setup.sh",
|
||||
"lint": "eslint .",
|
||||
"pretest": "tests/scripts/test_setup.sh",
|
||||
"test": "node tests/jsunit/test_runner.js"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
@@ -45,5 +45,8 @@
|
||||
"npm": "^4.4.4",
|
||||
"closure-library": "^1.43629075.2",
|
||||
"webdriverio": "^4.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "2.9.0"
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
# Find the Closure Compiler.
|
||||
if [ -f "$(npm root)/google-closure-compiler/compiler.jar" ]; then
|
||||
# Travis test.
|
||||
COMPILER="$(npm root)/google-closure-compiler/compiler.jar"
|
||||
elif [ -f *compiler*.jar ]; then
|
||||
# Manual test.
|
||||
COMPILER="*compiler*.jar"
|
||||
else
|
||||
echo "ERROR: Closure Compiler not found."
|
||||
echo "Download from this URL, and place jar file in current directory."
|
||||
echo "https://dl.google.com/closure-compiler/compiler-latest.zip"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm main_compressed.js 2> /dev/null
|
||||
echo Compiling Blockly...
|
||||
java -jar $COMPILER --js='main.js' \
|
||||
--js='../../core/**.js' \
|
||||
--js='../../blocks/**.js' \
|
||||
--js='../../generators/**.js' \
|
||||
--js='../../msg/js/**.js' \
|
||||
--js='../../../closure-library/closure/goog/**.js' \
|
||||
--js='../../../closure-library/third_party/closure/goog/**.js' \
|
||||
--generate_exports \
|
||||
--externs ../../externs/svg-externs.js \
|
||||
--compilation_level ADVANCED_OPTIMIZATIONS \
|
||||
--dependency_mode=STRICT --entry_point=Main \
|
||||
--js_output_file main_compressed.js
|
||||
if [ -s main_compressed.js ]; then
|
||||
echo Compilation OK.
|
||||
else
|
||||
echo Compilation FAIL.
|
||||
exit 1
|
||||
fi
|
||||
@@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Blockly Demo: Fixed Blockly built with Closure Compiler's advanced optimizations</title>
|
||||
<title>Blockly: Advanced Compilation Test</title>
|
||||
<script src="main_compressed.js"></script>
|
||||
<style>
|
||||
body {
|
||||
@@ -16,21 +16,16 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
<a href="https://developers.google.com/blockly/">Blockly</a> >
|
||||
<a href="../index.html">Demos</a> >
|
||||
Fixed Blockly built with Closure Compiler's advanced optimizations
|
||||
</h1>
|
||||
<h1>Blockly: Advanced Compilation Test</h1>
|
||||
|
||||
<p>
|
||||
This is a simple demo of injecting Blockly into a fixed-sized 'div' element
|
||||
from a Closure-compiled source code with advanced optimizations.
|
||||
</p>
|
||||
<p>To run this test manually, download
|
||||
<a href="https://dl.google.com/closure-compiler/compiler-latest.zip">closure-compiler-vxxxxxxxx.jar</a>,
|
||||
place it in this directory, then run compile.js from the command line.</p>
|
||||
|
||||
<p>→ More info on <a href="https://developers.google.com/blockly/guides/configure-blockly/web/fixed-size">injecting fixed-sized Blockly</a>…</p>
|
||||
<p>Measure the size of main_compressed.js (295kb as of October 2017), then reload
|
||||
this page and see if Blockly works.</p>
|
||||
|
||||
<div id="blocklyDiv" style="height: 480px; width: 600px;"></div>
|
||||
|
||||
<xml id="toolbox" style="display: none">
|
||||
<block type="controls_if"></block>
|
||||
<block type="logic_compare"></block>
|
||||
@@ -40,6 +35,5 @@
|
||||
<block type="text"></block>
|
||||
<block type="text_print"></block>
|
||||
</xml>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
goog.provide('Main');
|
||||
// Messages (in some language)
|
||||
goog.require('Blockly.Msg.en');
|
||||
// Core
|
||||
goog.require('Blockly');
|
||||
// Blocks
|
||||
goog.require('Blockly.Constants.Logic');
|
||||
goog.require('Blockly.Constants.Loops');
|
||||
goog.require('Blockly.Constants.Math');
|
||||
goog.require('Blockly.Constants.Text');
|
||||
|
||||
Main.init = function() {
|
||||
Blockly.inject('blocklyDiv', {
|
||||
'toolbox': document.getElementById('toolbox')
|
||||
});
|
||||
};
|
||||
window.addEventListener('load', Main.init);
|
||||
@@ -304,4 +304,4 @@ function helper_createConnection(x, y, type, opt_shared_workspace,
|
||||
conn.x_ = x;
|
||||
conn.y_ = y;
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Blockly Tests
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
function test_DB_getNeighbours() {
|
||||
var db = new Blockly.ConnectionDB();
|
||||
|
||||
// Search an empty list.
|
||||
assertEquals(helper_getNeighbours(db, 10 /* x */, 10 /* y */, 100 /* radius */).length, 0);
|
||||
|
||||
// Set up some connections.
|
||||
for (var i = 0; i < 10; i++) {
|
||||
db.addConnection_(helper_createConnection(0, i, Blockly.PREVIOUS_STATEMENT));
|
||||
}
|
||||
|
||||
// Test block belongs at beginning
|
||||
var result = helper_getNeighbours(db, 0, 0, 4);
|
||||
assertEquals(5, result.length);
|
||||
for (i = 0; i < result.length; i++) {
|
||||
assertNotEquals(result.indexOf(db[i]), -1); // contains
|
||||
}
|
||||
|
||||
// Test block belongs at middle
|
||||
result = helper_getNeighbours(db, 0, 4, 2);
|
||||
assertEquals(5, result.length);
|
||||
for (i = 0; i < result.length; i++) {
|
||||
assertNotEquals(result.indexOf(db[i + 2]), -1); // contains
|
||||
}
|
||||
|
||||
// Test block belongs at end
|
||||
result = helper_getNeighbours(db, 0, 9, 4);
|
||||
assertEquals(5, result.length);
|
||||
for (i = 0; i < result.length; i++) {
|
||||
assertNotEquals(result.indexOf(db[i + 5]), -1); // contains
|
||||
}
|
||||
|
||||
// Test block has no neighbours due to being out of range in the x direction
|
||||
result = helper_getNeighbours(db, 10, 9, 4);
|
||||
assertEquals(result.length, 0);
|
||||
|
||||
// Test block has no neighbours due to being out of range in the y direction
|
||||
result = helper_getNeighbours(db, 0, 19, 4);
|
||||
assertEquals(result.length, 0);
|
||||
|
||||
// Test block has no neighbours due to being out of range diagonally
|
||||
result = helper_getNeighbours(db, -2, -2, 2);
|
||||
assertEquals(result.length, 0);
|
||||
}
|
||||
|
||||
function helper_getNeighbours(db, x, y, radius) {
|
||||
return db.getNeighbours(helper_createConnection(x, y, Blockly.NEXT_STATEMENT), radius);
|
||||
}
|
||||
|
||||
function helper_createConnection(x, y, type) {
|
||||
var conn = new Blockly.Connection({workspace: {}}, type);
|
||||
conn.x_ = x;
|
||||
conn.y_ = y;
|
||||
return conn;
|
||||
}
|
||||
@@ -512,6 +512,48 @@ function test_events_mergeUi() {
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that events that collide on a (event, block, workspace) tuple
|
||||
* but cannot be merged do not get dropped during filtering.
|
||||
*/
|
||||
function test_events_stackclick() {
|
||||
eventTest_setUpWithMockBlocks();
|
||||
var block = workspace.newBlock('field_variable_test_block', '1');
|
||||
var events = [
|
||||
new Blockly.Events.Ui(block, 'click', undefined, undefined),
|
||||
new Blockly.Events.Ui(block, 'stackclick', undefined, undefined)
|
||||
];
|
||||
var filteredEvents = Blockly.Events.filter(events, true);
|
||||
// click and stackclick should both exist
|
||||
assertEquals(2, filteredEvents.length);
|
||||
assertEquals('click', filteredEvents[0].element);
|
||||
assertEquals('stackclick', filteredEvents[1].element);
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutator composition could result in move events for blocks
|
||||
* connected to the mutated block that were null operations. This
|
||||
* leads to events in the undo/redo queue that do nothing, requiring
|
||||
* an extra undo/redo to proceed to the next event. This test ensures
|
||||
* that two move events that do get merged (disconnecting and
|
||||
* reconnecting a block in response to a mutator change) are filtered
|
||||
* from the queue.
|
||||
*/
|
||||
function test_events_filteraftermerge() {
|
||||
eventTest_setUpWithMockBlocks();
|
||||
var block = workspace.newBlock('field_variable_test_block', '1');
|
||||
block.setParent(null);
|
||||
var events = [];
|
||||
helper_addMoveEventParent(events, block, null);
|
||||
helper_addMoveEventParent(events, block, null);
|
||||
var filteredEvents = Blockly.Events.filter(events, true);
|
||||
// The two events should be merged, but because nothing has changed
|
||||
// they will be filtered out.
|
||||
assertEquals(0, filteredEvents.length);
|
||||
eventTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to simulate block move events.
|
||||
*
|
||||
@@ -525,3 +567,9 @@ function helper_addMoveEvent(events, block, newX, newY) {
|
||||
block.xy_ = new goog.math.Coordinate(newX, newY);
|
||||
events[events.length-1].recordNew();
|
||||
}
|
||||
|
||||
function helper_addMoveEventParent(events, block, parent) {
|
||||
events.push(new Blockly.Events.BlockMove(block));
|
||||
block.setParent(parent);
|
||||
events[events.length-1].recordNew();
|
||||
}
|
||||
|
||||
@@ -8,26 +8,26 @@
|
||||
</head>
|
||||
<body>
|
||||
<script src="test_utilities.js"></script>
|
||||
<script src="utils_test.js"></script>
|
||||
<script src="connection_test.js"></script>
|
||||
<script src="connection_db_test.js"></script>
|
||||
<script src="extensions_test.js"></script>
|
||||
<script src="connection_test.js"></script>
|
||||
<script src="event_test.js"></script>
|
||||
<script src="field_test.js"></script>
|
||||
<script src="extensions_test.js"></script>
|
||||
<script src="field_angle_test.js"></script>
|
||||
<script src="field_number_test.js"></script>
|
||||
<script src="field_test.js"></script>
|
||||
<script src="field_variable_test.js"></script>
|
||||
<script src="generator_test.js"></script>
|
||||
<script src="gesture_test.js"></script>
|
||||
<script src="input_test.js"></script>
|
||||
<script src="json_test.js"></script>
|
||||
<script src="names_test.js"></script>
|
||||
<script src="procedures_test.js"></script>
|
||||
<script src="utils_test.js"></script>
|
||||
<script src="variable_map_test.js"></script>
|
||||
<script src="variable_model_test.js"></script>
|
||||
<script src="widget_div_test.js"></script>
|
||||
<script src="workspace_test.js"></script>
|
||||
<script src="workspace_undo_redo_test.js"></script>
|
||||
<script src="xml_test.js"></script>
|
||||
<script src="json_test.js"></script>
|
||||
<script src="procedures_test.js"></script>
|
||||
<script src="variable_model_test.js"></script>
|
||||
<script src="variable_map_test.js"></script>
|
||||
<script src="widget_div_test.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Tests for Blockly.Input
|
||||
*/
|
||||
* @fileoverview Tests for Blockly.Input
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
function test_appendField_simple() {
|
||||
@@ -157,7 +157,7 @@ function test_insertFieldAt_prefix() {
|
||||
var after = new Blockly.FieldLabel('after');
|
||||
var prefix = new Blockly.FieldLabel('prefix');
|
||||
var between = new Blockly.FieldLabel('between');
|
||||
between.prefixField = prefix
|
||||
between.prefixField = prefix;
|
||||
input.appendField(before);
|
||||
input.appendField(after);
|
||||
|
||||
@@ -175,7 +175,7 @@ function test_insertFieldAt_prefix() {
|
||||
assertEquals(after, input.fieldRow[3]);
|
||||
}
|
||||
|
||||
function test_insertFieldAt_prefix() {
|
||||
function test_insertFieldAt_suffix() {
|
||||
var ws = new Blockly.Workspace();
|
||||
var block = new Blockly.Block(ws);
|
||||
var input = new Blockly.Input(Blockly.DUMMY_INPUT, 'INPUT', block);
|
||||
@@ -183,7 +183,7 @@ function test_insertFieldAt_prefix() {
|
||||
var after = new Blockly.FieldLabel('after');
|
||||
var suffix = new Blockly.FieldLabel('suffix');
|
||||
var between = new Blockly.FieldLabel('between');
|
||||
between.suffixField = suffix
|
||||
between.suffixField = suffix;
|
||||
input.appendField(before);
|
||||
input.appendField(after);
|
||||
|
||||
@@ -199,4 +199,4 @@ function test_insertFieldAt_prefix() {
|
||||
assertEquals(between, input.fieldRow[1]);
|
||||
assertEquals(suffix, input.fieldRow[2]);
|
||||
assertEquals(after, input.fieldRow[3]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,4 +257,3 @@ function test_json_dropdown_image() {
|
||||
delete Blockly.Msg['ALTTEXT'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,4 +80,3 @@ function test_isNameUsed_True() {
|
||||
assertTrue(result);
|
||||
proceduresTest_tearDownWithMockBlocks();
|
||||
}
|
||||
|
||||
|
||||
+41
-25
@@ -42,14 +42,14 @@ function test_addClass() {
|
||||
assertEquals('Adding "three"', 'one two three', p.className);
|
||||
}
|
||||
|
||||
function test_hasClass() {
|
||||
var p = document.createElement('p');
|
||||
p.className = ' one three two three ';
|
||||
assertTrue('Has "one"', Blockly.utils.hasClass(p, 'one'));
|
||||
assertTrue('Has "two"', Blockly.utils.hasClass(p, 'two'));
|
||||
assertTrue('Has "three"', Blockly.utils.hasClass(p, 'three'));
|
||||
assertFalse('Has no "four"', Blockly.utils.hasClass(p, 'four'));
|
||||
assertFalse('Has no "t"', Blockly.utils.hasClass(p, 't'));
|
||||
function test_hasClass() {
|
||||
var p = document.createElement('p');
|
||||
p.className = ' one three two three ';
|
||||
assertTrue('Has "one"', Blockly.utils.hasClass(p, 'one'));
|
||||
assertTrue('Has "two"', Blockly.utils.hasClass(p, 'two'));
|
||||
assertTrue('Has "three"', Blockly.utils.hasClass(p, 'three'));
|
||||
assertFalse('Has no "four"', Blockly.utils.hasClass(p, 'four'));
|
||||
assertFalse('Has no "t"', Blockly.utils.hasClass(p, 't'));
|
||||
}
|
||||
|
||||
function test_removeClass() {
|
||||
@@ -128,19 +128,19 @@ function test_tokenizeInterpolation() {
|
||||
|
||||
tokens = Blockly.utils.tokenizeInterpolation('Hello');
|
||||
assertArrayEquals('No interpolation', ['Hello'], tokens);
|
||||
|
||||
|
||||
tokens = Blockly.utils.tokenizeInterpolation('Hello%World');
|
||||
assertArrayEquals('Unescaped %.', ['Hello%World'], tokens);
|
||||
|
||||
|
||||
tokens = Blockly.utils.tokenizeInterpolation('Hello%%World');
|
||||
assertArrayEquals('Escaped %.', ['Hello%World'], tokens);
|
||||
|
||||
|
||||
tokens = Blockly.utils.tokenizeInterpolation('Hello %1 World');
|
||||
assertArrayEquals('Interpolation.', ['Hello ', 1, ' World'], tokens);
|
||||
|
||||
|
||||
tokens = Blockly.utils.tokenizeInterpolation('%123Hello%456World%789');
|
||||
assertArrayEquals('Interpolations.', [123, 'Hello', 456, 'World', 789], tokens);
|
||||
|
||||
|
||||
tokens = Blockly.utils.tokenizeInterpolation('%%%x%%0%00%01%');
|
||||
assertArrayEquals('Torture interpolations.', ['%%x%0', 0, 1, '%'], tokens);
|
||||
|
||||
@@ -192,22 +192,13 @@ function test_tokenizeInterpolation() {
|
||||
function test_replaceMessageReferences() {
|
||||
Blockly.Msg = Blockly.Msg || {};
|
||||
Blockly.Msg.STRING_REF = 'test string';
|
||||
Blockly.Msg.SUBREF = 'subref';
|
||||
Blockly.Msg.STRING_REF_WITH_ARG = 'test %1 string';
|
||||
Blockly.Msg.STRING_REF_WITH_SUBREF = 'test %{bky_subref} string';
|
||||
|
||||
var resultString = Blockly.utils.replaceMessageReferences('');
|
||||
assertEquals('Empty string produces empty string', '', resultString);
|
||||
|
||||
resultString = Blockly.utils.replaceMessageReferences('%{bky_string_ref}');
|
||||
assertEquals('Message ref dereferenced.', 'test string', resultString);
|
||||
resultString = Blockly.utils.replaceMessageReferences('before %{bky_string_ref} after');
|
||||
assertEquals('Message ref dereferenced.', 'before test string after', resultString);
|
||||
|
||||
resultString = Blockly.utils.replaceMessageReferences('%1');
|
||||
assertEquals('Interpolation tokens ignored.', '%1', resultString);
|
||||
resultString = Blockly.utils.replaceMessageReferences('%1 %2');
|
||||
assertEquals('Interpolation tokens ignored.', '%1 %2', resultString);
|
||||
resultString = Blockly.utils.replaceMessageReferences('before %1 after');
|
||||
assertEquals('Interpolation tokens ignored.', 'before %1 after', resultString);
|
||||
|
||||
resultString = Blockly.utils.replaceMessageReferences('%%');
|
||||
assertEquals('Escaped %', '%', resultString);
|
||||
resultString = Blockly.utils.replaceMessageReferences('%%{bky_string_ref}');
|
||||
@@ -215,4 +206,29 @@ function test_replaceMessageReferences() {
|
||||
|
||||
resultString = Blockly.utils.replaceMessageReferences('%a');
|
||||
assertEquals('Unrecognized % escape code treated as literal', '%a', resultString);
|
||||
|
||||
resultString = Blockly.utils.replaceMessageReferences('%1');
|
||||
assertEquals('Interpolation tokens ignored.', '%1', resultString);
|
||||
resultString = Blockly.utils.replaceMessageReferences('%1 %2');
|
||||
assertEquals('Interpolation tokens ignored.', '%1 %2', resultString);
|
||||
resultString = Blockly.utils.replaceMessageReferences('before %1 after');
|
||||
assertEquals('Interpolation tokens ignored.', 'before %1 after', resultString);
|
||||
|
||||
// Blockly.Msg.STRING_REF cases:
|
||||
resultString = Blockly.utils.replaceMessageReferences('%{bky_string_ref}');
|
||||
assertEquals('Message ref dereferenced.', 'test string', resultString);
|
||||
resultString = Blockly.utils.replaceMessageReferences('before %{bky_string_ref} after');
|
||||
assertEquals('Message ref dereferenced.', 'before test string after', resultString);
|
||||
|
||||
// Blockly.Msg.STRING_REF_WITH_ARG cases:
|
||||
resultString = Blockly.utils.replaceMessageReferences('%{bky_string_ref_with_arg}');
|
||||
assertEquals('Message ref dereferenced with argument preserved.', 'test %1 string', resultString);
|
||||
resultString = Blockly.utils.replaceMessageReferences('before %{bky_string_ref_with_arg} after');
|
||||
assertEquals('Message ref dereferenced with argument preserved.', 'before test %1 string after', resultString);
|
||||
|
||||
// Blockly.Msg.STRING_REF_WITH_SUBREF cases:
|
||||
resultString = Blockly.utils.replaceMessageReferences('%{bky_string_ref_with_subref}');
|
||||
assertEquals('Message ref and subref dereferenced.', 'test subref string', resultString);
|
||||
resultString = Blockly.utils.replaceMessageReferences('before %{bky_string_ref_with_subref} after');
|
||||
assertEquals('Message ref and subref dereferenced.', 'before test subref string after', resultString);
|
||||
}
|
||||
|
||||
@@ -131,8 +131,7 @@ function test_createVariableNullId() {
|
||||
try {
|
||||
variable_map.createVariable('name1', 'type1', null);
|
||||
checkVariableValues(variable_map, 'name1', 'type1', '1');
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
}
|
||||
@@ -143,8 +142,7 @@ function test_createVariableUndefinedId() {
|
||||
try {
|
||||
variable_map.createVariable('name1', 'type1', undefined);
|
||||
checkVariableValues(variable_map, 'name1', 'type1', '1');
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
variableMapTest_tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,4 +151,3 @@ function test_widgetDiv_noXConflict_RTL() {
|
||||
anchorBBox, widgetDiv_test_widgetSize, true /* rtl */);
|
||||
assertEquals(anchorBBox.right - widgetDiv_test_widgetSize.width, calculated);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,7 @@ function test_emptyWorkspace() {
|
||||
assertEquals('Empty workspace (4).', 0, workspace.getTopBlocks(true).length);
|
||||
assertEquals('Empty workspace (5).', 0, workspace.getTopBlocks(false).length);
|
||||
assertEquals('Empty workspace (6).', 0, workspace.getAllBlocks().length);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
@@ -187,8 +186,7 @@ function test_updateVariableStore_TrivialNoClear() {
|
||||
workspace.updateVariableStore();
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
@@ -202,8 +200,7 @@ function test_updateVariableStore_NameNotInvariableMap_NoClear() {
|
||||
try {
|
||||
workspace.updateVariableStore();
|
||||
checkVariableValues(workspace, 'name1', '', '1');
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
@@ -219,8 +216,7 @@ function test_updateVariableStore_ClearAndAllInUse() {
|
||||
workspace.updateVariableStore(true);
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
checkVariableValues(workspace, 'name2', 'type2', 'id2');
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
@@ -237,8 +233,7 @@ function test_updateVariableStore_ClearAndOneInUse() {
|
||||
checkVariableValues(workspace, 'name1', 'type1', 'id1');
|
||||
var variabe = workspace.getVariable('name2');
|
||||
assertNull(variable);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
@@ -255,8 +250,7 @@ function test_addTopBlock_TrivialFlyoutIsTrue() {
|
||||
try {
|
||||
workspace.addTopBlock(block);
|
||||
checkVariableValues(workspace, 'name1', '', '1');
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
@@ -274,8 +268,7 @@ function test_clear_Trivial() {
|
||||
var varMapLength = Object.keys(workspace.variableMap_.variableMap_).length;
|
||||
assertEquals(0, topBlocks_length);
|
||||
assertEquals(0, varMapLength);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
@@ -291,8 +284,7 @@ function test_clear_NoVariables() {
|
||||
var varMapLength = Object.keys(workspace.variableMap_.variableMap_).length;
|
||||
assertEquals(0, topBlocks_length);
|
||||
assertEquals(0, varMapLength);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
@@ -312,8 +304,7 @@ function test_renameVariable_NoBlocks() {
|
||||
checkVariableValues(workspace, 'name2', '', '1');
|
||||
var variable = workspace.getVariable(oldName);
|
||||
assertNull(variable);
|
||||
}
|
||||
finally {
|
||||
} finally {
|
||||
workspaceTest_tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ function xmlTest_setUpWithMockBlocks() {
|
||||
'name': 'VAR',
|
||||
'variable': 'item'
|
||||
}
|
||||
],
|
||||
]
|
||||
}]);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ function xmlTest_checkNonVariableField(fieldDom, name, text) {
|
||||
assertEquals(text, fieldDom.textContent);
|
||||
assertEquals(name, fieldDom.getAttribute('name'));
|
||||
assertNull(fieldDom.getAttribute('id'));
|
||||
assertNull(fieldDom.getAttribute('variableType'));
|
||||
assertNull(fieldDom.getAttribute('variabletype'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +104,7 @@ function xmlTest_checkNonVariableField(fieldDom, name, text) {
|
||||
*/
|
||||
function xmlTest_checkVariableFieldDomValues(fieldDom, name, type, id, text) {
|
||||
assertEquals(name, fieldDom.getAttribute('name'));
|
||||
assertEquals(type, fieldDom.getAttribute('variableType'));
|
||||
assertEquals(type, fieldDom.getAttribute('variabletype'));
|
||||
assertEquals(id, fieldDom.getAttribute('id'));
|
||||
assertEquals(text, fieldDom.textContent);
|
||||
}
|
||||
@@ -166,7 +166,7 @@ function test_domToWorkspace_VariablesAtTop() {
|
||||
' <variable type="" id="id3">name3</variable>' +
|
||||
' </variables>' +
|
||||
' <block type="field_variable_test_block">' +
|
||||
' <field name="VAR" id="id3" variableType="">name3</field>' +
|
||||
' <field name="VAR" id="id3" variabletype="">name3</field>' +
|
||||
' </block>' +
|
||||
'</xml>');
|
||||
Blockly.Xml.domToWorkspace(dom, workspace);
|
||||
@@ -210,7 +210,7 @@ function test_domToWorkspace_VariablesAtTop_MissingType() {
|
||||
' <variable id="id1">name1</variable>' +
|
||||
' </variables>' +
|
||||
' <block type="field_variable_test_block">' +
|
||||
' <field name="VAR" id="id1" variableType="">name3</field>' +
|
||||
' <field name="VAR" id="id1" variabletype="">name3</field>' +
|
||||
' </block>' +
|
||||
'</xml>');
|
||||
Blockly.Xml.domToWorkspace(dom, workspace);
|
||||
@@ -233,7 +233,7 @@ function test_domToWorkspace_VariablesAtTop_MismatchBlockType() {
|
||||
' <variable type="type1" id="id1">name1</variable>' +
|
||||
' </variables>' +
|
||||
' <block type="field_variable_test_block">' +
|
||||
' <field name="VAR" id="id1" variableType="">name1</field>' +
|
||||
' <field name="VAR" id="id1" variabletype="">name1</field>' +
|
||||
' </block>' +
|
||||
'</xml>');
|
||||
Blockly.Xml.domToWorkspace(dom, workspace);
|
||||
@@ -364,3 +364,28 @@ function test_variablesToDom_noVariables() {
|
||||
assertEquals(1, resultDom.children.length);
|
||||
xmlTest_tearDown();
|
||||
}
|
||||
|
||||
function test_variableFieldXml_caseSensitive() {
|
||||
var id = 'testId';
|
||||
var type = 'testType';
|
||||
var name = 'testName';
|
||||
|
||||
var mockVariableModel = {
|
||||
type: type,
|
||||
name: name,
|
||||
getId: function() {
|
||||
return id;
|
||||
}
|
||||
};
|
||||
|
||||
var generatedXml = Blockly.Variables.generateVariableFieldXml_(mockVariableModel);
|
||||
// The field contains this XML tag as a result of how we're generating this
|
||||
// XML. This is not desirable, but the goal of this test is to make sure
|
||||
// we're preserving case-sensitivity.
|
||||
var xmlns = 'xmlns="http://www.w3.org/1999/xhtml"';
|
||||
var goldenXml =
|
||||
'<field ' + xmlns + ' name="VAR"' +
|
||||
' variabletype="' + type + '"' +
|
||||
' id="' + id + '">' + name + '</field>';
|
||||
assertEquals(goldenXml, generatedXml);
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ function check_command {
|
||||
fi
|
||||
}
|
||||
|
||||
check_command scripts/get_geckdriver.sh
|
||||
check_command tests/scripts/get_geckdriver.sh
|
||||
sleep 5
|
||||
check_command scripts/get_selenium.sh
|
||||
check_command tests/scripts/get_selenium.sh
|
||||
sleep 5
|
||||
check_command scripts/get_chromedriver.sh
|
||||
check_command tests/scripts/get_chromedriver.sh
|
||||
sleep 10
|
||||
check_command scripts/selenium_connect.sh
|
||||
check_command tests/scripts/selenium_connect.sh
|
||||
sleep 10
|
||||
|
||||
exit $EXIT_STATUS
|
||||
Reference in New Issue
Block a user