mirror of
https://github.com/google/blockly.git
synced 2026-06-17 00:25:14 +02:00
Merge pull request #2644 from google/rc/Jul_19
July 2019 release candidate (Q2 2019)
This commit is contained in:
@@ -8,6 +8,7 @@ gulpfile.js
|
||||
/tests/compile/*
|
||||
/tests/jsunit/*
|
||||
/tests/generators/*
|
||||
/tests/mocha/run_mocha_tests_in_browser.js
|
||||
/tests/test_runner.js
|
||||
/tests/workspace_svg/*
|
||||
/generators/*
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<!--
|
||||
- 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
|
||||
|
||||
<!-- 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
|
||||
|
||||
<!-- TODO: Please describe what should happen.
|
||||
- Include screenshots if applicable.
|
||||
-->
|
||||
|
||||
### Actual Behavior
|
||||
|
||||
<!-- TODO: Describe what actually happens.
|
||||
- Include screenshots if applicable.
|
||||
-->
|
||||
|
||||
### Steps to Reproduce
|
||||
|
||||
<!-- 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
|
||||
|
||||
<!-- 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()."
|
||||
-->
|
||||
|
||||
```
|
||||
Replace with error stack trace.
|
||||
```
|
||||
|
||||
### Operating System and Browser
|
||||
|
||||
<!-- TODO: If this issue is browser specific, uncomment the systems you have tested. -->
|
||||
|
||||
<!-- * 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]
|
||||
-->
|
||||
|
||||
### Additional Information
|
||||
|
||||
<!-- Anything else we should know? -->
|
||||
@@ -0,0 +1,64 @@
|
||||
<!--
|
||||
- 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
|
||||
-->
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
labels: 'type: bug, triage'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
**To Reproduce**
|
||||
|
||||
<!-- Explain what someone needs to do in order to see what's described above -->
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
**Screenshots**
|
||||
|
||||
<!-- If applicable, add screenshots to help explain your problem. -->
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Stack Traces**
|
||||
|
||||
<!-- 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()."
|
||||
-->
|
||||
|
||||
```
|
||||
Replace with error stack trace.
|
||||
```
|
||||
|
||||
**Additional context**
|
||||
|
||||
<!-- Add any other context about the problem here. -->
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
labels: 'type: feature request, triage'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
|
||||
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
|
||||
|
||||
**Describe the solution you'd like**
|
||||
|
||||
<!-- A clear and concise description of what you want to happen. -->
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
|
||||
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
|
||||
|
||||
**Additional context**
|
||||
|
||||
<!-- Add any other context or screenshots about the feature request here. -->
|
||||
@@ -48,6 +48,12 @@ Tested on:
|
||||
* Version [e.g. 22]
|
||||
-->
|
||||
|
||||
### Documentation
|
||||
|
||||
<!-- TODO: Does any documentation need to be created or updated because of this PR?
|
||||
- If so please explain.
|
||||
-->
|
||||
|
||||
### Additional Information
|
||||
|
||||
<!-- Anything else we should know? -->
|
||||
|
||||
@@ -5,6 +5,7 @@ node_js:
|
||||
- 8
|
||||
- 10
|
||||
addons:
|
||||
firefox: latest
|
||||
apt:
|
||||
packages:
|
||||
- google-chrome-stable
|
||||
|
||||
@@ -8,10 +8,46 @@ blocks together to build programs. All code is free and open source.
|
||||
|
||||

|
||||
|
||||
Blockly has an active [developer forum](https://groups.google.com/forum/#!forum/blockly). Please drop by and say hello. Show us your prototypes early; collectively we have a lot of experience and can offer hints which will save you time.
|
||||
Blockly has an active [developer forum](https://groups.google.com/forum/#!forum/blockly). Please drop by and say hello. Show us your prototypes early; collectively we have a lot of experience and can offer hints which will save you time. We actively monitor the forums and typically respond to questions within 2 working days.
|
||||
|
||||
Help us focus our development efforts by telling us [what you are doing with
|
||||
Blockly](https://developers.google.com/blockly/registration). The questionnaire only takes
|
||||
a few minutes and will help us better support the Blockly community.
|
||||
|
||||
Cross-browser Testing Platform and Open Source <3 Provided by [Sauce Labs](https://saucelabs.com)
|
||||
|
||||
Want to contribute? Great! First, read [our guidelines for contributors](https://developers.google.com/blockly/guides/modify/contributing).
|
||||
|
||||
## Releases
|
||||
|
||||
We release by pushing the latest code to the master branch, followed by updating our [docs](developers.google.com/blockly) and [demo pages](https://blockly-demo.appspot.com). We typically release a new version of Blockly once a quarter (every 3 months). If there are breaking bugs, such as a crash when performing a standard action or a rendering issue that makes Blockly unusable, we will cherry-pick fixes to master between releases to fix them. The [releases page](https://github.com/google/blockly/releases) has a list of all releases.
|
||||
|
||||
Releases are tagged by the release date (YYYYMMDD) with a leading '1.' and a trailing '.0' in case we ever need a major or minor version (such as [1.20190419.0](https://github.com/google/blockly/tree/1.20190419.0)). If you're using npm, a specific release can be installed by using its tag: `npm install git://github.com/google/blockly.git#1.20181219.0`
|
||||
|
||||
### New APIs
|
||||
|
||||
Once a new API is merged into master it is considered beta until the following release. We generally try to avoid changing an API after it has been merged to master, but sometimes we need to make changes after seeing how an API is used. If an API has been around for at least two releases we'll do our best to avoid breaking it.
|
||||
|
||||
Unreleased APIs may change radically. Anything that is in `develop` but not `master` is subject to change without warning.
|
||||
|
||||
### Branches
|
||||
|
||||
There are two main branches for Blockly.
|
||||
|
||||
**[master](https://github.com/google/blockly)** - This is the (mostly) stable current release of Blockly.
|
||||
|
||||
**[develop](https://github.com/google/blockly/tree/develop)** - This is where most of our work happens. Pull requests should always be made against develop. This branch will generally be usable, but may be less stable than the master branch. Once something is in develop we expect it to merge to master in the next release.
|
||||
|
||||
**other branches:** - Larger changes may have their own branches until they are good enough for people to try out. These will be developed separately until we think they are almost ready for release. These branches typically get merged into develop immediately after a release to allow extra time for testing.
|
||||
|
||||
## Issues and Milestones
|
||||
|
||||
We typically triage all bugs within 2 working days, which includes adding any appropriate labels and assigning it to a milestone. Please keep in mind, we are a small team so even feature reqeusts that everyone agrees on may not be prioritized.
|
||||
|
||||
### Milestones
|
||||
|
||||
**Upcoming release** - The upcoming release milestone is for all bugs we plan on fixing before the next release. This typically has the form of `year_quarter_release` (such as `2019_q2_release`). Some bugs will be added to this release when they are triaged, others may be added closer to a release.
|
||||
|
||||
**Bug Bash Backlog** - These are bugs that we're still prioritizing. They haven't been added to a specific release yet, but we'll consider them for each release depending on relative priority and available time.
|
||||
|
||||
**Icebox** - These are bugs that we do not intend to spend time on. They are either too much work or minor enough that we don't expect them to ever take priority. We are still happy to accept pull requests for these bugs.
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
Accessible Blockly
|
||||
==================
|
||||
|
||||
Google's Blockly is a web-based, visual programming editor that is accessible
|
||||
to blind users.
|
||||
|
||||
The code in this directory renders a version of the Blockly toolbox and
|
||||
workspace that is fully keyboard-navigable, and compatible with most screen
|
||||
readers. It is optimized for NVDA on Firefox.
|
||||
|
||||
In the future, Accessible Blockly may be modified to suit accessibility needs
|
||||
other than visual impairments. Note that deaf users are expected to continue
|
||||
using Blockly over Accessible Blockly.
|
||||
|
||||
|
||||
Using Accessible Blockly in Your Web App
|
||||
----------------------------------------
|
||||
The demo at blockly/demos/accessible covers the absolute minimum required to
|
||||
import Accessible Blockly into your web app. You will need to import the files
|
||||
in the same order as in the demo: utils.service.js will need to be the first
|
||||
Angular file imported.
|
||||
|
||||
When the DOMContentLoaded event fires, call ng.platform.browser.bootstrap() on
|
||||
the main component to be loaded. This will usually be blocklyApp.AppComponent,
|
||||
but if you have another component that wraps it, use that one instead.
|
||||
|
||||
|
||||
Customizing the Sidebar and Audio
|
||||
---------------------------------
|
||||
The Accessible Blockly workspace comes with a customizable sidebar.
|
||||
|
||||
To customize the sidebar, you will need to declare an ACCESSIBLE_GLOBALS object
|
||||
in the global scope that looks like this:
|
||||
|
||||
var ACCESSIBLE_GLOBALS = {
|
||||
mediaPathPrefix: null,
|
||||
customSidebarButtons: []
|
||||
};
|
||||
|
||||
The value of mediaPathPrefix should be the location of the accessible/media
|
||||
folder.
|
||||
|
||||
The value of 'customSidebarButtons' should be a list of objects, each
|
||||
representing buttons on the sidebar. Each of these objects should have the
|
||||
following keys:
|
||||
- 'text' (the text to display on the button)
|
||||
- 'action' (the function that gets run when the button is clicked)
|
||||
- 'id' (optional; the id of the button)
|
||||
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
- We do not support having multiple Accessible Blockly apps in a single webpage.
|
||||
- Accessible Blockly does not support the use of shadow blocks.
|
||||
@@ -1,109 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Top-level component for the Accessible Blockly application.
|
||||
* @author madeeha@google.com (Madeeha Ghori)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.AppComponent');
|
||||
|
||||
goog.require('Blockly');
|
||||
|
||||
goog.require('blocklyApp.AudioService');
|
||||
goog.require('blocklyApp.BlockConnectionService');
|
||||
goog.require('blocklyApp.BlockOptionsModalComponent');
|
||||
goog.require('blocklyApp.BlockOptionsModalService');
|
||||
goog.require('blocklyApp.KeyboardInputService');
|
||||
goog.require('blocklyApp.NotificationsService');
|
||||
goog.require('blocklyApp.SidebarComponent');
|
||||
goog.require('blocklyApp.ToolboxModalComponent');
|
||||
goog.require('blocklyApp.ToolboxModalService');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
goog.require('blocklyApp.TreeService');
|
||||
goog.require('blocklyApp.UtilsService');
|
||||
goog.require('blocklyApp.VariableAddModalComponent');
|
||||
goog.require('blocklyApp.VariableModalService');
|
||||
goog.require('blocklyApp.VariableRenameModalComponent');
|
||||
goog.require('blocklyApp.VariableRemoveModalComponent');
|
||||
goog.require('blocklyApp.WorkspaceComponent');
|
||||
|
||||
|
||||
blocklyApp.workspace = new Blockly.Workspace();
|
||||
|
||||
blocklyApp.AppComponent = ng.core.Component({
|
||||
selector: 'blockly-app',
|
||||
template: `
|
||||
<blockly-workspace></blockly-workspace>
|
||||
<blockly-sidebar></blockly-sidebar>
|
||||
<!-- Warning: Hiding this when there is no content looks visually nicer,
|
||||
but it can have unexpected side effects. In particular, it sometimes stops
|
||||
screenreaders from reading anything in this div. -->
|
||||
<div class="blocklyAriaLiveStatus">
|
||||
<span aria-live="polite" role="status">{{getAriaLiveReadout()}}</span>
|
||||
</div>
|
||||
|
||||
<blockly-add-variable-modal></blockly-add-variable-modal>
|
||||
<blockly-rename-variable-modal></blockly-rename-variable-modal>
|
||||
<blockly-remove-variable-modal></blockly-remove-variable-modal>
|
||||
<blockly-toolbox-modal></blockly-toolbox-modal>
|
||||
<blockly-block-options-modal></blockly-block-options-modal>
|
||||
|
||||
<label id="blockly-translate-button" aria-hidden="true" hidden>
|
||||
{{'BUTTON'|translate}}
|
||||
</label>
|
||||
<label id="blockly-translate-workspace-block" aria-hidden="true" hidden>
|
||||
{{'WORKSPACE_BLOCK'|translate}}
|
||||
</label>
|
||||
`,
|
||||
directives: [
|
||||
blocklyApp.BlockOptionsModalComponent,
|
||||
blocklyApp.SidebarComponent,
|
||||
blocklyApp.ToolboxModalComponent,
|
||||
blocklyApp.VariableAddModalComponent,
|
||||
blocklyApp.VariableRenameModalComponent,
|
||||
blocklyApp.VariableRemoveModalComponent,
|
||||
blocklyApp.WorkspaceComponent
|
||||
],
|
||||
pipes: [blocklyApp.TranslatePipe],
|
||||
// All services are declared here, so that all components in the application
|
||||
// use the same instance of the service.
|
||||
// https://www.sitepoint.com/angular-2-components-providers-classes-factories-values/
|
||||
providers: [
|
||||
blocklyApp.AudioService,
|
||||
blocklyApp.BlockConnectionService,
|
||||
blocklyApp.BlockOptionsModalService,
|
||||
blocklyApp.KeyboardInputService,
|
||||
blocklyApp.NotificationsService,
|
||||
blocklyApp.ToolboxModalService,
|
||||
blocklyApp.TreeService,
|
||||
blocklyApp.UtilsService,
|
||||
blocklyApp.VariableModalService
|
||||
]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.NotificationsService, function(notificationsService) {
|
||||
this.notificationsService = notificationsService;
|
||||
}
|
||||
],
|
||||
getAriaLiveReadout: function() {
|
||||
return this.notificationsService.getDisplayedMessage();
|
||||
}
|
||||
});
|
||||
@@ -1,96 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Service for playing audio files.
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.AudioService');
|
||||
|
||||
goog.require('blocklyApp.NotificationsService');
|
||||
|
||||
|
||||
blocklyApp.AudioService = ng.core.Class({
|
||||
constructor: [
|
||||
blocklyApp.NotificationsService, function(notificationsService) {
|
||||
this.notificationsService = notificationsService;
|
||||
|
||||
// We do not play any audio unless a media path prefix is specified.
|
||||
this.canPlayAudio = false;
|
||||
|
||||
if (ACCESSIBLE_GLOBALS.hasOwnProperty('mediaPathPrefix')) {
|
||||
this.canPlayAudio = true;
|
||||
var mediaPathPrefix = ACCESSIBLE_GLOBALS['mediaPathPrefix'];
|
||||
this.AUDIO_PATHS_ = {
|
||||
'connect': mediaPathPrefix + 'click.mp3',
|
||||
'delete': mediaPathPrefix + 'delete.mp3',
|
||||
'oops': mediaPathPrefix + 'oops.mp3'
|
||||
};
|
||||
}
|
||||
|
||||
this.cachedAudioFiles_ = {};
|
||||
// Store callback references here so that they can be removed if a new
|
||||
// call to this.play_() comes in.
|
||||
this.onEndedCallbacks_ = {
|
||||
'connect': [],
|
||||
'delete': [],
|
||||
'oops': []
|
||||
};
|
||||
}
|
||||
],
|
||||
play_: function(audioId, onEndedCallback) {
|
||||
if (this.canPlayAudio) {
|
||||
if (!this.cachedAudioFiles_.hasOwnProperty(audioId)) {
|
||||
this.cachedAudioFiles_[audioId] = new Audio(this.AUDIO_PATHS_[audioId]);
|
||||
}
|
||||
|
||||
if (onEndedCallback) {
|
||||
this.onEndedCallbacks_[audioId].push(onEndedCallback);
|
||||
this.cachedAudioFiles_[audioId].addEventListener(
|
||||
'ended', onEndedCallback);
|
||||
} else {
|
||||
var that = this;
|
||||
this.onEndedCallbacks_[audioId].forEach(function(callback) {
|
||||
that.cachedAudioFiles_[audioId].removeEventListener(
|
||||
'ended', callback);
|
||||
});
|
||||
this.onEndedCallbacks_[audioId].length = 0;
|
||||
}
|
||||
|
||||
this.cachedAudioFiles_[audioId].play();
|
||||
}
|
||||
},
|
||||
playConnectSound: function() {
|
||||
this.play_('connect');
|
||||
},
|
||||
playDeleteSound: function() {
|
||||
this.play_('delete');
|
||||
},
|
||||
playOopsSound: function(optionalStatusMessage) {
|
||||
if (optionalStatusMessage) {
|
||||
var that = this;
|
||||
this.play_('oops', function() {
|
||||
that.notificationsService.speak(optionalStatusMessage);
|
||||
});
|
||||
} else {
|
||||
this.play_('oops');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,135 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Service for handling the mechanics of how blocks
|
||||
* get connected to each other.
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.BlockConnectionService');
|
||||
|
||||
goog.require('blocklyApp.AudioService');
|
||||
goog.require('blocklyApp.NotificationsService');
|
||||
|
||||
|
||||
blocklyApp.BlockConnectionService = ng.core.Class({
|
||||
constructor: [
|
||||
blocklyApp.NotificationsService, blocklyApp.AudioService,
|
||||
function(_notificationsService, _audioService) {
|
||||
this.notificationsService = _notificationsService;
|
||||
this.audioService = _audioService;
|
||||
|
||||
// When a user "adds a link" to a block, the connection representing this
|
||||
// link is stored here.
|
||||
this.markedConnection_ = null;
|
||||
}],
|
||||
findCompatibleConnection_: function(block, targetConnection) {
|
||||
// Locates and returns a connection on the given block that is compatible
|
||||
// with the target connection, if one exists. Returns null if no such
|
||||
// connection exists.
|
||||
// Note: the targetConnection is assumed to be the markedConnection_, or
|
||||
// possibly its counterpart (in the case where the marked connection is
|
||||
// currently attached to another connection). This method therefore ignores
|
||||
// input connections on the given block, since one doesn't usually mark an
|
||||
// output connection and attach a block to it.
|
||||
if (!targetConnection || !targetConnection.getSourceBlock().workspace) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var desiredType = Blockly.OPPOSITE_TYPE[targetConnection.type];
|
||||
var potentialConnection = (
|
||||
desiredType == Blockly.OUTPUT_VALUE ? block.outputConnection :
|
||||
desiredType == Blockly.PREVIOUS_STATEMENT ? block.previousConnection :
|
||||
desiredType == Blockly.NEXT_STATEMENT ? block.nextConnection :
|
||||
null);
|
||||
|
||||
if (potentialConnection &&
|
||||
potentialConnection.checkType_(targetConnection)) {
|
||||
return potentialConnection;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
isAnyConnectionMarked: function() {
|
||||
return Boolean(this.markedConnection_);
|
||||
},
|
||||
getMarkedConnectionSourceBlock: function() {
|
||||
return this.markedConnection_ ?
|
||||
this.markedConnection_.getSourceBlock() : null;
|
||||
},
|
||||
canBeAttachedToMarkedConnection: function(block) {
|
||||
return Boolean(
|
||||
this.findCompatibleConnection_(block, this.markedConnection_));
|
||||
},
|
||||
canBeMovedToMarkedConnection: function(block) {
|
||||
if (!this.markedConnection_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// It should not be possible to move any ancestor of the block containing
|
||||
// the marked connection to the marked connection.
|
||||
var ancestorBlock = this.getMarkedConnectionSourceBlock();
|
||||
while (ancestorBlock) {
|
||||
if (ancestorBlock.id == block.id) {
|
||||
return false;
|
||||
}
|
||||
ancestorBlock = ancestorBlock.getParent();
|
||||
}
|
||||
|
||||
return this.canBeAttachedToMarkedConnection(block);
|
||||
},
|
||||
markConnection: function(connection) {
|
||||
this.markedConnection_ = connection;
|
||||
this.notificationsService.speak(Blockly.Msg.ADDED_LINK_MSG);
|
||||
},
|
||||
attachToMarkedConnection: function(block) {
|
||||
var xml = Blockly.Xml.blockToDom(block);
|
||||
var reconstitutedBlock = Blockly.Xml.domToBlock(xml, blocklyApp.workspace);
|
||||
|
||||
var targetConnection = null;
|
||||
if (this.markedConnection_.targetBlock() &&
|
||||
this.markedConnection_.type == Blockly.PREVIOUS_STATEMENT) {
|
||||
// Is the marked connection a 'previous' connection that is already
|
||||
// connected? If so, find the block that's currently connected to it, and
|
||||
// use that block's 'next' connection as the new marked connection.
|
||||
// Otherwise, splicing does not happen correctly, and inserting a block
|
||||
// in the middle of a group of two linked blocks will split the group.
|
||||
targetConnection = this.markedConnection_.targetConnection;
|
||||
} else {
|
||||
targetConnection = this.markedConnection_;
|
||||
}
|
||||
|
||||
var connection = this.findCompatibleConnection_(
|
||||
reconstitutedBlock, targetConnection);
|
||||
if (connection) {
|
||||
targetConnection.connect(connection);
|
||||
|
||||
this.markedConnection_ = null;
|
||||
this.audioService.playConnectSound();
|
||||
return reconstitutedBlock.id;
|
||||
} else {
|
||||
// We throw an error here, because we expect any UI controls that would
|
||||
// result in a non-connection to be disabled or hidden.
|
||||
throw Error(
|
||||
'Unable to connect block to marked connection. This should not ' +
|
||||
'happen.');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,146 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Component that represents the block options modal.
|
||||
*
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.BlockOptionsModalComponent');
|
||||
|
||||
goog.require('blocklyApp.AudioService');
|
||||
goog.require('blocklyApp.BlockOptionsModalService');
|
||||
goog.require('blocklyApp.KeyboardInputService');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
|
||||
goog.require('Blockly.CommonModal');
|
||||
|
||||
|
||||
blocklyApp.BlockOptionsModalComponent = ng.core.Component({
|
||||
selector: 'blockly-block-options-modal',
|
||||
template: `
|
||||
<div *ngIf="modalIsVisible" class="blocklyModalCurtain"
|
||||
(click)="dismissModal()">
|
||||
<!-- $event.stopPropagation() prevents the modal from closing when its
|
||||
interior is clicked. -->
|
||||
<div id="blockOptionsModal" class="blocklyModal" role="alertdialog"
|
||||
(click)="$event.stopPropagation()" tabindex="-1"
|
||||
aria-labelledby="blockOptionsModalHeading">
|
||||
<h3 id="blockOptionsModalHeading">{{'BLOCK_OPTIONS'|translate}}</h3>
|
||||
<div role="document">
|
||||
<div class="blocklyModalButtonContainer"
|
||||
*ngFor="#buttonInfo of actionButtonsInfo; #buttonIndex=index">
|
||||
<button [id]="getOptionId(buttonIndex)"
|
||||
(click)="buttonInfo.action(); hideModal();"
|
||||
[ngClass]="{activeButton: activeButtonIndex == buttonIndex}">
|
||||
{{buttonInfo.translationIdForText|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="blocklyModalButtonContainer">
|
||||
<button [id]="getCancelOptionId()"
|
||||
(click)="dismissModal()"
|
||||
[ngClass]="{activeButton: activeButtonIndex == actionButtonsInfo.length}">
|
||||
{{'CANCEL'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.BlockOptionsModalService, blocklyApp.KeyboardInputService,
|
||||
blocklyApp.AudioService,
|
||||
function(blockOptionsModalService_, keyboardInputService_, audioService_) {
|
||||
this.blockOptionsModalService = blockOptionsModalService_;
|
||||
this.keyboardInputService = keyboardInputService_;
|
||||
this.audioService = audioService_;
|
||||
|
||||
this.modalIsVisible = false;
|
||||
this.actionButtonsInfo = [];
|
||||
this.activeButtonIndex = -1;
|
||||
this.onDismissCallback = null;
|
||||
|
||||
var that = this;
|
||||
this.blockOptionsModalService.registerPreShowHook(
|
||||
function(newActionButtonsInfo, onDismissCallback) {
|
||||
that.modalIsVisible = true;
|
||||
that.actionButtonsInfo = newActionButtonsInfo;
|
||||
that.activeActionButtonIndex = -1;
|
||||
that.onDismissCallback = onDismissCallback;
|
||||
|
||||
Blockly.CommonModal.setupKeyboardOverrides(that);
|
||||
that.keyboardInputService.addOverride('13', function(evt) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
|
||||
if (that.activeButtonIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
var button = document.getElementById(
|
||||
that.getOptionId(that.activeButtonIndex));
|
||||
if (that.activeButtonIndex <
|
||||
that.actionButtonsInfo.length) {
|
||||
that.actionButtonsInfo[that.activeButtonIndex].action();
|
||||
} else {
|
||||
that.dismissModal();
|
||||
}
|
||||
|
||||
that.hideModal();
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
document.getElementById('blockOptionsModal').focus();
|
||||
}, 150);
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
focusOnOption: function(index) {
|
||||
var button = document.getElementById(this.getOptionId(index));
|
||||
button.focus();
|
||||
},
|
||||
// Counts the number of interactive elements for the modal.
|
||||
numInteractiveElements: function() {
|
||||
return this.actionButtonsInfo.length + 1;
|
||||
},
|
||||
// Returns the ID for the corresponding option button.
|
||||
getOptionId: function(index) {
|
||||
return 'block-options-modal-option-' + index;
|
||||
},
|
||||
// Returns the ID for the "cancel" option button.
|
||||
getCancelOptionId: function() {
|
||||
return this.getOptionId(this.actionButtonsInfo.length);
|
||||
},
|
||||
dismissModal: function() {
|
||||
this.onDismissCallback();
|
||||
this.hideModal();
|
||||
},
|
||||
// Closes the modal.
|
||||
hideModal: function() {
|
||||
this.modalIsVisible = false;
|
||||
this.keyboardInputService.clearOverride();
|
||||
this.blockOptionsModalService.hideModal();
|
||||
}
|
||||
});
|
||||
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Service for the block options modal.
|
||||
*
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.BlockOptionsModalService');
|
||||
|
||||
|
||||
blocklyApp.BlockOptionsModalService = ng.core.Class({
|
||||
constructor: [function() {
|
||||
this.actionButtonsInfo = [];
|
||||
// The aim of the pre-show hook is to populate the modal component with the
|
||||
// information it needs to display the modal (e.g., which action buttons to
|
||||
// display).
|
||||
this.preShowHook = function() {
|
||||
throw Error(
|
||||
'A pre-show hook must be defined for the block options modal ' +
|
||||
'before it can be shown.');
|
||||
};
|
||||
this.modalIsShown = false;
|
||||
this.onDismissCallback = null;
|
||||
}],
|
||||
registerPreShowHook: function(preShowHook) {
|
||||
var that = this;
|
||||
this.preShowHook = function() {
|
||||
preShowHook(that.actionButtonsInfo, that.onDismissCallback);
|
||||
};
|
||||
},
|
||||
isModalShown: function() {
|
||||
return this.modalIsShown;
|
||||
},
|
||||
showModal: function(actionButtonsInfo, onDismissCallback) {
|
||||
this.actionButtonsInfo = actionButtonsInfo;
|
||||
this.onDismissCallback = onDismissCallback;
|
||||
|
||||
this.preShowHook();
|
||||
this.modalIsShown = true;
|
||||
},
|
||||
hideModal: function() {
|
||||
this.modalIsShown = false;
|
||||
}
|
||||
});
|
||||
@@ -1,77 +0,0 @@
|
||||
goog.provide('Blockly.CommonModal');
|
||||
|
||||
|
||||
Blockly.CommonModal = function() {};
|
||||
|
||||
Blockly.CommonModal.setupKeyboardOverrides = function(component) {
|
||||
component.keyboardInputService.setOverride({
|
||||
// Tab key: navigates to the previous or next item in the list.
|
||||
'9': function(evt) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
|
||||
if (evt.shiftKey) {
|
||||
// Move to the previous item in the list.
|
||||
if (component.activeButtonIndex <= 0) {
|
||||
component.activeActionButtonIndex = 0;
|
||||
component.audioService.playOopsSound();
|
||||
} else {
|
||||
component.activeButtonIndex--;
|
||||
}
|
||||
} else {
|
||||
// Move to the next item in the list.
|
||||
if (component.activeButtonIndex == component.numInteractiveElements(component) - 1) {
|
||||
component.audioService.playOopsSound();
|
||||
} else {
|
||||
component.activeButtonIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
component.focusOnOption(component.activeButtonIndex, component);
|
||||
},
|
||||
// Escape key: closes the modal.
|
||||
'27': function() {
|
||||
component.dismissModal();
|
||||
},
|
||||
// Up key: no-op.
|
||||
'38': function(evt) {
|
||||
evt.preventDefault();
|
||||
},
|
||||
// Down key: no-op.
|
||||
'40': function(evt) {
|
||||
evt.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Blockly.CommonModal.getInteractiveElements = function(component) {
|
||||
return Array.prototype.filter.call(
|
||||
component.getInteractiveContainer().elements, function(element) {
|
||||
if (element.type === 'hidden') {
|
||||
return false;
|
||||
}
|
||||
if (element.disabled) {
|
||||
return false;
|
||||
}
|
||||
if (element.tabIndex < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
Blockly.CommonModal.numInteractiveElements = function(component) {
|
||||
var elements = this.getInteractiveElements(component);
|
||||
return elements.length;
|
||||
};
|
||||
|
||||
Blockly.CommonModal.focusOnOption = function(index, component) {
|
||||
var elements = this.getInteractiveElements(component);
|
||||
var button = elements[index];
|
||||
button.focus();
|
||||
};
|
||||
|
||||
Blockly.CommonModal.hideModal = function() {
|
||||
this.modalIsVisible = false;
|
||||
this.keyboardInputService.clearOverride();
|
||||
};
|
||||
@@ -1,206 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Component that renders a "field segment" (a group
|
||||
* of non-editable Blockly.Field followed by 0 or 1 editable Blockly.Field)
|
||||
* in a block. Also handles any interactions with the field.
|
||||
* @author madeeha@google.com (Madeeha Ghori)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.FieldSegmentComponent');
|
||||
|
||||
goog.require('blocklyApp.NotificationsService');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
goog.require('blocklyApp.VariableModalService');
|
||||
|
||||
|
||||
blocklyApp.FieldSegmentComponent = ng.core.Component({
|
||||
selector: 'blockly-field-segment',
|
||||
template: `
|
||||
<template [ngIf]="!mainField">
|
||||
<label [id]="mainFieldId">{{getPrefixText()}}</label>
|
||||
</template>
|
||||
|
||||
<template [ngIf]="mainField">
|
||||
<template [ngIf]="isTextInput()">
|
||||
{{getPrefixText()}}
|
||||
<input [id]="mainFieldId" type="text"
|
||||
[ngModel]="mainField.getValue()" (ngModelChange)="setTextValue($event)"
|
||||
[attr.aria-label]="getFieldDescription() + '. ' + ('PRESS_ENTER_TO_EDIT_TEXT'|translate)"
|
||||
tabindex="-1">
|
||||
</template>
|
||||
|
||||
<template [ngIf]="isNumberInput()">
|
||||
{{getPrefixText()}}
|
||||
<input [id]="mainFieldId" type="number"
|
||||
[ngModel]="mainField.getValue()" (ngModelChange)="setNumberValue($event)"
|
||||
[attr.aria-label]="getFieldDescription() + '. ' + ('PRESS_ENTER_TO_EDIT_NUMBER'|translate)"
|
||||
tabindex="-1">
|
||||
</template>
|
||||
|
||||
<template [ngIf]="isDropdown()">
|
||||
{{getPrefixText()}}
|
||||
<select [id]="mainFieldId" [name]="mainFieldId"
|
||||
[ngModel]="selectedOption" (ngModelChange)="setDropdownValue($event)"
|
||||
(keydown.enter)="selectOption()"
|
||||
tabindex="-1">
|
||||
<option *ngFor="#option of dropdownOptions" value="{{option.value}}">
|
||||
{{option.text}}
|
||||
</option>
|
||||
</select>
|
||||
</template>
|
||||
</template>
|
||||
`,
|
||||
inputs: ['prefixFields', 'mainField', 'mainFieldId', 'level'],
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.NotificationsService,
|
||||
blocklyApp.VariableModalService,
|
||||
function(notificationsService, variableModalService) {
|
||||
this.notificationsService = notificationsService;
|
||||
this.variableModalService = variableModalService;
|
||||
this.dropdownOptions = [];
|
||||
this.rawOptions = [];
|
||||
}],
|
||||
// Angular2 hook - called after initialization.
|
||||
ngAfterContentInit: function() {
|
||||
if (this.mainField) {
|
||||
this.mainField.initModel();
|
||||
}
|
||||
},
|
||||
// Angular2 hook - called to check if the cached component needs an update.
|
||||
ngDoCheck: function() {
|
||||
if (this.isDropdown() && this.shouldBreakCache()) {
|
||||
this.optionValue = this.mainField.getValue();
|
||||
this.fieldValue = this.mainField.getValue();
|
||||
this.rawOptions = this.mainField.getOptions();
|
||||
this.dropdownOptions = this.rawOptions.map(function(valueAndText) {
|
||||
return {
|
||||
text: valueAndText[0],
|
||||
value: valueAndText[1]
|
||||
};
|
||||
});
|
||||
|
||||
// Set the currently selected value to the variable on the field.
|
||||
for (var i = 0; i < this.dropdownOptions.length; i++) {
|
||||
if (this.dropdownOptions[i].text === this.fieldValue) {
|
||||
this.selectedOption = this.dropdownOptions[i].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// Returns whether the mutable, cached information needs to be refreshed.
|
||||
shouldBreakCache: function() {
|
||||
var newOptions = this.mainField.getOptions();
|
||||
if (newOptions.length != this.rawOptions.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.rawOptions.length; i++) {
|
||||
// Compare the value of the cached options with the values in the field.
|
||||
if (newOptions[i][0] != this.rawOptions[i][0]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.fieldValue != this.mainField.getValue()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
// Gets the prefix text, to be printed before a field.
|
||||
getPrefixText: function() {
|
||||
var prefixTexts = this.prefixFields.map(function(prefixField) {
|
||||
return prefixField.getText();
|
||||
});
|
||||
return prefixTexts.join(' ');
|
||||
},
|
||||
// Gets the description, for labeling a field.
|
||||
getFieldDescription: function() {
|
||||
var description = this.mainField.getText();
|
||||
if (this.prefixFields.length > 0) {
|
||||
description = this.getPrefixText() + ': ' + description;
|
||||
}
|
||||
return description;
|
||||
},
|
||||
// Returns true if the field is text input, false otherwise.
|
||||
isTextInput: function() {
|
||||
return this.mainField instanceof Blockly.FieldTextInput &&
|
||||
!(this.mainField instanceof Blockly.FieldNumber);
|
||||
},
|
||||
// Returns true if the field is number input, false otherwise.
|
||||
isNumberInput: function() {
|
||||
return this.mainField instanceof Blockly.FieldNumber;
|
||||
},
|
||||
// Returns true if the field is a dropdown, false otherwise.
|
||||
isDropdown: function() {
|
||||
return this.mainField instanceof Blockly.FieldDropdown;
|
||||
},
|
||||
// Sets the text value on the underlying field.
|
||||
setTextValue: function(newValue) {
|
||||
this.mainField.setValue(newValue);
|
||||
},
|
||||
// Sets the number value on the underlying field.
|
||||
setNumberValue: function(newValue) {
|
||||
// Do not permit a residual value of NaN after a backspace event.
|
||||
this.mainField.setValue(newValue || 0);
|
||||
},
|
||||
// Confirm a selection for dropdown fields.
|
||||
selectOption: function() {
|
||||
if (this.optionValue != Blockly.RENAME_VARIABLE_ID && this.optionValue !=
|
||||
Blockly.DELETE_VARIABLE_ID) {
|
||||
this.mainField.setValue(this.optionValue);
|
||||
}
|
||||
|
||||
if (this.optionValue == Blockly.RENAME_VARIABLE_ID) {
|
||||
this.variableModalService.showRenameModal_(this.mainField.getValue());
|
||||
}
|
||||
|
||||
if (this.optionValue == Blockly.DELETE_VARIABLE_ID) {
|
||||
this.variableModalService.showRemoveModal_(this.mainField.getValue());
|
||||
}
|
||||
},
|
||||
// Sets the value on a dropdown input.
|
||||
setDropdownValue: function(optionValue) {
|
||||
this.optionValue = optionValue;
|
||||
if (this.optionValue == 'NO_ACTION') {
|
||||
return;
|
||||
}
|
||||
|
||||
var optionText = undefined;
|
||||
for (var i = 0; i < this.dropdownOptions.length; i++) {
|
||||
if (this.dropdownOptions[i].value == optionValue) {
|
||||
optionText = this.dropdownOptions[i].text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!optionText) {
|
||||
throw Error(
|
||||
'There is no option text corresponding to the value: ' +
|
||||
this.optionValue);
|
||||
}
|
||||
|
||||
this.notificationsService.speak('Selected option ' + optionText);
|
||||
}
|
||||
});
|
||||
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Service for handling keyboard input.
|
||||
*
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.KeyboardInputService');
|
||||
|
||||
|
||||
blocklyApp.KeyboardInputService = ng.core.Class({
|
||||
constructor: [function() {
|
||||
// Default custom actions for global keystrokes. The keys of this object
|
||||
// are string representations of the key codes.
|
||||
this.keysToActions = {};
|
||||
// Override for the default keysToActions mapping (e.g. in a modal
|
||||
// context).
|
||||
this.keysToActionsOverride = null;
|
||||
|
||||
// Attach a keydown handler to the entire window.
|
||||
var that = this;
|
||||
document.addEventListener('keydown', function(evt) {
|
||||
var stringifiedKeycode = String(evt.keyCode);
|
||||
var actionsObject = that.keysToActionsOverride || that.keysToActions;
|
||||
|
||||
if (actionsObject.hasOwnProperty(stringifiedKeycode)) {
|
||||
actionsObject[stringifiedKeycode](evt);
|
||||
}
|
||||
});
|
||||
}],
|
||||
setOverride: function(newKeysToActions) {
|
||||
this.keysToActionsOverride = newKeysToActions;
|
||||
},
|
||||
addOverride: function(keyCode, action) {
|
||||
this.keysToActionsOverride[keyCode] = action;
|
||||
},
|
||||
clearOverride: function() {
|
||||
this.keysToActionsOverride = null;
|
||||
}
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
This folder contains the following dependencies for accessible Blockly:
|
||||
|
||||
* Angular2 (angular2-all.umd.min.js, angular2-polyfills.min.js)
|
||||
* RxJava (Rx.umd.min)
|
||||
|
||||
Used for data binding between the core Blockly workspace and accessible Blockly.
|
||||
RxJava is required by Angular2.
|
||||
Fetched from https://code.angularjs.org/
|
||||
The current version is 2.0.0-beta.16.
|
||||
|
||||
* ES6 Shim
|
||||
|
||||
Required by Angular2, for Javascript files.
|
||||
Fetched from https://github.com/paulmillr/es6-shim
|
||||
The current version is 0.35.1.
|
||||
Vendored
-748
@@ -1,748 +0,0 @@
|
||||
/**
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2015-2016 Netflix, Inc.
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
/**
|
||||
@license
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2015-2016 Netflix, Inc.
|
||||
|
||||
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.
|
||||
|
||||
**/
|
||||
(function(w){"object"===typeof exports&&"undefined"!==typeof module?module.exports=w():"function"===typeof define&&define.amd?define([],w):("undefined"!==typeof window?window:"undefined"!==typeof global?global:"undefined"!==typeof self?self:this).Rx=w()})(function(){return function a(b,f,g){function k(e,d){if(!f[e]){if(!b[e]){var c="function"==typeof require&&require;if(!d&&c)return c(e,!0);if(l)return l(e,!0);c=Error("Cannot find module '"+e+"'");throw c.code="MODULE_NOT_FOUND",c;}c=f[e]={exports:{}};
|
||||
b[e][0].call(c.exports,function(a){var c=b[e][1][a];return k(c?c:a)},c,c.exports,a,b,f,g)}return f[e].exports}for(var l="function"==typeof require&&require,h=0;h<g.length;h++)k(g[h]);return k}({1:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(h,e,d){a.call(this);this.parent=h;this.outerValue=e;this.outerIndex=d;
|
||||
this.index=0}g(b,a);b.prototype._next=function(a){this.parent.notifyNext(this.outerValue,a,this.outerIndex,this.index++,this)};b.prototype._error=function(a){this.parent.notifyError(a,this);this.unsubscribe()};b.prototype._complete=function(){this.parent.notifyComplete(this);this.unsubscribe()};return b}(a("./Subscriber").Subscriber);f.InnerSubscriber=a},{"./Subscriber":9}],2:[function(a,b,f){var g=a("./Observable");a=function(){function a(b,h,e){this.kind=b;this.value=h;this.exception=e;this.hasValue=
|
||||
"N"===b}a.prototype.observe=function(a){switch(this.kind){case "N":return a.next&&a.next(this.value);case "E":return a.error&&a.error(this.exception);case "C":return a.complete&&a.complete()}};a.prototype["do"]=function(a,b,e){switch(this.kind){case "N":return a&&a(this.value);case "E":return b&&b(this.exception);case "C":return e&&e()}};a.prototype.accept=function(a,b,e){return a&&"function"===typeof a.next?this.observe(a):this["do"](a,b,e)};a.prototype.toObservable=function(){switch(this.kind){case "N":return g.Observable.of(this.value);
|
||||
case "E":return g.Observable["throw"](this.exception);case "C":return g.Observable.empty()}};a.createNext=function(b){return"undefined"!==typeof b?new a("N",b):this.undefinedValueNotification};a.createError=function(b){return new a("E",void 0,b)};a.createComplete=function(){return this.completeNotification};a.completeNotification=new a("C");a.undefinedValueNotification=new a("N",void 0);return a}();f.Notification=a},{"./Observable":3}],3:[function(a,b,f){var g=a("./util/root"),k=a("./util/SymbolShim"),
|
||||
l=a("./util/toSubscriber"),h=a("./util/tryCatch"),e=a("./util/errorObject");a=function(){function a(c){this._isScalar=!1;c&&(this._subscribe=c)}a.prototype.lift=function(c){var m=new a;m.source=this;m.operator=c;return m};a.prototype.subscribe=function(a,d,e){var b=this.operator;a=l.toSubscriber(a,d,e);b?a.add(this._subscribe(b.call(a))):a.add(this._subscribe(a));if(a.syncErrorThrowable&&(a.syncErrorThrowable=!1,a.syncErrorThrown))throw a.syncErrorValue;return a};a.prototype.forEach=function(a,d,
|
||||
n){n||(g.root.Rx&&g.root.Rx.config&&g.root.Rx.config.Promise?n=g.root.Rx.config.Promise:g.root.Promise&&(n=g.root.Promise));if(!n)throw Error("no Promise impl found");var b=this;return new n(function(n,l){b.subscribe(function(n){h.tryCatch(a).call(d,n)===e.errorObject&&l(e.errorObject.e)},l,n)})};a.prototype._subscribe=function(a){return this.source.subscribe(a)};a.prototype[k.SymbolShim.observable]=function(){return this};a.create=function(c){return new a(c)};return a}();f.Observable=a},{"./util/SymbolShim":238,
|
||||
"./util/errorObject":239,"./util/root":249,"./util/toSubscriber":252,"./util/tryCatch":253}],4:[function(a,b,f){f.empty={isUnsubscribed:!0,next:function(a){},error:function(a){throw a;},complete:function(){}}},{}],5:[function(a,b,f){var g=a("./Subscriber");a=function(){function a(){}a.prototype.call=function(a){return new g.Subscriber(a)};return a}();f.Operator=a},{"./Subscriber":9}],6:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&
|
||||
(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(){a.apply(this,arguments)}g(b,a);b.prototype.notifyNext=function(a,e,d,c,m){this.destination.next(e)};b.prototype.notifyError=function(a,e){this.destination.error(a)};b.prototype.notifyComplete=function(a){this.destination.complete()};return b}(a("./Subscriber").Subscriber);f.OuterSubscriber=a},{"./Subscriber":9}],7:[function(a,b,f){b=a("./Subject");f.Subject=b.Subject;b=a("./Observable");f.Observable=
|
||||
b.Observable;a("./add/observable/combineLatest");a("./add/observable/concat");a("./add/observable/merge");a("./add/observable/race");a("./add/observable/bindCallback");a("./add/observable/bindNodeCallback");a("./add/observable/defer");a("./add/observable/empty");a("./add/observable/forkJoin");a("./add/observable/from");a("./add/observable/fromArray");a("./add/observable/fromEvent");a("./add/observable/fromEventPattern");a("./add/observable/fromPromise");a("./add/observable/interval");a("./add/observable/never");
|
||||
a("./add/observable/range");a("./add/observable/throw");a("./add/observable/timer");a("./add/observable/zip");a("./add/operator/buffer");a("./add/operator/bufferCount");a("./add/operator/bufferTime");a("./add/operator/bufferToggle");a("./add/operator/bufferWhen");a("./add/operator/cache");a("./add/operator/catch");a("./add/operator/combineAll");a("./add/operator/combineLatest");a("./add/operator/concat");a("./add/operator/concatAll");a("./add/operator/concatMap");a("./add/operator/concatMapTo");a("./add/operator/count");
|
||||
a("./add/operator/dematerialize");a("./add/operator/debounce");a("./add/operator/debounceTime");a("./add/operator/defaultIfEmpty");a("./add/operator/delay");a("./add/operator/delayWhen");a("./add/operator/distinctUntilChanged");a("./add/operator/do");a("./add/operator/expand");a("./add/operator/filter");a("./add/operator/finally");a("./add/operator/first");a("./add/operator/groupBy");a("./add/operator/ignoreElements");a("./add/operator/inspect");a("./add/operator/inspectTime");a("./add/operator/every");
|
||||
a("./add/operator/last");a("./add/operator/let");a("./add/operator/map");a("./add/operator/mapTo");a("./add/operator/materialize");a("./add/operator/merge");a("./add/operator/mergeAll");a("./add/operator/mergeMap");a("./add/operator/mergeMapTo");a("./add/operator/multicast");a("./add/operator/observeOn");a("./add/operator/partition");a("./add/operator/pluck");a("./add/operator/publish");a("./add/operator/publishBehavior");a("./add/operator/publishReplay");a("./add/operator/publishLast");a("./add/operator/race");
|
||||
a("./add/operator/reduce");a("./add/operator/repeat");a("./add/operator/retry");a("./add/operator/retryWhen");a("./add/operator/sample");a("./add/operator/sampleTime");a("./add/operator/scan");a("./add/operator/share");a("./add/operator/single");a("./add/operator/skip");a("./add/operator/skipUntil");a("./add/operator/skipWhile");a("./add/operator/startWith");a("./add/operator/subscribeOn");a("./add/operator/switch");a("./add/operator/switchMap");a("./add/operator/switchMapTo");a("./add/operator/take");
|
||||
a("./add/operator/takeLast");a("./add/operator/takeUntil");a("./add/operator/takeWhile");a("./add/operator/throttle");a("./add/operator/throttleTime");a("./add/operator/timeout");a("./add/operator/timeoutWith");a("./add/operator/toArray");a("./add/operator/toPromise");a("./add/operator/window");a("./add/operator/windowCount");a("./add/operator/windowTime");a("./add/operator/windowToggle");a("./add/operator/windowWhen");a("./add/operator/withLatestFrom");a("./add/operator/zip");a("./add/operator/zipAll");
|
||||
b=a("./Operator");f.Operator=b.Operator;b=a("./Subscription");f.Subscription=b.Subscription;f.UnsubscriptionError=b.UnsubscriptionError;b=a("./Subscriber");f.Subscriber=b.Subscriber;b=a("./subject/AsyncSubject");f.AsyncSubject=b.AsyncSubject;b=a("./subject/ReplaySubject");f.ReplaySubject=b.ReplaySubject;b=a("./subject/BehaviorSubject");f.BehaviorSubject=b.BehaviorSubject;b=a("./observable/ConnectableObservable");f.ConnectableObservable=b.ConnectableObservable;b=a("./Notification");f.Notification=
|
||||
b.Notification;b=a("./util/EmptyError");f.EmptyError=b.EmptyError;b=a("./util/ArgumentOutOfRangeError");f.ArgumentOutOfRangeError=b.ArgumentOutOfRangeError;b=a("./util/ObjectUnsubscribedError");f.ObjectUnsubscribedError=b.ObjectUnsubscribedError;b=a("./scheduler/asap");var g=a("./scheduler/queue");a=a("./symbol/rxSubscriber");f.Scheduler={asap:b.asap,queue:g.queue};f.Symbol={rxSubscriber:a.rxSubscriber}},{"./Notification":2,"./Observable":3,"./Operator":5,"./Subject":8,"./Subscriber":9,"./Subscription":10,
|
||||
"./add/observable/bindCallback":11,"./add/observable/bindNodeCallback":12,"./add/observable/combineLatest":13,"./add/observable/concat":14,"./add/observable/defer":15,"./add/observable/empty":16,"./add/observable/forkJoin":17,"./add/observable/from":18,"./add/observable/fromArray":19,"./add/observable/fromEvent":20,"./add/observable/fromEventPattern":21,"./add/observable/fromPromise":22,"./add/observable/interval":23,"./add/observable/merge":24,"./add/observable/never":25,"./add/observable/race":26,
|
||||
"./add/observable/range":27,"./add/observable/throw":28,"./add/observable/timer":29,"./add/observable/zip":30,"./add/operator/buffer":31,"./add/operator/bufferCount":32,"./add/operator/bufferTime":33,"./add/operator/bufferToggle":34,"./add/operator/bufferWhen":35,"./add/operator/cache":36,"./add/operator/catch":37,"./add/operator/combineAll":38,"./add/operator/combineLatest":39,"./add/operator/concat":40,"./add/operator/concatAll":41,"./add/operator/concatMap":42,"./add/operator/concatMapTo":43,"./add/operator/count":44,
|
||||
"./add/operator/debounce":45,"./add/operator/debounceTime":46,"./add/operator/defaultIfEmpty":47,"./add/operator/delay":48,"./add/operator/delayWhen":49,"./add/operator/dematerialize":50,"./add/operator/distinctUntilChanged":51,"./add/operator/do":52,"./add/operator/every":53,"./add/operator/expand":54,"./add/operator/filter":55,"./add/operator/finally":56,"./add/operator/first":57,"./add/operator/groupBy":58,"./add/operator/ignoreElements":59,"./add/operator/inspect":60,"./add/operator/inspectTime":61,
|
||||
"./add/operator/last":62,"./add/operator/let":63,"./add/operator/map":64,"./add/operator/mapTo":65,"./add/operator/materialize":66,"./add/operator/merge":67,"./add/operator/mergeAll":68,"./add/operator/mergeMap":69,"./add/operator/mergeMapTo":70,"./add/operator/multicast":71,"./add/operator/observeOn":72,"./add/operator/partition":73,"./add/operator/pluck":74,"./add/operator/publish":75,"./add/operator/publishBehavior":76,"./add/operator/publishLast":77,"./add/operator/publishReplay":78,"./add/operator/race":79,
|
||||
"./add/operator/reduce":80,"./add/operator/repeat":81,"./add/operator/retry":82,"./add/operator/retryWhen":83,"./add/operator/sample":84,"./add/operator/sampleTime":85,"./add/operator/scan":86,"./add/operator/share":87,"./add/operator/single":88,"./add/operator/skip":89,"./add/operator/skipUntil":90,"./add/operator/skipWhile":91,"./add/operator/startWith":92,"./add/operator/subscribeOn":93,"./add/operator/switch":94,"./add/operator/switchMap":95,"./add/operator/switchMapTo":96,"./add/operator/take":97,
|
||||
"./add/operator/takeLast":98,"./add/operator/takeUntil":99,"./add/operator/takeWhile":100,"./add/operator/throttle":101,"./add/operator/throttleTime":102,"./add/operator/timeout":103,"./add/operator/timeoutWith":104,"./add/operator/toArray":105,"./add/operator/toPromise":106,"./add/operator/window":107,"./add/operator/windowCount":108,"./add/operator/windowTime":109,"./add/operator/windowToggle":110,"./add/operator/windowWhen":111,"./add/operator/withLatestFrom":112,"./add/operator/zip":113,"./add/operator/zipAll":114,
|
||||
"./observable/ConnectableObservable":119,"./scheduler/asap":224,"./scheduler/queue":225,"./subject/AsyncSubject":226,"./subject/BehaviorSubject":227,"./subject/ReplaySubject":228,"./symbol/rxSubscriber":230,"./util/ArgumentOutOfRangeError":231,"./util/EmptyError":232,"./util/ObjectUnsubscribedError":237}],8:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var m in c)c.hasOwnProperty(m)&&(a[m]=c[m]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,
|
||||
new d)};b=a("./Observable");var k=a("./Subscriber"),l=a("./Subscription"),h=a("./subject/SubjectSubscription"),e=a("./symbol/rxSubscriber"),d=a("./util/throwError"),c=a("./util/ObjectUnsubscribedError");a=function(a){function b(c,d){a.call(this);this.destination=c;this.source=d;this.observers=[];this.hasCompleted=this.dispatching=this.hasErrored=this.isStopped=this.isUnsubscribed=!1}g(b,a);b.prototype.lift=function(a){var c=new b(this.destination||this,this);c.operator=a;return c};b.prototype.add=
|
||||
function(a){l.Subscription.prototype.add.call(this,a)};b.prototype.remove=function(a){l.Subscription.prototype.remove.call(this,a)};b.prototype.unsubscribe=function(){l.Subscription.prototype.unsubscribe.call(this)};b.prototype._subscribe=function(a){if(this.source)return this.source.subscribe(a);if(!a.isUnsubscribed){if(this.hasErrored)return a.error(this.errorValue);if(this.hasCompleted)return a.complete();this.throwIfUnsubscribed();var c=new h.SubjectSubscription(this,a);this.observers.push(a);
|
||||
return c}};b.prototype._unsubscribe=function(){this.source=null;this.isStopped=!0;this.destination=this.observers=null};b.prototype.next=function(a){this.throwIfUnsubscribed();this.isStopped||(this.dispatching=!0,this._next(a),this.dispatching=!1,this.hasErrored?this._error(this.errorValue):this.hasCompleted&&this._complete())};b.prototype.error=function(a){this.throwIfUnsubscribed();this.isStopped||(this.hasErrored=this.isStopped=!0,this.errorValue=a,this.dispatching||this._error(a))};b.prototype.complete=
|
||||
function(){this.throwIfUnsubscribed();this.isStopped||(this.hasCompleted=this.isStopped=!0,this.dispatching||this._complete())};b.prototype.asObservable=function(){return new m(this)};b.prototype._next=function(a){this.destination?this.destination.next(a):this._finalNext(a)};b.prototype._finalNext=function(a){for(var c=-1,d=this.observers.slice(0),m=d.length;++c<m;)d[c].next(a)};b.prototype._error=function(a){this.destination?this.destination.error(a):this._finalError(a)};b.prototype._finalError=
|
||||
function(a){var c=-1,d=this.observers;this.observers=null;this.isUnsubscribed=!0;if(d)for(var m=d.length;++c<m;)d[c].error(a);this.isUnsubscribed=!1;this.unsubscribe()};b.prototype._complete=function(){this.destination?this.destination.complete():this._finalComplete()};b.prototype._finalComplete=function(){var a=-1,c=this.observers;this.observers=null;this.isUnsubscribed=!0;if(c)for(var d=c.length;++a<d;)c[a].complete();this.isUnsubscribed=!1;this.unsubscribe()};b.prototype.throwIfUnsubscribed=function(){this.isUnsubscribed&&
|
||||
d.throwError(new c.ObjectUnsubscribedError)};b.prototype[e.rxSubscriber]=function(){return new k.Subscriber(this)};b.create=function(a,c){return new b(a,c)};return b}(b.Observable);f.Subject=a;var m=function(a){function c(d){a.call(this);this.source=d}g(c,a);return c}(b.Observable)},{"./Observable":3,"./Subscriber":9,"./Subscription":10,"./subject/SubjectSubscription":229,"./symbol/rxSubscriber":230,"./util/ObjectUnsubscribedError":237,"./util/throwError":251}],9:[function(a,b,f){var g=this&&this.__extends||
|
||||
function(a,c){function m(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(m.prototype=c.prototype,new m)},k=a("./util/isFunction");b=a("./Subscription");var l=a("./symbol/rxSubscriber"),h=a("./Observer");a=function(a){function c(m,n,b){a.call(this);this.syncErrorValue=null;this.isStopped=this.syncErrorThrowable=this.syncErrorThrown=!1;switch(arguments.length){case 0:this.destination=h.empty;break;case 1:if(!m){this.destination=h.empty;break}if("object"===
|
||||
typeof m){m instanceof c?this.destination=m:(this.syncErrorThrowable=!0,this.destination=new e(this,m));break}default:this.syncErrorThrowable=!0,this.destination=new e(this,m,n,b)}}g(c,a);c.create=function(a,d,e){a=new c(a,d,e);a.syncErrorThrowable=!1;return a};c.prototype.next=function(a){this.isStopped||this._next(a)};c.prototype.error=function(a){this.isStopped||(this.isStopped=!0,this._error(a))};c.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())};c.prototype.unsubscribe=
|
||||
function(){this.isUnsubscribed||(this.isStopped=!0,a.prototype.unsubscribe.call(this))};c.prototype._next=function(a){this.destination.next(a)};c.prototype._error=function(a){this.destination.error(a);this.unsubscribe()};c.prototype._complete=function(){this.destination.complete();this.unsubscribe()};c.prototype[l.rxSubscriber]=function(){return this};return c}(b.Subscription);f.Subscriber=a;var e=function(a){function c(c,e,b,h){a.call(this);this._parent=c;var f;c=this;k.isFunction(e)?f=e:e&&(c=e,
|
||||
f=e.next,b=e.error,h=e.complete);this._context=c;this._next=f;this._error=b;this._complete=h}g(c,a);c.prototype.next=function(a){if(!this.isStopped&&this._next){var c=this._parent;c.syncErrorThrowable?this.__tryOrSetError(c,this._next,a)&&this.unsubscribe():this.__tryOrUnsub(this._next,a)}};c.prototype.error=function(a){if(!this.isStopped){var c=this._parent;if(this._error)c.syncErrorThrowable?this.__tryOrSetError(c,this._error,a):this.__tryOrUnsub(this._error,a),this.unsubscribe();else if(c.syncErrorThrowable)c.syncErrorValue=
|
||||
a,c.syncErrorThrown=!0,this.unsubscribe();else throw this.unsubscribe(),a;}};c.prototype.complete=function(){if(!this.isStopped){var a=this._parent;this._complete&&(a.syncErrorThrowable?this.__tryOrSetError(a,this._complete):this.__tryOrUnsub(this._complete));this.unsubscribe()}};c.prototype.__tryOrUnsub=function(a,c){try{a.call(this._context,c)}catch(d){throw this.unsubscribe(),d;}};c.prototype.__tryOrSetError=function(a,c,d){try{c.call(this._context,d)}catch(e){return a.syncErrorValue=e,a.syncErrorThrown=
|
||||
!0}return!1};c.prototype._unsubscribe=function(){var a=this._parent;this._parent=this._context=null;a.unsubscribe()};return c}(a)},{"./Observer":4,"./Subscription":10,"./symbol/rxSubscriber":230,"./util/isFunction":242}],10:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("./util/isArray"),l=a("./util/isObject"),h=a("./util/isFunction"),
|
||||
e=a("./util/tryCatch"),d=a("./util/errorObject");a=function(){function a(c){this.isUnsubscribed=!1;c&&(this._unsubscribe=c)}a.prototype.unsubscribe=function(){var a=!1,m;if(!this.isUnsubscribed){this.isUnsubscribed=!0;var b=this._unsubscribe,f=this._subscriptions;this._subscriptions=null;if(h.isFunction(b)){var g=e.tryCatch(b).call(this);g===d.errorObject&&(a=!0,(m=m||[]).push(d.errorObject.e))}if(k.isArray(f))for(var b=-1,r=f.length;++b<r;)g=f[b],l.isObject(g)&&(g=e.tryCatch(g.unsubscribe).call(g),
|
||||
g===d.errorObject&&(a=!0,m=m||[],g=d.errorObject.e,g instanceof c?m=m.concat(g.errors):m.push(g)));if(a)throw new c(m);}};a.prototype.add=function(c){if(c&&c!==this&&c!==a.EMPTY){var d=c;switch(typeof c){case "function":d=new a(c);case "object":d.isUnsubscribed||"function"!==typeof d.unsubscribe||(this.isUnsubscribed?d.unsubscribe():(this._subscriptions||(this._subscriptions=[])).push(d));break;default:throw Error("Unrecognized subscription "+c+" added to Subscription.");}}};a.prototype.remove=function(c){if(null!=
|
||||
c&&c!==this&&c!==a.EMPTY){var d=this._subscriptions;d&&(c=d.indexOf(c),-1!==c&&d.splice(c,1))}};a.EMPTY=function(a){a.isUnsubscribed=!0;return a}(new a);return a}();f.Subscription=a;var c=function(a){function c(d){a.call(this,"unsubscriptoin error(s)");this.errors=d;this.name="UnsubscriptionError"}g(c,a);return c}(Error);f.UnsubscriptionError=c},{"./util/errorObject":239,"./util/isArray":240,"./util/isFunction":242,"./util/isObject":244,"./util/tryCatch":253}],11:[function(a,b,f){b=a("../../Observable");
|
||||
a=a("../../observable/BoundCallbackObservable");b.Observable.bindCallback=a.BoundCallbackObservable.create},{"../../Observable":3,"../../observable/BoundCallbackObservable":117}],12:[function(a,b,f){b=a("../../Observable");a=a("../../observable/BoundNodeCallbackObservable");b.Observable.bindNodeCallback=a.BoundNodeCallbackObservable.create},{"../../Observable":3,"../../observable/BoundNodeCallbackObservable":118}],13:[function(a,b,f){b=a("../../Observable");a=a("../../operator/combineLatest");b.Observable.combineLatest=
|
||||
a.combineLatestStatic},{"../../Observable":3,"../../operator/combineLatest":143}],14:[function(a,b,f){b=a("../../Observable");a=a("../../operator/concat");b.Observable.concat=a.concatStatic},{"../../Observable":3,"../../operator/concat":144}],15:[function(a,b,f){b=a("../../Observable");a=a("../../observable/DeferObservable");b.Observable.defer=a.DeferObservable.create},{"../../Observable":3,"../../observable/DeferObservable":120}],16:[function(a,b,f){b=a("../../Observable");a=a("../../observable/EmptyObservable");
|
||||
b.Observable.empty=a.EmptyObservable.create},{"../../Observable":3,"../../observable/EmptyObservable":121}],17:[function(a,b,f){b=a("../../Observable");a=a("../../observable/ForkJoinObservable");b.Observable.forkJoin=a.ForkJoinObservable.create},{"../../Observable":3,"../../observable/ForkJoinObservable":123}],18:[function(a,b,f){b=a("../../Observable");a=a("../../observable/FromObservable");b.Observable.from=a.FromObservable.create},{"../../Observable":3,"../../observable/FromObservable":126}],19:[function(a,
|
||||
b,f){b=a("../../Observable");a=a("../../observable/ArrayObservable");b.Observable.fromArray=a.ArrayObservable.create;b.Observable.of=a.ArrayObservable.of},{"../../Observable":3,"../../observable/ArrayObservable":116}],20:[function(a,b,f){b=a("../../Observable");a=a("../../observable/FromEventObservable");b.Observable.fromEvent=a.FromEventObservable.create},{"../../Observable":3,"../../observable/FromEventObservable":124}],21:[function(a,b,f){b=a("../../Observable");a=a("../../observable/FromEventPatternObservable");
|
||||
b.Observable.fromEventPattern=a.FromEventPatternObservable.create},{"../../Observable":3,"../../observable/FromEventPatternObservable":125}],22:[function(a,b,f){b=a("../../Observable");a=a("../../observable/PromiseObservable");b.Observable.fromPromise=a.PromiseObservable.create},{"../../Observable":3,"../../observable/PromiseObservable":130}],23:[function(a,b,f){b=a("../../Observable");a=a("../../observable/IntervalObservable");b.Observable.interval=a.IntervalObservable.create},{"../../Observable":3,
|
||||
"../../observable/IntervalObservable":127}],24:[function(a,b,f){b=a("../../Observable");a=a("../../operator/merge");b.Observable.merge=a.mergeStatic},{"../../Observable":3,"../../operator/merge":171}],25:[function(a,b,f){b=a("../../Observable");a=a("../../observable/NeverObservable");b.Observable.never=a.NeverObservable.create},{"../../Observable":3,"../../observable/NeverObservable":129}],26:[function(a,b,f){b=a("../../Observable");a=a("../../operator/race");b.Observable.race=a.raceStatic},{"../../Observable":3,
|
||||
"../../operator/race":183}],27:[function(a,b,f){b=a("../../Observable");a=a("../../observable/RangeObservable");b.Observable.range=a.RangeObservable.create},{"../../Observable":3,"../../observable/RangeObservable":131}],28:[function(a,b,f){b=a("../../Observable");a=a("../../observable/ErrorObservable");b.Observable["throw"]=a.ErrorObservable.create},{"../../Observable":3,"../../observable/ErrorObservable":122}],29:[function(a,b,f){b=a("../../Observable");a=a("../../observable/TimerObservable");b.Observable.timer=
|
||||
a.TimerObservable.create},{"../../Observable":3,"../../observable/TimerObservable":134}],30:[function(a,b,f){b=a("../../Observable");a=a("../../operator/zip");b.Observable.zip=a.zipStatic},{"../../Observable":3,"../../operator/zip":217}],31:[function(a,b,f){b=a("../../Observable");a=a("../../operator/buffer");b.Observable.prototype.buffer=a.buffer},{"../../Observable":3,"../../operator/buffer":135}],32:[function(a,b,f){b=a("../../Observable");a=a("../../operator/bufferCount");b.Observable.prototype.bufferCount=
|
||||
a.bufferCount},{"../../Observable":3,"../../operator/bufferCount":136}],33:[function(a,b,f){b=a("../../Observable");a=a("../../operator/bufferTime");b.Observable.prototype.bufferTime=a.bufferTime},{"../../Observable":3,"../../operator/bufferTime":137}],34:[function(a,b,f){b=a("../../Observable");a=a("../../operator/bufferToggle");b.Observable.prototype.bufferToggle=a.bufferToggle},{"../../Observable":3,"../../operator/bufferToggle":138}],35:[function(a,b,f){b=a("../../Observable");a=a("../../operator/bufferWhen");
|
||||
b.Observable.prototype.bufferWhen=a.bufferWhen},{"../../Observable":3,"../../operator/bufferWhen":139}],36:[function(a,b,f){b=a("../../Observable");a=a("../../operator/cache");b.Observable.prototype.cache=a.cache},{"../../Observable":3,"../../operator/cache":140}],37:[function(a,b,f){b=a("../../Observable");a=a("../../operator/catch");b.Observable.prototype["catch"]=a._catch},{"../../Observable":3,"../../operator/catch":141}],38:[function(a,b,f){b=a("../../Observable");a=a("../../operator/combineAll");
|
||||
b.Observable.prototype.combineAll=a.combineAll},{"../../Observable":3,"../../operator/combineAll":142}],39:[function(a,b,f){b=a("../../Observable");a=a("../../operator/combineLatest");b.Observable.prototype.combineLatest=a.combineLatest},{"../../Observable":3,"../../operator/combineLatest":143}],40:[function(a,b,f){b=a("../../Observable");a=a("../../operator/concat");b.Observable.prototype.concat=a.concat},{"../../Observable":3,"../../operator/concat":144}],41:[function(a,b,f){b=a("../../Observable");
|
||||
a=a("../../operator/concatAll");b.Observable.prototype.concatAll=a.concatAll},{"../../Observable":3,"../../operator/concatAll":145}],42:[function(a,b,f){b=a("../../Observable");a=a("../../operator/concatMap");b.Observable.prototype.concatMap=a.concatMap},{"../../Observable":3,"../../operator/concatMap":146}],43:[function(a,b,f){b=a("../../Observable");a=a("../../operator/concatMapTo");b.Observable.prototype.concatMapTo=a.concatMapTo},{"../../Observable":3,"../../operator/concatMapTo":147}],44:[function(a,
|
||||
b,f){b=a("../../Observable");a=a("../../operator/count");b.Observable.prototype.count=a.count},{"../../Observable":3,"../../operator/count":148}],45:[function(a,b,f){b=a("../../Observable");a=a("../../operator/debounce");b.Observable.prototype.debounce=a.debounce},{"../../Observable":3,"../../operator/debounce":149}],46:[function(a,b,f){b=a("../../Observable");a=a("../../operator/debounceTime");b.Observable.prototype.debounceTime=a.debounceTime},{"../../Observable":3,"../../operator/debounceTime":150}],
|
||||
47:[function(a,b,f){b=a("../../Observable");a=a("../../operator/defaultIfEmpty");b.Observable.prototype.defaultIfEmpty=a.defaultIfEmpty},{"../../Observable":3,"../../operator/defaultIfEmpty":151}],48:[function(a,b,f){b=a("../../Observable");a=a("../../operator/delay");b.Observable.prototype.delay=a.delay},{"../../Observable":3,"../../operator/delay":152}],49:[function(a,b,f){b=a("../../Observable");a=a("../../operator/delayWhen");b.Observable.prototype.delayWhen=a.delayWhen},{"../../Observable":3,
|
||||
"../../operator/delayWhen":153}],50:[function(a,b,f){b=a("../../Observable");a=a("../../operator/dematerialize");b.Observable.prototype.dematerialize=a.dematerialize},{"../../Observable":3,"../../operator/dematerialize":154}],51:[function(a,b,f){b=a("../../Observable");a=a("../../operator/distinctUntilChanged");b.Observable.prototype.distinctUntilChanged=a.distinctUntilChanged},{"../../Observable":3,"../../operator/distinctUntilChanged":155}],52:[function(a,b,f){b=a("../../Observable");a=a("../../operator/do");
|
||||
b.Observable.prototype["do"]=a._do},{"../../Observable":3,"../../operator/do":156}],53:[function(a,b,f){b=a("../../Observable");a=a("../../operator/every");b.Observable.prototype.every=a.every},{"../../Observable":3,"../../operator/every":157}],54:[function(a,b,f){b=a("../../Observable");a=a("../../operator/expand");b.Observable.prototype.expand=a.expand},{"../../Observable":3,"../../operator/expand":158}],55:[function(a,b,f){b=a("../../Observable");a=a("../../operator/filter");b.Observable.prototype.filter=
|
||||
a.filter},{"../../Observable":3,"../../operator/filter":159}],56:[function(a,b,f){b=a("../../Observable");a=a("../../operator/finally");b.Observable.prototype["finally"]=a._finally},{"../../Observable":3,"../../operator/finally":160}],57:[function(a,b,f){b=a("../../Observable");a=a("../../operator/first");b.Observable.prototype.first=a.first},{"../../Observable":3,"../../operator/first":161}],58:[function(a,b,f){b=a("../../Observable");a=a("../../operator/groupBy");b.Observable.prototype.groupBy=
|
||||
a.groupBy},{"../../Observable":3,"../../operator/groupBy":162}],59:[function(a,b,f){b=a("../../Observable");a=a("../../operator/ignoreElements");b.Observable.prototype.ignoreElements=a.ignoreElements},{"../../Observable":3,"../../operator/ignoreElements":163}],60:[function(a,b,f){b=a("../../Observable");a=a("../../operator/inspect");b.Observable.prototype.inspect=a.inspect},{"../../Observable":3,"../../operator/inspect":164}],61:[function(a,b,f){b=a("../../Observable");a=a("../../operator/inspectTime");
|
||||
b.Observable.prototype.inspectTime=a.inspectTime},{"../../Observable":3,"../../operator/inspectTime":165}],62:[function(a,b,f){b=a("../../Observable");a=a("../../operator/last");b.Observable.prototype.last=a.last},{"../../Observable":3,"../../operator/last":166}],63:[function(a,b,f){b=a("../../Observable");a=a("../../operator/let");b.Observable.prototype.let=a.letProto;b.Observable.prototype.letBind=a.letProto},{"../../Observable":3,"../../operator/let":167}],64:[function(a,b,f){b=a("../../Observable");
|
||||
a=a("../../operator/map");b.Observable.prototype.map=a.map},{"../../Observable":3,"../../operator/map":168}],65:[function(a,b,f){b=a("../../Observable");a=a("../../operator/mapTo");b.Observable.prototype.mapTo=a.mapTo},{"../../Observable":3,"../../operator/mapTo":169}],66:[function(a,b,f){b=a("../../Observable");a=a("../../operator/materialize");b.Observable.prototype.materialize=a.materialize},{"../../Observable":3,"../../operator/materialize":170}],67:[function(a,b,f){b=a("../../Observable");a=
|
||||
a("../../operator/merge");b.Observable.prototype.merge=a.merge},{"../../Observable":3,"../../operator/merge":171}],68:[function(a,b,f){b=a("../../Observable");a=a("../../operator/mergeAll");b.Observable.prototype.mergeAll=a.mergeAll},{"../../Observable":3,"../../operator/mergeAll":172}],69:[function(a,b,f){b=a("../../Observable");a=a("../../operator/mergeMap");b.Observable.prototype.mergeMap=a.mergeMap;b.Observable.prototype.flatMap=a.mergeMap},{"../../Observable":3,"../../operator/mergeMap":173}],
|
||||
70:[function(a,b,f){b=a("../../Observable");a=a("../../operator/mergeMapTo");b.Observable.prototype.mergeMapTo=a.mergeMapTo},{"../../Observable":3,"../../operator/mergeMapTo":174}],71:[function(a,b,f){b=a("../../Observable");a=a("../../operator/multicast");b.Observable.prototype.multicast=a.multicast},{"../../Observable":3,"../../operator/multicast":175}],72:[function(a,b,f){b=a("../../Observable");a=a("../../operator/observeOn");b.Observable.prototype.observeOn=a.observeOn},{"../../Observable":3,
|
||||
"../../operator/observeOn":176}],73:[function(a,b,f){b=a("../../Observable");a=a("../../operator/partition");b.Observable.prototype.partition=a.partition},{"../../Observable":3,"../../operator/partition":177}],74:[function(a,b,f){b=a("../../Observable");a=a("../../operator/pluck");b.Observable.prototype.pluck=a.pluck},{"../../Observable":3,"../../operator/pluck":178}],75:[function(a,b,f){b=a("../../Observable");a=a("../../operator/publish");b.Observable.prototype.publish=a.publish},{"../../Observable":3,
|
||||
"../../operator/publish":179}],76:[function(a,b,f){b=a("../../Observable");a=a("../../operator/publishBehavior");b.Observable.prototype.publishBehavior=a.publishBehavior},{"../../Observable":3,"../../operator/publishBehavior":180}],77:[function(a,b,f){b=a("../../Observable");a=a("../../operator/publishLast");b.Observable.prototype.publishLast=a.publishLast},{"../../Observable":3,"../../operator/publishLast":181}],78:[function(a,b,f){b=a("../../Observable");a=a("../../operator/publishReplay");b.Observable.prototype.publishReplay=
|
||||
a.publishReplay},{"../../Observable":3,"../../operator/publishReplay":182}],79:[function(a,b,f){b=a("../../Observable");a=a("../../operator/race");b.Observable.prototype.race=a.race},{"../../Observable":3,"../../operator/race":183}],80:[function(a,b,f){b=a("../../Observable");a=a("../../operator/reduce");b.Observable.prototype.reduce=a.reduce},{"../../Observable":3,"../../operator/reduce":184}],81:[function(a,b,f){b=a("../../Observable");a=a("../../operator/repeat");b.Observable.prototype.repeat=
|
||||
a.repeat},{"../../Observable":3,"../../operator/repeat":185}],82:[function(a,b,f){b=a("../../Observable");a=a("../../operator/retry");b.Observable.prototype.retry=a.retry},{"../../Observable":3,"../../operator/retry":186}],83:[function(a,b,f){b=a("../../Observable");a=a("../../operator/retryWhen");b.Observable.prototype.retryWhen=a.retryWhen},{"../../Observable":3,"../../operator/retryWhen":187}],84:[function(a,b,f){b=a("../../Observable");a=a("../../operator/sample");b.Observable.prototype.sample=
|
||||
a.sample},{"../../Observable":3,"../../operator/sample":188}],85:[function(a,b,f){b=a("../../Observable");a=a("../../operator/sampleTime");b.Observable.prototype.sampleTime=a.sampleTime},{"../../Observable":3,"../../operator/sampleTime":189}],86:[function(a,b,f){b=a("../../Observable");a=a("../../operator/scan");b.Observable.prototype.scan=a.scan},{"../../Observable":3,"../../operator/scan":190}],87:[function(a,b,f){b=a("../../Observable");a=a("../../operator/share");b.Observable.prototype.share=
|
||||
a.share},{"../../Observable":3,"../../operator/share":191}],88:[function(a,b,f){b=a("../../Observable");a=a("../../operator/single");b.Observable.prototype.single=a.single},{"../../Observable":3,"../../operator/single":192}],89:[function(a,b,f){b=a("../../Observable");a=a("../../operator/skip");b.Observable.prototype.skip=a.skip},{"../../Observable":3,"../../operator/skip":193}],90:[function(a,b,f){b=a("../../Observable");a=a("../../operator/skipUntil");b.Observable.prototype.skipUntil=a.skipUntil},
|
||||
{"../../Observable":3,"../../operator/skipUntil":194}],91:[function(a,b,f){b=a("../../Observable");a=a("../../operator/skipWhile");b.Observable.prototype.skipWhile=a.skipWhile},{"../../Observable":3,"../../operator/skipWhile":195}],92:[function(a,b,f){b=a("../../Observable");a=a("../../operator/startWith");b.Observable.prototype.startWith=a.startWith},{"../../Observable":3,"../../operator/startWith":196}],93:[function(a,b,f){b=a("../../Observable");a=a("../../operator/subscribeOn");b.Observable.prototype.subscribeOn=
|
||||
a.subscribeOn},{"../../Observable":3,"../../operator/subscribeOn":197}],94:[function(a,b,f){b=a("../../Observable");a=a("../../operator/switch");b.Observable.prototype["switch"]=a._switch},{"../../Observable":3,"../../operator/switch":198}],95:[function(a,b,f){b=a("../../Observable");a=a("../../operator/switchMap");b.Observable.prototype.switchMap=a.switchMap},{"../../Observable":3,"../../operator/switchMap":199}],96:[function(a,b,f){b=a("../../Observable");a=a("../../operator/switchMapTo");b.Observable.prototype.switchMapTo=
|
||||
a.switchMapTo},{"../../Observable":3,"../../operator/switchMapTo":200}],97:[function(a,b,f){b=a("../../Observable");a=a("../../operator/take");b.Observable.prototype.take=a.take},{"../../Observable":3,"../../operator/take":201}],98:[function(a,b,f){b=a("../../Observable");a=a("../../operator/takeLast");b.Observable.prototype.takeLast=a.takeLast},{"../../Observable":3,"../../operator/takeLast":202}],99:[function(a,b,f){b=a("../../Observable");a=a("../../operator/takeUntil");b.Observable.prototype.takeUntil=
|
||||
a.takeUntil},{"../../Observable":3,"../../operator/takeUntil":203}],100:[function(a,b,f){b=a("../../Observable");a=a("../../operator/takeWhile");b.Observable.prototype.takeWhile=a.takeWhile},{"../../Observable":3,"../../operator/takeWhile":204}],101:[function(a,b,f){b=a("../../Observable");a=a("../../operator/throttle");b.Observable.prototype.throttle=a.throttle},{"../../Observable":3,"../../operator/throttle":205}],102:[function(a,b,f){b=a("../../Observable");a=a("../../operator/throttleTime");b.Observable.prototype.throttleTime=
|
||||
a.throttleTime},{"../../Observable":3,"../../operator/throttleTime":206}],103:[function(a,b,f){b=a("../../Observable");a=a("../../operator/timeout");b.Observable.prototype.timeout=a.timeout},{"../../Observable":3,"../../operator/timeout":207}],104:[function(a,b,f){b=a("../../Observable");a=a("../../operator/timeoutWith");b.Observable.prototype.timeoutWith=a.timeoutWith},{"../../Observable":3,"../../operator/timeoutWith":208}],105:[function(a,b,f){b=a("../../Observable");a=a("../../operator/toArray");
|
||||
b.Observable.prototype.toArray=a.toArray},{"../../Observable":3,"../../operator/toArray":209}],106:[function(a,b,f){b=a("../../Observable");a=a("../../operator/toPromise");b.Observable.prototype.toPromise=a.toPromise},{"../../Observable":3,"../../operator/toPromise":210}],107:[function(a,b,f){b=a("../../Observable");a=a("../../operator/window");b.Observable.prototype.window=a.window},{"../../Observable":3,"../../operator/window":211}],108:[function(a,b,f){b=a("../../Observable");a=a("../../operator/windowCount");
|
||||
b.Observable.prototype.windowCount=a.windowCount},{"../../Observable":3,"../../operator/windowCount":212}],109:[function(a,b,f){b=a("../../Observable");a=a("../../operator/windowTime");b.Observable.prototype.windowTime=a.windowTime},{"../../Observable":3,"../../operator/windowTime":213}],110:[function(a,b,f){b=a("../../Observable");a=a("../../operator/windowToggle");b.Observable.prototype.windowToggle=a.windowToggle},{"../../Observable":3,"../../operator/windowToggle":214}],111:[function(a,b,f){b=
|
||||
a("../../Observable");a=a("../../operator/windowWhen");b.Observable.prototype.windowWhen=a.windowWhen},{"../../Observable":3,"../../operator/windowWhen":215}],112:[function(a,b,f){b=a("../../Observable");a=a("../../operator/withLatestFrom");b.Observable.prototype.withLatestFrom=a.withLatestFrom},{"../../Observable":3,"../../operator/withLatestFrom":216}],113:[function(a,b,f){b=a("../../Observable");a=a("../../operator/zip");b.Observable.prototype.zip=a.zipProto},{"../../Observable":3,"../../operator/zip":217}],
|
||||
114:[function(a,b,f){b=a("../../Observable");a=a("../../operator/zipAll");b.Observable.prototype.zipAll=a.zipAll},{"../../Observable":3,"../../operator/zipAll":218}],115:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};b=a("../Observable");var k=a("./ScalarObservable"),l=a("./EmptyObservable");a=function(a){function e(d,c,e,n){a.call(this);
|
||||
this.arrayLike=d;this.scheduler=n;c||n||1!==d.length||(this._isScalar=!0,this.value=d[0]);c&&(this.mapFn=c.bind(e))}g(e,a);e.create=function(a,c,m,n){var b=a.length;return 0===b?new l.EmptyObservable:1!==b||c?new e(a,c,m,n):new k.ScalarObservable(a[0],n)};e.dispatch=function(a){var c=a.arrayLike,e=a.index,n=a.length,b=a.mapFn,h=a.subscriber;h.isUnsubscribed||(e>=n?h.complete():(c=b?b(c[e],e):c[e],h.next(c),a.index=e+1,this.schedule(a)))};e.prototype._subscribe=function(a){var c=this.arrayLike,m=this.mapFn,
|
||||
n=this.scheduler,b=c.length;if(n)return n.schedule(e.dispatch,0,{arrayLike:c,index:0,length:b,mapFn:m,subscriber:a});for(n=0;n<b&&!a.isUnsubscribed;n++){var h=m?m(c[n],n):c[n];a.next(h)}a.complete()};return e}(b.Observable);f.ArrayLikeObservable=a},{"../Observable":3,"./EmptyObservable":121,"./ScalarObservable":132}],116:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var m in d)d.hasOwnProperty(m)&&(a[m]=d[m]);a.prototype=null===d?Object.create(d):(c.prototype=
|
||||
d.prototype,new c)};b=a("../Observable");var k=a("./ScalarObservable"),l=a("./EmptyObservable"),h=a("../util/isScheduler");a=function(a){function d(c,d){a.call(this);this.array=c;this.scheduler=d;d||1!==c.length||(this._isScalar=!0,this.value=c[0])}g(d,a);d.create=function(a,e){return new d(a,e)};d.of=function(){for(var a=[],e=0;e<arguments.length;e++)a[e-0]=arguments[e];e=a[a.length-1];h.isScheduler(e)?a.pop():e=null;var n=a.length;return 1<n?new d(a,e):1===n?new k.ScalarObservable(a[0],e):new l.EmptyObservable(e)};
|
||||
d.dispatch=function(a){var d=a.array,e=a.index,b=a.subscriber;e>=a.count?b.complete():(b.next(d[e]),b.isUnsubscribed||(a.index=e+1,this.schedule(a)))};d.prototype._subscribe=function(a){var e=this.array,n=e.length,b=this.scheduler;if(b)return b.schedule(d.dispatch,0,{array:e,index:0,count:n,subscriber:a});for(b=0;b<n&&!a.isUnsubscribed;b++)a.next(e[b]);a.complete()};return d}(b.Observable);f.ArrayObservable=a},{"../Observable":3,"../util/isScheduler":246,"./EmptyObservable":121,"./ScalarObservable":132}],
|
||||
117:[function(a,b,f){function g(a){var n=this,b=a.source;a=a.subscriber;var h=b.callbackFunc,f=b.args,g=b.scheduler,r=b.subject;if(!r){var r=b.subject=new c.AsyncSubject,v=function x(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];var m=x.source,c=m.selector,m=m.subject;c?(a=e.tryCatch(c).apply(this,a),a===d.errorObject?n.add(g.schedule(l,0,{err:d.errorObject.e,subject:m})):n.add(g.schedule(k,0,{value:a,subject:m}))):n.add(g.schedule(k,0,{value:1===a.length?a[0]:a,subject:m}))};v.source=
|
||||
b;e.tryCatch(h).apply(this,f.concat(v))===d.errorObject&&r.error(d.errorObject.e)}n.add(r.subscribe(a))}function k(a){var c=a.subject;c.next(a.value);c.complete()}function l(a){a.subject.error(a.err)}var h=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Observable");var e=a("../util/tryCatch"),d=a("../util/errorObject"),c=a("../subject/AsyncSubject");a=
|
||||
function(a){function n(c,d,e,n){a.call(this);this.callbackFunc=c;this.selector=d;this.args=e;this.scheduler=n}h(n,a);n.create=function(a,c,d){void 0===c&&(c=void 0);return function(){for(var e=[],m=0;m<arguments.length;m++)e[m-0]=arguments[m];return new n(a,c,e,d)}};n.prototype._subscribe=function(a){var m=this.callbackFunc,n=this.args,b=this.scheduler,h=this.subject;if(b)return b.schedule(g,0,{source:this,subscriber:a});h||(h=this.subject=new c.AsyncSubject,b=function y(){for(var a=[],c=0;c<arguments.length;c++)a[c-
|
||||
0]=arguments[c];var m=y.source,c=m.selector,m=m.subject;c?(a=e.tryCatch(c).apply(this,a),a===d.errorObject?m.error(d.errorObject.e):(m.next(a),m.complete())):(m.next(1===a.length?a[0]:a),m.complete())},b.source=this,e.tryCatch(m).apply(this,n.concat(b))===d.errorObject&&h.error(d.errorObject.e));return h.subscribe(a)};return n}(b.Observable);f.BoundCallbackObservable=a},{"../Observable":3,"../subject/AsyncSubject":226,"../util/errorObject":239,"../util/tryCatch":253}],118:[function(a,b,f){function g(a){var n=
|
||||
this,b=a.source;a=a.subscriber;var h=b.callbackFunc,f=b.args,g=b.scheduler,r=b.subject;if(!r){var r=b.subject=new c.AsyncSubject,v=function x(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];var m=x.source,c=m.selector,m=m.subject,b=a.shift();b?m.error(b):c?(a=e.tryCatch(c).apply(this,a),a===d.errorObject?n.add(g.schedule(l,0,{err:d.errorObject.e,subject:m})):n.add(g.schedule(k,0,{value:a,subject:m}))):n.add(g.schedule(k,0,{value:1===a.length?a[0]:a,subject:m}))};v.source=b;e.tryCatch(h).apply(this,
|
||||
f.concat(v))===d.errorObject&&r.error(d.errorObject.e)}n.add(r.subscribe(a))}function k(a){var c=a.subject;c.next(a.value);c.complete()}function l(a){a.subject.error(a.err)}var h=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Observable");var e=a("../util/tryCatch"),d=a("../util/errorObject"),c=a("../subject/AsyncSubject");a=function(a){function b(c,d,
|
||||
e,n){a.call(this);this.callbackFunc=c;this.selector=d;this.args=e;this.scheduler=n}h(b,a);b.create=function(a,c,d){void 0===c&&(c=void 0);return function(){for(var e=[],m=0;m<arguments.length;m++)e[m-0]=arguments[m];return new b(a,c,e,d)}};b.prototype._subscribe=function(a){var m=this.callbackFunc,b=this.args,n=this.scheduler,h=this.subject;if(n)return n.schedule(g,0,{source:this,subscriber:a});h||(h=this.subject=new c.AsyncSubject,n=function y(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];
|
||||
var m=y.source,c=m.selector,m=m.subject,b=a.shift();b?m.error(b):c?(a=e.tryCatch(c).apply(this,a),a===d.errorObject?m.error(d.errorObject.e):(m.next(a),m.complete())):(m.next(1===a.length?a[0]:a),m.complete())},n.source=this,e.tryCatch(m).apply(this,b.concat(n))===d.errorObject&&h.error(d.errorObject.e));return h.subscribe(a)};return b}(b.Observable);f.BoundNodeCallbackObservable=a},{"../Observable":3,"../subject/AsyncSubject":226,"../util/errorObject":239,"../util/tryCatch":253}],119:[function(a,
|
||||
b,f){var g=this&&this.__extends||function(a,d){function e(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(e.prototype=d.prototype,new e)};b=a("../Observable");var k=a("../Subscriber");a=a("../Subscription");var l=function(a){function d(e,m){a.call(this);this.source=e;this.subjectFactory=m}g(d,a);d.prototype._subscribe=function(a){return this.getSubject().subscribe(a)};d.prototype.getSubject=function(){var a=this.subject;return a&&!a.isUnsubscribed?
|
||||
a:this.subject=this.subjectFactory()};d.prototype.connect=function(){var a=this.subscription;if(a&&!a.isUnsubscribed)return a;a=this.source.subscribe(this.getSubject());a.add(new h(this));return this.subscription=a};d.prototype.refCount=function(){return new e(this)};d.prototype._closeSubscription=function(){this.subscription=this.subject=null};return d}(b.Observable);f.ConnectableObservable=l;var h=function(a){function d(e){a.call(this);this.connectable=e}g(d,a);d.prototype._unsubscribe=function(){this.connectable._closeSubscription();
|
||||
this.connectable=null};return d}(a.Subscription),e=function(a){function e(d,m){void 0===m&&(m=0);a.call(this);this.connectable=d;this.refCount=m}g(e,a);e.prototype._subscribe=function(a){var c=this.connectable;a=new d(a,this);var e=c.subscribe(a);e.isUnsubscribed||1!==++this.refCount||(a.connection=this.connection=c.connect());return e};return e}(b.Observable),d=function(a){function d(e,m){a.call(this,null);this.destination=e;this.refCountObservable=m;this.connection=m.connection;e.add(this)}g(d,
|
||||
a);d.prototype._next=function(a){this.destination.next(a)};d.prototype._error=function(a){this._resetConnectable();this.destination.error(a)};d.prototype._complete=function(){this._resetConnectable();this.destination.complete()};d.prototype._resetConnectable=function(){var a=this.refCountObservable,c=a.connection,d=this.connection;d&&d===c&&(a.refCount=0,c.unsubscribe(),a.connection=null,this.unsubscribe())};d.prototype._unsubscribe=function(){var a=this.refCountObservable;if(0!==a.refCount&&0===
|
||||
--a.refCount){var c=a.connection,d=this.connection;d&&d===c&&(c.unsubscribe(),a.connection=null)}};return d}(k.Subscriber)},{"../Observable":3,"../Subscriber":9,"../Subscription":10}],120:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};b=a("../Observable");var k=a("../util/tryCatch"),l=a("../util/errorObject");a=function(a){function e(d){a.call(this);
|
||||
this.observableFactory=d}g(e,a);e.create=function(a){return new e(a)};e.prototype._subscribe=function(a){var c=k.tryCatch(this.observableFactory)();c===l.errorObject?a.error(l.errorObject.e):c.subscribe(a)};return e}(b.Observable);f.DeferObservable=a},{"../Observable":3,"../util/errorObject":239,"../util/tryCatch":253}],121:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):
|
||||
(h.prototype=b.prototype,new h)};a=function(a){function b(h){a.call(this);this.scheduler=h}g(b,a);b.create=function(a){return new b(a)};b.dispatch=function(a){a.subscriber.complete()};b.prototype._subscribe=function(a){var e=this.scheduler;if(e)return e.schedule(b.dispatch,0,{subscriber:a});a.complete()};return b}(a("../Observable").Observable);f.EmptyObservable=a},{"../Observable":3}],122:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&
|
||||
(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(h,e){a.call(this);this.error=h;this.scheduler=e}g(b,a);b.create=function(a,e){return new b(a,e)};b.dispatch=function(a){a.subscriber.error(a.error)};b.prototype._subscribe=function(a){var e=this.error,d=this.scheduler;if(d)return d.schedule(b.dispatch,0,{error:e,subscriber:a});a.error(e)};return b}(a("../Observable").Observable);f.ErrorObservable=a},{"../Observable":3}],123:[function(a,b,f){function g(a){return null!==
|
||||
a}var k=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},l=a("../Observable");b=a("../Subscriber");var h=a("./PromiseObservable"),e=a("./EmptyObservable"),d=a("../util/isPromise"),c=a("../util/isArray");a=function(a){function b(c,d){a.call(this);this.sources=c;this.resultSelector=d}k(b,a);b.create=function(){for(var a=[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];
|
||||
if(null===a||0===arguments.length)return new e.EmptyObservable;d=null;"function"===typeof a[a.length-1]&&(d=a.pop());1===a.length&&c.isArray(a[0])&&(a=a[0]);return 0===a.length?new e.EmptyObservable:new b(a,d)};b.prototype._subscribe=function(a){for(var c=this.sources,e=c.length,b=[],n=0;n<e;n++)b.push(null);b={completed:0,total:e,values:b,selector:this.resultSelector};for(n=0;n<e;n++){var q=c[n];d.isPromise(q)&&(q=new h.PromiseObservable(q));q.subscribe(new m(a,n,b))}};return b}(l.Observable);f.ForkJoinObservable=
|
||||
a;var m=function(a){function c(d,e,m){a.call(this,d);this.index=e;this.context=m;this._value=null}k(c,a);c.prototype._next=function(a){this._value=a};c.prototype._complete=function(){var a=this.destination;null==this._value&&a.complete();var c=this.context;c.completed++;c.values[this.index]=this._value;var d=c.values;c.completed===d.length&&(d.every(g)&&(c=c.selector?c.selector.apply(this,d):d,a.next(c)),a.complete())};return c}(b.Subscriber)},{"../Observable":3,"../Subscriber":9,"../util/isArray":240,
|
||||
"../util/isPromise":245,"./EmptyObservable":121,"./PromiseObservable":130}],124:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var m in d)d.hasOwnProperty(m)&&(a[m]=d[m]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Observable");var k=a("../util/tryCatch"),l=a("../util/errorObject"),h=a("../Subscription");a=function(a){function d(c,d,b){a.call(this);this.sourceObj=c;this.eventName=d;this.selector=b}g(d,a);d.create=function(a,
|
||||
e,b){return new d(a,e,b)};d.setupSubscription=function(a,e,b,q){var f;if(a&&"[object NodeList]"===a.toString()||a&&"[object HTMLCollection]"===a.toString())for(var l=0,k=a.length;l<k;l++)d.setupSubscription(a[l],e,b,q);else a&&"function"===typeof a.addEventListener&&"function"===typeof a.removeEventListener?(a.addEventListener(e,b),f=function(){return a.removeEventListener(e,b)}):a&&"function"===typeof a.on&&"function"===typeof a.off?(a.on(e,b),f=function(){return a.off(e,b)}):a&&"function"===typeof a.addListener&&
|
||||
"function"===typeof a.removeListener&&(a.addListener(e,b),f=function(){return a.removeListener(e,b)});q.add(new h.Subscription(f))};d.prototype._subscribe=function(a){var e=this.selector;d.setupSubscription(this.sourceObj,this.eventName,e?function(){for(var d=[],b=0;b<arguments.length;b++)d[b-0]=arguments[b];d=k.tryCatch(e).apply(void 0,d);d===l.errorObject?a.error(l.errorObject.e):a.next(d)}:function(d){return a.next(d)},a)};return d}(b.Observable);f.FromEventObservable=a},{"../Observable":3,"../Subscription":10,
|
||||
"../util/errorObject":239,"../util/tryCatch":253}],125:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var m in d)d.hasOwnProperty(m)&&(a[m]=d[m]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Observable");var k=a("../Subscription"),l=a("../util/tryCatch"),h=a("../util/errorObject");a=function(a){function d(c,d,b){a.call(this);this.addHandler=c;this.removeHandler=d;this.selector=b}g(d,a);d.create=function(a,e,b){return new d(a,
|
||||
e,b)};d.prototype._subscribe=function(a){var d=this.removeHandler,e=this.selector,b=e?function(d){var m=l.tryCatch(e).apply(null,arguments);m===h.errorObject?a.error(m.e):a.next(m)}:function(d){a.next(d)},f=l.tryCatch(this.addHandler)(b);f===h.errorObject&&a.error(f.e);a.add(new k.Subscription(function(){d(b)}))};return d}(b.Observable);f.FromEventPatternObservable=a},{"../Observable":3,"../Subscription":10,"../util/errorObject":239,"../util/tryCatch":253}],126:[function(a,b,f){var g=this&&this.__extends||
|
||||
function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../util/isArray"),l=a("../util/isFunction"),h=a("../util/isPromise"),e=a("../util/isScheduler"),d=a("./PromiseObservable"),c=a("./IteratorObservable"),m=a("./ArrayObservable"),n=a("./ArrayLikeObservable"),q=a("../util/SymbolShim"),p=a("../Observable"),u=a("../operator/observeOn");a=function(a){function b(c,d){a.call(this,null);this.ish=
|
||||
c;this.scheduler=d}g(b,a);b.create=function(a,f,g,u){var t=null,z=null;l.isFunction(f)?(t=u||null,z=f):e.isScheduler(t)&&(t=f);if(null!=a){if("function"===typeof a[q.SymbolShim.observable])return a instanceof p.Observable&&!t?a:new b(a,t);if(k.isArray(a))return new m.ArrayObservable(a,t);if(h.isPromise(a))return new d.PromiseObservable(a,t);if("function"===typeof a[q.SymbolShim.iterator]||"string"===typeof a)return new c.IteratorObservable(a,null,null,t);if(a&&"number"===typeof a.length)return new n.ArrayLikeObservable(a,
|
||||
z,g,t)}throw new TypeError((null!==a&&typeof a||a)+" is not observable");};b.prototype._subscribe=function(a){var c=this.ish,d=this.scheduler;return null==d?c[q.SymbolShim.observable]().subscribe(a):c[q.SymbolShim.observable]().subscribe(new u.ObserveOnSubscriber(a,d,0))};return b}(p.Observable);f.FromObservable=a},{"../Observable":3,"../operator/observeOn":176,"../util/SymbolShim":238,"../util/isArray":240,"../util/isFunction":242,"../util/isPromise":245,"../util/isScheduler":246,"./ArrayLikeObservable":115,
|
||||
"./ArrayObservable":116,"./IteratorObservable":128,"./PromiseObservable":130}],127:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)},k=a("../util/isNumeric");b=a("../Observable");var l=a("../scheduler/asap");a=function(a){function e(d,c){void 0===d&&(d=0);void 0===c&&(c=l.asap);a.call(this);this.period=d;this.scheduler=c;if(!k.isNumeric(d)||
|
||||
0>d)this.period=0;c&&"function"===typeof c.schedule||(this.scheduler=l.asap)}g(e,a);e.create=function(a,c){void 0===a&&(a=0);void 0===c&&(c=l.asap);return new e(a,c)};e.dispatch=function(a){var c=a.subscriber,e=a.period;c.next(a.index);c.isUnsubscribed||(a.index+=1,this.schedule(a,e))};e.prototype._subscribe=function(a){var c=this.period;a.add(this.scheduler.schedule(e.dispatch,c,{index:0,subscriber:a,period:c}))};return e}(b.Observable);f.IntervalObservable=a},{"../Observable":3,"../scheduler/asap":224,
|
||||
"../util/isNumeric":243}],128:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../util/root"),l=a("../util/isObject"),h=a("../util/tryCatch");b=a("../Observable");var e=a("../util/isFunction"),d=a("../util/SymbolShim"),c=a("../util/errorObject");a=function(a){function b(c,h,f,q){a.call(this);if(null==c)throw Error("iterator cannot be null.");
|
||||
if(l.isObject(h))this.thisArg=h,this.scheduler=f;else if(e.isFunction(h))this.project=h,this.thisArg=f,this.scheduler=q;else if(null!=h)throw Error("When provided, `project` must be a function.");if((h=c[d.SymbolShim.iterator])||"string"!==typeof c)if(h||void 0===c.length){if(!h)throw new TypeError("Object is not iterable");c=c[d.SymbolShim.iterator]()}else c=new n(c);else c=new m(c);this.iterator=c}g(b,a);b.create=function(a,c,d,e){return new b(a,c,d,e)};b.dispatch=function(a){var d=a.index,e=a.thisArg,
|
||||
m=a.project,b=a.iterator,n=a.subscriber;a.hasError?n.error(a.error):(b=b.next(),b.done?n.complete():(m?(b=h.tryCatch(m).call(e,b.value,d),b===c.errorObject?(a.error=c.errorObject.e,a.hasError=!0):(n.next(b),a.index=d+1)):(n.next(b.value),a.index=d+1),n.isUnsubscribed||this.schedule(a)))};b.prototype._subscribe=function(a){var d=0,e=this.iterator,m=this.project,n=this.thisArg,f=this.scheduler;if(f)return f.schedule(b.dispatch,0,{index:d,thisArg:n,project:m,iterator:e,subscriber:a});do{f=e.next();if(f.done){a.complete();
|
||||
break}else if(m){f=h.tryCatch(m).call(n,f.value,d++);if(f===c.errorObject){a.error(c.errorObject.e);break}a.next(f)}else a.next(f.value);if(a.isUnsubscribed)break}while(1)};return b}(b.Observable);f.IteratorObservable=a;var m=function(){function a(c,d,e){void 0===d&&(d=0);void 0===e&&(e=c.length);this.str=c;this.idx=d;this.len=e}a.prototype[d.SymbolShim.iterator]=function(){return this};a.prototype.next=function(){return this.idx<this.len?{done:!1,value:this.str.charAt(this.idx++)}:{done:!0,value:void 0}};
|
||||
return a}(),n=function(){function a(c,d,e){void 0===d&&(d=0);if(void 0===e)if(e=+c.length,isNaN(e))e=0;else if(0!==e&&"number"===typeof e&&k.root.isFinite(e)){var m;m=+e;m=0===m?m:isNaN(m)?m:0>m?-1:1;e=m*Math.floor(Math.abs(e));e=0>=e?0:e>q?q:e}this.arr=c;this.idx=d;this.len=e}a.prototype[d.SymbolShim.iterator]=function(){return this};a.prototype.next=function(){return this.idx<this.len?{done:!1,value:this.arr[this.idx++]}:{done:!0,value:void 0}};return a}(),q=Math.pow(2,53)-1},{"../Observable":3,
|
||||
"../util/SymbolShim":238,"../util/errorObject":239,"../util/isFunction":242,"../util/isObject":244,"../util/root":249,"../util/tryCatch":253}],129:[function(a,b,f){var g=this&&this.__extends||function(a,b){function e(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(e.prototype=b.prototype,new e)};b=a("../Observable");var k=a("../util/noop");a=function(a){function b(){a.call(this)}g(b,a);b.create=function(){return new b};b.prototype._subscribe=
|
||||
function(a){k.noop()};return b}(b.Observable);f.NeverObservable=a},{"../Observable":3,"../util/noop":247}],130:[function(a,b,f){function g(a){var d=a.value;a=a.subscriber;a.isUnsubscribed||(a.next(d),a.complete())}function k(a){var d=a.err;a=a.subscriber;a.isUnsubscribed||a.error(d)}var l=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var m in d)d.hasOwnProperty(m)&&(a[m]=d[m]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)},h=a("../util/root");a=function(a){function d(c,
|
||||
d){void 0===d&&(d=null);a.call(this);this.promise=c;this.scheduler=d}l(d,a);d.create=function(a,e){void 0===e&&(e=null);return new d(a,e)};d.prototype._subscribe=function(a){var d=this,e=this.promise,b=this.scheduler;if(null==b)this._isScalar?a.isUnsubscribed||(a.next(this.value),a.complete()):e.then(function(e){d.value=e;d._isScalar=!0;a.isUnsubscribed||(a.next(e),a.complete())},function(d){a.isUnsubscribed||a.error(d)}).then(null,function(a){h.root.setTimeout(function(){throw a;})});else if(this._isScalar){if(!a.isUnsubscribed)return b.schedule(g,
|
||||
0,{value:this.value,subscriber:a})}else e.then(function(e){d.value=e;d._isScalar=!0;a.isUnsubscribed||a.add(b.schedule(g,0,{value:e,subscriber:a}))},function(d){a.isUnsubscribed||a.add(b.schedule(k,0,{err:d,subscriber:a}))}).then(null,function(a){h.root.setTimeout(function(){throw a;})})};return d}(a("../Observable").Observable);f.PromiseObservable=a},{"../Observable":3,"../util/root":249}],131:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&
|
||||
(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(h,e,d){a.call(this);this.start=h;this.end=e;this.scheduler=d}g(b,a);b.create=function(a,e,d){void 0===a&&(a=0);void 0===e&&(e=0);return new b(a,e,d)};b.dispatch=function(a){var e=a.start,d=a.index,c=a.subscriber;d>=a.end?c.complete():(c.next(e),c.isUnsubscribed||(a.index=d+1,a.start=e+1,this.schedule(a)))};b.prototype._subscribe=function(a){var e=0,d=this.start,c=this.end,m=this.scheduler;if(m)return m.schedule(b.dispatch,
|
||||
0,{index:e,end:c,start:d,subscriber:a});do{if(e++>=c){a.complete();break}a.next(d++);if(a.isUnsubscribed)break}while(1)};return b}(a("../Observable").Observable);f.RangeObservable=a},{"../Observable":3}],132:[function(a,b,f){var g=this&&this.__extends||function(a,b){function h(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(h.prototype=b.prototype,new h)};a=function(a){function b(h,e){a.call(this);this.value=h;this.scheduler=e;this._isScalar=
|
||||
!0}g(b,a);b.create=function(a,e){return new b(a,e)};b.dispatch=function(a){var e=a.value,d=a.subscriber;a.done?d.complete():(d.next(e),d.isUnsubscribed||(a.done=!0,this.schedule(a)))};b.prototype._subscribe=function(a){var e=this.value,d=this.scheduler;if(d)return d.schedule(b.dispatch,0,{done:!1,value:e,subscriber:a});a.next(e);a.isUnsubscribed||a.complete()};return b}(a("../Observable").Observable);f.ScalarObservable=a},{"../Observable":3}],133:[function(a,b,f){var g=this&&this.__extends||function(a,
|
||||
e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};b=a("../Observable");var k=a("../scheduler/asap"),l=a("../util/isNumeric");a=function(a){function e(d,c,e){void 0===c&&(c=0);void 0===e&&(e=k.asap);a.call(this);this.source=d;this.delayTime=c;this.scheduler=e;if(!l.isNumeric(c)||0>c)this.delayTime=0;e&&"function"===typeof e.schedule||(this.scheduler=k.asap)}g(e,a);e.create=function(a,c,m){void 0===
|
||||
c&&(c=0);void 0===m&&(m=k.asap);return new e(a,c,m)};e.dispatch=function(a){return a.source.subscribe(a.subscriber)};e.prototype._subscribe=function(a){return this.scheduler.schedule(e.dispatch,this.delayTime,{source:this.source,subscriber:a})};return e}(b.Observable);f.SubscribeOnObservable=a},{"../Observable":3,"../scheduler/asap":224,"../util/isNumeric":243}],134:[function(a,b,f){var g=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=
|
||||
c[b]);a.prototype=null===c?Object.create(c):(e.prototype=c.prototype,new e)},k=a("../util/isNumeric");b=a("../Observable");var l=a("../scheduler/asap"),h=a("../util/isScheduler"),e=a("../util/isDate");a=function(a){function c(c,b,f){void 0===c&&(c=0);a.call(this);this.period=-1;this.dueTime=0;k.isNumeric(b)?this.period=1>+b&&1||+b:h.isScheduler(b)&&(f=b);h.isScheduler(f)||(f=l.asap);this.scheduler=f;this.dueTime=e.isDate(c)?+c-this.scheduler.now():c}g(c,a);c.create=function(a,d,e){void 0===a&&(a=
|
||||
0);return new c(a,d,e)};c.dispatch=function(a){var c=a.index,d=a.period,e=a.subscriber;e.next(c);if(!e.isUnsubscribed){if(-1===d)return e.complete();a.index=c+1;this.schedule(a,d)}};c.prototype._subscribe=function(a){return this.scheduler.schedule(c.dispatch,this.dueTime,{index:0,period:this.period,subscriber:a})};return c}(b.Observable);f.TimerObservable=a},{"../Observable":3,"../scheduler/asap":224,"../util/isDate":241,"../util/isNumeric":243,"../util/isScheduler":246}],135:[function(a,b,f){var g=
|
||||
this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.buffer=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.closingNotifier=d}a.prototype.call=function(a){return new h(a,this.closingNotifier)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.buffer=[];this.add(k.subscribeToResult(this,
|
||||
d))}g(d,a);d.prototype._next=function(a){this.buffer.push(a)};d.prototype.notifyNext=function(a,d,e,b,h){a=this.buffer;this.buffer=[];this.destination.next(a)};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],136:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.bufferCount=function(a,
|
||||
e){void 0===e&&(e=null);return this.lift(new k(a,e))};var k=function(){function a(e,d){this.bufferSize=e;this.startBufferEvery=d}a.prototype.call=function(a){return new l(a,this.bufferSize,this.startBufferEvery)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.bufferSize=c;this.startBufferEvery=e;this.buffers=[[]];this.count=0}g(e,a);e.prototype._next=function(a){var c=this.count+=1,e=this.destination,b=this.bufferSize,h=this.buffers,f=h.length,k=-1;0===c%(null==this.startBufferEvery?
|
||||
b:this.startBufferEvery)&&h.push([]);for(c=0;c<f;c++){var l=h[c];l.push(a);l.length===b&&(k=c,e.next(l))}-1!==k&&h.splice(k,1)};e.prototype._complete=function(){for(var d=this.destination,c=this.buffers;0<c.length;){var e=c.shift();0<e.length&&d.next(e)}a.prototype._complete.call(this)};return e}(a.Subscriber)},{"../Subscriber":9}],137:[function(a,b,f){function g(a){var c=a.subscriber,d=a.buffer;d&&c.closeBuffer(d);a.buffer=c.openBuffer();c.isUnsubscribed||this.schedule(a,a.bufferTimeSpan)}function k(a){var c=
|
||||
a.bufferCreationInterval,d=a.bufferTimeSpan,e=a.subscriber,b=a.scheduler,h=e.openBuffer();e.isUnsubscribed||(this.add(b.schedule(l,d,{subscriber:e,buffer:h})),this.schedule(a,c))}function l(a){a.subscriber.closeBuffer(a.buffer)}var h=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Subscriber");var e=a("../scheduler/asap");f.bufferTime=function(a,c,b){void 0===
|
||||
c&&(c=null);void 0===b&&(b=e.asap);return this.lift(new d(a,c,b))};var d=function(){function a(c,d,e){this.bufferTimeSpan=c;this.bufferCreationInterval=d;this.scheduler=e}a.prototype.call=function(a){return new c(a,this.bufferTimeSpan,this.bufferCreationInterval,this.scheduler)};return a}(),c=function(a){function c(d,e,b,n){a.call(this,d);this.bufferTimeSpan=e;this.bufferCreationInterval=b;this.scheduler=n;this.buffers=[];d=this.openBuffer();if(null!==b&&0<=b){var h={bufferTimeSpan:e,bufferCreationInterval:b,
|
||||
subscriber:this,scheduler:n};this.add(n.schedule(l,e,{subscriber:this,buffer:d}));this.add(n.schedule(k,b,h))}else this.add(n.schedule(g,e,{subscriber:this,buffer:d,bufferTimeSpan:e}))}h(c,a);c.prototype._next=function(a){for(var c=this.buffers,d=c.length,e=0;e<d;e++)c[e].push(a)};c.prototype._error=function(c){this.buffers.length=0;a.prototype._error.call(this,c)};c.prototype._complete=function(){for(var c=this.buffers,d=this.destination;0<c.length;)d.next(c.shift());a.prototype._complete.call(this)};
|
||||
c.prototype._unsubscribe=function(){this.buffers=null};c.prototype.openBuffer=function(){var a=[];this.buffers.push(a);return a};c.prototype.closeBuffer=function(a){this.destination.next(a);var c=this.buffers;c.splice(c.indexOf(a),1)};return c}(b.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],138:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,
|
||||
new d)};b=a("../Subscriber");var k=a("../Subscription"),l=a("../util/tryCatch"),h=a("../util/errorObject");f.bufferToggle=function(a,c){return this.lift(new e(a,c))};var e=function(){function a(c,d){this.openings=c;this.closingSelector=d}a.prototype.call=function(a){return new d(a,this.openings,this.closingSelector)};return a}(),d=function(a){function d(e,b,m){a.call(this,e);this.openings=b;this.closingSelector=m;this.contexts=[];this.add(this.openings.subscribe(new c(this)))}g(d,a);d.prototype._next=
|
||||
function(a){for(var c=this.contexts,d=c.length,e=0;e<d;e++)c[e].buffer.push(a)};d.prototype._error=function(c){for(var d=this.contexts;0<d.length;){var e=d.shift();e.subscription.unsubscribe();e.buffer=null;e.subscription=null}this.contexts=null;a.prototype._error.call(this,c)};d.prototype._complete=function(){for(var c=this.contexts;0<c.length;){var d=c.shift();this.destination.next(d.buffer);d.subscription.unsubscribe();d.buffer=null;d.subscription=null}this.contexts=null;a.prototype._complete.call(this)};
|
||||
d.prototype.openBuffer=function(a){var c=this.contexts,d=l.tryCatch(this.closingSelector)(a);d===h.errorObject?this._error(h.errorObject.e):(a={buffer:[],subscription:new k.Subscription},c.push(a),c=new m(this,a),c=d.subscribe(c),a.subscription.add(c),this.add(c))};d.prototype.closeBuffer=function(a){var c=this.contexts;if(null!==c){var d=a.subscription;this.destination.next(a.buffer);c.splice(c.indexOf(a),1);this.remove(d);d.unsubscribe()}};return d}(b.Subscriber),c=function(a){function c(d){a.call(this,
|
||||
null);this.parent=d}g(c,a);c.prototype._next=function(a){this.parent.openBuffer(a)};c.prototype._error=function(a){this.parent.error(a)};c.prototype._complete=function(){};return c}(b.Subscriber),m=function(a){function c(d,e){a.call(this,null);this.parent=d;this.context=e}g(c,a);c.prototype._next=function(){this.parent.closeBuffer(this.context)};c.prototype._error=function(a){this.parent.error(a)};c.prototype._complete=function(){this.parent.closeBuffer(this.context)};return c}(b.Subscriber)},{"../Subscriber":9,
|
||||
"../Subscription":10,"../util/errorObject":239,"../util/tryCatch":253}],139:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../Subscription"),l=a("../util/tryCatch"),h=a("../util/errorObject");b=a("../OuterSubscriber");var e=a("../util/subscribeToResult");f.bufferWhen=function(a){return this.lift(new d(a))};var d=function(){function a(c){this.closingSelector=
|
||||
c}a.prototype.call=function(a){return new c(a,this.closingSelector)};return a}(),c=function(a){function c(d,e){a.call(this,d);this.closingSelector=e;this.subscribing=!1;this.openBuffer()}g(c,a);c.prototype._next=function(a){this.buffer.push(a)};c.prototype._complete=function(){var c=this.buffer;c&&this.destination.next(c);a.prototype._complete.call(this)};c.prototype._unsubscribe=function(){this.buffer=null;this.subscribing=!1};c.prototype.notifyNext=function(a,c,d,e,b){this.openBuffer()};c.prototype.notifyComplete=
|
||||
function(){this.subscribing?this.complete():this.openBuffer()};c.prototype.openBuffer=function(){var a=this.closingSubscription;a&&(this.remove(a),a.unsubscribe());(a=this.buffer)&&this.destination.next(a);this.buffer=[];var c=l.tryCatch(this.closingSelector)();c===h.errorObject?this.error(h.errorObject.e):(this.closingSubscription=a=new k.Subscription,this.add(a),this.subscribing=!0,a.add(e.subscribeToResult(this,c)),this.subscribing=!1)};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subscription":10,
|
||||
"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],140:[function(a,b,f){var g=a("./publishReplay");f.cache=function(a,b,h){void 0===a&&(a=Number.POSITIVE_INFINITY);void 0===b&&(b=Number.POSITIVE_INFINITY);return g.publishReplay.call(this,a,b,h).refCount()}},{"./publishReplay":182}],141:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=
|
||||
e.prototype,new d)};a=a("../Subscriber");f._catch=function(a){a=new k(a);var e=this.lift(a);return a.caught=e};var k=function(){function a(e){this.selector=e}a.prototype.call=function(a){return new l(a,this.selector,this.caught)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.selector=c;this.caught=e}g(e,a);e.prototype.error=function(a){if(!this.isStopped){var c=void 0;try{c=this.selector(a,this.caught)}catch(e){this.destination.error(e);return}this._innerSub(c)}};e.prototype._innerSub=
|
||||
function(a){this.unsubscribe();this.destination.remove(this);a.subscribe(this.destination)};return e}(a.Subscriber)},{"../Subscriber":9}],142:[function(a,b,f){var g=a("./combineLatest");f.combineAll=function(a){return this.lift(new g.CombineLatestOperator(a))}},{"./combineLatest":143}],143:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},
|
||||
k=a("../observable/ArrayObservable"),l=a("../util/isArray"),h=a("../util/isScheduler");b=a("../OuterSubscriber");var e=a("../util/subscribeToResult");f.combineLatest=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];c=null;"function"===typeof a[a.length-1]&&(c=a.pop());1===a.length&&l.isArray(a[0])&&(a=a[0]);a.unshift(this);return(new k.ArrayObservable(a)).lift(new d(c))};f.combineLatestStatic=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];var e=c=null;
|
||||
h.isScheduler(a[a.length-1])&&(e=a.pop());"function"===typeof a[a.length-1]&&(c=a.pop());1===a.length&&l.isArray(a[0])&&(a=a[0]);return(new k.ArrayObservable(a,e)).lift(new d(c))};var d=function(){function a(c){this.project=c}a.prototype.call=function(a){return new c(a,this.project)};return a}();f.CombineLatestOperator=d;var c=function(a){function c(d,e){a.call(this,d);this.project=e;this.active=0;this.values=[];this.observables=[];this.toRespond=[]}g(c,a);c.prototype._next=function(a){var c=this.toRespond;
|
||||
c.push(c.length);this.observables.push(a)};c.prototype._complete=function(){var a=this.observables,c=a.length;if(0===c)this.destination.complete();else{this.active=c;for(var d=0;d<c;d++){var b=a[d];this.add(e.subscribeToResult(this,b,b,d))}}};c.prototype.notifyComplete=function(a){0===--this.active&&this.destination.complete()};c.prototype.notifyNext=function(a,c,d,e,b){a=this.values;a[d]=c;c=this.toRespond;0<c.length&&(d=c.indexOf(d),-1!==d&&c.splice(d,1));0===c.length&&(this.project?this._tryProject(a):
|
||||
this.destination.next(a))};c.prototype._tryProject=function(a){var c;try{c=this.project.apply(this,a)}catch(d){this.destination.error(d);return}this.destination.next(c)};return c}(b.OuterSubscriber);f.CombineLatestSubscriber=c},{"../OuterSubscriber":6,"../observable/ArrayObservable":116,"../util/isArray":240,"../util/isScheduler":246,"../util/subscribeToResult":250}],144:[function(a,b,f){function g(){for(var a=[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];d=null;k.isScheduler(a[a.length-1])&&
|
||||
(d=a.pop());return(new l.ArrayObservable(a,d)).lift(new h.MergeAllOperator(1))}var k=a("../util/isScheduler"),l=a("../observable/ArrayObservable"),h=a("./mergeAll");f.concat=function(){for(var a=[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];return g.apply(void 0,[this].concat(a))};f.concatStatic=g},{"../observable/ArrayObservable":116,"../util/isScheduler":246,"./mergeAll":172}],145:[function(a,b,f){var g=a("./mergeAll");f.concatAll=function(){return this.lift(new g.MergeAllOperator(1))}},{"./mergeAll":172}],
|
||||
146:[function(a,b,f){var g=a("./mergeMap");f.concatMap=function(a,b){return this.lift(new g.MergeMapOperator(a,b,1))}},{"./mergeMap":173}],147:[function(a,b,f){var g=a("./mergeMapTo");f.concatMapTo=function(a,b){return this.lift(new g.MergeMapToOperator(a,b,1))}},{"./mergeMapTo":174}],148:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=
|
||||
a("../Subscriber");f.count=function(a){return this.lift(new k(a,this))};var k=function(){function a(e,d){this.predicate=e;this.source=d}a.prototype.call=function(a){return new l(a,this.predicate,this.source)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.predicate=c;this.source=e;this.index=this.count=0}g(e,a);e.prototype._next=function(a){this.predicate?this._tryPredicate(a):this.count++};e.prototype._tryPredicate=function(a){var c;try{c=this.predicate(a,this.index++,this.source)}catch(e){this.destination.error(e);
|
||||
return}c&&this.count++};e.prototype._complete=function(){this.destination.next(this.count);this.destination.complete()};return e}(a.Subscriber)},{"../Subscriber":9}],149:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.debounce=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.durationSelector=
|
||||
d}a.prototype.call=function(a){return new h(a,this.durationSelector)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.durationSelector=d;this.hasValue=!1;this.durationSubscription=null}g(d,a);d.prototype._next=function(a){try{var d=this.durationSelector.call(this,a);d&&this._tryNext(a,d)}catch(e){this.destination.error(e)}};d.prototype._complete=function(){this.emitValue();this.destination.complete()};d.prototype._tryNext=function(a,d){var e=this.durationSubscription;this.value=a;this.hasValue=
|
||||
!0;e&&(e.unsubscribe(),this.remove(e));e=k.subscribeToResult(this,d);e.isUnsubscribed||this.add(this.durationSubscription=e)};d.prototype.notifyNext=function(a,d,e,b,h){this.emitValue()};d.prototype.notifyComplete=function(){this.emitValue()};d.prototype.emitValue=function(){if(this.hasValue){var c=this.value,d=this.durationSubscription;d&&(this.durationSubscription=null,d.unsubscribe(),this.remove(d));this.value=null;this.hasValue=!1;a.prototype._next.call(this,c)}};return d}(b.OuterSubscriber)},
|
||||
{"../OuterSubscriber":6,"../util/subscribeToResult":250}],150:[function(a,b,f){function g(a){a.debouncedNext()}var k=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(e.prototype=c.prototype,new e)};b=a("../Subscriber");var l=a("../scheduler/asap");f.debounceTime=function(a,c){void 0===c&&(c=l.asap);return this.lift(new h(a,c))};var h=function(){function a(c,d){this.dueTime=c;this.scheduler=d}
|
||||
a.prototype.call=function(a){return new e(a,this.dueTime,this.scheduler)};return a}(),e=function(a){function c(c,e,b){a.call(this,c);this.dueTime=e;this.scheduler=b;this.lastValue=this.debouncedSubscription=null;this.hasValue=!1}k(c,a);c.prototype._next=function(a){this.clearDebounce();this.lastValue=a;this.hasValue=!0;this.add(this.debouncedSubscription=this.scheduler.schedule(g,this.dueTime,this))};c.prototype._complete=function(){this.debouncedNext();this.destination.complete()};c.prototype.debouncedNext=
|
||||
function(){this.clearDebounce();this.hasValue&&(this.destination.next(this.lastValue),this.lastValue=null,this.hasValue=!1)};c.prototype.clearDebounce=function(){var a=this.debouncedSubscription;null!==a&&(this.remove(a),a.unsubscribe(),this.debouncedSubscription=null)};return c}(b.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],151:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===
|
||||
e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.defaultIfEmpty=function(a){void 0===a&&(a=null);return this.lift(new k(a))};var k=function(){function a(e){this.defaultValue=e}a.prototype.call=function(a){return new l(a,this.defaultValue)};return a}(),l=function(a){function e(d,c){a.call(this,d);this.defaultValue=c;this.isEmpty=!0}g(e,a);e.prototype._next=function(a){this.isEmpty=!1;this.destination.next(a)};e.prototype._complete=function(){this.isEmpty&&this.destination.next(this.defaultValue);
|
||||
this.destination.complete()};return e}(a.Subscriber)},{"../Subscriber":9}],152:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../scheduler/asap"),l=a("../util/isDate");b=a("../Subscriber");var h=a("../Notification");f.delay=function(a,c){void 0===c&&(c=k.asap);var d=l.isDate(a)?+a-c.now():Math.abs(a);return this.lift(new e(d,c))};var e=
|
||||
function(){function a(c,d){this.delay=c;this.scheduler=d}a.prototype.call=function(a){return new d(a,this.delay,this.scheduler)};return a}(),d=function(a){function d(c,e,b){a.call(this,c);this.delay=e;this.scheduler=b;this.queue=[];this.errored=this.active=!1}g(d,a);d.dispatch=function(a){for(var c=a.source,d=c.queue,e=a.scheduler,b=a.destination;0<d.length&&0>=d[0].time-e.now();)d.shift().notification.observe(b);0<d.length?(c=Math.max(0,d[0].time-e.now()),this.schedule(a,c)):c.active=!1};d.prototype._schedule=
|
||||
function(a){this.active=!0;this.add(a.schedule(d.dispatch,this.delay,{source:this,destination:this.destination,scheduler:a}))};d.prototype.scheduleNotification=function(a){if(!0!==this.errored){var d=this.scheduler;a=new c(d.now()+this.delay,a);this.queue.push(a);!1===this.active&&this._schedule(d)}};d.prototype._next=function(a){this.scheduleNotification(h.Notification.createNext(a))};d.prototype._error=function(a){this.errored=!0;this.queue=[];this.destination.error(a)};d.prototype._complete=function(){this.scheduleNotification(h.Notification.createComplete())};
|
||||
return d}(b.Subscriber),c=function(){return function(a,c){this.time=a;this.notification=c}}()},{"../Notification":2,"../Subscriber":9,"../scheduler/asap":224,"../util/isDate":241}],153:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Subscriber");var k=a("../Observable"),l=a("../OuterSubscriber"),h=a("../util/subscribeToResult");f.delayWhen=
|
||||
function(a,d){return d?(new c(this,d)).lift(new e(a)):this.lift(new e(a))};var e=function(){function a(c){this.delayDurationSelector=c}a.prototype.call=function(a){return new d(a,this.delayDurationSelector)};return a}(),d=function(a){function c(d,e){a.call(this,d);this.delayDurationSelector=e;this.completed=!1;this.delayNotifierSubscriptions=[];this.values=[]}g(c,a);c.prototype.notifyNext=function(a,c,d,e,b){this.destination.next(a);this.removeSubscription(b);this.tryComplete()};c.prototype.notifyError=
|
||||
function(a,c){this._error(a)};c.prototype.notifyComplete=function(a){(a=this.removeSubscription(a))&&this.destination.next(a);this.tryComplete()};c.prototype._next=function(a){try{var c=this.delayDurationSelector(a);c&&this.tryDelay(c,a)}catch(d){this.destination.error(d)}};c.prototype._complete=function(){this.completed=!0;this.tryComplete()};c.prototype.removeSubscription=function(a){a.unsubscribe();a=this.delayNotifierSubscriptions.indexOf(a);var c=null;-1!==a&&(c=this.values[a],this.delayNotifierSubscriptions.splice(a,
|
||||
1),this.values.splice(a,1));return c};c.prototype.tryDelay=function(a,c){var d=h.subscribeToResult(this,a,c);this.add(d);this.delayNotifierSubscriptions.push(d);this.values.push(c)};c.prototype.tryComplete=function(){this.completed&&0===this.delayNotifierSubscriptions.length&&this.destination.complete()};return c}(l.OuterSubscriber),c=function(a){function c(d,e){a.call(this);this.source=d;this.subscriptionDelay=e}g(c,a);c.prototype._subscribe=function(a){this.subscriptionDelay.subscribe(new m(a,this.source))};
|
||||
return c}(k.Observable),m=function(a){function c(d,e){a.call(this);this.parent=d;this.source=e;this.sourceSubscribed=!1}g(c,a);c.prototype._next=function(a){this.subscribeToSource()};c.prototype._error=function(a){this.unsubscribe();this.parent.error(a)};c.prototype._complete=function(){this.subscribeToSource()};c.prototype.subscribeToSource=function(){this.sourceSubscribed||(this.sourceSubscribed=!0,this.unsubscribe(),this.source.subscribe(this.parent))};return c}(b.Subscriber)},{"../Observable":3,
|
||||
"../OuterSubscriber":6,"../Subscriber":9,"../util/subscribeToResult":250}],154:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.dematerialize=function(){return this.lift(new k)};var k=function(){function a(){}a.prototype.call=function(a){return new l(a)};return a}(),l=function(a){function e(d){a.call(this,d)}g(e,a);
|
||||
e.prototype._next=function(a){a.observe(this.destination)};return e}(a.Subscriber)},{"../Subscriber":9}],155:[function(a,b,f){var g=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(e.prototype=c.prototype,new e)};b=a("../Subscriber");var k=a("../util/tryCatch"),l=a("../util/errorObject");f.distinctUntilChanged=function(a,c){return this.lift(new h(a,c))};var h=function(){function a(c,d){this.compare=
|
||||
c;this.keySelector=d}a.prototype.call=function(a){return new e(a,this.compare,this.keySelector)};return a}(),e=function(a){function c(c,e,b){a.call(this,c);this.keySelector=b;this.hasKey=!1;"function"===typeof e&&(this.compare=e)}g(c,a);c.prototype.compare=function(a,c){return a===c};c.prototype._next=function(a){var c=a;if(this.keySelector&&(c=k.tryCatch(this.keySelector)(a),c===l.errorObject))return this.destination.error(l.errorObject.e);var d=!1;if(this.hasKey){if(d=k.tryCatch(this.compare)(this.key,
|
||||
c),d===l.errorObject)return this.destination.error(l.errorObject.e)}else this.hasKey=!0;!1===!!d&&(this.key=c,this.destination.next(a))};return c}(b.Subscriber)},{"../Subscriber":9,"../util/errorObject":239,"../util/tryCatch":253}],156:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/noop");f._do=function(a,
|
||||
d,c){var b;a&&"object"===typeof a?(b=a.next,d=a.error,c=a.complete):b=a;return this.lift(new l(b||k.noop,d||k.noop,c||k.noop))};var l=function(){function a(d,c,e){this.next=d;this.error=c;this.complete=e}a.prototype.call=function(a){return new h(a,this.next,this.error,this.complete)};return a}(),h=function(a){function d(c,d,b,h){a.call(this,c);this.__next=d;this.__error=b;this.__complete=h}g(d,a);d.prototype._next=function(a){try{this.__next(a)}catch(d){this.destination.error(d);return}this.destination.next(a)};
|
||||
d.prototype._error=function(a){try{this.__error(a)}catch(d){this.destination.error(d);return}this.destination.error(a)};d.prototype._complete=function(){try{this.__complete()}catch(a){this.destination.error(a);return}this.destination.complete()};return d}(b.Subscriber)},{"../Subscriber":9,"../util/noop":247}],157:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=
|
||||
e.prototype,new d)};a=a("../Subscriber");f.every=function(a,e){return this.lift(new k(a,e,this))};var k=function(){function a(e,d,c){this.predicate=e;this.thisArg=d;this.source=c}a.prototype.call=function(a){return new l(a,this.predicate,this.thisArg,this.source)};return a}(),l=function(a){function e(d,c,e,b){a.call(this,d);this.predicate=c;this.thisArg=e;this.source=b;this.index=0;this.thisArg=e||this}g(e,a);e.prototype.notifyComplete=function(a){this.destination.next(a);this.destination.complete()};
|
||||
e.prototype._next=function(a){var c=!1;try{c=this.predicate.call(this.thisArg,a,this.index++,this.source)}catch(e){this.destination.error(e);return}c||this.notifyComplete(!1)};e.prototype._complete=function(){this.notifyComplete(!0)};return e}(a.Subscriber)},{"../Subscriber":9}],158:[function(a,b,f){var g=this&&this.__extends||function(a,d){function e(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(e.prototype=d.prototype,new e)},k=a("../util/tryCatch"),
|
||||
l=a("../util/errorObject");b=a("../OuterSubscriber");var h=a("../util/subscribeToResult");f.expand=function(a,d,b){void 0===d&&(d=Number.POSITIVE_INFINITY);void 0===b&&(b=void 0);d=1>(d||0)?Number.POSITIVE_INFINITY:d;return this.lift(new e(a,d,b))};var e=function(){function a(c,d,e){this.project=c;this.concurrent=d;this.scheduler=e}a.prototype.call=function(a){return new d(a,this.project,this.concurrent,this.scheduler)};return a}();f.ExpandOperator=e;var d=function(a){function d(e,b,m,h){a.call(this,
|
||||
e);this.project=b;this.concurrent=m;this.scheduler=h;this.active=this.index=0;this.hasCompleted=!1;m<Number.POSITIVE_INFINITY&&(this.buffer=[])}g(d,a);d.dispatch=function(a){a.subscriber.subscribeToProjection(a.result,a.value,a.index)};d.prototype._next=function(a){var c=this.destination;if(c.isUnsubscribed)this._complete();else{var e=this.index++;if(this.active<this.concurrent){c.next(a);var b=k.tryCatch(this.project)(a,e);b===l.errorObject?c.error(l.errorObject.e):this.scheduler?this.add(this.scheduler.schedule(d.dispatch,
|
||||
0,{subscriber:this,result:b,value:a,index:e})):this.subscribeToProjection(b,a,e)}else this.buffer.push(a)}};d.prototype.subscribeToProjection=function(a,c,d){this.active++;this.add(h.subscribeToResult(this,a,c,d))};d.prototype._complete=function(){(this.hasCompleted=!0,0===this.active)&&this.destination.complete()};d.prototype.notifyNext=function(a,c,d,e,b){this._next(c)};d.prototype.notifyComplete=function(a){var c=this.buffer;this.remove(a);this.active--;c&&0<c.length&&this._next(c.shift());this.hasCompleted&&
|
||||
0===this.active&&this.destination.complete()};return d}(b.OuterSubscriber);f.ExpandSubscriber=d},{"../OuterSubscriber":6,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],159:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.filter=function(a,e){return this.lift(new k(a,e))};var k=function(){function a(e,
|
||||
d){this.select=e;this.thisArg=d}a.prototype.call=function(a){return new l(a,this.select,this.thisArg)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.select=c;this.thisArg=e;this.count=0;this.select=c}g(e,a);e.prototype._next=function(a){var c;try{c=this.select.call(this.thisArg,a,this.count++)}catch(e){this.destination.error(e);return}c&&this.destination.next(a)};return e}(a.Subscriber)},{"../Subscriber":9}],160:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=
|
||||
a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../Subscription");f._finally=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.finallySelector=d}a.prototype.call=function(a){return new h(a,this.finallySelector)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.add(new k.Subscription(d))}g(d,a);return d}(b.Subscriber)},{"../Subscriber":9,"../Subscription":10}],
|
||||
161:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/EmptyError");f.first=function(a,d,c){return this.lift(new l(a,d,c,this))};var l=function(){function a(d,c,e,b){this.predicate=d;this.resultSelector=c;this.defaultValue=e;this.source=b}a.prototype.call=function(a){return new h(a,this.predicate,this.resultSelector,
|
||||
this.defaultValue,this.source)};return a}(),h=function(a){function d(c,d,b,h,f){a.call(this,c);this.predicate=d;this.resultSelector=b;this.defaultValue=h;this.source=f;this.index=0;this.hasCompleted=!1}g(d,a);d.prototype._next=function(a){var d=this.index++;this.predicate?this._tryPredicate(a,d):this._emit(a,d)};d.prototype._tryPredicate=function(a,d){var e;try{e=this.predicate(a,d,this.source)}catch(b){this.destination.error(b);return}e&&this._emit(a,d)};d.prototype._emit=function(a,d){this.resultSelector?
|
||||
this._tryResultSelector(a,d):this._emitFinal(a)};d.prototype._tryResultSelector=function(a,d){var e;try{e=this.resultSelector(a,d)}catch(b){this.destination.error(b);return}this._emitFinal(e)};d.prototype._emitFinal=function(a){var d=this.destination;d.next(a);d.complete();this.hasCompleted=!0};d.prototype._complete=function(){var a=this.destination;this.hasCompleted||"undefined"===typeof this.defaultValue?this.hasCompleted||a.error(new k.EmptyError):(a.next(this.defaultValue),a.complete())};return d}(b.Subscriber)},
|
||||
{"../Subscriber":9,"../util/EmptyError":232}],162:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Subscriber");var k=a("../Subscription"),l=a("../Observable"),h=a("../Operator"),e=a("../Subject"),d=a("../util/Map"),c=a("../util/FastMap");f.groupBy=function(a,c,d){return this.lift(new m(this,a,c,d))};var m=function(a){function c(d,
|
||||
e,b,m){a.call(this);this.source=d;this.keySelector=e;this.elementSelector=b;this.durationSelector=m}g(c,a);c.prototype.call=function(a){return new n(a,this.keySelector,this.elementSelector,this.durationSelector)};return c}(h.Operator),n=function(a){function b(c,d,e,m){a.call(this);this.keySelector=d;this.elementSelector=e;this.durationSelector=m;this.groups=null;this.attemptedToUnsubscribe=!1;this.count=0;this.destination=c;this.add(c)}g(b,a);b.prototype._next=function(a){var c;try{c=this.keySelector(a)}catch(d){this.error(d);
|
||||
return}this._group(a,c)};b.prototype._group=function(a,b){var m=this.groups;m||(m=this.groups="string"===typeof b?new c.FastMap:new d.Map);var h=m.get(b);h||(m.set(b,h=new e.Subject),m=new p(b,h,this),this.durationSelector&&this._selectDuration(b,h),this.destination.next(m));this.elementSelector?this._selectElement(a,h):this.tryGroupNext(a,h)};b.prototype._selectElement=function(a,c){var d;try{d=this.elementSelector(a)}catch(e){this.error(e);return}this.tryGroupNext(d,c)};b.prototype._selectDuration=
|
||||
function(a,c){var d;try{d=this.durationSelector(new p(a,c))}catch(e){this.error(e);return}this.add(d.subscribe(new q(a,c,this)))};b.prototype.tryGroupNext=function(a,c){c.isUnsubscribed||c.next(a)};b.prototype._error=function(a){var c=this.groups;c&&(c.forEach(function(c,d){c.error(a)}),c.clear());this.destination.error(a)};b.prototype._complete=function(){var a=this.groups;a&&(a.forEach(function(a,c){a.complete()}),a.clear());this.destination.complete()};b.prototype.removeGroup=function(a){this.groups["delete"](a)};
|
||||
b.prototype.unsubscribe=function(){this.isUnsubscribed||this.attemptedToUnsubscribe||(this.attemptedToUnsubscribe=!0,0===this.count&&a.prototype.unsubscribe.call(this))};return b}(b.Subscriber),q=function(a){function c(d,e,b){a.call(this);this.key=d;this.group=e;this.parent=b}g(c,a);c.prototype._next=function(a){this.tryComplete()};c.prototype._error=function(a){this.tryError(a)};c.prototype._complete=function(){this.tryComplete()};c.prototype.tryError=function(a){var c=this.group;c.isUnsubscribed||
|
||||
c.error(a);this.parent.removeGroup(this.key)};c.prototype.tryComplete=function(){var a=this.group;a.isUnsubscribed||a.complete();this.parent.removeGroup(this.key)};return c}(b.Subscriber),p=function(a){function c(d,e,b){a.call(this);this.key=d;this.groupSubject=e;this.refCountSubscription=b}g(c,a);c.prototype._subscribe=function(a){var c=new k.Subscription,d=this.refCountSubscription,e=this.groupSubject;d&&!d.isUnsubscribed&&c.add(new u(d));c.add(e.subscribe(a));return c};return c}(l.Observable);
|
||||
f.GroupedObservable=p;var u=function(a){function c(d){a.call(this);this.parent=d;d.count++}g(c,a);c.prototype.unsubscribe=function(){var c=this.parent;c.isUnsubscribed||this.isUnsubscribed||(a.prototype.unsubscribe.call(this),--c.count,0===c.count&&c.attemptedToUnsubscribe&&c.unsubscribe())};return c}(k.Subscription)},{"../Observable":3,"../Operator":5,"../Subject":8,"../Subscriber":9,"../Subscription":10,"../util/FastMap":233,"../util/Map":235}],163:[function(a,b,f){var g=this&&this.__extends||function(a,
|
||||
d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/noop");f.ignoreElements=function(){return this.lift(new l)};var l=function(){function a(){}a.prototype.call=function(a){return new h(a)};return a}(),h=function(a){function d(){a.apply(this,arguments)}g(d,a);d.prototype._next=function(a){k.noop()};return d}(b.Subscriber)},{"../Subscriber":9,"../util/noop":247}],
|
||||
164:[function(a,b,f){var g=this&&this.__extends||function(a,d){function e(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(e.prototype=d.prototype,new e)},k=a("../util/tryCatch"),l=a("../util/errorObject");b=a("../OuterSubscriber");var h=a("../util/subscribeToResult");f.inspect=function(a){return this.lift(new e(a))};var e=function(){function a(c){this.durationSelector=c}a.prototype.call=function(a){return new d(a,this.durationSelector)};
|
||||
return a}(),d=function(a){function d(e,b){a.call(this,e);this.durationSelector=b;this.hasValue=!1}g(d,a);d.prototype._next=function(a){this.value=a;this.hasValue=!0;this.throttled||(a=k.tryCatch(this.durationSelector)(a),a===l.errorObject?this.destination.error(l.errorObject.e):this.add(this.throttled=h.subscribeToResult(this,a)))};d.prototype.clearThrottle=function(){var a=this.value,c=this.hasValue,d=this.throttled;d&&(this.remove(d),this.throttled=null,d.unsubscribe());c&&(this.value=null,this.hasValue=
|
||||
!1,this.destination.next(a))};d.prototype.notifyNext=function(a,c,d,e){this.clearThrottle()};d.prototype.notifyComplete=function(){this.clearThrottle()};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],165:[function(a,b,f){function g(a){a.clearThrottle()}var k=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):
|
||||
(e.prototype=c.prototype,new e)},l=a("../scheduler/asap");a=a("../Subscriber");f.inspectTime=function(a,c){void 0===c&&(c=l.asap);return this.lift(new h(a,c))};var h=function(){function a(c,d){this.delay=c;this.scheduler=d}a.prototype.call=function(a){return new e(a,this.delay,this.scheduler)};return a}(),e=function(a){function c(c,e,b){a.call(this,c);this.delay=e;this.scheduler=b;this.hasValue=!1}k(c,a);c.prototype._next=function(a){this.value=a;this.hasValue=!0;this.throttled||this.add(this.throttled=
|
||||
this.scheduler.schedule(g,this.delay,this))};c.prototype.clearThrottle=function(){var a=this.value,c=this.hasValue,d=this.throttled;d&&(this.remove(d),this.throttled=null,d.unsubscribe());c&&(this.value=null,this.hasValue=!1,this.destination.next(a))};return c}(a.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],166:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):
|
||||
(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/EmptyError");f.last=function(a,d,c){return this.lift(new l(a,d,c,this))};var l=function(){function a(d,c,e,b){this.predicate=d;this.resultSelector=c;this.defaultValue=e;this.source=b}a.prototype.call=function(a){return new h(a,this.predicate,this.resultSelector,this.defaultValue,this.source)};return a}(),h=function(a){function d(c,d,b,h,f){a.call(this,c);this.predicate=d;this.resultSelector=b;this.defaultValue=h;this.source=f;
|
||||
this.hasValue=!1;this.index=0;"undefined"!==typeof h&&(this.lastValue=h,this.hasValue=!0)}g(d,a);d.prototype._next=function(a){var d=this.index++;this.predicate?this._tryPredicate(a,d):this.resultSelector?this._tryResultSelector(a,d):(this.lastValue=a,this.hasValue=!0)};d.prototype._tryPredicate=function(a,d){var e;try{e=this.predicate(a,d,this.source)}catch(b){this.destination.error(b);return}e&&(this.resultSelector?this._tryResultSelector(a,d):(this.lastValue=a,this.hasValue=!0))};d.prototype._tryResultSelector=
|
||||
function(a,d){var e;try{e=this.resultSelector(a,d)}catch(b){this.destination.error(b);return}this.lastValue=e;this.hasValue=!0};d.prototype._complete=function(){var a=this.destination;this.hasValue?(a.next(this.lastValue),a.complete()):a.error(new k.EmptyError)};return d}(b.Subscriber)},{"../Subscriber":9,"../util/EmptyError":232}],167:[function(a,b,f){f.letProto=function(a){return a(this)}},{}],168:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&
|
||||
(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.map=function(a,e){if("function"!==typeof a)throw new TypeError("argument is not a function. Are you looking for `mapTo()`?");return this.lift(new k(a,e))};var k=function(){function a(e,d){this.project=e;this.thisArg=d}a.prototype.call=function(a){return new l(a,this.project,this.thisArg)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.project=c;this.count=0;this.thisArg=e||this}
|
||||
g(e,a);e.prototype._next=function(a){var c;try{c=this.project.call(this.thisArg,a,this.count++)}catch(e){this.destination.error(e);return}this.destination.next(c)};return e}(a.Subscriber)},{"../Subscriber":9}],169:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.mapTo=function(a){return this.lift(new k(a))};var k=function(){function a(e){this.value=
|
||||
e}a.prototype.call=function(a){return new l(a,this.value)};return a}(),l=function(a){function e(d,c){a.call(this,d);this.value=c}g(e,a);e.prototype._next=function(a){this.destination.next(this.value)};return e}(a.Subscriber)},{"../Subscriber":9}],170:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../Notification");
|
||||
f.materialize=function(){return this.lift(new l)};var l=function(){function a(){}a.prototype.call=function(a){return new h(a)};return a}(),h=function(a){function d(c){a.call(this,c)}g(d,a);d.prototype._next=function(a){this.destination.next(k.Notification.createNext(a))};d.prototype._error=function(a){var d=this.destination;d.next(k.Notification.createError(a));d.complete()};d.prototype._complete=function(){var a=this.destination;a.next(k.Notification.createComplete());a.complete()};return d}(b.Subscriber)},
|
||||
{"../Notification":2,"../Subscriber":9}],171:[function(a,b,f){function g(){for(var a=[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];var d=Number.POSITIVE_INFINITY,c=null,b=a[a.length-1];h.isScheduler(b)?(c=a.pop(),1<a.length&&"number"===typeof a[a.length-1]&&(d=a.pop())):"number"===typeof b&&(d=a.pop());return 1===a.length?a[0]:(new k.ArrayObservable(a,c)).lift(new l.MergeAllOperator(d))}var k=a("../observable/ArrayObservable"),l=a("./mergeAll"),h=a("../util/isScheduler");f.merge=function(){for(var a=
|
||||
[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];a.unshift(this);return g.apply(this,a)};f.mergeStatic=g},{"../observable/ArrayObservable":116,"../util/isScheduler":246,"./mergeAll":172}],172:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.mergeAll=function(a){void 0===a&&
|
||||
(a=Number.POSITIVE_INFINITY);return this.lift(new l(a))};var l=function(){function a(d){this.concurrent=d}a.prototype.call=function(a){return new h(a,this.concurrent)};return a}();f.MergeAllOperator=l;var h=function(a){function d(c,d){a.call(this,c);this.concurrent=d;this.hasCompleted=!1;this.buffer=[];this.active=0}g(d,a);d.prototype._next=function(a){this.active<this.concurrent?(this.active++,this.add(k.subscribeToResult(this,a))):this.buffer.push(a)};d.prototype._complete=function(){this.hasCompleted=
|
||||
!0;0===this.active&&0===this.buffer.length&&this.destination.complete()};d.prototype.notifyComplete=function(a){var d=this.buffer;this.remove(a);this.active--;0<d.length?this._next(d.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()};return d}(b.OuterSubscriber);f.MergeAllSubscriber=h},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],173:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=
|
||||
d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)},k=a("../util/subscribeToResult");a=a("../OuterSubscriber");f.mergeMap=function(a,d,c){void 0===c&&(c=Number.POSITIVE_INFINITY);return this.lift(new l(a,d,c))};var l=function(){function a(d,c,e){void 0===e&&(e=Number.POSITIVE_INFINITY);this.project=d;this.resultSelector=c;this.concurrent=e}a.prototype.call=function(a){return new h(a,this.project,this.resultSelector,this.concurrent)};return a}();f.MergeMapOperator=l;var h=
|
||||
function(a){function d(c,d,b,f){void 0===f&&(f=Number.POSITIVE_INFINITY);a.call(this,c);this.project=d;this.resultSelector=b;this.concurrent=f;this.hasCompleted=!1;this.buffer=[];this.index=this.active=0}g(d,a);d.prototype._next=function(a){this.active<this.concurrent?this._tryNext(a):this.buffer.push(a)};d.prototype._tryNext=function(a){var d,e=this.index++;try{d=this.project(a,e)}catch(b){this.destination.error(b);return}this.active++;this._innerSub(d,a,e)};d.prototype._innerSub=function(a,d,e){this.add(k.subscribeToResult(this,
|
||||
a,d,e))};d.prototype._complete=function(){this.hasCompleted=!0;0===this.active&&0===this.buffer.length&&this.destination.complete()};d.prototype.notifyNext=function(a,d,e,b,f){this.resultSelector?this._notifyResultSelector(a,d,e,b):this.destination.next(d)};d.prototype._notifyResultSelector=function(a,d,e,b){var f;try{f=this.resultSelector(a,d,e,b)}catch(h){this.destination.error(h);return}this.destination.next(f)};d.prototype.notifyComplete=function(a){var d=this.buffer;this.remove(a);this.active--;
|
||||
0<d.length?this._next(d.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()};return d}(a.OuterSubscriber);f.MergeMapSubscriber=h},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],174:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.mergeMapTo=function(a,
|
||||
d,c){void 0===c&&(c=Number.POSITIVE_INFINITY);return this.lift(new l(a,d,c))};var l=function(){function a(d,c,e){void 0===e&&(e=Number.POSITIVE_INFINITY);this.ish=d;this.resultSelector=c;this.concurrent=e}a.prototype.call=function(a){return new h(a,this.ish,this.resultSelector,this.concurrent)};return a}();f.MergeMapToOperator=l;var h=function(a){function d(c,d,b,f){void 0===f&&(f=Number.POSITIVE_INFINITY);a.call(this,c);this.ish=d;this.resultSelector=b;this.concurrent=f;this.hasCompleted=!1;this.buffer=
|
||||
[];this.index=this.active=0}g(d,a);d.prototype._next=function(a){if(this.active<this.concurrent){var d=this.resultSelector,e=this.index++,b=this.ish,f=this.destination;this.active++;this._innerSub(b,f,d,a,e)}else this.buffer.push(a)};d.prototype._innerSub=function(a,d,e,b,f){this.add(k.subscribeToResult(this,a,b,f))};d.prototype._complete=function(){this.hasCompleted=!0;0===this.active&&0===this.buffer.length&&this.destination.complete()};d.prototype.notifyNext=function(a,d,e,b,f){f=this.destination;
|
||||
this.resultSelector?this.trySelectResult(a,d,e,b):f.next(d)};d.prototype.trySelectResult=function(a,d,e,b){var f=this.resultSelector,h=this.destination,k;try{k=f(a,d,e,b)}catch(l){h.error(l);return}h.next(k)};d.prototype.notifyError=function(a){this.destination.error(a)};d.prototype.notifyComplete=function(a){var d=this.buffer;this.remove(a);this.active--;0<d.length?this._next(d.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()};return d}(b.OuterSubscriber);f.MergeMapToSubscriber=
|
||||
h},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],175:[function(a,b,f){var g=a("../observable/ConnectableObservable");f.multicast=function(a){return new g.ConnectableObservable(this,"function"===typeof a?a:function(){return a})}},{"../observable/ConnectableObservable":119}],176:[function(a,b,f){var g=this&&this.__extends||function(a,c){function e(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(e.prototype=c.prototype,new e)};b=
|
||||
a("../Subscriber");var k=a("../Notification");f.observeOn=function(a,c){void 0===c&&(c=0);return this.lift(new l(a,c))};var l=function(){function a(c,d){void 0===d&&(d=0);this.scheduler=c;this.delay=d}a.prototype.call=function(a){return new h(a,this.scheduler,this.delay)};return a}();f.ObserveOnOperator=l;var h=function(a){function c(c,e,b){void 0===b&&(b=0);a.call(this,c);this.scheduler=e;this.delay=b}g(c,a);c.dispatch=function(a){a.notification.observe(a.destination)};c.prototype.scheduleMessage=
|
||||
function(a){this.add(this.scheduler.schedule(c.dispatch,this.delay,new e(a,this.destination)))};c.prototype._next=function(a){this.scheduleMessage(k.Notification.createNext(a))};c.prototype._error=function(a){this.scheduleMessage(k.Notification.createError(a))};c.prototype._complete=function(){this.scheduleMessage(k.Notification.createComplete())};return c}(b.Subscriber);f.ObserveOnSubscriber=h;var e=function(){return function(a,c){this.notification=a;this.destination=c}}()},{"../Notification":2,
|
||||
"../Subscriber":9}],177:[function(a,b,f){var g=a("../util/not"),k=a("./filter");f.partition=function(a,b){return[k.filter.call(this,a),k.filter.call(this,g.not(a,b))]}},{"../util/not":248,"./filter":159}],178:[function(a,b,f){function g(a,b){return function(e){var d=e;for(e=0;e<b;e++)if(d=d[a[e]],"undefined"===typeof d)return;return d}}var k=a("./map");f.pluck=function(){for(var a=[],b=0;b<arguments.length;b++)a[b-0]=arguments[b];b=a.length;if(0===b)throw Error("List of properties cannot be empty.");
|
||||
return k.map.call(this,g(a,b))}},{"./map":168}],179:[function(a,b,f){var g=a("../Subject"),k=a("./multicast");f.publish=function(){return k.multicast.call(this,new g.Subject)}},{"../Subject":8,"./multicast":175}],180:[function(a,b,f){var g=a("../subject/BehaviorSubject"),k=a("./multicast");f.publishBehavior=function(a){return k.multicast.call(this,new g.BehaviorSubject(a))}},{"../subject/BehaviorSubject":227,"./multicast":175}],181:[function(a,b,f){var g=a("../subject/AsyncSubject"),k=a("./multicast");
|
||||
f.publishLast=function(){return k.multicast.call(this,new g.AsyncSubject)}},{"../subject/AsyncSubject":226,"./multicast":175}],182:[function(a,b,f){var g=a("../subject/ReplaySubject"),k=a("./multicast");f.publishReplay=function(a,b,e){void 0===a&&(a=Number.POSITIVE_INFINITY);void 0===b&&(b=Number.POSITIVE_INFINITY);return k.multicast.call(this,new g.ReplaySubject(a,b,e))}},{"../subject/ReplaySubject":228,"./multicast":175}],183:[function(a,b,f){function g(){for(var a=[],c=0;c<arguments.length;c++)a[c-
|
||||
0]=arguments[c];if(1===a.length)if(l.isArray(a[0]))a=a[0];else return a[0];return(new h.ArrayObservable(a)).lift(new d)}var k=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},l=a("../util/isArray"),h=a("../observable/ArrayObservable");b=a("../OuterSubscriber");var e=a("../util/subscribeToResult");f.race=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=
|
||||
arguments[c];1===a.length&&l.isArray(a[0])&&(a=a[0]);a.unshift(this);return g.apply(this,a)};f.raceStatic=g;var d=function(){function a(){}a.prototype.call=function(a){return new c(a)};return a}();f.RaceOperator=d;var c=function(a){function c(d){a.call(this,d);this.hasFirst=!1;this.observables=[];this.subscriptions=[]}k(c,a);c.prototype._next=function(a){this.observables.push(a)};c.prototype._complete=function(){var a=this.observables,c=a.length;if(0===c)this.destination.complete();else{for(var d=
|
||||
0;d<c;d++){var b=a[d],b=e.subscribeToResult(this,b,b,d);this.subscriptions.push(b);this.add(b)}this.observables=null}};c.prototype.notifyNext=function(a,c,d,e,b){if(!this.hasFirst){this.hasFirst=!0;for(a=0;a<this.subscriptions.length;a++)a!==d&&(e=this.subscriptions[a],e.unsubscribe(),this.remove(e));this.subscriptions=null}this.destination.next(c)};return c}(b.OuterSubscriber);f.RaceSubscriber=c},{"../OuterSubscriber":6,"../observable/ArrayObservable":116,"../util/isArray":240,"../util/subscribeToResult":250}],
|
||||
184:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.reduce=function(a,e){return this.lift(new k(a,e))};var k=function(){function a(e,d){this.project=e;this.seed=d}a.prototype.call=function(a){return new l(a,this.project,this.seed)};return a}();f.ReduceOperator=k;var l=function(a){function e(d,c,e){a.call(this,d);this.hasValue=
|
||||
!1;this.acc=e;this.project=c;this.hasSeed="undefined"!==typeof e}g(e,a);e.prototype._next=function(a){this.hasValue||(this.hasValue=this.hasSeed)?this._tryReduce(a):(this.acc=a,this.hasValue=!0)};e.prototype._tryReduce=function(a){var c;try{c=this.project(this.acc,a)}catch(e){this.destination.error(e);return}this.acc=c};e.prototype._complete=function(){(this.hasValue||this.hasSeed)&&this.destination.next(this.acc);this.destination.complete()};return e}(a.Subscriber);f.ReduceSubscriber=l},{"../Subscriber":9}],
|
||||
185:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../observable/EmptyObservable");f.repeat=function(a){void 0===a&&(a=-1);return 0===a?new k.EmptyObservable:0>a?this.lift(new l(-1,this)):this.lift(new l(a-1,this))};var l=function(){function a(d,c){this.count=d;this.source=c}a.prototype.call=function(a){return new h(a,
|
||||
this.count,this.source)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.count=d;this.source=b}g(d,a);d.prototype.complete=function(){if(!this.isStopped){var c=this.source,d=this.count;if(0===d)return a.prototype.complete.call(this);-1<d&&(this.count=d-1);this.unsubscribe();this.isUnsubscribed=this.isStopped=!1;c.subscribe(this)}};return d}(b.Subscriber)},{"../Subscriber":9,"../observable/EmptyObservable":121}],186:[function(a,b,f){var g=this&&this.__extends||function(a,e){function d(){this.constructor=
|
||||
a}for(var c in e)e.hasOwnProperty(c)&&(a[c]=e[c]);a.prototype=null===e?Object.create(e):(d.prototype=e.prototype,new d)};a=a("../Subscriber");f.retry=function(a){void 0===a&&(a=-1);return this.lift(new k(a,this))};var k=function(){function a(e,d){this.count=e;this.source=d}a.prototype.call=function(a){return new l(a,this.count,this.source)};return a}(),l=function(a){function e(d,c,e){a.call(this,d);this.count=c;this.source=e}g(e,a);e.prototype.error=function(d){if(!this.isStopped){var c=this.source,
|
||||
e=this.count;if(0===e)return a.prototype.error.call(this,d);-1<e&&(this.count=e-1);this.unsubscribe();this.isUnsubscribed=this.isStopped=!1;c.subscribe(this)}};return e}(a.Subscriber)},{"../Subscriber":9}],187:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../Subject"),l=a("../util/tryCatch"),h=a("../util/errorObject");b=a("../OuterSubscriber");
|
||||
var e=a("../util/subscribeToResult");f.retryWhen=function(a){return this.lift(new d(a,this))};var d=function(){function a(c,d){this.notifier=c;this.source=d}a.prototype.call=function(a){return new c(a,this.notifier,this.source)};return a}(),c=function(a){function c(d,e,b){a.call(this,d);this.notifier=e;this.source=b}g(c,a);c.prototype.error=function(c){if(!this.isStopped){var d=this.errors,b=this.retries,f=this.retriesSubscription;if(b)this.retriesSubscription=this.errors=null;else{d=new k.Subject;
|
||||
b=l.tryCatch(this.notifier)(d);if(b===h.errorObject)return a.prototype.error.call(this,h.errorObject.e);f=e.subscribeToResult(this,b)}this.unsubscribe();this.isUnsubscribed=!1;this.errors=d;this.retries=b;this.retriesSubscription=f;d.next(c)}};c.prototype._unsubscribe=function(){var a=this.errors,c=this.retriesSubscription;a&&(a.unsubscribe(),this.errors=null);c&&(c.unsubscribe(),this.retriesSubscription=null);this.retries=null};c.prototype.notifyNext=function(a,c,d,e,b){a=this.errors;c=this.retries;
|
||||
d=this.retriesSubscription;this.retriesSubscription=this.retries=this.errors=null;this.unsubscribe();this.isUnsubscribed=this.isStopped=!1;this.errors=a;this.retries=c;this.retriesSubscription=d;this.source.subscribe(this)};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subject":8,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],188:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&
|
||||
(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.sample=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.notifier=d}a.prototype.call=function(a){return new h(a,this.notifier)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.hasValue=!1;this.add(k.subscribeToResult(this,d))}g(d,a);d.prototype._next=function(a){this.value=a;this.hasValue=!0};d.prototype.notifyNext=
|
||||
function(a,d,b,e,f){this.emitValue()};d.prototype.notifyComplete=function(){this.emitValue()};d.prototype.emitValue=function(){this.hasValue&&(this.hasValue=!1,this.destination.next(this.value))};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],189:[function(a,b,f){function g(a){var c=a.delay;a.subscriber.notifyNext();this.schedule(a,c)}var k=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=
|
||||
null===c?Object.create(c):(b.prototype=c.prototype,new b)};b=a("../Subscriber");var l=a("../scheduler/asap");f.sampleTime=function(a,c){void 0===c&&(c=l.asap);return this.lift(new h(a,c))};var h=function(){function a(c,d){this.delay=c;this.scheduler=d}a.prototype.call=function(a){return new e(a,this.delay,this.scheduler)};return a}(),e=function(a){function c(c,b,e){a.call(this,c);this.delay=b;this.scheduler=e;this.hasValue=!1;this.add(e.schedule(g,b,{subscriber:this,delay:b}))}k(c,a);c.prototype._next=
|
||||
function(a){this.lastValue=a;this.hasValue=!0};c.prototype.notifyNext=function(){this.hasValue&&(this.hasValue=!1,this.destination.next(this.lastValue))};return c}(b.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],190:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.scan=function(a,b){return this.lift(new k(a,
|
||||
b))};var k=function(){function a(b,d){this.accumulator=b;this.seed=d}a.prototype.call=function(a){return new l(a,this.accumulator,this.seed)};return a}(),l=function(a){function b(d,c,e){a.call(this,d);this.accumulator=c;this.accumulatorSet=!1;this.seed=e;this.accumulator=c;this.accumulatorSet="undefined"!==typeof e}g(b,a);Object.defineProperty(b.prototype,"seed",{get:function(){return this._seed},set:function(a){this.accumulatorSet=!0;this._seed=a},enumerable:!0,configurable:!0});b.prototype._next=
|
||||
function(a){if(this.accumulatorSet)return this._tryNext(a);this.seed=a;this.destination.next(a)};b.prototype._tryNext=function(a){var c;try{c=this.accumulator(this.seed,a)}catch(b){this.destination.error(b)}this.seed=c;this.destination.next(c)};return b}(a.Subscriber)},{"../Subscriber":9}],191:[function(a,b,f){function g(){return new l.Subject}var k=a("./multicast"),l=a("../Subject");f.share=function(){return k.multicast.call(this,g).refCount()}},{"../Subject":8,"./multicast":175}],192:[function(a,
|
||||
b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../util/EmptyError");f.single=function(a){return this.lift(new l(a,this))};var l=function(){function a(d,c){this.predicate=d;this.source=c}a.prototype.call=function(a){return new h(a,this.predicate,this.source)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.predicate=
|
||||
d;this.source=b;this.seenValue=!1;this.index=0}g(d,a);d.prototype.applySingleValue=function(a){this.seenValue?this.destination.error("Sequence contains more than one element"):(this.seenValue=!0,this.singleValue=a)};d.prototype._next=function(a){var d=this.predicate;this.index++;d?this.tryNext(a):this.applySingleValue(a)};d.prototype.tryNext=function(a){try{this.predicate(a,this.index,this.source)&&this.applySingleValue(a)}catch(d){this.destination.error(d)}};d.prototype._complete=function(){var a=
|
||||
this.destination;0<this.index?(a.next(this.seenValue?this.singleValue:void 0),a.complete()):a.error(new k.EmptyError)};return d}(b.Subscriber)},{"../Subscriber":9,"../util/EmptyError":232}],193:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.skip=function(a){return this.lift(new k(a))};var k=function(){function a(b){this.total=
|
||||
b}a.prototype.call=function(a){return new l(a,this.total)};return a}(),l=function(a){function b(d,c){a.call(this,d);this.total=c;this.count=0}g(b,a);b.prototype._next=function(a){++this.count>this.total&&this.destination.next(a)};return b}(a.Subscriber)},{"../Subscriber":9}],194:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");
|
||||
var k=a("../util/subscribeToResult");f.skipUntil=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.notifier=d}a.prototype.call=function(a){return new h(a,this.notifier)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.isInnerStopped=this.hasValue=!1;this.add(k.subscribeToResult(this,d))}g(d,a);d.prototype._next=function(c){this.hasValue&&a.prototype._next.call(this,c)};d.prototype._complete=function(){this.isInnerStopped?a.prototype._complete.call(this):this.unsubscribe()};
|
||||
d.prototype.notifyNext=function(a,d,b,e,f){this.hasValue=!0};d.prototype.notifyComplete=function(){this.isInnerStopped=!0;this.isStopped&&a.prototype._complete.call(this)};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],195:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.skipWhile=
|
||||
function(a){return this.lift(new k(a))};var k=function(){function a(b){this.predicate=b}a.prototype.call=function(a){return new l(a,this.predicate)};return a}(),l=function(a){function b(d,c){a.call(this,d);this.predicate=c;this.skipping=!0;this.index=0}g(b,a);b.prototype._next=function(a){var c=this.destination;this.skipping&&this.tryCallPredicate(a);this.skipping||c.next(a)};b.prototype.tryCallPredicate=function(a){try{this.skipping=!!this.predicate(a,this.index++)}catch(c){this.destination.error(c)}};
|
||||
return b}(a.Subscriber)},{"../Subscriber":9}],196:[function(a,b,f){var g=a("../observable/ArrayObservable"),k=a("../observable/ScalarObservable"),l=a("../observable/EmptyObservable"),h=a("./concat"),e=a("../util/isScheduler");f.startWith=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];c=a[a.length-1];e.isScheduler(c)?a.pop():c=null;var b=a.length;return 1===b?h.concatStatic(new k.ScalarObservable(a[0],c),this):1<b?h.concatStatic(new g.ArrayObservable(a,c),this):h.concatStatic(new l.EmptyObservable(c),
|
||||
this)}},{"../observable/ArrayObservable":116,"../observable/EmptyObservable":121,"../observable/ScalarObservable":132,"../util/isScheduler":246,"./concat":144}],197:[function(a,b,f){var g=a("../observable/SubscribeOnObservable");f.subscribeOn=function(a,b){void 0===b&&(b=0);return new g.SubscribeOnObservable(this,b,a)}},{"../observable/SubscribeOnObservable":133}],198:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=
|
||||
d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f._switch=function(){return this.lift(new l)};var l=function(){function a(){}a.prototype.call=function(a){return new h(a)};return a}(),h=function(a){function d(c){a.call(this,c);this.active=0;this.hasCompleted=!1}g(d,a);d.prototype._next=function(a){this.unsubscribeInner();this.active++;this.add(this.innerSubscription=k.subscribeToResult(this,a))};d.prototype._complete=
|
||||
function(){this.hasCompleted=!0;0===this.active&&this.destination.complete()};d.prototype.unsubscribeInner=function(){this.active=0<this.active?this.active-1:0;var a=this.innerSubscription;a&&(a.unsubscribe(),this.remove(a))};d.prototype.notifyNext=function(a,d,b,e,f){this.destination.next(d)};d.prototype.notifyError=function(a){this.destination.error(a)};d.prototype.notifyComplete=function(){this.unsubscribeInner();this.hasCompleted&&0===this.active&&this.destination.complete()};return d}(b.OuterSubscriber)},
|
||||
{"../OuterSubscriber":6,"../util/subscribeToResult":250}],199:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.switchMap=function(a,d){return this.lift(new l(a,d))};var l=function(){function a(d,c){this.project=d;this.resultSelector=c}a.prototype.call=function(a){return new h(a,
|
||||
this.project,this.resultSelector)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.project=d;this.resultSelector=b;this.index=0}g(d,a);d.prototype._next=function(a){var d,b=this.index++;try{d=this.project(a,b)}catch(e){this.destination.error(e);return}this._innerSub(d,a,b)};d.prototype._innerSub=function(a,d,b){var e=this.innerSubscription;e&&e.unsubscribe();this.add(this.innerSubscription=k.subscribeToResult(this,a,d,b))};d.prototype._complete=function(){var c=this.innerSubscription;
|
||||
c&&!c.isUnsubscribed||a.prototype._complete.call(this)};d.prototype._unsubscribe=function(){this.innerSubscription=null};d.prototype.notifyComplete=function(c){this.remove(c);this.innerSubscription=null;this.isStopped&&a.prototype._complete.call(this)};d.prototype.notifyNext=function(a,d,b,e,f){this.resultSelector?this._tryNotifyNext(a,d,b,e):this.destination.next(d)};d.prototype._tryNotifyNext=function(a,d,b,e){var f;try{f=this.resultSelector(a,d,b,e)}catch(h){this.destination.error(h);return}this.destination.next(f)};
|
||||
return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],200:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.switchMapTo=function(a,d){return this.lift(new l(a,d))};var l=function(){function a(d,c){this.observable=d;this.resultSelector=c}a.prototype.call=
|
||||
function(a){return new h(a,this.observable,this.resultSelector)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.inner=d;this.resultSelector=b;this.index=0}g(d,a);d.prototype._next=function(a){var d=this.innerSubscription;d&&d.unsubscribe();this.add(this.innerSubscription=k.subscribeToResult(this,this.inner,a,this.index++))};d.prototype._complete=function(){var c=this.innerSubscription;c&&!c.isUnsubscribed||a.prototype._complete.call(this)};d.prototype._unsubscribe=function(){this.innerSubscription=
|
||||
null};d.prototype.notifyComplete=function(c){this.remove(c);this.innerSubscription=null;this.isStopped&&a.prototype._complete.call(this)};d.prototype.notifyNext=function(a,d,b,e,f){f=this.destination;this.resultSelector?this.tryResultSelector(a,d,b,e):f.next(d)};d.prototype.tryResultSelector=function(a,d,b,e){var f=this.resultSelector,h=this.destination,k;try{k=f(a,d,b,e)}catch(g){h.error(g);return}h.next(k)};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],
|
||||
201:[function(a,b,f){var g=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)};b=a("../Subscriber");var k=a("../util/ArgumentOutOfRangeError"),l=a("../observable/EmptyObservable");f.take=function(a){return 0===a?new l.EmptyObservable:this.lift(new h(a))};var h=function(){function a(c){this.total=c;if(0>this.total)throw new k.ArgumentOutOfRangeError;}a.prototype.call=
|
||||
function(a){return new e(a,this.total)};return a}(),e=function(a){function c(c,b){a.call(this,c);this.total=b;this.count=0}g(c,a);c.prototype._next=function(a){var c=this.total;++this.count<=c&&(this.destination.next(a),this.count===c&&this.destination.complete())};return c}(b.Subscriber)},{"../Subscriber":9,"../observable/EmptyObservable":121,"../util/ArgumentOutOfRangeError":231}],202:[function(a,b,f){var g=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&
|
||||
(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)};b=a("../Subscriber");var k=a("../util/ArgumentOutOfRangeError"),l=a("../observable/EmptyObservable");f.takeLast=function(a){return 0===a?new l.EmptyObservable:this.lift(new h(a))};var h=function(){function a(c){this.total=c;if(0>this.total)throw new k.ArgumentOutOfRangeError;}a.prototype.call=function(a){return new e(a,this.total)};return a}(),e=function(a){function c(c,b){a.call(this,c);this.total=b;this.index=this.count=
|
||||
0;this.ring=Array(b)}g(c,a);c.prototype._next=function(a){var c=this.index,d=this.ring,b=this.total,e=this.count;1<b?e<b?(this.count=e+1,this.index=c+1):this.index=0===c?++c:c<b?c+1:c=0:e<b&&(this.count=b);d[c]=a};c.prototype._complete=function(){for(var a=-1,c=this.ring,d=this.count,b=this.total,e=this.destination,f=1===b||d<b?0:this.index-1;++a<d;)a+f===b&&(f=b-a),e.next(c[a+f]);e.complete()};return c}(b.Subscriber)},{"../Subscriber":9,"../observable/EmptyObservable":121,"../util/ArgumentOutOfRangeError":231}],
|
||||
203:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.takeUntil=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.notifier=d}a.prototype.call=function(a){return new h(a,this.notifier)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.notifier=
|
||||
d;this.add(k.subscribeToResult(this,d))}g(d,a);d.prototype.notifyNext=function(a,d,b,e,f){this.complete()};d.prototype.notifyComplete=function(){};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],204:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.takeWhile=function(a){return this.lift(new k(a))};
|
||||
var k=function(){function a(b){this.predicate=b}a.prototype.call=function(a){return new l(a,this.predicate)};return a}(),l=function(a){function b(d,c){a.call(this,d);this.predicate=c;this.index=0}g(b,a);b.prototype._next=function(a){var c=this.destination,b;try{b=this.predicate(a,this.index++)}catch(e){c.error(e);return}this.nextOrComplete(a,b)};b.prototype.nextOrComplete=function(a,c){var b=this.destination;c?b.next(a):b.complete()};return b}(a.Subscriber)},{"../Subscriber":9}],205:[function(a,b,
|
||||
f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.throttle=function(a){return this.lift(new l(a))};var l=function(){function a(d){this.durationSelector=d}a.prototype.call=function(a){return new h(a,this.durationSelector)};return a}(),h=function(a){function d(c,d){a.call(this,c);this.destination=
|
||||
c;this.durationSelector=d}g(d,a);d.prototype._next=function(a){this.throttled||this.tryDurationSelector(a)};d.prototype.tryDurationSelector=function(a){var d=null;try{d=this.durationSelector(a)}catch(b){this.destination.error(b);return}this.emitAndThrottle(a,d)};d.prototype.emitAndThrottle=function(a,d){this.add(this.throttled=k.subscribeToResult(this,d));this.destination.next(a)};d.prototype._unsubscribe=function(){var a=this.throttled;a&&(this.remove(a),this.throttled=null,a.unsubscribe())};d.prototype.notifyNext=
|
||||
function(a,d,b,e,f){this._unsubscribe()};d.prototype.notifyComplete=function(){this._unsubscribe()};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../util/subscribeToResult":250}],206:[function(a,b,f){function g(a){a.subscriber.clearThrottle()}var k=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)};b=a("../Subscriber");var l=a("../scheduler/asap");f.throttleTime=
|
||||
function(a,c){void 0===c&&(c=l.asap);return this.lift(new h(a,c))};var h=function(){function a(c,d){this.delay=c;this.scheduler=d}a.prototype.call=function(a){return new e(a,this.delay,this.scheduler)};return a}(),e=function(a){function c(c,b,e){a.call(this,c);this.delay=b;this.scheduler=e}k(c,a);c.prototype._next=function(a){this.throttled||(this.add(this.throttled=this.scheduler.schedule(g,this.delay,{subscriber:this})),this.destination.next(a))};c.prototype.clearThrottle=function(){var a=this.throttled;
|
||||
a&&(a.unsubscribe(),this.remove(a),this.throttled=null)};return c}(b.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224}],207:[function(a,b,f){var g=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)},k=a("../scheduler/asap"),l=a("../util/isDate");a=a("../Subscriber");f.timeout=function(a,c,b){void 0===c&&(c=null);void 0===b&&(b=k.asap);var e=l.isDate(a);a=e?
|
||||
+a-b.now():Math.abs(a);return this.lift(new h(a,e,c,b))};var h=function(){function a(c,d,b,e){this.waitFor=c;this.absoluteTimeout=d;this.errorToSend=b;this.scheduler=e}a.prototype.call=function(a){return new e(a,this.absoluteTimeout,this.waitFor,this.errorToSend,this.scheduler)};return a}(),e=function(a){function c(c,b,e,f,h){a.call(this,c);this.absoluteTimeout=b;this.waitFor=e;this.errorToSend=f;this.scheduler=h;this._previousIndex=this.index=0;this._hasCompleted=!1;this.scheduleTimeout()}g(c,a);
|
||||
Object.defineProperty(c.prototype,"previousIndex",{get:function(){return this._previousIndex},enumerable:!0,configurable:!0});Object.defineProperty(c.prototype,"hasCompleted",{get:function(){return this._hasCompleted},enumerable:!0,configurable:!0});c.dispatchTimeout=function(a){var c=a.subscriber;a=a.index;c.hasCompleted||c.previousIndex!==a||c.notifyTimeout()};c.prototype.scheduleTimeout=function(){var a=this.index;this.scheduler.schedule(c.dispatchTimeout,this.waitFor,{subscriber:this,index:a});
|
||||
this.index++;this._previousIndex=a};c.prototype._next=function(a){this.destination.next(a);this.absoluteTimeout||this.scheduleTimeout()};c.prototype._error=function(a){this.destination.error(a);this._hasCompleted=!0};c.prototype._complete=function(){this.destination.complete();this._hasCompleted=!0};c.prototype.notifyTimeout=function(){this.error(this.errorToSend||Error("timeout"))};return c}(a.Subscriber)},{"../Subscriber":9,"../scheduler/asap":224,"../util/isDate":241}],208:[function(a,b,f){var g=
|
||||
this&&this.__extends||function(a,d){function b(){this.constructor=a}for(var e in d)d.hasOwnProperty(e)&&(a[e]=d[e]);a.prototype=null===d?Object.create(d):(b.prototype=d.prototype,new b)},k=a("../scheduler/asap"),l=a("../util/isDate");b=a("../OuterSubscriber");var h=a("../util/subscribeToResult");f.timeoutWith=function(a,d,b){void 0===b&&(b=k.asap);var f=l.isDate(a);a=f?+a-b.now():Math.abs(a);return this.lift(new e(a,f,d,b))};var e=function(){function a(c,d,b,e){this.waitFor=c;this.absoluteTimeout=
|
||||
d;this.withObservable=b;this.scheduler=e}a.prototype.call=function(a){return new d(a,this.absoluteTimeout,this.waitFor,this.withObservable,this.scheduler)};return a}(),d=function(a){function d(b,e,f,h,k){a.call(this);this.destination=b;this.absoluteTimeout=e;this.waitFor=f;this.withObservable=h;this.scheduler=k;this.timeoutSubscription=void 0;this._previousIndex=this.index=0;this._hasCompleted=!1;b.add(this);this.scheduleTimeout()}g(d,a);Object.defineProperty(d.prototype,"previousIndex",{get:function(){return this._previousIndex},
|
||||
enumerable:!0,configurable:!0});Object.defineProperty(d.prototype,"hasCompleted",{get:function(){return this._hasCompleted},enumerable:!0,configurable:!0});d.dispatchTimeout=function(a){var c=a.subscriber;a=a.index;c.hasCompleted||c.previousIndex!==a||c.handleTimeout()};d.prototype.scheduleTimeout=function(){var a=this.index;this.scheduler.schedule(d.dispatchTimeout,this.waitFor,{subscriber:this,index:a});this.index++;this._previousIndex=a};d.prototype._next=function(a){this.destination.next(a);this.absoluteTimeout||
|
||||
this.scheduleTimeout()};d.prototype._error=function(a){this.destination.error(a);this._hasCompleted=!0};d.prototype._complete=function(){this.destination.complete();this._hasCompleted=!0};d.prototype.handleTimeout=function(){if(!this.isUnsubscribed){var a=this.withObservable;this.unsubscribe();this.destination.add(this.timeoutSubscription=h.subscribeToResult(this,a))}};return d}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../scheduler/asap":224,"../util/isDate":241,"../util/subscribeToResult":250}],
|
||||
209:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};a=a("../Subscriber");f.toArray=function(){return this.lift(new k)};var k=function(){function a(){}a.prototype.call=function(a){return new l(a)};return a}(),l=function(a){function b(d){a.call(this,d);this.array=[]}g(b,a);b.prototype._next=function(a){this.array.push(a)};b.prototype._complete=
|
||||
function(){this.destination.next(this.array);this.destination.complete()};return b}(a.Subscriber)},{"../Subscriber":9}],210:[function(a,b,f){var g=a("../util/root");f.toPromise=function(a){var b=this;a||(g.root.Rx&&g.root.Rx.config&&g.root.Rx.config.Promise?a=g.root.Rx.config.Promise:g.root.Promise&&(a=g.root.Promise));if(!a)throw Error("no Promise impl found");return new a(function(a,e){var d;b.subscribe(function(a){return d=a},function(a){return e(a)},function(){return a(d)})})}},{"../util/root":249}],
|
||||
211:[function(a,b,f){var g=this&&this.__extends||function(a,c){function b(){this.constructor=a}for(var e in c)c.hasOwnProperty(e)&&(a[e]=c[e]);a.prototype=null===c?Object.create(c):(b.prototype=c.prototype,new b)},k=a("../Subject");b=a("../OuterSubscriber");var l=a("../util/subscribeToResult");f.window=function(a){return this.lift(new h(a))};var h=function(){function a(c){this.closingNotifier=c}a.prototype.call=function(a){return new e(a,this.closingNotifier)};return a}(),e=function(a){function c(c,
|
||||
b){a.call(this,c);this.destination=c;this.closingNotifier=b;this.add(l.subscribeToResult(this,b));this.openWindow()}g(c,a);c.prototype.notifyNext=function(a,c,d,b,e){this.openWindow()};c.prototype.notifyError=function(a,c){this._error(a)};c.prototype.notifyComplete=function(a){this._complete()};c.prototype._next=function(a){this.window.next(a)};c.prototype._error=function(a){this.window.error(a);this.destination.error(a)};c.prototype._complete=function(){this.window.complete();this.destination.complete()};
|
||||
c.prototype.openWindow=function(){var a=this.window;a&&a.complete();var a=this.destination,c=this.window=new k.Subject;a.add(c);a.next(c)};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subject":8,"../util/subscribeToResult":250}],212:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../Subscriber");var k=a("../Subject");f.windowCount=
|
||||
function(a,d){void 0===d&&(d=0);return this.lift(new l(a,d))};var l=function(){function a(d,c){this.windowSize=d;this.startWindowEvery=c}a.prototype.call=function(a){return new h(a,this.windowSize,this.startWindowEvery)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.destination=c;this.windowSize=d;this.startWindowEvery=b;this.windows=[new k.Subject];this.count=0;d=this.windows[0];c.add(d);c.next(d)}g(d,a);d.prototype._next=function(a){for(var d=0<this.startWindowEvery?this.startWindowEvery:
|
||||
this.windowSize,b=this.destination,e=this.windowSize,f=this.windows,h=f.length,g=0;g<h;g++)f[g].next(a);a=this.count-e+1;0<=a&&0===a%d&&f.shift().complete();0===++this.count%d&&(d=new k.Subject,f.push(d),b.add(d),b.next(d))};d.prototype._error=function(a){for(var d=this.windows;0<d.length;)d.shift().error(a);this.destination.error(a)};d.prototype._complete=function(){for(var a=this.windows;0<a.length;)a.shift().complete();this.destination.complete()};return d}(b.Subscriber)},{"../Subject":8,"../Subscriber":9}],
|
||||
213:[function(a,b,f){function g(a){var c=a.subscriber,d=a.windowTimeSpan,b=a.window;b&&b.complete();a.window=c.openWindow();this.schedule(a,d)}function k(a){var c=a.windowTimeSpan,d=a.subscriber,b=a.scheduler,e=a.windowCreationInterval,f=d.openWindow(),h={action:this,subscription:null};h.subscription=b.schedule(l,c,{subscriber:d,window:f,context:h});this.add(h.subscription);this.schedule(a,e)}function l(a){var c=a.subscriber,d=a.window;(a=a.context)&&a.action&&a.subscription&&a.action.remove(a.subscription);
|
||||
c.closeWindow(d)}var h=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)};b=a("../Subscriber");var e=a("../Subject"),d=a("../scheduler/asap");f.windowTime=function(a,b,e){void 0===b&&(b=null);void 0===e&&(e=d.asap);return this.lift(new c(a,b,e))};var c=function(){function a(c,d,b){this.windowTimeSpan=c;this.windowCreationInterval=d;this.scheduler=b}a.prototype.call=
|
||||
function(a){return new m(a,this.windowTimeSpan,this.windowCreationInterval,this.scheduler)};return a}(),m=function(a){function c(d,b,e,f){a.call(this,d);this.destination=d;this.windowTimeSpan=b;this.windowCreationInterval=e;this.scheduler=f;this.windows=[];if(null!==e&&0<=e){d={subscriber:this,window:this.openWindow(),context:null};var h={windowTimeSpan:b,windowCreationInterval:e,subscriber:this,scheduler:f};this.add(f.schedule(l,b,d));this.add(f.schedule(k,e,h))}else e={subscriber:this,window:this.openWindow(),
|
||||
windowTimeSpan:b},this.add(f.schedule(g,b,e))}h(c,a);c.prototype._next=function(a){for(var c=this.windows,d=c.length,b=0;b<d;b++){var e=c[b];e.isUnsubscribed||e.next(a)}};c.prototype._error=function(a){for(var c=this.windows;0<c.length;)c.shift().error(a);this.destination.error(a)};c.prototype._complete=function(){for(var a=this.windows;0<a.length;){var c=a.shift();c.isUnsubscribed||c.complete()}this.destination.complete()};c.prototype.openWindow=function(){var a=new e.Subject;this.windows.push(a);
|
||||
var c=this.destination;c.add(a);c.next(a);return a};c.prototype.closeWindow=function(a){a.complete();var c=this.windows;c.splice(c.indexOf(a),1)};return c}(b.Subscriber)},{"../Subject":8,"../Subscriber":9,"../scheduler/asap":224}],214:[function(a,b,f){var g=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../Subject"),l=a("../Subscription"),h=a("../util/tryCatch"),
|
||||
e=a("../util/errorObject");b=a("../OuterSubscriber");var d=a("../util/subscribeToResult");f.windowToggle=function(a,d){return this.lift(new c(a,d))};var c=function(){function a(c,d){this.openings=c;this.closingSelector=d}a.prototype.call=function(a){return new m(a,this.openings,this.closingSelector)};return a}(),m=function(a){function c(b,e,f){a.call(this,b);this.openings=e;this.closingSelector=f;this.contexts=[];this.add(this.openSubscription=d.subscribeToResult(this,e,e))}g(c,a);c.prototype._next=
|
||||
function(a){var c=this.contexts;if(c)for(var d=c.length,b=0;b<d;b++)c[b].window.next(a)};c.prototype._error=function(c){var d=this.contexts;this.contexts=null;if(d)for(var b=d.length,e=-1;++e<b;){var f=d[e];f.window.error(c);f.subscription.unsubscribe()}a.prototype._error.call(this,c)};c.prototype._complete=function(){var c=this.contexts;this.contexts=null;if(c)for(var d=c.length,b=-1;++b<d;){var e=c[b];e.window.complete();e.subscription.unsubscribe()}a.prototype._complete.call(this)};c.prototype._unsubscribe=
|
||||
function(){var a=this.contexts;this.contexts=null;if(a)for(var c=a.length,d=-1;++d<c;){var b=a[d];b.window.unsubscribe();b.subscription.unsubscribe()}};c.prototype.notifyNext=function(a,c,b,f,g){if(a===this.openings){f=h.tryCatch(this.closingSelector)(c);if(f===e.errorObject)return this.error(e.errorObject.e);a=new k.Subject;c=new l.Subscription;b={window:a,subscription:c};this.contexts.push(b);f=d.subscribeToResult(this,f,b);f.context=b;c.add(f);this.destination.next(a)}else this.closeWindow(this.contexts.indexOf(a))};
|
||||
c.prototype.notifyError=function(a){this.error(a)};c.prototype.notifyComplete=function(a){a!==this.openSubscription&&this.closeWindow(this.contexts.indexOf(a.context))};c.prototype.closeWindow=function(a){var c=this.contexts,d=c[a],b=d.window,d=d.subscription;c.splice(a,1);b.complete();d.unsubscribe()};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subject":8,"../Subscription":10,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],215:[function(a,b,f){var g=
|
||||
this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},k=a("../Subject"),l=a("../util/tryCatch"),h=a("../util/errorObject");b=a("../OuterSubscriber");var e=a("../util/subscribeToResult");f.windowWhen=function(a){return this.lift(new d(a))};var d=function(){function a(c){this.closingSelector=c}a.prototype.call=function(a){return new c(a,this.closingSelector)};return a}(),
|
||||
c=function(a){function c(d,b){a.call(this,d);this.destination=d;this.closingSelector=b;this.openWindow()}g(c,a);c.prototype.notifyNext=function(a,c,d,b,e){this.openWindow(e)};c.prototype.notifyError=function(a,c){this._error(a)};c.prototype.notifyComplete=function(a){this.openWindow(a)};c.prototype._next=function(a){this.window.next(a)};c.prototype._error=function(a){this.window.error(a);this.destination.error(a);this.unsubscribeClosingNotification()};c.prototype._complete=function(){this.window.complete();
|
||||
this.destination.complete();this.unsubscribeClosingNotification()};c.prototype.unsubscribeClosingNotification=function(){this.closingNotification&&this.closingNotification.unsubscribe()};c.prototype.openWindow=function(a){void 0===a&&(a=null);a&&(this.remove(a),a.unsubscribe());(a=this.window)&&a.complete();a=this.window=new k.Subject;this.destination.next(a);var c=l.tryCatch(this.closingSelector)();c===h.errorObject?(a=h.errorObject.e,this.destination.error(a),this.window.error(a)):(this.add(this.closingNotification=
|
||||
e.subscribeToResult(this,c)),this.add(a))};return c}(b.OuterSubscriber)},{"../OuterSubscriber":6,"../Subject":8,"../util/errorObject":239,"../util/subscribeToResult":250,"../util/tryCatch":253}],216:[function(a,b,f){var g=this&&this.__extends||function(a,d){function c(){this.constructor=a}for(var b in d)d.hasOwnProperty(b)&&(a[b]=d[b]);a.prototype=null===d?Object.create(d):(c.prototype=d.prototype,new c)};b=a("../OuterSubscriber");var k=a("../util/subscribeToResult");f.withLatestFrom=function(){for(var a=
|
||||
[],d=0;d<arguments.length;d++)a[d-0]=arguments[d];var c;"function"===typeof a[a.length-1]&&(c=a.pop());return this.lift(new l(a,c))};var l=function(){function a(d,c){this.observables=d;this.project=c}a.prototype.call=function(a){return new h(a,this.observables,this.project)};return a}(),h=function(a){function d(c,d,b){a.call(this,c);this.observables=d;this.project=b;this.toRespond=[];c=d.length;this.values=Array(c);for(b=0;b<c;b++)this.toRespond.push(b);for(b=0;b<c;b++){var f=d[b];this.add(k.subscribeToResult(this,
|
||||
f,f,b))}}g(d,a);d.prototype.notifyNext=function(a,d,b,e,f){this.values[b]=d;a=this.toRespond;0<a.length&&(b=a.indexOf(b),-1!==b&&a.splice(b,1))};d.prototype.notifyComplete=function(){};d.prototype._next=function(a){0===this.toRespond.length&&(a=[a].concat(this.values),this.project?this._tryProject(a):this.destination.next(a))};d.prototype._tryProject=function(a){var d;try{d=this.project.apply(this,a)}catch(b){this.destination.error(b);return}this.destination.next(d)};return d}(b.OuterSubscriber)},
|
||||
{"../OuterSubscriber":6,"../util/subscribeToResult":250}],217:[function(a,b,f){function g(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];c=a[a.length-1];"function"===typeof c&&a.pop();return(new l.ArrayObservable(a)).lift(new m(c))}var k=this&&this.__extends||function(a,c){function d(){this.constructor=a}for(var b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);a.prototype=null===c?Object.create(c):(d.prototype=c.prototype,new d)},l=a("../observable/ArrayObservable"),h=a("../util/isArray");b=
|
||||
a("../Subscriber");var e=a("../OuterSubscriber"),d=a("../util/subscribeToResult"),c=a("../util/SymbolShim");f.zipProto=function(){for(var a=[],c=0;c<arguments.length;c++)a[c-0]=arguments[c];a.unshift(this);return g.apply(this,a)};f.zipStatic=g;var m=function(){function a(c){this.project=c}a.prototype.call=function(a){return new n(a,this.project)};return a}();f.ZipOperator=m;var n=function(a){function d(c,b,e){void 0===e&&(e=Object.create(null));a.call(this,c);this.index=0;this.iterators=[];this.active=
|
||||
0;this.project="function"===typeof b?b:null;this.values=e}k(d,a);d.prototype._next=function(a){var d=this.iterators,b=this.index++;h.isArray(a)?d.push(new p(a)):"function"===typeof a[c.SymbolShim.iterator]?d.push(new q(a[c.SymbolShim.iterator]())):d.push(new u(this.destination,this,a,b))};d.prototype._complete=function(){var a=this.iterators,c=a.length;this.active=c;for(var d=0;d<c;d++){var b=a[d];b.stillUnsubscribed?this.add(b.subscribe(b,d)):this.active--}};d.prototype.notifyInactive=function(){this.active--;
|
||||
0===this.active&&this.destination.complete()};d.prototype.checkIterators=function(){for(var a=this.iterators,c=a.length,d=this.destination,b=0;b<c;b++){var e=a[b];if("function"===typeof e.hasValue&&!e.hasValue())return}for(var f=!1,h=[],b=0;b<c;b++){var e=a[b],g=e.next();e.hasCompleted()&&(f=!0);if(g.done){d.complete();return}h.push(g.value)}this.project?this._tryProject(h):d.next(h);f&&d.complete()};d.prototype._tryProject=function(a){var c;try{c=this.project.apply(this,a)}catch(d){this.destination.error(d);
|
||||
return}this.destination.next(c)};return d}(b.Subscriber);f.ZipSubscriber=n;var q=function(){function a(c){this.iterator=c;this.nextResult=c.next()}a.prototype.hasValue=function(){return!0};a.prototype.next=function(){var a=this.nextResult;this.nextResult=this.iterator.next();return a};a.prototype.hasCompleted=function(){var a=this.nextResult;return a&&a.done};return a}(),p=function(){function a(c){this.array=c;this.length=this.index=0;this.length=c.length}a.prototype[c.SymbolShim.iterator]=function(){return this};
|
||||
a.prototype.next=function(a){a=this.index++;var c=this.array;return a<this.length?{value:c[a],done:!1}:{done:!0}};a.prototype.hasValue=function(){return this.array.length>this.index};a.prototype.hasCompleted=function(){return this.array.length===this.index};return a}(),u=function(a){function b(c,d,e,f){a.call(this,c);this.parent=d;this.observable=e;this.index=f;this.stillUnsubscribed=!0;this.buffer=[];this.isComplete=!1}k(b,a);b.prototype[c.SymbolShim.iterator]=function(){return this};b.prototype.next=
|
||||
function(){var a=this.buffer;return 0===a.length&&this.isComplete?{done:!0}:{value:a.shift(),done:!1}};b.prototype.hasValue=function(){return 0<this.buffer.length};b.prototype.hasCompleted=function(){return 0===this.buffer.length&&this.isComplete};b.prototype.notifyComplete=function(){0<this.buffer.length?(this.isComplete=!0,this.parent.notifyInactive()):this.destination.complete()};b.prototype.notifyNext=function(a,c,d,b,e){this.buffer.push(c);this.parent.checkIterators()};b.prototype.subscribe=
|
||||
function(a,c){return d.subscribeToResult(this,this.observable,this,c)};return b}(e.OuterSubscriber)},{"../OuterSubscriber":6,"../Subscriber":9,"../observable/ArrayObservable":116,"../util/SymbolShim":238,"../util/isArray":240,"../util/subscribeToResult":250}],218:[function(a,b,f){var g=a("./zip");f.zipAll=function(a){return this.lift(new g.ZipOperator(a))}},{"./zip":217}],219:[function(a,b,f){var g=this&&this.__extends||function(a,b){function e(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&
|
||||
(a[d]=b[d]);a.prototype=null===b?Object.create(b):(e.prototype=b.prototype,new e)},k=a("../util/Immediate");a=function(a){function b(){a.apply(this,arguments)}g(b,a);b.prototype._schedule=function(b,d){void 0===d&&(d=0);if(0<d)return a.prototype._schedule.call(this,b,d);this.delay=d;this.state=b;var c=this.scheduler;c.actions.push(this);c.scheduledId||(c.scheduledId=k.Immediate.setImmediate(function(){c.scheduledId=null;c.flush()}));return this};b.prototype._unsubscribe=function(){var b=this.scheduler,
|
||||
d=b.scheduledId,c=b.actions;a.prototype._unsubscribe.call(this);0===c.length&&(b.active=!1,null!=d&&(b.scheduledId=null,k.Immediate.clearImmediate(d)))};return b}(a("./FutureAction").FutureAction);f.AsapAction=a},{"../util/Immediate":234,"./FutureAction":221}],220:[function(a,b,f){var g=this&&this.__extends||function(a,b){function e(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(e.prototype=b.prototype,new e)},k=a("./AsapAction");a=function(a){function b(){a.apply(this,
|
||||
arguments)}g(b,a);b.prototype.scheduleNow=function(a,b){return(new k.AsapAction(this,a)).schedule(b)};return b}(a("./QueueScheduler").QueueScheduler);f.AsapScheduler=a},{"./AsapAction":219,"./QueueScheduler":223}],221:[function(a,b,f){var g=this&&this.__extends||function(a,b){function e(){this.constructor=a}for(var d in b)b.hasOwnProperty(d)&&(a[d]=b[d]);a.prototype=null===b?Object.create(b):(e.prototype=b.prototype,new e)},k=a("../util/root");a=function(a){function b(e,d){a.call(this);this.scheduler=
|
||||
e;this.work=d}g(b,a);b.prototype.execute=function(){if(this.isUnsubscribed)throw Error("How did did we execute a canceled Action?");this.work(this.state)};b.prototype.schedule=function(a,b){void 0===b&&(b=0);return this.isUnsubscribed?this:this._schedule(a,b)};b.prototype._schedule=function(a,b){var c=this;void 0===b&&(b=0);this.delay=b;this.state=a;var f=this.id;null!=f&&(this.id=void 0,k.root.clearTimeout(f));this.id=k.root.setTimeout(function(){c.id=null;var a=c.scheduler;a.actions.push(c);a.flush()},
|
||||
b);return this};b.prototype._unsubscribe=function(){var a=this.id,b=this.scheduler.actions,c=b.indexOf(this);null!=a&&(this.id=null,k.root.clearTimeout(a));-1!==c&&b.splice(c,1);this.scheduler=this.state=this.work=null};return b}(a("../Subscription").Subscription);f.FutureAction=a},{"../Subscription":10,"../util/root":249}],222:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):
|
||||
(f.prototype=b.prototype,new f)};a=function(a){function b(){a.apply(this,arguments)}g(b,a);b.prototype._schedule=function(b,e){void 0===e&&(e=0);if(0<e)return a.prototype._schedule.call(this,b,e);this.delay=e;this.state=b;var d=this.scheduler;d.actions.push(this);d.flush();return this};return b}(a("./FutureAction").FutureAction);f.QueueAction=a},{"./FutureAction":221}],223:[function(a,b,f){var g=a("./QueueAction"),k=a("./FutureAction");a=function(){function a(){this.active=!1;this.actions=[];this.scheduledId=
|
||||
null}a.prototype.now=function(){return Date.now()};a.prototype.flush=function(){if(!this.active&&!this.scheduledId){this.active=!0;for(var a=this.actions,b=void 0;b=a.shift();)b.execute();this.active=!1}};a.prototype.schedule=function(a,b,d){void 0===b&&(b=0);return 0>=b?this.scheduleNow(a,d):this.scheduleLater(a,b,d)};a.prototype.scheduleNow=function(a,b){return(new g.QueueAction(this,a)).schedule(b)};a.prototype.scheduleLater=function(a,b,d){return(new k.FutureAction(this,a)).schedule(d,b)};return a}();
|
||||
f.QueueScheduler=a},{"./FutureAction":221,"./QueueAction":222}],224:[function(a,b,f){a=a("./AsapScheduler");f.asap=new a.AsapScheduler},{"./AsapScheduler":220}],225:[function(a,b,f){a=a("./QueueScheduler");f.queue=new a.QueueScheduler},{"./QueueScheduler":223}],226:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(){a.apply(this,
|
||||
arguments);this.value=null;this.hasNext=!1}g(b,a);b.prototype._subscribe=function(b){this.hasCompleted&&this.hasNext&&b.next(this.value);return a.prototype._subscribe.call(this,b)};b.prototype._next=function(a){this.value=a;this.hasNext=!0};b.prototype._complete=function(){var a=-1,b=this.observers,d=b.length;this.isUnsubscribed=!0;if(this.hasNext)for(;++a<d;){var c=b[a];c.next(this.value);c.complete()}else for(;++a<d;)b[a].complete();this.isUnsubscribed=!1;this.unsubscribe()};return b}(a("../Subject").Subject);
|
||||
f.AsyncSubject=a},{"../Subject":8}],227:[function(a,b,f){var g=this&&this.__extends||function(a,b){function d(){this.constructor=a}for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);a.prototype=null===b?Object.create(b):(d.prototype=b.prototype,new d)};b=a("../Subject");var k=a("../util/throwError"),l=a("../util/ObjectUnsubscribedError");a=function(a){function b(d){a.call(this);this._value=d}g(b,a);b.prototype.getValue=function(){if(this.hasErrored)k.throwError(this.errorValue);else if(this.isUnsubscribed)k.throwError(new l.ObjectUnsubscribedError);
|
||||
else return this._value};Object.defineProperty(b.prototype,"value",{get:function(){return this.getValue()},enumerable:!0,configurable:!0});b.prototype._subscribe=function(b){var c=a.prototype._subscribe.call(this,b);c&&!c.isUnsubscribed&&b.next(this._value);return c};b.prototype._next=function(b){a.prototype._next.call(this,this._value=b)};b.prototype._error=function(b){this.hasErrored=!0;a.prototype._error.call(this,this.errorValue=b)};return b}(b.Subject);f.BehaviorSubject=a},{"../Subject":8,"../util/ObjectUnsubscribedError":237,
|
||||
"../util/throwError":251}],228:[function(a,b,f){var g=this&&this.__extends||function(a,b){function c(){this.constructor=a}for(var f in b)b.hasOwnProperty(f)&&(a[f]=b[f]);a.prototype=null===b?Object.create(b):(c.prototype=b.prototype,new c)};b=a("../Subject");var k=a("../scheduler/queue"),l=a("../operator/observeOn");a=function(a){function b(c,d,f){void 0===c&&(c=Number.POSITIVE_INFINITY);void 0===d&&(d=Number.POSITIVE_INFINITY);a.call(this);this.events=[];this.scheduler=f;this.bufferSize=1>c?1:c;
|
||||
this._windowTime=1>d?1:d}g(b,a);b.prototype._next=function(b){var d=this._getNow();this.events.push(new h(d,b));this._trimBufferThenGetEvents(d);a.prototype._next.call(this,b)};b.prototype._subscribe=function(b){var d=this._trimBufferThenGetEvents(this._getNow()),f=this.scheduler;f&&b.add(b=new l.ObserveOnSubscriber(b,f));for(var f=-1,g=d.length;++f<g&&!b.isUnsubscribed;)b.next(d[f].value);return a.prototype._subscribe.call(this,b)};b.prototype._getNow=function(){return(this.scheduler||k.queue).now()};
|
||||
b.prototype._trimBufferThenGetEvents=function(a){for(var b=this.bufferSize,d=this._windowTime,e=this.events,f=e.length,g=0;g<f&&!(a-e[g].time<d);)g+=1;f>b&&(g=Math.max(g,f-b));0<g&&e.splice(0,g);return e};return b}(b.Subject);f.ReplaySubject=a;var h=function(){return function(a,b){this.time=a;this.value=b}}()},{"../Subject":8,"../operator/observeOn":176,"../scheduler/queue":225}],229:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&
|
||||
(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(f,e){a.call(this);this.subject=f;this.observer=e;this.isUnsubscribed=!1}g(b,a);b.prototype.unsubscribe=function(){if(!this.isUnsubscribed){this.isUnsubscribed=!0;var a=this.subject,b=a.observers;this.subject=null;b&&0!==b.length&&!a.isUnsubscribed&&(a=b.indexOf(this.observer),-1!==a&&b.splice(a,1))}};return b}(a("../Subscription").Subscription);f.SubjectSubscription=a},{"../Subscription":10}],
|
||||
230:[function(a,b,f){a=a("../util/SymbolShim");f.rxSubscriber=a.SymbolShim["for"]("rxSubscriber")},{"../util/SymbolShim":238}],231:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(){a.call(this,"argument out of range");this.name="ArgumentOutOfRangeError"}g(b,a);return b}(Error);f.ArgumentOutOfRangeError=a},{}],232:[function(a,
|
||||
b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(){a.call(this,"no elements in sequence");this.name="EmptyError"}g(b,a);return b}(Error);f.EmptyError=a},{}],233:[function(a,b,f){a=function(){function a(){this.values={}}a.prototype["delete"]=function(a){this.values[a]=null;return!0};a.prototype.set=function(a,b){this.values[a]=
|
||||
b;return this};a.prototype.get=function(a){return this.values[a]};a.prototype.forEach=function(a,b){var f=this.values,e;for(e in f)f.hasOwnProperty(e)&&null!==f[e]&&a.call(b,f[e],e)};a.prototype.clear=function(){this.values={}};return a}();f.FastMap=a},{}],234:[function(a,b,f){a=a("./root");b=function(){function a(b){this.root=b;b.setImmediate&&"function"===typeof b.setImmediate?(this.setImmediate=b.setImmediate.bind(b),this.clearImmediate=b.clearImmediate.bind(b)):(this.nextHandle=1,this.tasksByHandle=
|
||||
{},this.currentlyRunningATask=!1,this.canUseProcessNextTick()?this.setImmediate=this.createProcessNextTickSetImmediate():this.canUsePostMessage()?this.setImmediate=this.createPostMessageSetImmediate():this.canUseMessageChannel()?this.setImmediate=this.createMessageChannelSetImmediate():this.canUseReadyStateChange()?this.setImmediate=this.createReadyStateChangeSetImmediate():this.setImmediate=this.createSetTimeoutSetImmediate(),b=function h(a){delete h.instance.tasksByHandle[a]},b.instance=this,this.clearImmediate=
|
||||
b)}a.prototype.identify=function(a){return this.root.Object.prototype.toString.call(a)};a.prototype.canUseProcessNextTick=function(){return"[object process]"===this.identify(this.root.process)};a.prototype.canUseMessageChannel=function(){return!!this.root.MessageChannel};a.prototype.canUseReadyStateChange=function(){var a=this.root.document;return!!(a&&"onreadystatechange"in a.createElement("script"))};a.prototype.canUsePostMessage=function(){var a=this.root;if(a.postMessage&&!a.importScripts){var b=
|
||||
!0,f=a.onmessage;a.onmessage=function(){b=!1};a.postMessage("","*");a.onmessage=f;return b}return!1};a.prototype.partiallyApplied=function(a){for(var b=[],f=1;f<arguments.length;f++)b[f-1]=arguments[f];f=function d(){var a=d.handler,b=d.args;"function"===typeof a?a.apply(void 0,b):(new Function(""+a))()};f.handler=a;f.args=b;return f};a.prototype.addFromSetImmediateArguments=function(a){this.tasksByHandle[this.nextHandle]=this.partiallyApplied.apply(void 0,a);return this.nextHandle++};a.prototype.createProcessNextTickSetImmediate=
|
||||
function(){var a=function h(){var a=h.instance,b=a.addFromSetImmediateArguments(arguments);a.root.process.nextTick(a.partiallyApplied(a.runIfPresent,b));return b};a.instance=this;return a};a.prototype.createPostMessageSetImmediate=function(){var a=this.root,b="setImmediate$"+a.Math.random()+"$",f=function d(c){var f=d.instance;c.source===a&&"string"===typeof c.data&&0===c.data.indexOf(b)&&f.runIfPresent(+c.data.slice(b.length))};f.instance=this;a.addEventListener("message",f,!1);f=function c(){var a=
|
||||
c,b=a.messagePrefix,a=a.instance,f=a.addFromSetImmediateArguments(arguments);a.root.postMessage(b+f,"*");return f};f.instance=this;f.messagePrefix=b;return f};a.prototype.runIfPresent=function(a){if(this.currentlyRunningATask)this.root.setTimeout(this.partiallyApplied(this.runIfPresent,a),0);else{var b=this.tasksByHandle[a];if(b){this.currentlyRunningATask=!0;try{b()}finally{this.clearImmediate(a),this.currentlyRunningATask=!1}}}};a.prototype.createMessageChannelSetImmediate=function(){var a=this,
|
||||
b=new this.root.MessageChannel;b.port1.onmessage=function(b){a.runIfPresent(b.data)};var f=function d(){var a=d,b=a.channel,a=a.instance.addFromSetImmediateArguments(arguments);b.port2.postMessage(a);return a};f.channel=b;f.instance=this;return f};a.prototype.createReadyStateChangeSetImmediate=function(){var a=function h(){var a=h.instance,b=a.root.document,c=b.documentElement,f=a.addFromSetImmediateArguments(arguments),g=b.createElement("script");g.onreadystatechange=function(){a.runIfPresent(f);
|
||||
g.onreadystatechange=null;c.removeChild(g);g=null};c.appendChild(g);return f};a.instance=this;return a};a.prototype.createSetTimeoutSetImmediate=function(){var a=function h(){var a=h.instance,b=a.addFromSetImmediateArguments(arguments);a.root.setTimeout(a.partiallyApplied(a.runIfPresent,b),0);return b};a.instance=this;return a};return a}();f.ImmediateDefinition=b;f.Immediate=new b(a.root)},{"./root":249}],235:[function(a,b,f){b=a("./root");a=a("./MapPolyfill");f.Map=b.root.Map||a.MapPolyfill},{"./MapPolyfill":236,
|
||||
"./root":249}],236:[function(a,b,f){a=function(){function a(){this.size=0;this._values=[];this._keys=[]}a.prototype.get=function(a){a=this._keys.indexOf(a);return-1===a?void 0:this._values[a]};a.prototype.set=function(a,b){var f=this._keys.indexOf(a);-1===f?(this._keys.push(a),this._values.push(b),this.size++):this._values[f]=b;return this};a.prototype["delete"]=function(a){a=this._keys.indexOf(a);if(-1===a)return!1;this._values.splice(a,1);this._keys.splice(a,1);this.size--;return!0};a.prototype.clear=
|
||||
function(){this._keys.length=0;this.size=this._values.length=0};a.prototype.forEach=function(a,b){for(var f=0;f<this.size;f++)a.call(b,this._values[f],this._keys[f])};return a}();f.MapPolyfill=a},{}],237:[function(a,b,f){var g=this&&this.__extends||function(a,b){function f(){this.constructor=a}for(var e in b)b.hasOwnProperty(e)&&(a[e]=b[e]);a.prototype=null===b?Object.create(b):(f.prototype=b.prototype,new f)};a=function(a){function b(){a.call(this,"object unsubscribed");this.name="ObjectUnsubscribedError"}
|
||||
g(b,a);return b}(Error);f.ObjectUnsubscribedError=a},{}],238:[function(a,b,f){function g(a){var b=l(a);e(b,a);d(b);k(b);return b}function k(a){a["for"]||(a["for"]=h)}function l(a){a.Symbol||(a.Symbol=function(a){return"@@Symbol("+a+"):"+c++});return a.Symbol}function h(a){return"@@"+a}function e(a,b){if(!a.iterator)if("function"===typeof a["for"])a.iterator=a["for"]("iterator");else if(b.Set&&"function"===typeof(new b.Set)["@@iterator"])a.iterator="@@iterator";else if(b.Map)for(var c=Object.getOwnPropertyNames(b.Map.prototype),
|
||||
d=0;d<c.length;++d){var e=c[d];if("entries"!==e&&"size"!==e&&b.Map.prototype[e]===b.Map.prototype.entries){a.iterator=e;break}}else a.iterator="@@iterator"}function d(a){a.observable||(a.observable="function"===typeof a["for"]?a["for"]("observable"):"@@observable")}a=a("./root");f.polyfillSymbol=g;f.ensureFor=k;var c=0;f.ensureSymbol=l;f.symbolForPolyfill=h;f.ensureIterator=e;f.ensureObservable=d;f.SymbolShim=g(a.root)},{"./root":249}],239:[function(a,b,f){f.errorObject={e:{}}},{}],240:[function(a,
|
||||
b,f){f.isArray=Array.isArray||function(a){return a&&"number"===typeof a.length}},{}],241:[function(a,b,f){f.isDate=function(a){return a instanceof Date&&!isNaN(+a)}},{}],242:[function(a,b,f){f.isFunction=function(a){return"function"===typeof a}},{}],243:[function(a,b,f){var g=a("../util/isArray");f.isNumeric=function(a){return!g.isArray(a)&&0<=a-parseFloat(a)+1}},{"../util/isArray":240}],244:[function(a,b,f){f.isObject=function(a){return null!=a&&"object"===typeof a}},{}],245:[function(a,b,f){f.isPromise=
|
||||
function(a){return a&&"function"!==typeof a.subscribe&&"function"===typeof a.then}},{}],246:[function(a,b,f){f.isScheduler=function(a){return a&&"function"===typeof a.schedule}},{}],247:[function(a,b,f){f.noop=function(){}},{}],248:[function(a,b,f){f.not=function(a,b){function f(){return!f.pred.apply(f.thisArg,arguments)}f.pred=a;f.thisArg=b;return f}},{}],249:[function(a,b,f){a="undefined"!==typeof global?global:"undefined"!==typeof self?self:"undefined"!==typeof window?window:{};b={"boolean":!1,
|
||||
"function":!0,object:!0,number:!1,string:!1,undefined:!1};f.root=b[typeof self]&&self||b[typeof window]&&window;!(a=b[typeof a]&&a)||a.global!==a&&a.window!==a||(f.root=a)},{}],250:[function(a,b,f){var g=a("./root"),k=a("./isArray"),l=a("./isPromise"),h=a("../Observable"),e=a("../util/SymbolShim"),d=a("../InnerSubscriber");f.subscribeToResult=function(a,b,f,q){var p=new d.InnerSubscriber(a,f,q);if(!p.isUnsubscribed){if(b instanceof h.Observable){if(b._isScalar){p.next(b.value);p.complete();return}return b.subscribe(p)}if(k.isArray(b)){a=
|
||||
0;for(f=b.length;a<f&&!p.isUnsubscribed;a++)p.next(b[a]);p.isUnsubscribed||p.complete()}else{if(l.isPromise(b))return b.then(function(a){p.isUnsubscribed||(p.next(a),p.complete())},function(a){return p.error(a)}).then(null,function(a){g.root.setTimeout(function(){throw a;})}),p;if("function"===typeof b[e.SymbolShim.iterator]){for(a=0;a<b.length&&(p.next(b[a]),!p.isUnsubscribed);a++);p.isUnsubscribed||p.complete()}else if("function"===typeof b[e.SymbolShim.observable])if(b=b[e.SymbolShim.observable](),
|
||||
"function"!==typeof b.subscribe)p.error("invalid observable");else return b.subscribe(new d.InnerSubscriber(a,f,q));else p.error(new TypeError("unknown type returned"))}}}},{"../InnerSubscriber":1,"../Observable":3,"../util/SymbolShim":238,"./isArray":240,"./isPromise":245,"./root":249}],251:[function(a,b,f){f.throwError=function(a){throw a;}},{}],252:[function(a,b,f){var g=a("../Subscriber"),k=a("../symbol/rxSubscriber");f.toSubscriber=function(a,b,e){if(a&&"object"===typeof a){if(a instanceof g.Subscriber)return a;
|
||||
if("function"===typeof a[k.rxSubscriber])return a[k.rxSubscriber]()}return new g.Subscriber(a,b,e)}},{"../Subscriber":9,"../symbol/rxSubscriber":230}],253:[function(a,b,f){function g(){try{return l.apply(this,arguments)}catch(a){return k.errorObject.e=a,k.errorObject}}var k=a("./errorObject"),l;f.tryCatch=function(a){l=a;return g}},{"./errorObject":239}]},{},[7])(7)});
|
||||
|
||||
-44
File diff suppressed because one or more lines are too long
-24
File diff suppressed because one or more lines are too long
Vendored
-12
File diff suppressed because one or more lines are too long
@@ -1,80 +0,0 @@
|
||||
.blocklyWorkspaceColumn {
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
width: 800px;
|
||||
}
|
||||
.blocklySidebarColumn {
|
||||
border-left: 1px solid #888;
|
||||
float: left;
|
||||
padding-left: 20px;
|
||||
margin-top: 20px;
|
||||
min-height: 700px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.blocklySidebarButton {
|
||||
background-color: #fff;
|
||||
border: 1px solid #333;
|
||||
border-radius: 4px;
|
||||
color: #000;
|
||||
font-size: 1em;
|
||||
margin: 10px 0 10px 30px;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.blocklySidebarButton[disabled] {
|
||||
border: 1px solid #ccc;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.blocklyAriaLiveStatus {
|
||||
background: #c8f7be;
|
||||
border-radius: 10px;
|
||||
bottom: 80px;
|
||||
left: 20px;
|
||||
max-width: 275px;
|
||||
padding: 10px;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.blocklyTree .blocklyActiveDescendant > label,
|
||||
.blocklyTree .blocklyActiveDescendant > div > label,
|
||||
.blocklyActiveDescendant > button,
|
||||
.blocklyActiveDescendant > input,
|
||||
.blocklyActiveDescendant > select,
|
||||
.blocklyActiveDescendant > blockly-field-segment > label,
|
||||
.blocklyActiveDescendant > blockly-field-segment > input,
|
||||
.blocklyActiveDescendant > blockly-field-segment > select {
|
||||
outline: 2px dotted #00f;
|
||||
}
|
||||
|
||||
.blocklyDropdownListItem[aria-selected="true"] button {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.blocklyModalCurtain {
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
height: 100%;
|
||||
left: 0;
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
.blocklyModal {
|
||||
background-color: #fefefe;
|
||||
border: 1px solid #888;
|
||||
margin: 10% auto;
|
||||
max-width: 600px;
|
||||
padding: 20px;
|
||||
width: 60%;
|
||||
}
|
||||
.blocklyModalButtonContainer {
|
||||
margin: 10px 0;
|
||||
}
|
||||
.blocklyModal .activeButton {
|
||||
border: 1px solid blue;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,62 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Visual Blocks Language
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Translatable string constants for Accessible Blockly.
|
||||
* @author madeeha@google.com (Madeeha Ghori)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Blockly.Msg.WORKSPACE = 'Workspace';
|
||||
Blockly.Msg.WORKSPACE_BLOCK =
|
||||
'workspace block. Move right to edit. Press Enter for more options.';
|
||||
|
||||
Blockly.Msg.ATTACH_NEW_BLOCK_TO_LINK = 'Attach new block to link...';
|
||||
Blockly.Msg.CREATE_NEW_BLOCK_GROUP = 'Create new block group...';
|
||||
Blockly.Msg.ERASE_WORKSPACE = 'Erase Workspace';
|
||||
Blockly.Msg.NO_BLOCKS_IN_WORKSPACE = 'There are no blocks in the workspace.';
|
||||
|
||||
Blockly.Msg.COPY_BLOCK = 'Copy block';
|
||||
Blockly.Msg.DELETE = 'Delete block';
|
||||
Blockly.Msg.MARK_SPOT_BEFORE = 'Add link before';
|
||||
Blockly.Msg.MARK_SPOT_AFTER = 'Add link after';
|
||||
Blockly.Msg.MARK_THIS_SPOT = 'Add link inside';
|
||||
Blockly.Msg.MOVE_TO_MARKED_SPOT = 'Move to existing link';
|
||||
Blockly.Msg.PASTE_AFTER = 'Paste after';
|
||||
Blockly.Msg.PASTE_BEFORE = 'Paste before';
|
||||
Blockly.Msg.PASTE_INSIDE = 'Paste inside';
|
||||
|
||||
Blockly.Msg.BLOCK_OPTIONS = 'Block Options';
|
||||
Blockly.Msg.SELECT_A_BLOCK = 'Select a block...';
|
||||
Blockly.Msg.CANCEL = 'Cancel';
|
||||
|
||||
Blockly.Msg.ANY = 'any';
|
||||
Blockly.Msg.BLOCK = 'block';
|
||||
Blockly.Msg.BUTTON = 'Button.';
|
||||
Blockly.Msg.FOR = 'for';
|
||||
Blockly.Msg.VALUE = 'value';
|
||||
|
||||
Blockly.Msg.ADDED_LINK_MSG = 'Added link.';
|
||||
Blockly.Msg.ATTACHED_BLOCK_TO_LINK_MSG = 'attached to link. ';
|
||||
Blockly.Msg.COPIED_BLOCK_MSG = 'copied. ';
|
||||
Blockly.Msg.PASTED_BLOCK_FROM_CLIPBOARD_MSG = 'pasted. ';
|
||||
|
||||
Blockly.Msg.PRESS_ENTER_TO_EDIT_NUMBER = 'Press Enter to edit number. ';
|
||||
Blockly.Msg.PRESS_ENTER_TO_EDIT_TEXT = 'Press Enter to edit text. ';
|
||||
@@ -1,61 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Service for updating the ARIA live region that
|
||||
* allows screenreaders to notify the user about actions that they have taken.
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.NotificationsService');
|
||||
|
||||
|
||||
blocklyApp.NotificationsService = ng.core.Class({
|
||||
constructor: [function() {
|
||||
this.currentMessage = '';
|
||||
this.timeouts = [];
|
||||
}],
|
||||
setDisplayedMessage_: function(newMessage) {
|
||||
this.currentMessage = newMessage;
|
||||
},
|
||||
getDisplayedMessage: function() {
|
||||
return this.currentMessage;
|
||||
},
|
||||
speak: function(newMessage) {
|
||||
// Clear and reset any existing timeouts.
|
||||
this.timeouts.forEach(function(timeout) {
|
||||
clearTimeout(timeout);
|
||||
});
|
||||
this.timeouts.length = 0;
|
||||
|
||||
// Clear the current message, so that if, e.g., two operations of the same
|
||||
// type are performed, both messages will be read in succession.
|
||||
this.setDisplayedMessage_('');
|
||||
|
||||
// We need a non-zero timeout here, otherwise NVDA does not read the
|
||||
// notification messages properly.
|
||||
var that = this;
|
||||
this.timeouts.push(setTimeout(function() {
|
||||
that.setDisplayedMessage_(newMessage);
|
||||
}, 20));
|
||||
this.timeouts.push(setTimeout(function() {
|
||||
that.setDisplayedMessage_('');
|
||||
}, 5000));
|
||||
}
|
||||
});
|
||||
@@ -1,132 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Component representing the sidebar that is shown next
|
||||
* to the workspace.
|
||||
*
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.SidebarComponent');
|
||||
|
||||
goog.require('blocklyApp.UtilsService');
|
||||
|
||||
goog.require('blocklyApp.BlockConnectionService');
|
||||
goog.require('blocklyApp.ToolboxModalService');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
goog.require('blocklyApp.TreeService');
|
||||
goog.require('blocklyApp.VariableModalService');
|
||||
|
||||
|
||||
blocklyApp.SidebarComponent = ng.core.Component({
|
||||
selector: 'blockly-sidebar',
|
||||
template: `
|
||||
<div class="blocklySidebarColumn">
|
||||
<button *ngFor="#buttonConfig of customSidebarButtons"
|
||||
id="{{buttonConfig.id || undefined}}"
|
||||
(click)="buttonConfig.action()"
|
||||
class="blocklySidebarButton">
|
||||
{{buttonConfig.text}}
|
||||
</button>
|
||||
<button id="{{ID_FOR_ATTACH_TO_LINK_BUTTON}}"
|
||||
(click)="showToolboxModalForAttachToMarkedConnection()"
|
||||
[attr.disabled]="!isAnyConnectionMarked() ? 'disabled' : undefined"
|
||||
[attr.aria-disabled]="!isAnyConnectionMarked()"
|
||||
class="blocklySidebarButton">
|
||||
{{'ATTACH_NEW_BLOCK_TO_LINK'|translate}}
|
||||
</button>
|
||||
<button id="{{ID_FOR_CREATE_NEW_GROUP_BUTTON}}"
|
||||
(click)="showToolboxModalForCreateNewGroup()"
|
||||
class="blocklySidebarButton">
|
||||
{{'CREATE_NEW_BLOCK_GROUP'|translate}}
|
||||
</button>
|
||||
<button id="clear-workspace" (click)="clearWorkspace()"
|
||||
[attr.disabled]="isWorkspaceEmpty() ? 'disabled' : undefined"
|
||||
[attr.aria-disabled]="isWorkspaceEmpty()"
|
||||
class="blocklySidebarButton">
|
||||
{{'ERASE_WORKSPACE'|translate}}
|
||||
</button>
|
||||
<button *ngIf="hasVariableCategory()" id="add-variable"
|
||||
(click)="showAddVariableModal()"
|
||||
class="blocklySidebarButton">
|
||||
Add Variable
|
||||
</button>
|
||||
</div>
|
||||
`,
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.BlockConnectionService,
|
||||
blocklyApp.ToolboxModalService,
|
||||
blocklyApp.TreeService,
|
||||
blocklyApp.UtilsService,
|
||||
blocklyApp.VariableModalService,
|
||||
function(
|
||||
blockConnectionService, toolboxModalService, treeService,
|
||||
utilsService, variableService) {
|
||||
// ACCESSIBLE_GLOBALS is a global variable defined by the containing
|
||||
// page. It should contain a key, customSidebarButtons, describing
|
||||
// additional buttons that should be displayed after the default ones.
|
||||
// See README.md for details.
|
||||
this.customSidebarButtons =
|
||||
ACCESSIBLE_GLOBALS && ACCESSIBLE_GLOBALS.customSidebarButtons ?
|
||||
ACCESSIBLE_GLOBALS.customSidebarButtons : [];
|
||||
|
||||
this.blockConnectionService = blockConnectionService;
|
||||
this.toolboxModalService = toolboxModalService;
|
||||
this.treeService = treeService;
|
||||
this.utilsService = utilsService;
|
||||
this.variableModalService = variableService;
|
||||
|
||||
this.ID_FOR_ATTACH_TO_LINK_BUTTON = 'blocklyAttachToLinkBtn';
|
||||
this.ID_FOR_CREATE_NEW_GROUP_BUTTON = 'blocklyCreateNewGroupBtn';
|
||||
}
|
||||
],
|
||||
isAnyConnectionMarked: function() {
|
||||
return this.blockConnectionService.isAnyConnectionMarked();
|
||||
},
|
||||
isWorkspaceEmpty: function() {
|
||||
return this.utilsService.isWorkspaceEmpty();
|
||||
},
|
||||
hasVariableCategory: function() {
|
||||
return this.toolboxModalService.toolboxHasVariableCategory();
|
||||
},
|
||||
clearWorkspace: function() {
|
||||
blocklyApp.workspace.clear();
|
||||
this.treeService.clearAllActiveDescs();
|
||||
// The timeout is needed in order to give the blocks time to be cleared
|
||||
// from the workspace, and for the 'workspace is empty' button to show up.
|
||||
setTimeout(function() {
|
||||
document.getElementById(blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN).focus();
|
||||
}, 50);
|
||||
},
|
||||
showToolboxModalForAttachToMarkedConnection: function() {
|
||||
this.toolboxModalService.showToolboxModalForAttachToMarkedConnection(
|
||||
this.ID_FOR_ATTACH_TO_LINK_BUTTON);
|
||||
},
|
||||
showToolboxModalForCreateNewGroup: function() {
|
||||
this.toolboxModalService.showToolboxModalForCreateNewGroup(
|
||||
this.ID_FOR_CREATE_NEW_GROUP_BUTTON);
|
||||
},
|
||||
showAddVariableModal: function() {
|
||||
this.variableModalService.showAddModal_("item");
|
||||
}
|
||||
});
|
||||
@@ -1,188 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Component representing the toolbox modal.
|
||||
*
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.ToolboxModalComponent');
|
||||
|
||||
goog.require('Blockly.CommonModal');
|
||||
goog.require('blocklyApp.AudioService');
|
||||
goog.require('blocklyApp.KeyboardInputService');
|
||||
goog.require('blocklyApp.ToolboxModalService');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
goog.require('blocklyApp.TreeService');
|
||||
goog.require('blocklyApp.UtilsService');
|
||||
|
||||
|
||||
blocklyApp.ToolboxModalComponent = ng.core.Component({
|
||||
selector: 'blockly-toolbox-modal',
|
||||
template: `
|
||||
<div *ngIf="modalIsVisible" class="blocklyModalCurtain"
|
||||
(click)="dismissModal()">
|
||||
<!-- $event.stopPropagation() prevents the modal from closing when its
|
||||
interior is clicked. -->
|
||||
<div id="toolboxModal" class="blocklyModal" role="alertdialog"
|
||||
(click)="$event.stopPropagation()" tabindex="-1"
|
||||
aria-labelledby="toolboxModalHeading">
|
||||
<h3 id="toolboxModalHeading">{{'SELECT_A_BLOCK'|translate}}</h3>
|
||||
|
||||
<div *ngFor="#toolboxCategory of toolboxCategories; #categoryIndex=index">
|
||||
<h4 *ngIf="toolboxCategory.categoryName">{{toolboxCategory.categoryName}}</h4>
|
||||
<div class="blocklyModalButtonContainer"
|
||||
*ngFor="#block of toolboxCategory.blocks; #blockIndex=index">
|
||||
<button [id]="getOptionId(getOverallIndex(categoryIndex, blockIndex))"
|
||||
(click)="selectBlock(getBlock(categoryIndex, blockIndex))"
|
||||
[ngClass]="{activeButton: activeButtonIndex == getOverallIndex(categoryIndex, blockIndex)}">
|
||||
{{getBlockDescription(block)}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="blocklyModalButtonContainer">
|
||||
<button [id]="getCancelOptionId()" (click)="dismissModal()"
|
||||
[ngClass]="{activeButton: activeButtonIndex == totalNumBlocks}">
|
||||
{{'CANCEL'|translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.ToolboxModalService, blocklyApp.KeyboardInputService,
|
||||
blocklyApp.AudioService, blocklyApp.UtilsService, blocklyApp.TreeService,
|
||||
function(
|
||||
toolboxModalService_, keyboardInputService_, audioService_,
|
||||
utilsService_, treeService_) {
|
||||
this.toolboxModalService = toolboxModalService_;
|
||||
this.keyboardInputService = keyboardInputService_;
|
||||
this.audioService = audioService_;
|
||||
this.utilsService = utilsService_;
|
||||
this.treeService = treeService_;
|
||||
|
||||
this.modalIsVisible = false;
|
||||
this.toolboxCategories = [];
|
||||
this.onSelectBlockCallback = null;
|
||||
this.onDismissCallback = null;
|
||||
|
||||
this.firstBlockIndexes = [];
|
||||
this.activeButtonIndex = -1;
|
||||
this.totalNumBlocks = 0;
|
||||
|
||||
var that = this;
|
||||
this.toolboxModalService.registerPreShowHook(
|
||||
function(
|
||||
toolboxCategories, onSelectBlockCallback, onDismissCallback) {
|
||||
that.modalIsVisible = true;
|
||||
that.toolboxCategories = toolboxCategories;
|
||||
that.onSelectBlockCallback = onSelectBlockCallback;
|
||||
that.onDismissCallback = onDismissCallback;
|
||||
|
||||
// The indexes of the buttons corresponding to the first block in
|
||||
// each category, as well as the 'cancel' button at the end.
|
||||
that.firstBlockIndexes = [];
|
||||
that.activeButtonIndex = -1;
|
||||
that.totalNumBlocks = 0;
|
||||
|
||||
var cumulativeIndex = 0;
|
||||
that.toolboxCategories.forEach(function(category) {
|
||||
that.firstBlockIndexes.push(cumulativeIndex);
|
||||
cumulativeIndex += category.blocks.length;
|
||||
});
|
||||
that.firstBlockIndexes.push(cumulativeIndex);
|
||||
that.totalNumBlocks = cumulativeIndex;
|
||||
|
||||
Blockly.CommonModal.setupKeyboardOverrides(that);
|
||||
that.keyboardInputService.addOverride('13', function(evt) {
|
||||
evt.preventDefault();
|
||||
evt.stopPropagation();
|
||||
|
||||
if (that.activeButtonIndex == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
var button = document.getElementById(
|
||||
that.getOptionId(that.activeButtonIndex));
|
||||
|
||||
for (var i = 0; i < that.toolboxCategories.length; i++) {
|
||||
if (that.firstBlockIndexes[i + 1] > that.activeButtonIndex) {
|
||||
var categoryIndex = i;
|
||||
var blockIndex =
|
||||
that.activeButtonIndex - that.firstBlockIndexes[i];
|
||||
var block = that.getBlock(categoryIndex, blockIndex);
|
||||
that.selectBlock(block);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// The 'Cancel' button has been pressed.
|
||||
that.dismissModal();
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
document.getElementById('toolboxModal').focus();
|
||||
}, 150);
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
// Closes the modal (on both success and failure).
|
||||
hideModal_: Blockly.CommonModal.hideModal,
|
||||
// Focuses on the button represented by the given index.
|
||||
focusOnOption: function(index) {
|
||||
var button = document.getElementById(this.getOptionId(index));
|
||||
button.focus();
|
||||
},
|
||||
// Counts the number of interactive elements for the modal.
|
||||
numInteractiveElements: function() {
|
||||
return this.totalNumBlocks + 1;
|
||||
},
|
||||
getOverallIndex: function(categoryIndex, blockIndex) {
|
||||
return this.firstBlockIndexes[categoryIndex] + blockIndex;
|
||||
},
|
||||
getBlock: function(categoryIndex, blockIndex) {
|
||||
return this.toolboxCategories[categoryIndex].blocks[blockIndex];
|
||||
},
|
||||
getBlockDescription: function(block) {
|
||||
return this.utilsService.getBlockDescription(block);
|
||||
},
|
||||
// Returns the ID for the corresponding option button.
|
||||
getOptionId: function(index) {
|
||||
return 'toolbox-modal-option-' + index;
|
||||
},
|
||||
// Returns the ID for the "cancel" option button.
|
||||
getCancelOptionId: function() {
|
||||
return 'toolbox-modal-option-' + this.totalNumBlocks;
|
||||
},
|
||||
selectBlock: function(block) {
|
||||
this.onSelectBlockCallback(block);
|
||||
this.hideModal_();
|
||||
},
|
||||
// Dismisses and closes the modal.
|
||||
dismissModal: function() {
|
||||
this.hideModal_();
|
||||
this.onDismissCallback();
|
||||
}
|
||||
});
|
||||
@@ -1,230 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Service for the toolbox modal.
|
||||
*
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.ToolboxModalService');
|
||||
|
||||
goog.require('blocklyApp.UtilsService');
|
||||
|
||||
goog.require('blocklyApp.BlockConnectionService');
|
||||
goog.require('blocklyApp.NotificationsService');
|
||||
goog.require('blocklyApp.TreeService');
|
||||
|
||||
|
||||
blocklyApp.ToolboxModalService = ng.core.Class({
|
||||
constructor: [
|
||||
blocklyApp.BlockConnectionService,
|
||||
blocklyApp.NotificationsService,
|
||||
blocklyApp.TreeService,
|
||||
blocklyApp.UtilsService,
|
||||
function(
|
||||
blockConnectionService, notificationsService, treeService,
|
||||
utilsService) {
|
||||
this.blockConnectionService = blockConnectionService;
|
||||
this.notificationsService = notificationsService;
|
||||
this.treeService = treeService;
|
||||
this.utilsService = utilsService;
|
||||
|
||||
this.modalIsShown = false;
|
||||
|
||||
this.selectedToolboxCategories = null;
|
||||
this.onSelectBlockCallback = null;
|
||||
this.onDismissCallback = null;
|
||||
this.hasVariableCategory = null;
|
||||
// The aim of the pre-show hook is to populate the modal component with
|
||||
// the information it needs to display the modal (e.g., which categories
|
||||
// and blocks to display).
|
||||
this.preShowHook = function() {
|
||||
throw Error(
|
||||
'A pre-show hook must be defined for the toolbox modal before it ' +
|
||||
'can be shown.');
|
||||
};
|
||||
}
|
||||
],
|
||||
populateToolbox_: function() {
|
||||
// Populate the toolbox categories.
|
||||
this.allToolboxCategories = [];
|
||||
var toolboxXmlElt = document.getElementById('blockly-toolbox-xml');
|
||||
var toolboxCategoryElts = toolboxXmlElt.getElementsByTagName('category');
|
||||
if (toolboxCategoryElts.length) {
|
||||
this.allToolboxCategories = Array.from(toolboxCategoryElts).map(
|
||||
function(categoryElt) {
|
||||
var tmpWorkspace = new Blockly.Workspace();
|
||||
var custom = categoryElt.attributes.custom;
|
||||
// TODO (corydiers): Implement custom flyouts once #1153 is solved.
|
||||
if (custom && custom.value == Blockly.VARIABLE_CATEGORY_NAME) {
|
||||
var varBlocks =
|
||||
Blockly.Variables.flyoutCategoryBlocks(blocklyApp.workspace);
|
||||
varBlocks.forEach(function(block) {
|
||||
Blockly.Xml.domToBlock(block, tmpWorkspace);
|
||||
});
|
||||
} else {
|
||||
Blockly.Xml.domToWorkspace(categoryElt, tmpWorkspace);
|
||||
}
|
||||
return {
|
||||
categoryName: categoryElt.attributes.name.value,
|
||||
blocks: tmpWorkspace.topBlocks_
|
||||
};
|
||||
}
|
||||
);
|
||||
this.computeCategoriesForCreateNewGroupModal_();
|
||||
} else {
|
||||
var that = this;
|
||||
// If there are no top-level categories, we create a single category
|
||||
// containing all the top-level blocks.
|
||||
var tmpWorkspace = new Blockly.Workspace();
|
||||
Array.from(toolboxXmlElt.children).forEach(function(topLevelNode) {
|
||||
Blockly.Xml.domToBlock(topLevelNode, tmpWorkspace);
|
||||
});
|
||||
|
||||
that.allToolboxCategories = [{
|
||||
categoryName: '',
|
||||
blocks: tmpWorkspace.topBlocks_
|
||||
}];
|
||||
|
||||
that.computeCategoriesForCreateNewGroupModal_();
|
||||
}
|
||||
},
|
||||
computeCategoriesForCreateNewGroupModal_: function() {
|
||||
// Precompute toolbox categories for blocks that have no output
|
||||
// connection (and that can therefore be used as the base block of a
|
||||
// "create new block group" action).
|
||||
this.toolboxCategoriesForNewGroup = [];
|
||||
var that = this;
|
||||
this.allToolboxCategories.forEach(function(toolboxCategory) {
|
||||
var baseBlocks = toolboxCategory.blocks.filter(function(block) {
|
||||
return !block.outputConnection;
|
||||
});
|
||||
|
||||
if (baseBlocks.length > 0) {
|
||||
that.toolboxCategoriesForNewGroup.push({
|
||||
categoryName: toolboxCategory.categoryName,
|
||||
blocks: baseBlocks
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
registerPreShowHook: function(preShowHook) {
|
||||
var that = this;
|
||||
this.preShowHook = function() {
|
||||
preShowHook(
|
||||
that.selectedToolboxCategories, that.onSelectBlockCallback,
|
||||
that.onDismissCallback);
|
||||
};
|
||||
},
|
||||
isModalShown: function() {
|
||||
return this.modalIsShown;
|
||||
},
|
||||
toolboxHasVariableCategory: function() {
|
||||
if (this.hasVariableCategory === null) {
|
||||
var toolboxXmlElt = document.getElementById('blockly-toolbox-xml');
|
||||
var toolboxCategoryElts = toolboxXmlElt.getElementsByTagName('category');
|
||||
var that = this;
|
||||
Array.from(toolboxCategoryElts).forEach(
|
||||
function(categoryElt) {
|
||||
var custom = categoryElt.attributes.custom;
|
||||
if (custom && custom.value == Blockly.VARIABLE_CATEGORY_NAME) {
|
||||
that.hasVariableCategory = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (this.hasVariableCategory === null) {
|
||||
this.hasVariableCategory = false;
|
||||
}
|
||||
}
|
||||
|
||||
return this.hasVariableCategory;
|
||||
},
|
||||
showModal_: function(
|
||||
selectedToolboxCategories, onSelectBlockCallback, onDismissCallback) {
|
||||
this.selectedToolboxCategories = selectedToolboxCategories;
|
||||
this.onSelectBlockCallback = onSelectBlockCallback;
|
||||
this.onDismissCallback = onDismissCallback;
|
||||
|
||||
this.preShowHook();
|
||||
this.modalIsShown = true;
|
||||
},
|
||||
hideModal: function() {
|
||||
this.modalIsShown = false;
|
||||
},
|
||||
showToolboxModalForAttachToMarkedConnection: function(sourceButtonId) {
|
||||
var that = this;
|
||||
|
||||
var selectedToolboxCategories = [];
|
||||
this.populateToolbox_();
|
||||
this.allToolboxCategories.forEach(function(toolboxCategory) {
|
||||
var selectedBlocks = toolboxCategory.blocks.filter(function(block) {
|
||||
return that.blockConnectionService.canBeAttachedToMarkedConnection(
|
||||
block);
|
||||
});
|
||||
|
||||
if (selectedBlocks.length > 0) {
|
||||
selectedToolboxCategories.push({
|
||||
categoryName: toolboxCategory.categoryName,
|
||||
blocks: selectedBlocks
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.showModal_(selectedToolboxCategories, function(block) {
|
||||
var blockDescription = that.utilsService.getBlockDescription(block);
|
||||
|
||||
// Clear the active desc for the destination tree, so that it can be
|
||||
// cleanly reinstated after the new block is attached.
|
||||
var destinationTreeId = that.treeService.getTreeIdForBlock(
|
||||
that.blockConnectionService.getMarkedConnectionSourceBlock().id);
|
||||
that.treeService.clearActiveDesc(destinationTreeId);
|
||||
var newBlockId = that.blockConnectionService.attachToMarkedConnection(
|
||||
block);
|
||||
|
||||
// Invoke a digest cycle, so that the DOM settles.
|
||||
setTimeout(function() {
|
||||
that.treeService.focusOnBlock(newBlockId);
|
||||
that.notificationsService.speak(
|
||||
'Attached. Now on, ' + blockDescription + ', block in workspace.');
|
||||
});
|
||||
}, function() {
|
||||
document.getElementById(sourceButtonId).focus();
|
||||
});
|
||||
},
|
||||
showToolboxModalForCreateNewGroup: function(sourceButtonId) {
|
||||
var that = this;
|
||||
this.populateToolbox_();
|
||||
this.showModal_(this.toolboxCategoriesForNewGroup, function(block) {
|
||||
var blockDescription = that.utilsService.getBlockDescription(block);
|
||||
var xml = Blockly.Xml.blockToDom(block);
|
||||
var newBlockId = Blockly.Xml.domToBlock(xml, blocklyApp.workspace).id;
|
||||
|
||||
// Invoke a digest cycle, so that the DOM settles.
|
||||
setTimeout(function() {
|
||||
that.treeService.focusOnBlock(newBlockId);
|
||||
that.notificationsService.speak(
|
||||
'Created new group in workspace. Now on, ' + blockDescription +
|
||||
', block in workspace.');
|
||||
});
|
||||
}, function() {
|
||||
document.getElementById(sourceButtonId).focus();
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Pipe for internationalizing Blockly message strings.
|
||||
* @author sll@google.com (Sean Lip)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.TranslatePipe');
|
||||
|
||||
|
||||
blocklyApp.TranslatePipe = ng.core.Pipe({
|
||||
name: 'translate'
|
||||
})
|
||||
.Class({
|
||||
constructor: function() {},
|
||||
transform: function(messageId) {
|
||||
return Blockly.Msg[messageId];
|
||||
}
|
||||
});
|
||||
@@ -1,609 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Service that handles keyboard navigation on workspace
|
||||
* block groups (internally represented as trees). This is a singleton service
|
||||
* for the entire application.
|
||||
*
|
||||
* @author madeeha@google.com (Madeeha Ghori)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.TreeService');
|
||||
|
||||
goog.require('blocklyApp.UtilsService');
|
||||
|
||||
goog.require('blocklyApp.AudioService');
|
||||
goog.require('blocklyApp.BlockConnectionService');
|
||||
goog.require('blocklyApp.BlockOptionsModalService');
|
||||
goog.require('blocklyApp.NotificationsService');
|
||||
goog.require('blocklyApp.VariableModalService');
|
||||
|
||||
|
||||
blocklyApp.TreeService = ng.core.Class({
|
||||
constructor: [
|
||||
blocklyApp.AudioService,
|
||||
blocklyApp.BlockConnectionService,
|
||||
blocklyApp.BlockOptionsModalService,
|
||||
blocklyApp.NotificationsService,
|
||||
blocklyApp.UtilsService,
|
||||
blocklyApp.VariableModalService,
|
||||
function(
|
||||
audioService, blockConnectionService, blockOptionsModalService,
|
||||
notificationsService, utilsService, variableModalService) {
|
||||
this.audioService = audioService;
|
||||
this.blockConnectionService = blockConnectionService;
|
||||
this.blockOptionsModalService = blockOptionsModalService;
|
||||
this.notificationsService = notificationsService;
|
||||
this.utilsService = utilsService;
|
||||
this.variableModalService = variableModalService;
|
||||
|
||||
// The suffix used for all IDs of block root elements.
|
||||
this.BLOCK_ROOT_ID_SUFFIX_ = blocklyApp.BLOCK_ROOT_ID_SUFFIX;
|
||||
// Maps tree IDs to the IDs of their active descendants.
|
||||
this.activeDescendantIds_ = {};
|
||||
// Array containing all the sidebar button elements.
|
||||
this.sidebarButtonElements_ = Array.from(
|
||||
document.querySelectorAll('button.blocklySidebarButton'));
|
||||
}
|
||||
],
|
||||
scrollToElement_: function(elementId) {
|
||||
var element = document.getElementById(elementId);
|
||||
var documentElement = document.body || document.documentElement;
|
||||
if (element.offsetTop < documentElement.scrollTop ||
|
||||
element.offsetTop > documentElement.scrollTop + window.innerHeight) {
|
||||
window.scrollTo(0, element.offsetTop - 10);
|
||||
}
|
||||
},
|
||||
|
||||
isLi_: function(node) {
|
||||
return node.tagName == 'LI';
|
||||
},
|
||||
getParentLi_: function(element) {
|
||||
var nextNode = element.parentNode;
|
||||
while (nextNode && !this.isLi_(nextNode)) {
|
||||
nextNode = nextNode.parentNode;
|
||||
}
|
||||
return nextNode;
|
||||
},
|
||||
getFirstChildLi_: function(element) {
|
||||
var childList = element.children;
|
||||
for (var i = 0; i < childList.length; i++) {
|
||||
if (this.isLi_(childList[i])) {
|
||||
return childList[i];
|
||||
} else {
|
||||
var potentialElement = this.getFirstChildLi_(childList[i]);
|
||||
if (potentialElement) {
|
||||
return potentialElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getLastChildLi_: function(element) {
|
||||
var childList = element.children;
|
||||
for (var i = childList.length - 1; i >= 0; i--) {
|
||||
if (this.isLi_(childList[i])) {
|
||||
return childList[i];
|
||||
} else {
|
||||
var potentialElement = this.getLastChildLi_(childList[i]);
|
||||
if (potentialElement) {
|
||||
return potentialElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getInitialSiblingLi_: function(element) {
|
||||
while (true) {
|
||||
var previousSibling = this.getPreviousSiblingLi_(element);
|
||||
if (previousSibling && previousSibling.id != element.id) {
|
||||
element = previousSibling;
|
||||
} else {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
},
|
||||
getPreviousSiblingLi_: function(element) {
|
||||
if (element.previousElementSibling) {
|
||||
var sibling = element.previousElementSibling;
|
||||
return this.isLi_(sibling) ? sibling : this.getLastChildLi_(sibling);
|
||||
} else {
|
||||
var parent = element.parentNode;
|
||||
while (parent && parent.tagName != 'OL') {
|
||||
if (parent.previousElementSibling) {
|
||||
var node = parent.previousElementSibling;
|
||||
return this.isLi_(node) ? node : this.getLastChildLi_(node);
|
||||
} else {
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
getNextSiblingLi_: function(element) {
|
||||
if (element.nextElementSibling) {
|
||||
var sibling = element.nextElementSibling;
|
||||
return this.isLi_(sibling) ? sibling : this.getFirstChildLi_(sibling);
|
||||
} else {
|
||||
var parent = element.parentNode;
|
||||
while (parent && parent.tagName != 'OL') {
|
||||
if (parent.nextElementSibling) {
|
||||
var node = parent.nextElementSibling;
|
||||
return this.isLi_(node) ? node : this.getFirstChildLi_(node);
|
||||
} else {
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
getFinalSiblingLi_: function(element) {
|
||||
while (true) {
|
||||
var nextSibling = this.getNextSiblingLi_(element);
|
||||
if (nextSibling && nextSibling.id != element.id) {
|
||||
element = nextSibling;
|
||||
} else {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Returns a list of all focus targets in the workspace, including the
|
||||
// "Create new group" button that appears when no blocks are present.
|
||||
getWorkspaceFocusTargets_: function() {
|
||||
return Array.from(
|
||||
document.querySelectorAll('.blocklyWorkspaceFocusTarget'));
|
||||
},
|
||||
getAllFocusTargets_: function() {
|
||||
return this.getWorkspaceFocusTargets_().concat(this.sidebarButtonElements_);
|
||||
},
|
||||
getNextFocusTargetId_: function(treeId) {
|
||||
var trees = this.getAllFocusTargets_();
|
||||
for (var i = 0; i < trees.length - 1; i++) {
|
||||
if (trees[i].id == treeId) {
|
||||
return trees[i + 1].id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
getPreviousFocusTargetId_: function(treeId) {
|
||||
var trees = this.getAllFocusTargets_();
|
||||
for (var i = trees.length - 1; i > 0; i--) {
|
||||
if (trees[i].id == treeId) {
|
||||
return trees[i - 1].id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getActiveDescId: function(treeId) {
|
||||
return this.activeDescendantIds_[treeId] || '';
|
||||
},
|
||||
// Set the active desc for this tree to its first child.
|
||||
initActiveDesc: function(treeId) {
|
||||
var tree = document.getElementById(treeId);
|
||||
this.setActiveDesc(this.getFirstChildLi_(tree).id, treeId);
|
||||
},
|
||||
// Make a given element the active descendant of a given tree.
|
||||
setActiveDesc: function(newActiveDescId, treeId) {
|
||||
if (this.getActiveDescId(treeId)) {
|
||||
this.clearActiveDesc(treeId);
|
||||
}
|
||||
document.getElementById(newActiveDescId).classList.add(
|
||||
'blocklyActiveDescendant');
|
||||
this.activeDescendantIds_[treeId] = newActiveDescId;
|
||||
|
||||
// Scroll the new active desc into view, if needed. This has no effect
|
||||
// for blind users, but is helpful for sighted onlookers.
|
||||
this.scrollToElement_(newActiveDescId);
|
||||
},
|
||||
// This clears the active descendant of the given tree. It is used just
|
||||
// before the tree is deleted.
|
||||
clearActiveDesc: function(treeId) {
|
||||
var activeDesc = document.getElementById(this.getActiveDescId(treeId));
|
||||
if (activeDesc) {
|
||||
activeDesc.classList.remove('blocklyActiveDescendant');
|
||||
}
|
||||
|
||||
if (this.activeDescendantIds_[treeId]) {
|
||||
delete this.activeDescendantIds_[treeId];
|
||||
}
|
||||
},
|
||||
clearAllActiveDescs: function() {
|
||||
for (var treeId in this.activeDescendantIds_) {
|
||||
var activeDesc = document.getElementById(this.getActiveDescId(treeId));
|
||||
if (activeDesc) {
|
||||
activeDesc.classList.remove('blocklyActiveDescendant');
|
||||
}
|
||||
}
|
||||
|
||||
this.activeDescendantIds_ = {};
|
||||
},
|
||||
|
||||
isTreeRoot_: function(element) {
|
||||
return element.classList.contains('blocklyTree');
|
||||
},
|
||||
getBlockRootId_: function(blockId) {
|
||||
return blockId + this.BLOCK_ROOT_ID_SUFFIX_;
|
||||
},
|
||||
// Return the 'lowest' Blockly block in the DOM tree that contains the given
|
||||
// DOM element.
|
||||
getContainingBlock_: function(domElement) {
|
||||
var potentialBlockRoot = domElement;
|
||||
while (potentialBlockRoot.id.indexOf(this.BLOCK_ROOT_ID_SUFFIX_) === -1) {
|
||||
potentialBlockRoot = potentialBlockRoot.parentNode;
|
||||
}
|
||||
|
||||
var blockRootId = potentialBlockRoot.id;
|
||||
var blockId = blockRootId.substring(
|
||||
0, blockRootId.length - this.BLOCK_ROOT_ID_SUFFIX_.length);
|
||||
return blocklyApp.workspace.getBlockById(blockId);
|
||||
},
|
||||
isTopLevelBlock_: function(block) {
|
||||
return !block.getParent();
|
||||
},
|
||||
// Returns whether the given block is at the top level, and has no siblings.
|
||||
isIsolatedTopLevelBlock_: function(block) {
|
||||
var blockHasNoSiblings = (
|
||||
(!block.nextConnection ||
|
||||
!block.nextConnection.targetConnection) &&
|
||||
(!block.previousConnection ||
|
||||
!block.previousConnection.targetConnection));
|
||||
return this.isTopLevelBlock_(block) && blockHasNoSiblings;
|
||||
},
|
||||
safelyRemoveBlock_: function(block, deleteBlockFunc, areNextBlocksRemoved) {
|
||||
// Runs the given deleteBlockFunc (which should have the effect of deleting
|
||||
// the given block, and possibly others after it if `areNextBlocksRemoved`
|
||||
// is true) and then does one of two things:
|
||||
// - If the deleted block was an isolated top-level block, or it is a top-
|
||||
// level block and the next blocks are going to be removed, this means
|
||||
// the current tree has no more blocks after the deletion. So, pick a new
|
||||
// tree to focus on.
|
||||
// - Otherwise, set the correct new active desc for the current tree.
|
||||
var treeId = this.getTreeIdForBlock(block.id);
|
||||
|
||||
var treeCeasesToExist = areNextBlocksRemoved ?
|
||||
this.isTopLevelBlock_(block) : this.isIsolatedTopLevelBlock_(block);
|
||||
|
||||
if (treeCeasesToExist) {
|
||||
// Find the node to focus on after the deletion happens.
|
||||
var nextElementToFocusOn = null;
|
||||
var focusTargets = this.getWorkspaceFocusTargets_();
|
||||
for (var i = 0; i < focusTargets.length; i++) {
|
||||
if (focusTargets[i].id == treeId) {
|
||||
if (i + 1 < focusTargets.length) {
|
||||
nextElementToFocusOn = focusTargets[i + 1];
|
||||
} else if (i > 0) {
|
||||
nextElementToFocusOn = focusTargets[i - 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.clearActiveDesc(treeId);
|
||||
deleteBlockFunc();
|
||||
// Invoke a digest cycle, so that the DOM settles (and the "Create new
|
||||
// group" button in the workspace shows up, if applicable).
|
||||
setTimeout(function() {
|
||||
if (nextElementToFocusOn) {
|
||||
nextElementToFocusOn.focus();
|
||||
} else {
|
||||
document.getElementById(
|
||||
blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN).focus();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var blockRootId = this.getBlockRootId_(block.id);
|
||||
var blockRootElement = document.getElementById(blockRootId);
|
||||
|
||||
// Find the new active desc for the current tree by trying the following
|
||||
// possibilities in order: the parent, the next sibling, and the previous
|
||||
// sibling. (If `areNextBlocksRemoved` is true, the next sibling would be
|
||||
// moved together with the moved block, so we don't check it.)
|
||||
if (areNextBlocksRemoved) {
|
||||
var newActiveDesc =
|
||||
this.getParentLi_(blockRootElement) ||
|
||||
this.getPreviousSiblingLi_(blockRootElement);
|
||||
} else {
|
||||
var newActiveDesc =
|
||||
this.getParentLi_(blockRootElement) ||
|
||||
this.getNextSiblingLi_(blockRootElement) ||
|
||||
this.getPreviousSiblingLi_(blockRootElement);
|
||||
}
|
||||
|
||||
this.clearActiveDesc(treeId);
|
||||
deleteBlockFunc();
|
||||
// Invoke a digest cycle, so that the DOM settles.
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
that.setActiveDesc(newActiveDesc.id, treeId);
|
||||
document.getElementById(treeId).focus();
|
||||
});
|
||||
}
|
||||
},
|
||||
getTreeIdForBlock: function(blockId) {
|
||||
// Walk up the DOM until we get to the root element of the tree.
|
||||
var potentialRoot = document.getElementById(this.getBlockRootId_(blockId));
|
||||
while (!this.isTreeRoot_(potentialRoot)) {
|
||||
potentialRoot = potentialRoot.parentNode;
|
||||
}
|
||||
return potentialRoot.id;
|
||||
},
|
||||
// Set focus to the tree containing the given block, and set the tree's
|
||||
// active desc to the root element of the given block.
|
||||
focusOnBlock: function(blockId) {
|
||||
// Invoke a digest cycle, in order to allow the ID of the newly-created
|
||||
// tree to be set in the DOM.
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
var treeId = that.getTreeIdForBlock(blockId);
|
||||
document.getElementById(treeId).focus();
|
||||
that.setActiveDesc(that.getBlockRootId_(blockId), treeId);
|
||||
});
|
||||
},
|
||||
showBlockOptionsModal: function(block) {
|
||||
var that = this;
|
||||
var actionButtonsInfo = [];
|
||||
|
||||
if (block.previousConnection) {
|
||||
actionButtonsInfo.push({
|
||||
action: function() {
|
||||
that.blockConnectionService.markConnection(block.previousConnection);
|
||||
that.focusOnBlock(block.id);
|
||||
},
|
||||
translationIdForText: 'MARK_SPOT_BEFORE'
|
||||
});
|
||||
}
|
||||
|
||||
if (block.nextConnection) {
|
||||
actionButtonsInfo.push({
|
||||
action: function() {
|
||||
that.blockConnectionService.markConnection(block.nextConnection);
|
||||
that.focusOnBlock(block.id);
|
||||
},
|
||||
translationIdForText: 'MARK_SPOT_AFTER'
|
||||
});
|
||||
}
|
||||
|
||||
if (this.blockConnectionService.canBeMovedToMarkedConnection(block)) {
|
||||
actionButtonsInfo.push({
|
||||
action: function() {
|
||||
var blockDescription = that.utilsService.getBlockDescription(block);
|
||||
var oldDestinationTreeId = that.getTreeIdForBlock(
|
||||
that.blockConnectionService.getMarkedConnectionSourceBlock().id);
|
||||
that.clearActiveDesc(oldDestinationTreeId);
|
||||
|
||||
var newBlockId = that.blockConnectionService.attachToMarkedConnection(
|
||||
block);
|
||||
that.safelyRemoveBlock_(block, function() {
|
||||
block.dispose(false);
|
||||
}, true);
|
||||
|
||||
// Invoke a digest cycle, so that the DOM settles.
|
||||
setTimeout(function() {
|
||||
that.focusOnBlock(newBlockId);
|
||||
var newDestinationTreeId = that.getTreeIdForBlock(newBlockId);
|
||||
|
||||
if (newDestinationTreeId != oldDestinationTreeId) {
|
||||
// The tree ID for a moved block does not seem to behave
|
||||
// predictably. E.g. start with two separate groups of one block
|
||||
// each, add a link before the block in the second group, and
|
||||
// move the block in the first group to that link. The tree ID of
|
||||
// the resulting group ends up being the tree ID for the group
|
||||
// that was originally first, not second as might be expected.
|
||||
// Here, we double-check to ensure that all affected trees have
|
||||
// an active desc set.
|
||||
if (document.getElementById(oldDestinationTreeId)) {
|
||||
var activeDescId = that.getActiveDescId(oldDestinationTreeId);
|
||||
var activeDescTreeId = null;
|
||||
if (activeDescId) {
|
||||
var oldDestinationBlock = that.getContainingBlock_(
|
||||
document.getElementById(activeDescId));
|
||||
activeDescTreeId = that.getTreeIdForBlock(
|
||||
oldDestinationBlock);
|
||||
if (activeDescTreeId != oldDestinationTreeId) {
|
||||
that.clearActiveDesc(oldDestinationTreeId);
|
||||
}
|
||||
}
|
||||
that.initActiveDesc(oldDestinationTreeId);
|
||||
}
|
||||
}
|
||||
|
||||
that.notificationsService.speak(
|
||||
blockDescription + ' ' +
|
||||
Blockly.Msg.ATTACHED_BLOCK_TO_LINK_MSG +
|
||||
'. Now on attached block in workspace.');
|
||||
});
|
||||
},
|
||||
translationIdForText: 'MOVE_TO_MARKED_SPOT'
|
||||
});
|
||||
}
|
||||
|
||||
actionButtonsInfo.push({
|
||||
action: function() {
|
||||
var blockDescription = that.utilsService.getBlockDescription(block);
|
||||
|
||||
that.safelyRemoveBlock_(block, function() {
|
||||
block.dispose(true);
|
||||
that.audioService.playDeleteSound();
|
||||
}, false);
|
||||
|
||||
setTimeout(function() {
|
||||
var message = blockDescription + ' deleted. ' + (
|
||||
that.utilsService.isWorkspaceEmpty() ?
|
||||
'Workspace is empty.' : 'Now on workspace.');
|
||||
that.notificationsService.speak(message);
|
||||
});
|
||||
},
|
||||
translationIdForText: 'DELETE'
|
||||
});
|
||||
|
||||
this.blockOptionsModalService.showModal(actionButtonsInfo, function() {
|
||||
that.focusOnBlock(block.id);
|
||||
});
|
||||
},
|
||||
|
||||
moveUpOneLevel_: function(treeId) {
|
||||
var activeDesc = document.getElementById(this.getActiveDescId(treeId));
|
||||
var nextNode = this.getParentLi_(activeDesc);
|
||||
if (nextNode) {
|
||||
this.setActiveDesc(nextNode.id, treeId);
|
||||
} else {
|
||||
this.audioService.playOopsSound();
|
||||
}
|
||||
},
|
||||
onKeypress: function(e, tree) {
|
||||
// TODO(sll): Instead of this, have a common ActiveContextService which
|
||||
// returns true if at least one modal is shown, and false otherwise.
|
||||
if (this.blockOptionsModalService.isModalShown() ||
|
||||
this.variableModalService.isModalShown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var treeId = tree.id;
|
||||
var activeDesc = document.getElementById(this.getActiveDescId(treeId));
|
||||
if (!activeDesc) {
|
||||
// The underlying Blockly instance may have decided blocks needed to
|
||||
// be deleted. This is not necessarily an error, but needs to be repaired.
|
||||
this.initActiveDesc(treeId);
|
||||
activeDesc = document.getElementById(this.getActiveDescId(treeId));
|
||||
}
|
||||
|
||||
if (e.altKey || e.ctrlKey) {
|
||||
// Do not intercept combinations such as Alt+Home.
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.activeElement.tagName == 'INPUT' ||
|
||||
document.activeElement.tagName == 'SELECT') {
|
||||
// For input fields, Esc, Enter, and Tab keystrokes are handled specially.
|
||||
if (e.keyCode == 9 || e.keyCode == 13 || e.keyCode == 27) {
|
||||
// Return the focus to the workspace tree containing the input field.
|
||||
document.getElementById(treeId).focus();
|
||||
|
||||
// Note that Tab and Enter events stop propagating, this behavior is
|
||||
// handled on other listeners.
|
||||
if (e.keyCode == 27 || e.keyCode == 13) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Outside an input field, Enter, Tab, Esc and navigation keys are all
|
||||
// recognized.
|
||||
if (e.keyCode == 13) {
|
||||
// Enter key. The user wants to interact with a button, interact with
|
||||
// an input field, or open the block options modal.
|
||||
// Algorithm to find the field: do a DFS through the children until
|
||||
// we find an INPUT, BUTTON or SELECT element (in which case we use it).
|
||||
// Truncate the search at child LI elements.
|
||||
e.stopPropagation();
|
||||
|
||||
var found = false;
|
||||
var dfsStack = Array.from(activeDesc.children);
|
||||
while (dfsStack.length) {
|
||||
var currentNode = dfsStack.shift();
|
||||
if (currentNode.tagName == 'BUTTON') {
|
||||
currentNode.click();
|
||||
found = true;
|
||||
break;
|
||||
} else if (currentNode.tagName == 'INPUT') {
|
||||
currentNode.focus();
|
||||
currentNode.select();
|
||||
this.notificationsService.speak(
|
||||
'Type a value, then press Escape to exit');
|
||||
found = true;
|
||||
break;
|
||||
} else if (currentNode.tagName == 'SELECT') {
|
||||
currentNode.focus();
|
||||
found = true;
|
||||
return;
|
||||
} else if (currentNode.tagName == 'LI') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentNode.children) {
|
||||
var reversedChildren = Array.from(currentNode.children).reverse();
|
||||
reversedChildren.forEach(function(childNode) {
|
||||
dfsStack.unshift(childNode);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// If we cannot find a field to interact with, we open the modal for
|
||||
// the current block instead.
|
||||
if (!found) {
|
||||
var block = this.getContainingBlock_(activeDesc);
|
||||
this.showBlockOptionsModal(block);
|
||||
}
|
||||
} else if (e.keyCode == 9) {
|
||||
// Tab key. The event is allowed to propagate through.
|
||||
} else if ([27, 35, 36, 37, 38, 39, 40].indexOf(e.keyCode) !== -1) {
|
||||
if (e.keyCode == 27 || e.keyCode == 37) {
|
||||
// Esc or left arrow key. Go up a level, if possible.
|
||||
this.moveUpOneLevel_(treeId);
|
||||
} else if (e.keyCode == 35) {
|
||||
// End key. Go to the last sibling in the subtree.
|
||||
var potentialFinalSibling = this.getFinalSiblingLi_(activeDesc);
|
||||
if (potentialFinalSibling) {
|
||||
this.setActiveDesc(potentialFinalSibling.id, treeId);
|
||||
}
|
||||
} else if (e.keyCode == 36) {
|
||||
// Home key. Go to the first sibling in the subtree.
|
||||
var potentialInitialSibling = this.getInitialSiblingLi_(activeDesc);
|
||||
if (potentialInitialSibling) {
|
||||
this.setActiveDesc(potentialInitialSibling.id, treeId);
|
||||
}
|
||||
} else if (e.keyCode == 38) {
|
||||
// Up arrow key. Go to the previous sibling, if possible.
|
||||
var potentialPrevSibling = this.getPreviousSiblingLi_(activeDesc);
|
||||
if (potentialPrevSibling) {
|
||||
this.setActiveDesc(potentialPrevSibling.id, treeId);
|
||||
} else {
|
||||
var statusMessage = 'Reached top of list.';
|
||||
if (this.getParentLi_(activeDesc)) {
|
||||
statusMessage += ' Press left to go to parent list.';
|
||||
}
|
||||
this.audioService.playOopsSound(statusMessage);
|
||||
}
|
||||
} else if (e.keyCode == 39) {
|
||||
// Right arrow key. Go down a level, if possible.
|
||||
var potentialFirstChild = this.getFirstChildLi_(activeDesc);
|
||||
if (potentialFirstChild) {
|
||||
this.setActiveDesc(potentialFirstChild.id, treeId);
|
||||
} else {
|
||||
this.audioService.playOopsSound();
|
||||
}
|
||||
} else if (e.keyCode == 40) {
|
||||
// Down arrow key. Go to the next sibling, if possible.
|
||||
var potentialNextSibling = this.getNextSiblingLi_(activeDesc);
|
||||
if (potentialNextSibling) {
|
||||
this.setActiveDesc(potentialNextSibling.id, treeId);
|
||||
} else {
|
||||
this.audioService.playOopsSound('Reached bottom of list.');
|
||||
}
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 utility service for multiple components. This is a
|
||||
* singleton service that is used for the entire application. In general, it
|
||||
* should only be used as a stateless adapter for native Blockly functions.
|
||||
*
|
||||
* @author madeeha@google.com (Madeeha Ghori)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.UtilsService');
|
||||
|
||||
|
||||
blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN = 'blocklyEmptyWorkspaceBtn';
|
||||
blocklyApp.BLOCK_ROOT_ID_SUFFIX = '-blockRoot';
|
||||
|
||||
blocklyApp.UtilsService = ng.core.Class({
|
||||
constructor: [function() {}],
|
||||
getBlockDescription: function(block) {
|
||||
// We use 'BLANK' instead of the default '?' so that the string is read
|
||||
// out. (By default, screen readers tend to ignore punctuation.)
|
||||
return block.toString(undefined, 'BLANK');
|
||||
},
|
||||
isWorkspaceEmpty: function() {
|
||||
return !blocklyApp.workspace.topBlocks_.length;
|
||||
}
|
||||
});
|
||||
@@ -1,118 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* 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 Component representing the variable rename modal.
|
||||
*
|
||||
* @author corydiers@google.com (Cory Diers)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.VariableAddModalComponent');
|
||||
|
||||
goog.require('blocklyApp.AudioService');
|
||||
goog.require('blocklyApp.KeyboardInputService');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
goog.require('blocklyApp.VariableModalService');
|
||||
|
||||
goog.require('Blockly.CommonModal');
|
||||
|
||||
|
||||
blocklyApp.VariableAddModalComponent = ng.core.Component({
|
||||
selector: 'blockly-add-variable-modal',
|
||||
template: `
|
||||
<div *ngIf="modalIsVisible"class="blocklyModalCurtain"
|
||||
(click)="dismissModal()">
|
||||
<!-- $event.stopPropagation() prevents the modal from closing when its
|
||||
interior is clicked. -->
|
||||
<div id="varModal" class="blocklyModal" role="alertdialog"
|
||||
(click)="$event.stopPropagation()" tabindex="0"
|
||||
aria-labelledby="variableModalHeading">
|
||||
<h3 id="variableModalHeading">Add a variable...</h3>
|
||||
|
||||
<form id="varForm">
|
||||
<p id="inputLabel">New Variable Name:
|
||||
<input id="mainFieldId" type="text" [ngModel]="VALUE"
|
||||
(ngModelChange)="setTextValue($event)" tabindex="0"
|
||||
aria-labelledby="inputLabel" />
|
||||
</p>
|
||||
<hr>
|
||||
<button type="button" id="submitButton" (click)="submit()">
|
||||
SUBMIT
|
||||
</button>
|
||||
<button type="button" id="cancelButton" (click)="dismissModal()">
|
||||
CANCEL
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.AudioService, blocklyApp.KeyboardInputService, blocklyApp.VariableModalService,
|
||||
function(audioService, keyboardService, variableService) {
|
||||
this.workspace = blocklyApp.workspace;
|
||||
this.variableModalService = variableService;
|
||||
this.audioService = audioService;
|
||||
this.keyboardInputService = keyboardService;
|
||||
this.modalIsVisible = false;
|
||||
this.activeButtonIndex = -1;
|
||||
|
||||
var that = this;
|
||||
this.variableModalService.registerPreAddShowHook(
|
||||
function() {
|
||||
that.modalIsVisible = true;
|
||||
|
||||
Blockly.CommonModal.setupKeyboardOverrides(that);
|
||||
|
||||
setTimeout(function() {
|
||||
document.getElementById('varModal').focus();
|
||||
}, 150);
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
// Caches the current text variable as the user types.
|
||||
setTextValue: function(newValue) {
|
||||
this.variableName = newValue;
|
||||
},
|
||||
// Closes the modal (on both success and failure).
|
||||
hideModal_: Blockly.CommonModal.hideModal,
|
||||
// Focuses on the button represented by the given index.
|
||||
focusOnOption: Blockly.CommonModal.focusOnOption,
|
||||
// Counts the number of interactive elements for the modal.
|
||||
numInteractiveElements: Blockly.CommonModal.numInteractiveElements,
|
||||
// Gets all the interactive elements for the modal.
|
||||
getInteractiveElements: Blockly.CommonModal.getInteractiveElements,
|
||||
// Gets the container with interactive elements.
|
||||
getInteractiveContainer: function() {
|
||||
return document.getElementById('varForm');
|
||||
},
|
||||
// Submits the name change for the variable.
|
||||
submit: function() {
|
||||
this.workspace.createVariable(this.variableName);
|
||||
this.dismissModal();
|
||||
},
|
||||
// Dismisses and closes the modal.
|
||||
dismissModal: function() {
|
||||
this.variableModalService.hideModal();
|
||||
this.hideModal_();
|
||||
}
|
||||
})
|
||||
@@ -1,91 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* 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 Angular2 Service for the variable modal.
|
||||
*
|
||||
* @author corydiers@google.com (Cory Diers)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.VariableModalService');
|
||||
|
||||
blocklyApp.VariableModalService = ng.core.Class({
|
||||
constructor: [
|
||||
function() {
|
||||
this.modalIsShown = false;
|
||||
}
|
||||
],
|
||||
// Registers a hook to be called before the add modal is shown.
|
||||
registerPreAddShowHook: function(preShowHook) {
|
||||
this.preAddShowHook = function() {
|
||||
preShowHook();
|
||||
};
|
||||
},
|
||||
// Registers a hook to be called before the rename modal is shown.
|
||||
registerPreRenameShowHook: function(preShowHook) {
|
||||
this.preRenameShowHook = function(oldName) {
|
||||
preShowHook(oldName);
|
||||
};
|
||||
},
|
||||
// Registers a hook to be called before the remove modal is shown.
|
||||
registerPreRemoveShowHook: function(preShowHook) {
|
||||
this.preRemoveShowHook = function(oldName, count) {
|
||||
preShowHook(oldName, count);
|
||||
};
|
||||
},
|
||||
// Returns true if the variable modal is shown.
|
||||
isModalShown: function() {
|
||||
return this.modalIsShown;
|
||||
},
|
||||
// Show the add variable modal.
|
||||
showAddModal_: function() {
|
||||
this.preAddShowHook();
|
||||
this.modalIsShown = true;
|
||||
},
|
||||
// Show the rename variable modal.
|
||||
showRenameModal_: function(oldName) {
|
||||
this.preRenameShowHook(oldName);
|
||||
this.modalIsShown = true;
|
||||
},
|
||||
// Show the remove variable modal.
|
||||
showRemoveModal_: function(oldName) {
|
||||
var count = this.getNumVariables(oldName);
|
||||
this.modalIsShown = true;
|
||||
if (count > 1) {
|
||||
this.preRemoveShowHook(oldName, count);
|
||||
} else {
|
||||
var variable = blocklyApp.workspace.getVariable(oldName);
|
||||
blocklyApp.workspace.deleteVariableInternal_(variable);
|
||||
// Allow the execution loop to finish before "closing" the modal. While
|
||||
// the modal never opens, its being "open" should prevent other keypresses
|
||||
// anyway.
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
that.modalIsShown = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
getNumVariables: function(oldName) {
|
||||
return blocklyApp.workspace.getVariableUses(oldName).length;
|
||||
},
|
||||
// Hide the variable modal.
|
||||
hideModal: function() {
|
||||
this.modalIsShown = false;
|
||||
}
|
||||
});
|
||||
@@ -1,125 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* 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 Component representing the variable remove modal.
|
||||
*
|
||||
* @author corydiers@google.com (Cory Diers)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.VariableRemoveModalComponent');
|
||||
|
||||
goog.require('blocklyApp.AudioService');
|
||||
goog.require('blocklyApp.KeyboardInputService');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
goog.require('blocklyApp.TreeService');
|
||||
goog.require('blocklyApp.VariableModalService');
|
||||
|
||||
goog.require('Blockly.CommonModal');
|
||||
|
||||
|
||||
blocklyApp.VariableRemoveModalComponent = ng.core.Component({
|
||||
selector: 'blockly-remove-variable-modal',
|
||||
template: `
|
||||
<div *ngIf="modalIsVisible"class="blocklyModalCurtain"
|
||||
(click)="dismissModal()">
|
||||
<!-- $event.stopPropagation() prevents the modal from closing when its
|
||||
interior is clicked. -->
|
||||
<div id="varModal" class="blocklyModal" role="alertdialog"
|
||||
(click)="$event.stopPropagation()" tabindex="0"
|
||||
aria-labelledby="variableModalHeading">
|
||||
<h3 id="variableModalHeading">
|
||||
Delete {{getNumVariables()}} uses of the "{{currentVariableName}}"
|
||||
variable?
|
||||
</h3>
|
||||
|
||||
<form id="varForm">
|
||||
<hr>
|
||||
<button type="button" id="yesButton" (click)="submit()">
|
||||
YES
|
||||
</button>
|
||||
<button type="button" id="noButton" (click)="dismissModal()">
|
||||
NO
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.AudioService,
|
||||
blocklyApp.KeyboardInputService,
|
||||
blocklyApp.TreeService,
|
||||
blocklyApp.VariableModalService,
|
||||
function(audioService, keyboardService, treeService, variableService) {
|
||||
this.workspace = blocklyApp.workspace;
|
||||
this.treeService = treeService;
|
||||
this.variableModalService = variableService;
|
||||
this.audioService = audioService;
|
||||
this.keyboardInputService = keyboardService;
|
||||
this.modalIsVisible = false;
|
||||
this.activeButtonIndex = -1;
|
||||
this.currentVariableName = '';
|
||||
this.count = 0;
|
||||
|
||||
var that = this;
|
||||
this.variableModalService.registerPreRemoveShowHook(
|
||||
function(name, count) {
|
||||
that.currentVariableName = name;
|
||||
that.count = count;
|
||||
that.modalIsVisible = true;
|
||||
|
||||
Blockly.CommonModal.setupKeyboardOverrides(that);
|
||||
|
||||
setTimeout(function() {
|
||||
document.getElementById('varModal').focus();
|
||||
}, 150);
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
// Closes the modal (on both success and failure).
|
||||
hideModal_: Blockly.CommonModal.hideModal,
|
||||
// Focuses on the button represented by the given index.
|
||||
focusOnOption: Blockly.CommonModal.focusOnOption,
|
||||
// Counts the number of interactive elements for the modal.
|
||||
numInteractiveElements: Blockly.CommonModal.numInteractiveElements,
|
||||
// Gets all the interactive elements for the modal.
|
||||
getInteractiveElements: Blockly.CommonModal.getInteractiveElements,
|
||||
// Gets the container with interactive elements.
|
||||
getInteractiveContainer: function() {
|
||||
return document.getElementById('varForm');
|
||||
},
|
||||
getNumVariables: function() {
|
||||
return this.variableModalService.getNumVariables(this.currentVariableName);
|
||||
},
|
||||
// Submits the name change for the variable.
|
||||
submit: function() {
|
||||
var variable = blocklyApp.workspace.getVariable(this.currentVariableName);
|
||||
blocklyApp.workspace.deleteVariableInternal_(variable);
|
||||
this.dismissModal();
|
||||
},
|
||||
// Dismisses and closes the modal.
|
||||
dismissModal: function() {
|
||||
this.variableModalService.hideModal();
|
||||
this.hideModal_();
|
||||
}
|
||||
})
|
||||
@@ -1,121 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* 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 Component representing the variable rename modal.
|
||||
*
|
||||
* @author corydiers@google.com (Cory Diers)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.VariableRenameModalComponent');
|
||||
|
||||
goog.require('Blockly.CommonModal');
|
||||
goog.require('blocklyApp.AudioService');
|
||||
goog.require('blocklyApp.KeyboardInputService');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
goog.require('blocklyApp.VariableModalService');
|
||||
|
||||
|
||||
blocklyApp.VariableRenameModalComponent = ng.core.Component({
|
||||
selector: 'blockly-rename-variable-modal',
|
||||
template: `
|
||||
<div *ngIf="modalIsVisible"class="blocklyModalCurtain"
|
||||
(click)="dismissModal()">
|
||||
<!-- $event.stopPropagation() prevents the modal from closing when its
|
||||
interior is clicked. -->
|
||||
<div id="varModal" class="blocklyModal" role="alertdialog"
|
||||
(click)="$event.stopPropagation()" tabindex="0"
|
||||
aria-labelledby="variableModalHeading">
|
||||
<h3 id="variableModalHeading">
|
||||
Rename the "{{currentVariableName}}" variable...
|
||||
</h3>
|
||||
|
||||
<form id="varForm">
|
||||
<p id="inputLabel">New Variable Name:
|
||||
<input id="mainFieldId" type="text" [ngModel]="VALUE"
|
||||
(ngModelChange)="setTextValue($event)" tabindex="0"
|
||||
aria-labelledby="inputLabel" />
|
||||
</p>
|
||||
<hr>
|
||||
<button type="button" id="submitButton" (click)="submit()">
|
||||
SUBMIT
|
||||
</button>
|
||||
<button type="button" id="cancelButton" (click)="dismissModal()">
|
||||
CANCEL
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.AudioService, blocklyApp.KeyboardInputService, blocklyApp.VariableModalService,
|
||||
function(audioService, keyboardService, variableService) {
|
||||
this.workspace = blocklyApp.workspace;
|
||||
this.variableModalService = variableService;
|
||||
this.audioService = audioService;
|
||||
this.keyboardInputService = keyboardService;
|
||||
this.modalIsVisible = false;
|
||||
this.activeButtonIndex = -1;
|
||||
this.currentVariableName = '';
|
||||
|
||||
var that = this;
|
||||
this.variableModalService.registerPreRenameShowHook(
|
||||
function(oldName) {
|
||||
that.currentVariableName = oldName;
|
||||
that.modalIsVisible = true;
|
||||
|
||||
Blockly.CommonModal.setupKeyboardOverrides(that);
|
||||
|
||||
setTimeout(function() {
|
||||
document.getElementById('varModal').focus();
|
||||
}, 150);
|
||||
}
|
||||
);
|
||||
}
|
||||
],
|
||||
// Caches the current text variable as the user types.
|
||||
setTextValue: function(newValue) {
|
||||
this.variableName = newValue;
|
||||
},
|
||||
// Closes the modal (on both success and failure).
|
||||
hideModal_: Blockly.CommonModal.hideModal,
|
||||
// Focuses on the button represented by the given index.
|
||||
focusOnOption: Blockly.CommonModal.focusOnOption,
|
||||
// Counts the number of interactive elements for the modal.
|
||||
numInteractiveElements: Blockly.CommonModal.numInteractiveElements,
|
||||
// Gets all the interactive elements for the modal.
|
||||
getInteractiveElements: Blockly.CommonModal.getInteractiveElements,
|
||||
// Gets the container with interactive elements.
|
||||
getInteractiveContainer: function() {
|
||||
return document.getElementById('varForm');
|
||||
},
|
||||
// Submits the name change for the variable.
|
||||
submit: function() {
|
||||
this.workspace.renameVariable(this.currentVariableName, this.variableName);
|
||||
this.dismissModal();
|
||||
},
|
||||
// Dismisses and closes the modal.
|
||||
dismissModal: function() {
|
||||
this.variableModalService.hideModal();
|
||||
this.hideModal_();
|
||||
}
|
||||
})
|
||||
@@ -1,216 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Component representing a Blockly.Block in the
|
||||
* workspace.
|
||||
* @author madeeha@google.com (Madeeha Ghori)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.WorkspaceBlockComponent');
|
||||
|
||||
goog.require('blocklyApp.UtilsService');
|
||||
|
||||
goog.require('blocklyApp.AudioService');
|
||||
goog.require('blocklyApp.BlockConnectionService');
|
||||
goog.require('blocklyApp.FieldSegmentComponent');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
goog.require('blocklyApp.TreeService');
|
||||
|
||||
|
||||
blocklyApp.WorkspaceBlockComponent = ng.core.Component({
|
||||
selector: 'blockly-workspace-block',
|
||||
template: `
|
||||
<li [id]="componentIds.blockRoot" role="treeitem"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(componentIds.blockSummary, 'blockly-translate-workspace-block')"
|
||||
[attr.aria-level]="level">
|
||||
<label #blockSummaryLabel [id]="componentIds.blockSummary">{{getBlockDescription()}}</label>
|
||||
|
||||
<ol role="group">
|
||||
<template ngFor #blockInput [ngForOf]="block.inputList" #i="index">
|
||||
<li [id]="componentIds.inputs[i].inputLi" role="treeitem"
|
||||
*ngIf="blockInput.fieldRow.length"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(componentIds.inputs[i].fieldLabel)"
|
||||
[attr.aria-level]="level + 1">
|
||||
<blockly-field-segment *ngFor="#fieldSegment of inputListAsFieldSegments[i]"
|
||||
[prefixFields]="fieldSegment.prefixFields"
|
||||
[mainField]="fieldSegment.mainField"
|
||||
[mainFieldId]="componentIds.inputs[i].fieldLabel"
|
||||
[level]="level + 2">
|
||||
</blockly-field-segment>
|
||||
</li>
|
||||
|
||||
<template [ngIf]="blockInput.connection">
|
||||
<blockly-workspace-block *ngIf="blockInput.connection.targetBlock()"
|
||||
[block]="blockInput.connection.targetBlock()"
|
||||
[level]="level + 1"
|
||||
[tree]="tree">
|
||||
</blockly-workspace-block>
|
||||
<li [id]="componentIds.inputs[i].actionButtonLi" role="treeitem"
|
||||
*ngIf="!blockInput.connection.targetBlock()"
|
||||
[attr.aria-labelledBy]="generateAriaLabelledByAttr(componentIds.inputs[i].buttonLabel)"
|
||||
[attr.aria-level]="level + 1">
|
||||
<label [id]="componentIds.inputs[i].label">
|
||||
{{getBlockNeededLabel(blockInput)}}
|
||||
</label>
|
||||
<button [id]="componentIds.inputs[i].actionButton"
|
||||
(click)="addInteriorLink(blockInput.connection)"
|
||||
tabindex="-1">
|
||||
{{'MARK_THIS_SPOT'|translate}}
|
||||
</button>
|
||||
</li>
|
||||
</template>
|
||||
</template>
|
||||
</ol>
|
||||
</li>
|
||||
|
||||
<blockly-workspace-block *ngIf= "block.nextConnection && block.nextConnection.targetBlock()"
|
||||
[block]="block.nextConnection.targetBlock()"
|
||||
[level]="level" [tree]="tree">
|
||||
</blockly-workspace-block>
|
||||
`,
|
||||
directives: [blocklyApp.FieldSegmentComponent, ng.core.forwardRef(function() {
|
||||
return blocklyApp.WorkspaceBlockComponent;
|
||||
})],
|
||||
inputs: ['block', 'level', 'tree'],
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.AudioService,
|
||||
blocklyApp.BlockConnectionService,
|
||||
blocklyApp.TreeService,
|
||||
blocklyApp.UtilsService,
|
||||
function(audioService, blockConnectionService, treeService, utilsService) {
|
||||
this.audioService = audioService;
|
||||
this.blockConnectionService = blockConnectionService;
|
||||
this.treeService = treeService;
|
||||
this.utilsService = utilsService;
|
||||
this.cachedBlockId = null;
|
||||
}
|
||||
],
|
||||
ngDoCheck: function() {
|
||||
// The block ID can change if, for example, a block is spliced between two
|
||||
// linked blocks. We need to refresh the fields and component IDs when this
|
||||
// happens.
|
||||
if (this.cachedBlockId != this.block.id) {
|
||||
this.cachedBlockId = this.block.id;
|
||||
|
||||
var SUPPORTED_FIELDS = [Blockly.FieldTextInput, Blockly.FieldDropdown];
|
||||
this.inputListAsFieldSegments = this.block.inputList.map(function(input) {
|
||||
// Converts the input list to an array of field segments. Each field
|
||||
// segment represents a user-editable field, prefixed by an arbitrary
|
||||
// number of non-editable fields.
|
||||
var fieldSegments = [];
|
||||
|
||||
var bufferedFields = [];
|
||||
input.fieldRow.forEach(function(field) {
|
||||
var fieldIsSupported = SUPPORTED_FIELDS.some(function(fieldType) {
|
||||
return (field instanceof fieldType);
|
||||
});
|
||||
|
||||
if (fieldIsSupported) {
|
||||
var fieldSegment = {
|
||||
prefixFields: [],
|
||||
mainField: field
|
||||
};
|
||||
bufferedFields.forEach(function(bufferedField) {
|
||||
fieldSegment.prefixFields.push(bufferedField);
|
||||
});
|
||||
fieldSegments.push(fieldSegment);
|
||||
bufferedFields = [];
|
||||
} else {
|
||||
bufferedFields.push(field);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle leftover text at the end.
|
||||
if (bufferedFields.length) {
|
||||
fieldSegments.push({
|
||||
prefixFields: bufferedFields,
|
||||
mainField: null
|
||||
});
|
||||
}
|
||||
|
||||
return fieldSegments;
|
||||
});
|
||||
|
||||
// Generate unique IDs for elements in this component.
|
||||
this.componentIds = {};
|
||||
this.componentIds.blockRoot =
|
||||
this.block.id + blocklyApp.BLOCK_ROOT_ID_SUFFIX;
|
||||
this.componentIds.blockSummary = this.block.id + '-blockSummary';
|
||||
|
||||
var that = this;
|
||||
this.componentIds.inputs = this.block.inputList.map(function(input, i) {
|
||||
var idsToGenerate = ['inputLi', 'fieldLabel'];
|
||||
if (input.connection && !input.connection.targetBlock()) {
|
||||
idsToGenerate.push('actionButtonLi', 'actionButton', 'buttonLabel');
|
||||
}
|
||||
|
||||
var inputIds = {};
|
||||
idsToGenerate.forEach(function(idBaseString) {
|
||||
inputIds[idBaseString] = [that.block.id, i, idBaseString].join('-');
|
||||
});
|
||||
|
||||
return inputIds;
|
||||
});
|
||||
}
|
||||
},
|
||||
ngAfterViewInit: function() {
|
||||
// If this is a top-level tree in the workspace, ensure that it has an
|
||||
// active descendant. (Note that a timeout is needed here in order to
|
||||
// trigger Angular change detection.)
|
||||
var that = this;
|
||||
setTimeout(function() {
|
||||
if (that.level === 0 && !that.treeService.getActiveDescId(that.tree.id)) {
|
||||
that.treeService.setActiveDesc(
|
||||
that.componentIds.blockRoot, that.tree.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
addInteriorLink: function(connection) {
|
||||
this.blockConnectionService.markConnection(connection);
|
||||
},
|
||||
getBlockDescription: function() {
|
||||
var blockDescription = this.utilsService.getBlockDescription(this.block);
|
||||
|
||||
var parentBlock = this.block.getSurroundParent();
|
||||
if (parentBlock) {
|
||||
var fullDescription = blockDescription + ' inside ' +
|
||||
this.utilsService.getBlockDescription(parentBlock);
|
||||
return fullDescription;
|
||||
} else {
|
||||
return blockDescription;
|
||||
}
|
||||
},
|
||||
getBlockNeededLabel: function(blockInput) {
|
||||
// The input type name, or 'any' if any official input type qualifies.
|
||||
var inputTypeLabel = (
|
||||
blockInput.connection.check_ ?
|
||||
blockInput.connection.check_.join(', ') : Blockly.Msg.ANY);
|
||||
var blockTypeLabel = (
|
||||
blockInput.type == Blockly.NEXT_STATEMENT ?
|
||||
Blockly.Msg.BLOCK : Blockly.Msg.VALUE);
|
||||
return inputTypeLabel + ' ' + blockTypeLabel + ' needed:';
|
||||
},
|
||||
generateAriaLabelledByAttr: function(mainLabel, secondLabel) {
|
||||
return mainLabel + (secondLabel ? ' ' + secondLabel : '');
|
||||
}
|
||||
});
|
||||
@@ -1,106 +0,0 @@
|
||||
/**
|
||||
* AccessibleBlockly
|
||||
*
|
||||
* Copyright 2016 Google Inc.
|
||||
* https://developers.google.com/blockly/
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Angular2 Component that details how a Blockly.Workspace is
|
||||
* rendered in AccessibleBlockly.
|
||||
*
|
||||
* @author madeeha@google.com (Madeeha Ghori)
|
||||
*/
|
||||
|
||||
goog.provide('blocklyApp.WorkspaceComponent');
|
||||
|
||||
goog.require('blocklyApp.NotificationsService');
|
||||
goog.require('blocklyApp.ToolboxModalService');
|
||||
goog.require('blocklyApp.TranslatePipe');
|
||||
goog.require('blocklyApp.TreeService');
|
||||
|
||||
goog.require('blocklyApp.WorkspaceBlockComponent');
|
||||
|
||||
|
||||
blocklyApp.WorkspaceComponent = ng.core.Component({
|
||||
selector: 'blockly-workspace',
|
||||
template: `
|
||||
<div class="blocklyWorkspaceColumn">
|
||||
<h3 #workspaceTitle id="blockly-workspace-title">{{'WORKSPACE'|translate}}</h3>
|
||||
|
||||
<div *ngIf="workspace" class="blocklyWorkspace">
|
||||
<ol #tree *ngFor="#topBlock of workspace.topBlocks_; #groupIndex = index"
|
||||
[id]="tree.id || getNewTreeId()"
|
||||
tabindex="0" role="tree" class="blocklyTree blocklyWorkspaceFocusTarget"
|
||||
[attr.aria-activedescendant]="getActiveDescId(tree.id)"
|
||||
[attr.aria-labelledby]="workspaceTitle.id"
|
||||
(keydown)="onKeypress($event, tree)"
|
||||
(focus)="speakLocation(groupIndex, tree.id)">
|
||||
<blockly-workspace-block [level]="0" [block]="topBlock" [tree]="tree">
|
||||
</blockly-workspace-block>
|
||||
</ol>
|
||||
|
||||
<span *ngIf="workspace.topBlocks_.length === 0">
|
||||
<p id="emptyWorkspaceBtnLabel">
|
||||
{{'NO_BLOCKS_IN_WORKSPACE'|translate}}
|
||||
<button (click)="showToolboxModalForCreateNewGroup()"
|
||||
class="blocklyWorkspaceFocusTarget"
|
||||
id="{{ID_FOR_EMPTY_WORKSPACE_BTN}}"
|
||||
aria-describedby="emptyWorkspaceBtnLabel">
|
||||
{{'CREATE_NEW_BLOCK_GROUP'|translate}}
|
||||
</button>
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
directives: [blocklyApp.WorkspaceBlockComponent],
|
||||
pipes: [blocklyApp.TranslatePipe]
|
||||
})
|
||||
.Class({
|
||||
constructor: [
|
||||
blocklyApp.NotificationsService,
|
||||
blocklyApp.ToolboxModalService,
|
||||
blocklyApp.TreeService,
|
||||
function(notificationsService, toolboxModalService, treeService) {
|
||||
this.notificationsService = notificationsService;
|
||||
this.toolboxModalService = toolboxModalService;
|
||||
this.treeService = treeService;
|
||||
|
||||
this.ID_FOR_EMPTY_WORKSPACE_BTN = blocklyApp.ID_FOR_EMPTY_WORKSPACE_BTN;
|
||||
this.workspace = blocklyApp.workspace;
|
||||
this.currentTreeId = 0;
|
||||
}
|
||||
],
|
||||
getNewTreeId: function() {
|
||||
this.currentTreeId++;
|
||||
return 'blockly-tree-' + this.currentTreeId;
|
||||
},
|
||||
getActiveDescId: function(treeId) {
|
||||
return this.treeService.getActiveDescId(treeId);
|
||||
},
|
||||
onKeypress: function(e, tree) {
|
||||
this.treeService.onKeypress(e, tree);
|
||||
},
|
||||
showToolboxModalForCreateNewGroup: function() {
|
||||
this.toolboxModalService.showToolboxModalForCreateNewGroup(
|
||||
this.ID_FOR_EMPTY_WORKSPACE_BTN);
|
||||
},
|
||||
speakLocation: function(groupIndex, treeId) {
|
||||
this.notificationsService.speak(
|
||||
'Now in workspace group ' + (groupIndex + 1) + ' of ' +
|
||||
this.workspace.topBlocks_.length);
|
||||
}
|
||||
});
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
application: blockly-demo
|
||||
version: 20190419
|
||||
version: 20190722
|
||||
runtime: python27
|
||||
api_version: 1
|
||||
threadsafe: no
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+505
-524
File diff suppressed because it is too large
Load Diff
+609
-577
File diff suppressed because one or more lines are too long
+9
-11
@@ -146,7 +146,7 @@ Blockly.Blocks['lists_create_with'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
container.setAttribute('items', this.itemCount_);
|
||||
return container;
|
||||
},
|
||||
@@ -334,7 +334,7 @@ Blockly.Blocks['lists_getIndex'] = {
|
||||
this.setStyle('list_blocks');
|
||||
var modeMenu = new Blockly.FieldDropdown(MODE, function(value) {
|
||||
var isStatement = (value == 'REMOVE');
|
||||
this.sourceBlock_.updateStatement_(isStatement);
|
||||
this.getSourceBlock().updateStatement_(isStatement);
|
||||
});
|
||||
this.appendValueInput('VALUE')
|
||||
.setCheck('Array')
|
||||
@@ -414,7 +414,7 @@ Blockly.Blocks['lists_getIndex'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
var isStatement = !this.outputConnection;
|
||||
container.setAttribute('statement', isStatement);
|
||||
var isAt = this.getInput('AT').type == Blockly.INPUT_VALUE;
|
||||
@@ -480,7 +480,7 @@ Blockly.Blocks['lists_getIndex'] = {
|
||||
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_;
|
||||
var block = this.getSourceBlock();
|
||||
block.updateAt_(newAt);
|
||||
// This menu has been destroyed and replaced. Update the replacement.
|
||||
block.setFieldValue(value, 'WHERE');
|
||||
@@ -578,7 +578,7 @@ Blockly.Blocks['lists_setIndex'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
var isAt = this.getInput('AT').type == Blockly.INPUT_VALUE;
|
||||
container.setAttribute('at', isAt);
|
||||
return container;
|
||||
@@ -618,7 +618,7 @@ Blockly.Blocks['lists_setIndex'] = {
|
||||
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_;
|
||||
var block = this.getSourceBlock();
|
||||
block.updateAt_(newAt);
|
||||
// This menu has been destroyed and replaced. Update the replacement.
|
||||
block.setFieldValue(value, 'WHERE');
|
||||
@@ -676,7 +676,7 @@ Blockly.Blocks['lists_getSublist'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
var isAt1 = this.getInput('AT1').type == Blockly.INPUT_VALUE;
|
||||
container.setAttribute('at1', isAt1);
|
||||
var isAt2 = this.getInput('AT2').type == Blockly.INPUT_VALUE;
|
||||
@@ -723,14 +723,13 @@ Blockly.Blocks['lists_getSublist'] = {
|
||||
// The 'isAt' variable is available due to this function being a
|
||||
// closure.
|
||||
if (newAt != isAt) {
|
||||
var block = this.sourceBlock_;
|
||||
var block = this.getSourceBlock();
|
||||
block.updateAt_(n, newAt);
|
||||
// This menu has been destroyed and replaced.
|
||||
// Update the replacement.
|
||||
block.setFieldValue(value, 'WHERE' + n);
|
||||
return null;
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
this.getInput('AT' + n)
|
||||
.appendField(menu, 'WHERE' + n);
|
||||
@@ -831,7 +830,6 @@ Blockly.Blocks['lists_split'] = {
|
||||
updateType_: function(newMode) {
|
||||
var mode = this.getFieldValue('MODE');
|
||||
if (mode != newMode) {
|
||||
this.setFieldValue(newMode, 'MODE');
|
||||
var inputConnection = this.getInput('INPUT').connection;
|
||||
inputConnection.setShadowDom(null);
|
||||
var inputBlock = inputConnection.targetBlock();
|
||||
@@ -858,7 +856,7 @@ Blockly.Blocks['lists_split'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
container.setAttribute('mode', this.getFieldValue('MODE'));
|
||||
return container;
|
||||
},
|
||||
|
||||
+8
-2
@@ -305,6 +305,12 @@ Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
elseifCount_: 0,
|
||||
elseCount_: 0,
|
||||
|
||||
/**
|
||||
* Don't automatically add STATEMENT_PREFIX and STATEMENT_SUFFIX to generated
|
||||
* code. These will be handled manually in this block's generators.
|
||||
*/
|
||||
suppressPrefixSuffix: true,
|
||||
|
||||
/**
|
||||
* Create XML to represent the number of else-if and else inputs.
|
||||
* @return {Element} XML storage element.
|
||||
@@ -314,7 +320,7 @@ Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
if (!this.elseifCount_ && !this.elseCount_) {
|
||||
return null;
|
||||
}
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
if (this.elseifCount_) {
|
||||
container.setAttribute('elseif', this.elseifCount_);
|
||||
}
|
||||
@@ -462,7 +468,7 @@ Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN = {
|
||||
i++;
|
||||
}
|
||||
// Rebuild block.
|
||||
for (var i = 1; i <= this.elseifCount_; i++) {
|
||||
for (i = 1; i <= this.elseifCount_; i++) {
|
||||
this.appendValueInput('IF' + i)
|
||||
.setCheck('Boolean')
|
||||
.appendField(Blockly.Msg['CONTROLS_IF_MSG_ELSEIF']);
|
||||
|
||||
+38
-19
@@ -258,7 +258,7 @@ Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
customContextMenu: function(options) {
|
||||
if (this.isInFlyout){
|
||||
if (this.isInFlyout) {
|
||||
return;
|
||||
}
|
||||
var variable = this.getField('VAR').getVariable();
|
||||
@@ -268,7 +268,7 @@ Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN = {
|
||||
option.text =
|
||||
Blockly.Msg['VARIABLES_SET_CREATE_GET'].replace('%1', varName);
|
||||
var xmlField = Blockly.Variables.generateVariableFieldDom(variable);
|
||||
var xmlBlock = document.createElement('block');
|
||||
var xmlBlock = Blockly.utils.xml.createElement('block');
|
||||
xmlBlock.setAttribute('type', 'variables_get');
|
||||
xmlBlock.appendChild(xmlField);
|
||||
option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
|
||||
@@ -302,38 +302,57 @@ Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = {
|
||||
* To add a new loop type add this to your code:
|
||||
* Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.push('custom_loop');
|
||||
*/
|
||||
LOOP_TYPES: ['controls_repeat', 'controls_repeat_ext', 'controls_forEach',
|
||||
'controls_for', 'controls_whileUntil'],
|
||||
LOOP_TYPES: [
|
||||
'controls_repeat',
|
||||
'controls_repeat_ext',
|
||||
'controls_forEach',
|
||||
'controls_for',
|
||||
'controls_whileUntil'
|
||||
],
|
||||
|
||||
/**
|
||||
* Don't automatically add STATEMENT_PREFIX and STATEMENT_SUFFIX to generated
|
||||
* code. These will be handled manually in this block's generators.
|
||||
*/
|
||||
suppressPrefixSuffix: true,
|
||||
|
||||
/**
|
||||
* Is the given block enclosed (at any level) by a loop?
|
||||
* @param {!Blockly.Block} block Current block.
|
||||
* @return {Blockly.Block} The nearest surrounding loop, or null if none.
|
||||
*/
|
||||
getSurroundLoop: function(block) {
|
||||
// Is the block nested in a loop?
|
||||
do {
|
||||
if (Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES
|
||||
.indexOf(block.type) != -1) {
|
||||
return block;
|
||||
}
|
||||
block = block.getSurroundParent();
|
||||
} while (block);
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called whenever anything on the workspace changes.
|
||||
* Add warning if this flow block is not nested inside a loop.
|
||||
* @param {!Blockly.Events.Abstract} e Change event.
|
||||
* @param {!Blockly.Events.Abstract} _e Change event.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
onchange: function(/* e */) {
|
||||
onchange: function(_e) {
|
||||
if (!this.workspace.isDragging || this.workspace.isDragging()) {
|
||||
return; // Don't change state at the start of a drag.
|
||||
}
|
||||
var legal = false;
|
||||
// Is the block nested in a loop?
|
||||
var block = this;
|
||||
do {
|
||||
if (this.LOOP_TYPES.indexOf(block.type) != -1) {
|
||||
legal = true;
|
||||
break;
|
||||
}
|
||||
block = block.getSurroundParent();
|
||||
} while (block);
|
||||
if (legal) {
|
||||
if (Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN
|
||||
.getSurroundLoop(this)) {
|
||||
this.setWarningText(null);
|
||||
if (!this.isInFlyout) {
|
||||
this.setDisabled(false);
|
||||
this.setEnabled(true);
|
||||
}
|
||||
} else {
|
||||
this.setWarningText(Blockly.Msg['CONTROLS_FLOW_STATEMENTS_WARNING']);
|
||||
if (!this.isInFlyout && !this.getInheritedDisabled()) {
|
||||
this.setDisabled(true);
|
||||
this.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -460,7 +460,7 @@ Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
var divisorInput = (this.getFieldValue('PROPERTY') == 'DIVISIBLE_BY');
|
||||
container.setAttribute('divisor_input', divisorInput);
|
||||
return container;
|
||||
@@ -504,7 +504,7 @@ Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN = {
|
||||
Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION = function() {
|
||||
this.getField('PROPERTY').setValidator(function(option) {
|
||||
var divisorInput = (option == 'DIVISIBLE_BY');
|
||||
this.sourceBlock_.updateShape_(divisorInput);
|
||||
this.getSourceBlock().updateShape_(divisorInput);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -545,7 +545,7 @@ Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
container.setAttribute('op', this.getFieldValue('OP'));
|
||||
return container;
|
||||
},
|
||||
|
||||
+79
-61
@@ -108,12 +108,12 @@ Blockly.Blocks['procedures_defnoreturn'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function(opt_paramIds) {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
if (opt_paramIds) {
|
||||
container.setAttribute('name', this.getFieldValue('NAME'));
|
||||
}
|
||||
for (var i = 0; i < this.argumentVarModels_.length; i++) {
|
||||
var parameter = document.createElement('arg');
|
||||
var parameter = Blockly.utils.xml.createElement('arg');
|
||||
var argModel = this.argumentVarModels_[i];
|
||||
parameter.setAttribute('name', argModel.name);
|
||||
parameter.setAttribute('varid', argModel.getId());
|
||||
@@ -164,28 +164,48 @@ Blockly.Blocks['procedures_defnoreturn'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
decompose: function(workspace) {
|
||||
var containerBlock = workspace.newBlock('procedures_mutatorcontainer');
|
||||
containerBlock.initSvg();
|
||||
/*
|
||||
* Creates the following XML:
|
||||
* <block type="procedures_mutatorcontainer">
|
||||
* <statement name="STACK">
|
||||
* <block type="procedures_mutatorarg">
|
||||
* <field name="NAME">arg1_name</field>
|
||||
* <next>etc...</next>
|
||||
* </block>
|
||||
* </statement>
|
||||
* </block>
|
||||
*/
|
||||
|
||||
// Check/uncheck the allow statement box.
|
||||
if (this.getInput('RETURN')) {
|
||||
containerBlock.setFieldValue(
|
||||
this.hasStatements_ ? 'TRUE' : 'FALSE', 'STATEMENTS');
|
||||
} else {
|
||||
containerBlock.getInput('STATEMENT_INPUT').setVisible(false);
|
||||
}
|
||||
var containerBlockNode = Blockly.utils.xml.createElement('block');
|
||||
containerBlockNode.setAttribute('type', 'procedures_mutatorcontainer');
|
||||
var statementNode = Blockly.utils.xml.createElement('statement');
|
||||
statementNode.setAttribute('name', 'STACK');
|
||||
containerBlockNode.appendChild(statementNode);
|
||||
|
||||
// Parameter list.
|
||||
var connection = containerBlock.getInput('STACK').connection;
|
||||
var node = statementNode;
|
||||
for (var i = 0; i < this.arguments_.length; i++) {
|
||||
var paramBlock = workspace.newBlock('procedures_mutatorarg');
|
||||
paramBlock.initSvg();
|
||||
paramBlock.setFieldValue(this.arguments_[i], 'NAME');
|
||||
// Store the old location.
|
||||
paramBlock.oldLocation = i;
|
||||
connection.connect(paramBlock.previousConnection);
|
||||
connection = paramBlock.nextConnection;
|
||||
var argBlockNode = Blockly.utils.xml.createElement('block');
|
||||
argBlockNode.setAttribute('type', 'procedures_mutatorarg');
|
||||
var fieldNode = Blockly.utils.xml.createElement('field');
|
||||
fieldNode.setAttribute('name', 'NAME');
|
||||
var argumentName = Blockly.utils.xml.createTextNode(this.arguments_[i]);
|
||||
fieldNode.appendChild(argumentName);
|
||||
argBlockNode.appendChild(fieldNode);
|
||||
var nextNode = Blockly.utils.xml.createElement('next');
|
||||
argBlockNode.appendChild(nextNode);
|
||||
|
||||
node.appendChild(argBlockNode);
|
||||
node = nextNode;
|
||||
}
|
||||
|
||||
var containerBlock = Blockly.Xml.domToBlock(containerBlockNode, workspace);
|
||||
|
||||
if (this.type == 'procedures_defreturn') {
|
||||
containerBlock.setFieldValue(this.hasStatements_, 'STATEMENTS');
|
||||
} else {
|
||||
containerBlock.removeInput('STATEMENT_INPUT');
|
||||
}
|
||||
|
||||
// Initialize procedure's callers with blank IDs.
|
||||
Blockly.Procedures.mutateCallers(this);
|
||||
return containerBlock;
|
||||
@@ -205,11 +225,7 @@ Blockly.Blocks['procedures_defnoreturn'] = {
|
||||
var varName = paramBlock.getFieldValue('NAME');
|
||||
this.arguments_.push(varName);
|
||||
var variable = this.workspace.getVariable(varName, '');
|
||||
if (variable != null) {
|
||||
this.argumentVarModels_.push(variable);
|
||||
} else {
|
||||
console.log('Failed to get variable named ' + varName + ', ignoring.');
|
||||
}
|
||||
this.argumentVarModels_.push(variable);
|
||||
|
||||
this.paramIds_.push(paramBlock.id);
|
||||
paramBlock = paramBlock.nextConnection &&
|
||||
@@ -349,21 +365,21 @@ Blockly.Blocks['procedures_defnoreturn'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
customContextMenu: function(options) {
|
||||
if (this.isInFlyout){
|
||||
if (this.isInFlyout) {
|
||||
return;
|
||||
}
|
||||
// Add option to create caller.
|
||||
var option = {enabled: true};
|
||||
var name = this.getFieldValue('NAME');
|
||||
option.text = Blockly.Msg['PROCEDURES_CREATE_DO'].replace('%1', name);
|
||||
var xmlMutation = document.createElement('mutation');
|
||||
var xmlMutation = Blockly.utils.xml.createElement('mutation');
|
||||
xmlMutation.setAttribute('name', name);
|
||||
for (var i = 0; i < this.arguments_.length; i++) {
|
||||
var xmlArg = document.createElement('arg');
|
||||
var xmlArg = Blockly.utils.xml.createElement('arg');
|
||||
xmlArg.setAttribute('name', this.arguments_[i]);
|
||||
xmlMutation.appendChild(xmlArg);
|
||||
}
|
||||
var xmlBlock = document.createElement('block');
|
||||
var xmlBlock = Blockly.utils.xml.createElement('block');
|
||||
xmlBlock.setAttribute('type', this.callType_);
|
||||
xmlBlock.appendChild(xmlMutation);
|
||||
option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
|
||||
@@ -372,17 +388,18 @@ Blockly.Blocks['procedures_defnoreturn'] = {
|
||||
// Add options to create getters for each parameter.
|
||||
if (!this.isCollapsed()) {
|
||||
for (var i = 0; i < this.argumentVarModels_.length; i++) {
|
||||
var option = {enabled: true};
|
||||
var argOption = {enabled: true};
|
||||
var argVar = this.argumentVarModels_[i];
|
||||
var name = argVar.name;
|
||||
option.text = Blockly.Msg['VARIABLES_SET_CREATE_GET'].replace('%1', name);
|
||||
argOption.text = Blockly.Msg['VARIABLES_SET_CREATE_GET']
|
||||
.replace('%1', argVar.name);
|
||||
|
||||
var xmlField = Blockly.Variables.generateVariableFieldDom(argVar);
|
||||
var xmlBlock = document.createElement('block');
|
||||
xmlBlock.setAttribute('type', 'variables_get');
|
||||
xmlBlock.appendChild(xmlField);
|
||||
option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
|
||||
options.push(option);
|
||||
var argXmlField = Blockly.Variables.generateVariableFieldDom(argVar);
|
||||
var argXmlBlock = Blockly.utils.xml.createElement('block');
|
||||
argXmlBlock.setAttribute('type', 'variables_get');
|
||||
argXmlBlock.appendChild(argXmlField);
|
||||
argOption.callback =
|
||||
Blockly.ContextMenu.callbackFactory(this, argXmlBlock);
|
||||
options.push(argOption);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -489,7 +506,7 @@ Blockly.Blocks['procedures_mutatorcontainer'] = {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (event.type != Blockly.Events.BLOCK_CREATE) {
|
||||
return;
|
||||
}
|
||||
@@ -526,7 +543,6 @@ Blockly.Blocks['procedures_mutatorcontainer'] = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Blockly.Blocks['procedures_mutatorarg'] = {
|
||||
/**
|
||||
* Mutator block for procedure argument.
|
||||
@@ -572,15 +588,15 @@ Blockly.Blocks['procedures_mutatorarg'] = {
|
||||
* @this Blockly.FieldTextInput
|
||||
*/
|
||||
validator_: function(varName) {
|
||||
var outerWs = Blockly.Mutator.findParentWs(this.sourceBlock_.workspace);
|
||||
var outerWs = Blockly.Mutator.findParentWs(this.getSourceBlock().workspace);
|
||||
varName = varName.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
|
||||
if (!varName) {
|
||||
return null;
|
||||
}
|
||||
// Prevents duplicate parameter names in functions
|
||||
var blocks = this.sourceBlock_.workspace.getAllBlocks();
|
||||
var blocks = this.getSourceBlock().workspace.getAllBlocks();
|
||||
for (var i = 0; i < blocks.length; i += 1) {
|
||||
if (blocks[i].id == this.sourceBlock_.id) {
|
||||
if (blocks[i].id == this.getSourceBlock().id) {
|
||||
continue;
|
||||
}
|
||||
if (blocks[i].getFieldValue('NAME') == varName) {
|
||||
@@ -590,6 +606,7 @@ Blockly.Blocks['procedures_mutatorarg'] = {
|
||||
var model = outerWs.getVariable(varName, '');
|
||||
if (model && model.name != varName) {
|
||||
// Rename the variable (case change)
|
||||
// TODO: This function doesn't exist on the workspace.
|
||||
outerWs.renameVarById(model.getId(), varName);
|
||||
}
|
||||
if (!model) {
|
||||
@@ -609,7 +626,7 @@ Blockly.Blocks['procedures_mutatorarg'] = {
|
||||
* @this Blockly.FieldTextInput
|
||||
*/
|
||||
deleteIntermediateVars_: function(newText) {
|
||||
var outerWs = Blockly.Mutator.findParentWs(this.sourceBlock_.workspace);
|
||||
var outerWs = Blockly.Mutator.findParentWs(this.getSourceBlock().workspace);
|
||||
if (!outerWs) {
|
||||
return;
|
||||
}
|
||||
@@ -639,7 +656,7 @@ Blockly.Blocks['procedures_callnoreturn'] = {
|
||||
this.argumentVarModels_ = [];
|
||||
this.quarkConnections_ = {};
|
||||
this.quarkIds_ = null;
|
||||
this.previousDisabledState_ = false;
|
||||
this.previousEnabledState_ = true;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -815,10 +832,10 @@ Blockly.Blocks['procedures_callnoreturn'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
container.setAttribute('name', this.getProcedureCall());
|
||||
for (var i = 0; i < this.arguments_.length; i++) {
|
||||
var parameter = document.createElement('arg');
|
||||
var parameter = Blockly.utils.xml.createElement('arg');
|
||||
parameter.setAttribute('name', this.arguments_[i]);
|
||||
container.appendChild(parameter);
|
||||
}
|
||||
@@ -881,7 +898,7 @@ Blockly.Blocks['procedures_callnoreturn'] = {
|
||||
Blockly.Events.setGroup(event.group);
|
||||
/**
|
||||
* Create matching definition block.
|
||||
* <xml>
|
||||
* <xml xmlns="https://developers.google.com/blockly/xml">
|
||||
* <block type="procedures_defreturn" x="10" y="20">
|
||||
* <mutation name="test">
|
||||
* <arg name="x"></arg>
|
||||
@@ -890,8 +907,8 @@ Blockly.Blocks['procedures_callnoreturn'] = {
|
||||
* </block>
|
||||
* </xml>
|
||||
*/
|
||||
var xml = document.createElement('xml');
|
||||
var block = document.createElement('block');
|
||||
var xml = Blockly.utils.xml.createElement('xml');
|
||||
var block = Blockly.utils.xml.createElement('block');
|
||||
block.setAttribute('type', this.defType_);
|
||||
var xy = this.getRelativeToSurfaceXY();
|
||||
var x = xy.x + Blockly.SNAP_RADIUS * (this.RTL ? -1 : 1);
|
||||
@@ -900,9 +917,10 @@ Blockly.Blocks['procedures_callnoreturn'] = {
|
||||
block.setAttribute('y', y);
|
||||
var mutation = this.mutationToDom();
|
||||
block.appendChild(mutation);
|
||||
var field = document.createElement('field');
|
||||
var field = Blockly.utils.xml.createElement('field');
|
||||
field.setAttribute('name', 'NAME');
|
||||
field.appendChild(document.createTextNode(this.getProcedureCall()));
|
||||
field.appendChild(Blockly.utils.xml.createTextNode(
|
||||
this.getProcedureCall()));
|
||||
block.appendChild(field);
|
||||
xml.appendChild(block);
|
||||
Blockly.Xml.domToWorkspace(xml, this.workspace);
|
||||
@@ -933,10 +951,10 @@ Blockly.Blocks['procedures_callnoreturn'] = {
|
||||
}
|
||||
Blockly.Events.setGroup(event.group);
|
||||
if (event.newValue) {
|
||||
this.previousDisabledState_ = this.disabled;
|
||||
this.setDisabled(true);
|
||||
this.previousEnabledState_ = this.isEnabled();
|
||||
this.setEnabled(false);
|
||||
} else {
|
||||
this.setDisabled(this.previousDisabledState_);
|
||||
this.setEnabled(this.previousEnabledState_);
|
||||
}
|
||||
Blockly.Events.setGroup(oldGroup);
|
||||
}
|
||||
@@ -985,7 +1003,7 @@ Blockly.Blocks['procedures_callreturn'] = {
|
||||
this.arguments_ = [];
|
||||
this.quarkConnections_ = {};
|
||||
this.quarkIds_ = null;
|
||||
this.previousDisabledState_ = false;
|
||||
this.previousEnabledState_ = true;
|
||||
},
|
||||
|
||||
getProcedureCall: Blockly.Blocks['procedures_callnoreturn'].getProcedureCall,
|
||||
@@ -1027,7 +1045,7 @@ Blockly.Blocks['procedures_ifreturn'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
container.setAttribute('value', Number(this.hasReturnValue_));
|
||||
return container;
|
||||
},
|
||||
@@ -1048,10 +1066,10 @@ Blockly.Blocks['procedures_ifreturn'] = {
|
||||
/**
|
||||
* Called whenever anything on the workspace changes.
|
||||
* Add warning if this flow block is not nested inside a loop.
|
||||
* @param {!Blockly.Events.Abstract} e Change event.
|
||||
* @param {!Blockly.Events.Abstract} _e Change event.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
onchange: function(/* e */) {
|
||||
onchange: function(_e) {
|
||||
if (!this.workspace.isDragging || this.workspace.isDragging()) {
|
||||
return; // Don't change state at the start of a drag.
|
||||
}
|
||||
@@ -1081,12 +1099,12 @@ Blockly.Blocks['procedures_ifreturn'] = {
|
||||
}
|
||||
this.setWarningText(null);
|
||||
if (!this.isInFlyout) {
|
||||
this.setDisabled(false);
|
||||
this.setEnabled(true);
|
||||
}
|
||||
} else {
|
||||
this.setWarningText(Blockly.Msg['PROCEDURES_IFRETURN_WARNING']);
|
||||
if (!this.isInFlyout && !this.getInheritedDisabled()) {
|
||||
this.setDisabled(true);
|
||||
this.setEnabled(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+6
-10
@@ -243,7 +243,7 @@ Blockly.Blocks['text_getSubstring'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
var isAt1 = this.getInput('AT1').type == Blockly.INPUT_VALUE;
|
||||
container.setAttribute('at1', isAt1);
|
||||
var isAt2 = this.getInput('AT2').type == Blockly.INPUT_VALUE;
|
||||
@@ -296,7 +296,7 @@ Blockly.Blocks['text_getSubstring'] = {
|
||||
// The 'isAt' variable is available due to this function being a
|
||||
// closure.
|
||||
if (newAt != isAt) {
|
||||
var block = this.sourceBlock_;
|
||||
var block = this.getSourceBlock();
|
||||
block.updateAt_(n, newAt);
|
||||
// This menu has been destroyed and replaced.
|
||||
// Update the replacement.
|
||||
@@ -423,7 +423,7 @@ Blockly.Blocks['text_prompt_ext'] = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
container.setAttribute('type', this.getFieldValue('TYPE'));
|
||||
return container;
|
||||
},
|
||||
@@ -660,7 +660,7 @@ Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
container.setAttribute('items', this.itemCount_);
|
||||
return container;
|
||||
},
|
||||
@@ -810,7 +810,7 @@ Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
mutationToDom: function() {
|
||||
var container = document.createElement('mutation');
|
||||
var container = Blockly.utils.xml.createElement('mutation');
|
||||
container.setAttribute('at', !!this.isAt_);
|
||||
return container;
|
||||
},
|
||||
@@ -862,13 +862,9 @@ Blockly.Constants.Text.TEXT_CHARAT_EXTENSION = function() {
|
||||
dropdown.setValidator(function(value) {
|
||||
var newAt = (value == 'FROM_START') || (value == 'FROM_END');
|
||||
if (newAt != this.isAt_) {
|
||||
var block = this.sourceBlock_;
|
||||
var block = this.getSourceBlock();
|
||||
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.
|
||||
|
||||
+5
-5
@@ -100,7 +100,7 @@ Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN = {
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
customContextMenu: function(options) {
|
||||
if (!this.isInFlyout){
|
||||
if (!this.isInFlyout) {
|
||||
// Getter blocks have the option to create a setter block, and vice versa.
|
||||
if (this.type == 'variables_get') {
|
||||
var opposite_type = 'variables_set';
|
||||
@@ -113,17 +113,17 @@ Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN = {
|
||||
var option = {enabled: this.workspace.remainingCapacity() > 0};
|
||||
var name = this.getField('VAR').getText();
|
||||
option.text = contextMenuMsg.replace('%1', name);
|
||||
var xmlField = document.createElement('field');
|
||||
var xmlField = Blockly.utils.xml.createElement('field');
|
||||
xmlField.setAttribute('name', 'VAR');
|
||||
xmlField.appendChild(document.createTextNode(name));
|
||||
var xmlBlock = document.createElement('block');
|
||||
xmlField.appendChild(Blockly.utils.xml.createTextNode(name));
|
||||
var xmlBlock = Blockly.utils.xml.createElement('block');
|
||||
xmlBlock.setAttribute('type', opposite_type);
|
||||
xmlBlock.appendChild(xmlField);
|
||||
option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
|
||||
options.push(option);
|
||||
// Getter blocks have the option to rename or delete that variable.
|
||||
} else {
|
||||
if (this.type == 'variables_get' || this.type == 'variables_get_reporter'){
|
||||
if (this.type == 'variables_get' || this.type == 'variables_get_reporter') {
|
||||
var renameOption = {
|
||||
text: Blockly.Msg.RENAME_VARIABLE,
|
||||
enabled: true,
|
||||
|
||||
@@ -114,11 +114,11 @@ Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MI
|
||||
var option = {enabled: this.workspace.remainingCapacity() > 0};
|
||||
var name = this.getField('VAR').getText();
|
||||
option.text = contextMenuMsg.replace('%1', name);
|
||||
var xmlField = document.createElement('field');
|
||||
var xmlField = Blockly.utils.xml.createElement('field');
|
||||
xmlField.setAttribute('name', 'VAR');
|
||||
xmlField.setAttribute('variabletype', varType);
|
||||
xmlField.appendChild(document.createTextNode(name));
|
||||
var xmlBlock = document.createElement('block');
|
||||
xmlField.appendChild(Blockly.utils.xml.createTextNode(name));
|
||||
var xmlBlock = Blockly.utils.xml.createElement('block');
|
||||
xmlBlock.setAttribute('type', opposite_type);
|
||||
xmlBlock.appendChild(xmlField);
|
||||
option.callback = Blockly.ContextMenu.callbackFactory(this, xmlBlock);
|
||||
@@ -142,9 +142,15 @@ Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MI
|
||||
}
|
||||
}
|
||||
},
|
||||
onchange: function() {
|
||||
/**
|
||||
* Called whenever anything on the workspace changes.
|
||||
* Set the connection type for this block.
|
||||
* @param {!Blockly.Events.Abstract} _e Change event.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
onchange: function(_e) {
|
||||
var id = this.getFieldValue('VAR');
|
||||
var variableModel = this.workspace.getVariableById(id);
|
||||
var variableModel = Blockly.Variables.getVariable(this.workspace, id);
|
||||
if (this.type == 'variables_get_dynamic') {
|
||||
this.outputConnection.setCheck(variableModel.type);
|
||||
} else {
|
||||
|
||||
+60
-60
@@ -9,7 +9,7 @@ align:"RIGHT"},{type:"input_value",name:"COLOUR2",check:"Colour",align:"RIGHT"},
|
||||
Blockly.defineBlocksWithJsonArray([{type:"lists_create_empty",message0:"%{BKY_LISTS_CREATE_EMPTY_TITLE}",output:"Array",style:"list_blocks",tooltip:"%{BKY_LISTS_CREATE_EMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_CREATE_EMPTY_HELPURL}"},{type:"lists_repeat",message0:"%{BKY_LISTS_REPEAT_TITLE}",args0:[{type:"input_value",name:"ITEM"},{type:"input_value",name:"NUM",check:"Number"}],output:"Array",style:"list_blocks",tooltip:"%{BKY_LISTS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_LISTS_REPEAT_HELPURL}"},{type:"lists_reverse",
|
||||
message0:"%{BKY_LISTS_REVERSE_MESSAGE0}",args0:[{type:"input_value",name:"LIST",check:"Array"}],output:"Array",inputsInline:!0,style:"list_blocks",tooltip:"%{BKY_LISTS_REVERSE_TOOLTIP}",helpUrl:"%{BKY_LISTS_REVERSE_HELPURL}"},{type:"lists_isEmpty",message0:"%{BKY_LISTS_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Boolean",style:"list_blocks",tooltip:"%{BKY_LISTS_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_ISEMPTY_HELPURL}"},{type:"lists_length",message0:"%{BKY_LISTS_LENGTH_TITLE}",
|
||||
args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",style:"list_blocks",tooltip:"%{BKY_LISTS_LENGTH_TOOLTIP}",helpUrl:"%{BKY_LISTS_LENGTH_HELPURL}"}]);
|
||||
Blockly.Blocks.lists_create_with={init:function(){this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);this.setStyle("list_blocks");this.itemCount_=3;this.updateShape_();this.setOutput(!0,"Array");this.setMutator(new Blockly.Mutator(["lists_create_with_item"]));this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),
|
||||
Blockly.Blocks.lists_create_with={init:function(){this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);this.setStyle("list_blocks");this.itemCount_=3;this.updateShape_();this.setOutput(!0,"Array");this.setMutator(new Blockly.Mutator(["lists_create_with_item"]));this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP)},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),
|
||||
10);this.updateShape_()},decompose:function(a){var b=a.newBlock("lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("lists_create_with_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;
|
||||
c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||
|
||||
this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a);0==a&&b.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH)}for(;this.getInput("ADD"+a);)this.removeInput("ADD"+a),a++}};
|
||||
@@ -18,27 +18,27 @@ Blockly.Blocks.lists_create_with_item={init:function(){this.setStyle("list_block
|
||||
Blockly.Blocks.lists_indexOf={init:function(){var a=[[Blockly.Msg.LISTS_INDEX_OF_FIRST,"FIRST"],[Blockly.Msg.LISTS_INDEX_OF_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_INDEX_OF_HELPURL);this.setStyle("list_blocks");this.setOutput(!0,"Number");this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST);this.appendValueInput("FIND").appendField(new Blockly.FieldDropdown(a),"END");this.setInputsInline(!0);var b=this;this.setTooltip(function(){return Blockly.Msg.LISTS_INDEX_OF_TOOLTIP.replace("%1",
|
||||
b.workspace.options.oneBasedIndex?"0":"-1")})}};
|
||||
Blockly.Blocks.lists_getIndex={init:function(){var a=[[Blockly.Msg.LISTS_GET_INDEX_GET,"GET"],[Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE,"GET_REMOVE"],[Blockly.Msg.LISTS_GET_INDEX_REMOVE,"REMOVE"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);this.setStyle("list_blocks");
|
||||
a=new Blockly.FieldDropdown(a,function(a){this.sourceBlock_.updateStatement_("REMOVE"==a)});this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST);this.appendDummyInput().appendField(a,"MODE").appendField("","SPACE");this.appendDummyInput("AT");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_INDEX_TAIL);this.setInputsInline(!0);this.setOutput(!0);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=
|
||||
a=new Blockly.FieldDropdown(a,function(a){a="REMOVE"==a;this.getSourceBlock().updateStatement_(a)});this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST);this.appendDummyInput().appendField(a,"MODE").appendField("","SPACE");this.appendDummyInput("AT");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_INDEX_TAIL);this.setInputsInline(!0);this.setOutput(!0);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=
|
||||
b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "GET FROM_START":case "GET FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM;break;case "GET FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST;break;case "GET LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST;break;case "GET RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM;break;case "GET_REMOVE FROM_START":case "GET_REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM;break;case "GET_REMOVE FIRST":e=
|
||||
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST;break;case "GET_REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST;break;case "GET_REMOVE RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM;break;case "REMOVE FROM_START":case "REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM;break;case "REMOVE FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST;break;case "REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST;break;case "REMOVE RANDOM":e=
|
||||
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+("FROM_START"==d?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP).replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("statement",!this.outputConnection);var b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){var b="true"==
|
||||
a.getAttribute("statement");this.updateStatement_(b);a="false"!=a.getAttribute("at");this.updateAt_(a)},updateStatement_:function(a){a!=!this.outputConnection&&(this.unplug(!0,!0),a?(this.setOutput(!1),this.setPreviousStatement(!0),this.setNextStatement(!0)):(this.setPreviousStatement(!1),this.setNextStatement(!1),this.setOutput(!0)))},updateAt_:function(a){this.removeInput("AT");this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
|
||||
this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.sourceBlock_;e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.getInput("AT").appendField(b,"WHERE");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.moveInputBefore("TAIL",null)}};
|
||||
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+("FROM_START"==d?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP).replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("statement",!this.outputConnection);var b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){var b=
|
||||
"true"==a.getAttribute("statement");this.updateStatement_(b);a="false"!=a.getAttribute("at");this.updateAt_(a)},updateStatement_:function(a){a!=!this.outputConnection&&(this.unplug(!0,!0),a?(this.setOutput(!1),this.setPreviousStatement(!0),this.setNextStatement(!0)):(this.setPreviousStatement(!1),this.setNextStatement(!1),this.setOutput(!0)))},updateAt_:function(a){this.removeInput("AT");this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&
|
||||
this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.getSourceBlock();e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.getInput("AT").appendField(b,"WHERE");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.moveInputBefore("TAIL",null)}};
|
||||
Blockly.Blocks.lists_setIndex={init:function(){var a=[[Blockly.Msg.LISTS_SET_INDEX_SET,"SET"],[Blockly.Msg.LISTS_SET_INDEX_INSERT,"INSERT"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_SET_INDEX_HELPURL);this.setStyle("list_blocks");this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST);
|
||||
this.appendDummyInput().appendField(new Blockly.FieldDropdown(a),"MODE").appendField("","SPACE");this.appendDummyInput("AT");this.appendValueInput("TO").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_TO);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_SET_INDEX_TOOLTIP);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "SET FROM_START":case "SET FROM_END":e=
|
||||
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM;break;case "SET FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST;break;case "SET LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST;break;case "SET RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM;break;case "INSERT FROM_START":case "INSERT FROM_END":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM;break;case "INSERT FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST;break;case "INSERT LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST;
|
||||
break;case "INSERT RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP.replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=document.createElement("mutation"),b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT");
|
||||
this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.sourceBlock_;e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.moveInputBefore("AT","TO");this.getInput("ORDINAL")&&this.moveInputBefore("ORDINAL",
|
||||
break;case "INSERT RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP.replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation"),b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT");
|
||||
this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.getSourceBlock();e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.moveInputBefore("AT","TO");this.getInput("ORDINAL")&&this.moveInputBefore("ORDINAL",
|
||||
"TO");this.getInput("AT").appendField(b,"WHERE")}};
|
||||
Blockly.Blocks.lists_getSublist={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);this.setStyle("list_blocks");
|
||||
this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);this.setInputsInline(!0);this.setOutput(!0,"Array");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation"),b=this.getInput("AT1").type==
|
||||
Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
|
||||
this.appendDummyInput("AT"+a);var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.sourceBlock_;f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&this.moveInputBefore("ORDINAL1","AT2"));Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.moveInputBefore("TAIL",null)}};
|
||||
this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);this.setInputsInline(!0);this.setOutput(!0,"Array");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP)},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation"),
|
||||
b=this.getInput("AT1").type==Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
|
||||
this.appendDummyInput("AT"+a);var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.getSourceBlock();f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&this.moveInputBefore("ORDINAL1","AT2"));Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.moveInputBefore("TAIL",null)}};
|
||||
Blockly.Blocks.lists_sort={init:function(){this.jsonInit({message0:Blockly.Msg.LISTS_SORT_TITLE,args0:[{type:"field_dropdown",name:"TYPE",options:[[Blockly.Msg.LISTS_SORT_TYPE_NUMERIC,"NUMERIC"],[Blockly.Msg.LISTS_SORT_TYPE_TEXT,"TEXT"],[Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE,"IGNORE_CASE"]]},{type:"field_dropdown",name:"DIRECTION",options:[[Blockly.Msg.LISTS_SORT_ORDER_ASCENDING,"1"],[Blockly.Msg.LISTS_SORT_ORDER_DESCENDING,"-1"]]},{type:"input_value",name:"LIST",check:"Array"}],output:"Array",style:"list_blocks",
|
||||
tooltip:Blockly.Msg.LISTS_SORT_TOOLTIP,helpUrl:Blockly.Msg.LISTS_SORT_HELPURL})}};
|
||||
Blockly.Blocks.lists_split={init:function(){var a=this,b=new Blockly.FieldDropdown([[Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT,"SPLIT"],[Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST,"JOIN"]],function(b){a.updateType_(b)});this.setHelpUrl(Blockly.Msg.LISTS_SPLIT_HELPURL);this.setStyle("list_blocks");this.appendValueInput("INPUT").setCheck("String").appendField(b,"MODE");this.appendValueInput("DELIM").setCheck("String").appendField(Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER);this.setInputsInline(!0);this.setOutput(!0,
|
||||
"Array");this.setTooltip(function(){var b=a.getFieldValue("MODE");if("SPLIT"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT;if("JOIN"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN;throw Error("Unknown mode: "+b);})},updateType_:function(a){if(this.getFieldValue("MODE")!=a){this.setFieldValue(a,"MODE");var b=this.getInput("INPUT").connection;b.setShadowDom(null);var c=b.targetBlock();c&&(b.disconnect(),c.isShadow()?c.dispose():this.bumpNeighbours_())}"SPLIT"==a?(this.outputConnection.setCheck("Array"),
|
||||
this.getInput("INPUT").setCheck("String")):(this.outputConnection.setCheck("String"),this.getInput("INPUT").setCheck("Array"))},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("mode",this.getFieldValue("MODE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("mode"))}};Blockly.Blocks.logic={};Blockly.Constants.Logic={};Blockly.Constants.Logic.HUE=210;
|
||||
"Array");this.setTooltip(function(){var b=a.getFieldValue("MODE");if("SPLIT"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT;if("JOIN"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN;throw Error("Unknown mode: "+b);})},updateType_:function(a){if(this.getFieldValue("MODE")!=a){var b=this.getInput("INPUT").connection;b.setShadowDom(null);var c=b.targetBlock();c&&(b.disconnect(),c.isShadow()?c.dispose():this.bumpNeighbours_())}"SPLIT"==a?(this.outputConnection.setCheck("Array"),this.getInput("INPUT").setCheck("String")):
|
||||
(this.outputConnection.setCheck("String"),this.getInput("INPUT").setCheck("Array"))},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("mode",this.getFieldValue("MODE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("mode"))}};Blockly.Blocks.logic={};Blockly.Constants.Logic={};Blockly.Constants.Logic.HUE=210;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"logic_boolean",message0:"%1",args0:[{type:"field_dropdown",name:"BOOL",options:[["%{BKY_LOGIC_BOOLEAN_TRUE}","TRUE"],["%{BKY_LOGIC_BOOLEAN_FALSE}","FALSE"]]}],output:"Boolean",style:"logic_blocks",tooltip:"%{BKY_LOGIC_BOOLEAN_TOOLTIP}",helpUrl:"%{BKY_LOGIC_BOOLEAN_HELPURL}"},{type:"controls_if",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",
|
||||
name:"DO0"}],previousStatement:null,nextStatement:null,style:"logic_blocks",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",mutator:"controls_if_mutator",extensions:["controls_if_tooltip"]},{type:"controls_ifelse",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",name:"DO0"}],message2:"%{BKY_CONTROLS_IF_MSG_ELSE} %1",args2:[{type:"input_statement",name:"ELSE"}],previousStatement:null,nextStatement:null,
|
||||
style:"logic_blocks",tooltip:"%{BKYCONTROLS_IF_TOOLTIP_2}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",extensions:["controls_if_tooltip"]},{type:"logic_compare",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A"},{type:"field_dropdown",name:"OP",options:[["=","EQ"],["\u2260","NEQ"],["\u200f<","LT"],["\u200f\u2264","LTE"],["\u200f>","GT"],["\u200f\u2265","GTE"]]},{type:"input_value",name:"B"}],inputsInline:!0,output:"Boolean",style:"logic_blocks",helpUrl:"%{BKY_LOGIC_COMPARE_HELPURL}",extensions:["logic_compare",
|
||||
@@ -48,12 +48,12 @@ args2:[{type:"input_value",name:"ELSE"}],output:null,style:"logic_blocks",toolti
|
||||
Blockly.defineBlocksWithJsonArray([{type:"controls_if_if",message0:"%{BKY_CONTROLS_IF_IF_TITLE_IF}",nextStatement:null,enableContextMenu:!1,style:"logic_blocks",tooltip:"%{BKY_CONTROLS_IF_IF_TOOLTIP}"},{type:"controls_if_elseif",message0:"%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}",previousStatement:null,nextStatement:null,enableContextMenu:!1,style:"logic_blocks",tooltip:"%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}"},{type:"controls_if_else",message0:"%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}",previousStatement:null,
|
||||
enableContextMenu:!1,style:"logic_blocks",tooltip:"%{BKY_CONTROLS_IF_ELSE_TOOLTIP}"}]);Blockly.Constants.Logic.TOOLTIPS_BY_OP={EQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_EQ}",NEQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_NEQ}",LT:"%{BKY_LOGIC_COMPARE_TOOLTIP_LT}",LTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_LTE}",GT:"%{BKY_LOGIC_COMPARE_TOOLTIP_GT}",GTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_GTE}",AND:"%{BKY_LOGIC_OPERATION_TOOLTIP_AND}",OR:"%{BKY_LOGIC_OPERATION_TOOLTIP_OR}"};
|
||||
Blockly.Extensions.register("logic_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Logic.TOOLTIPS_BY_OP));
|
||||
Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN={elseifCount_:0,elseCount_:0,mutationToDom:function(){if(!this.elseifCount_&&!this.elseCount_)return null;var a=document.createElement("mutation");this.elseifCount_&&a.setAttribute("elseif",this.elseifCount_);this.elseCount_&&a.setAttribute("else",1);return a},domToMutation:function(a){this.elseifCount_=parseInt(a.getAttribute("elseif"),10)||0;this.elseCount_=parseInt(a.getAttribute("else"),10)||0;this.rebuildShape_()},decompose:function(a){var b=
|
||||
a.newBlock("controls_if_if");b.initSvg();for(var c=b.nextConnection,d=1;d<=this.elseifCount_;d++){var e=a.newBlock("controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=a.newBlock("controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){a=a.nextConnection.targetBlock();this.elseCount_=this.elseifCount_=0;for(var b=[null],c=[null],d=null;a;){switch(a.type){case "controls_if_elseif":this.elseifCount_++;b.push(a.valueConnection_);
|
||||
c.push(a.statementConnection_);break;case "controls_if_else":this.elseCount_++;d=a.statementConnection_;break;default:throw TypeError("Unknown block type: "+a.type);}a=a.nextConnection&&a.nextConnection.targetBlock()}this.updateShape_();this.reconnectChildBlocks_(b,c,d)},saveConnections:function(a){a=a.nextConnection.targetBlock();for(var b=1;a;){switch(a.type){case "controls_if_elseif":var c=this.getInput("IF"+b),d=this.getInput("DO"+b);a.valueConnection_=c&&c.connection.targetConnection;a.statementConnection_=
|
||||
d&&d.connection.targetConnection;b++;break;case "controls_if_else":d=this.getInput("ELSE");a.statementConnection_=d&&d.connection.targetConnection;break;default:throw TypeError("Unknown block type: "+a.type);}a=a.nextConnection&&a.nextConnection.targetBlock()}},rebuildShape_:function(){var a=[null],b=[null],c=null;this.getInput("ELSE")&&(c=this.getInput("ELSE").connection.targetConnection);for(var d=1;this.getInput("IF"+d);){var e=this.getInput("IF"+d),f=this.getInput("DO"+d);a.push(e.connection.targetConnection);
|
||||
b.push(f.connection.targetConnection);d++}this.updateShape_();this.reconnectChildBlocks_(a,b,c)},updateShape_:function(){this.getInput("ELSE")&&this.removeInput("ELSE");for(var a=1;this.getInput("IF"+a);)this.removeInput("IF"+a),this.removeInput("DO"+a),a++;for(a=1;a<=this.elseifCount_;a++)this.appendValueInput("IF"+a).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),this.appendStatementInput("DO"+a).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)},
|
||||
reconnectChildBlocks_:function(a,b,c){for(var d=1;d<=this.elseifCount_;d++)Blockly.Mutator.reconnect(a[d],this,"IF"+d),Blockly.Mutator.reconnect(b[d],this,"DO"+d);Blockly.Mutator.reconnect(c,this,"ELSE")}};Blockly.Extensions.registerMutator("controls_if_mutator",Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN,null,["controls_if_elseif","controls_if_else"]);
|
||||
Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN={elseifCount_:0,elseCount_:0,suppressPrefixSuffix:!0,mutationToDom:function(){if(!this.elseifCount_&&!this.elseCount_)return null;var a=Blockly.utils.xml.createElement("mutation");this.elseifCount_&&a.setAttribute("elseif",this.elseifCount_);this.elseCount_&&a.setAttribute("else",1);return a},domToMutation:function(a){this.elseifCount_=parseInt(a.getAttribute("elseif"),10)||0;this.elseCount_=parseInt(a.getAttribute("else"),10)||0;this.rebuildShape_()},
|
||||
decompose:function(a){var b=a.newBlock("controls_if_if");b.initSvg();for(var c=b.nextConnection,d=1;d<=this.elseifCount_;d++){var e=a.newBlock("controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=a.newBlock("controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){a=a.nextConnection.targetBlock();this.elseCount_=this.elseifCount_=0;for(var b=[null],c=[null],d=null;a;){switch(a.type){case "controls_if_elseif":this.elseifCount_++;
|
||||
b.push(a.valueConnection_);c.push(a.statementConnection_);break;case "controls_if_else":this.elseCount_++;d=a.statementConnection_;break;default:throw TypeError("Unknown block type: "+a.type);}a=a.nextConnection&&a.nextConnection.targetBlock()}this.updateShape_();this.reconnectChildBlocks_(b,c,d)},saveConnections:function(a){a=a.nextConnection.targetBlock();for(var b=1;a;){switch(a.type){case "controls_if_elseif":var c=this.getInput("IF"+b),d=this.getInput("DO"+b);a.valueConnection_=c&&c.connection.targetConnection;
|
||||
a.statementConnection_=d&&d.connection.targetConnection;b++;break;case "controls_if_else":d=this.getInput("ELSE");a.statementConnection_=d&&d.connection.targetConnection;break;default:throw TypeError("Unknown block type: "+a.type);}a=a.nextConnection&&a.nextConnection.targetBlock()}},rebuildShape_:function(){var a=[null],b=[null],c=null;this.getInput("ELSE")&&(c=this.getInput("ELSE").connection.targetConnection);for(var d=1;this.getInput("IF"+d);){var e=this.getInput("IF"+d),f=this.getInput("DO"+
|
||||
d);a.push(e.connection.targetConnection);b.push(f.connection.targetConnection);d++}this.updateShape_();this.reconnectChildBlocks_(a,b,c)},updateShape_:function(){this.getInput("ELSE")&&this.removeInput("ELSE");for(var a=1;this.getInput("IF"+a);)this.removeInput("IF"+a),this.removeInput("DO"+a),a++;for(a=1;a<=this.elseifCount_;a++)this.appendValueInput("IF"+a).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),this.appendStatementInput("DO"+a).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);
|
||||
this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)},reconnectChildBlocks_:function(a,b,c){for(var d=1;d<=this.elseifCount_;d++)Blockly.Mutator.reconnect(a[d],this,"IF"+d),Blockly.Mutator.reconnect(b[d],this,"DO"+d);Blockly.Mutator.reconnect(c,this,"ELSE")}};Blockly.Extensions.registerMutator("controls_if_mutator",Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN,null,["controls_if_elseif","controls_if_else"]);
|
||||
Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION=function(){this.setTooltip(function(){if(this.elseifCount_||this.elseCount_){if(!this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;if(this.elseifCount_&&!this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;if(this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_4}else return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;return""}.bind(this))};Blockly.Extensions.register("controls_if_tooltip",Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION);
|
||||
Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN={onchange:function(a){this.prevBlocks_||(this.prevBlocks_=[null,null]);var b=this.getInputTargetBlock("A"),c=this.getInputTargetBlock("B");b&&c&&!b.outputConnection.checkType_(c.outputConnection)&&(Blockly.Events.setGroup(a.group),a=this.prevBlocks_[0],a!==b&&(b.unplug(),a&&!a.isShadow()&&this.getInput("A").connection.connect(a.outputConnection)),b=this.prevBlocks_[1],b!==c&&(c.unplug(),b&&!b.isShadow()&&this.getInput("B").connection.connect(b.outputConnection)),
|
||||
this.bumpNeighbours_(),Blockly.Events.setGroup(!1));this.prevBlocks_[0]=this.getInputTargetBlock("A");this.prevBlocks_[1]=this.getInputTargetBlock("B")}};Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION=function(){this.mixin(Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN)};Blockly.Extensions.register("logic_compare",Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION);
|
||||
@@ -66,10 +66,10 @@ check:"Number",align:"RIGHT"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",arg
|
||||
args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FOREACH_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_forEach_tooltip"]},{type:"controls_flow_statements",message0:"%1",args0:[{type:"field_dropdown",name:"FLOW",options:[["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}","BREAK"],["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}","CONTINUE"]]}],previousStatement:null,style:"loop_blocks",helpUrl:"%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}",
|
||||
extensions:["controls_flow_tooltip","controls_flow_in_loop_check"]}]);Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS={WHILE:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}",UNTIL:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}"};Blockly.Extensions.register("controls_whileUntil_tooltip",Blockly.Extensions.buildTooltipForDropdown("MODE",Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS={BREAK:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}",CONTINUE:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}"};
|
||||
Blockly.Extensions.register("controls_flow_tooltip",Blockly.Extensions.buildTooltipForDropdown("FLOW",Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
|
||||
Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){var b=this.getField("VAR").getVariable(),c=b.name;if(!this.isCollapsed()&&null!=c){var d={enabled:!0};d.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c);b=Blockly.Variables.generateVariableFieldDom(b);c=document.createElement("block");c.setAttribute("type","variables_get");c.appendChild(b);d.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(d)}}}};
|
||||
Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){var b=this.getField("VAR").getVariable(),c=b.name;if(!this.isCollapsed()&&null!=c){var d={enabled:!0};d.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c);b=Blockly.Variables.generateVariableFieldDom(b);c=Blockly.utils.xml.createElement("block");c.setAttribute("type","variables_get");c.appendChild(b);d.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(d)}}}};
|
||||
Blockly.Extensions.registerMixin("contextMenu_newGetVariableBlock",Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);Blockly.Extensions.register("controls_for_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOR_TOOLTIP}","VAR"));Blockly.Extensions.register("controls_forEach_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOREACH_TOOLTIP}","VAR"));
|
||||
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN={LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"],onchange:function(){if(this.workspace.isDragging&&!this.workspace.isDragging()){var a=!1,b=this;do{if(-1!=this.LOOP_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);a?(this.setWarningText(null),this.isInFlyout||this.setDisabled(!1)):(this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING),this.isInFlyout||
|
||||
this.getInheritedDisabled()||this.setDisabled(!0))}}};Blockly.Extensions.registerMixin("controls_flow_in_loop_check",Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);Blockly.Blocks.math={};Blockly.Constants.Math={};Blockly.Constants.Math.HUE=230;
|
||||
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN={LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"],suppressPrefixSuffix:!0,getSurroundLoop:function(a){do{if(-1!=Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.indexOf(a.type))return a;a=a.getSurroundParent()}while(a);return null},onchange:function(a){this.workspace.isDragging&&!this.workspace.isDragging()&&(Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(this)?
|
||||
(this.setWarningText(null),this.isInFlyout||this.setEnabled(!0)):(this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING),this.isInFlyout||this.getInheritedDisabled()||this.setEnabled(!1)))}};Blockly.Extensions.registerMixin("controls_flow_in_loop_check",Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);Blockly.Blocks.math={};Blockly.Constants.Math={};Blockly.Constants.Math.HUE=230;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"math_number",message0:"%1",args0:[{type:"field_number",name:"NUM",value:0}],output:"Number",helpUrl:"%{BKY_MATH_NUMBER_HELPURL}",style:"math_blocks",tooltip:"%{BKY_MATH_NUMBER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"math_arithmetic",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Number"},{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ADDITION_SYMBOL}","ADD"],["%{BKY_MATH_SUBTRACTION_SYMBOL}","MINUS"],["%{BKY_MATH_MULTIPLICATION_SYMBOL}",
|
||||
"MULTIPLY"],["%{BKY_MATH_DIVISION_SYMBOL}","DIVIDE"],["%{BKY_MATH_POWER_SYMBOL}","POWER"]]},{type:"input_value",name:"B",check:"Number"}],inputsInline:!0,output:"Number",style:"math_blocks",helpUrl:"%{BKY_MATH_ARITHMETIC_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_single",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_SINGLE_OP_ROOT}","ROOT"],["%{BKY_MATH_SINGLE_OP_ABSOLUTE}","ABS"],["-","NEG"],["ln","LN"],["log10","LOG10"],["e^","EXP"],["10^","POW10"]]},
|
||||
{type:"input_value",name:"NUM",check:"Number"}],output:"Number",style:"math_blocks",helpUrl:"%{BKY_MATH_SINGLE_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_trig",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_TRIG_SIN}","SIN"],["%{BKY_MATH_TRIG_COS}","COS"],["%{BKY_MATH_TRIG_TAN}","TAN"],["%{BKY_MATH_TRIG_ASIN}","ASIN"],["%{BKY_MATH_TRIG_ACOS}","ACOS"],["%{BKY_MATH_TRIG_ATAN}","ATAN"]]},{type:"input_value",name:"NUM",check:"Number"}],output:"Number",style:"math_blocks",
|
||||
@@ -84,21 +84,22 @@ name:"Y",check:"Number"}],inputsInline:!0,output:"Number",style:"math_blocks",to
|
||||
Blockly.Constants.Math.TOOLTIPS_BY_OP={ADD:"%{BKY_MATH_ARITHMETIC_TOOLTIP_ADD}",MINUS:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MINUS}",MULTIPLY:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MULTIPLY}",DIVIDE:"%{BKY_MATH_ARITHMETIC_TOOLTIP_DIVIDE}",POWER:"%{BKY_MATH_ARITHMETIC_TOOLTIP_POWER}",ROOT:"%{BKY_MATH_SINGLE_TOOLTIP_ROOT}",ABS:"%{BKY_MATH_SINGLE_TOOLTIP_ABS}",NEG:"%{BKY_MATH_SINGLE_TOOLTIP_NEG}",LN:"%{BKY_MATH_SINGLE_TOOLTIP_LN}",LOG10:"%{BKY_MATH_SINGLE_TOOLTIP_LOG10}",EXP:"%{BKY_MATH_SINGLE_TOOLTIP_EXP}",POW10:"%{BKY_MATH_SINGLE_TOOLTIP_POW10}",
|
||||
SIN:"%{BKY_MATH_TRIG_TOOLTIP_SIN}",COS:"%{BKY_MATH_TRIG_TOOLTIP_COS}",TAN:"%{BKY_MATH_TRIG_TOOLTIP_TAN}",ASIN:"%{BKY_MATH_TRIG_TOOLTIP_ASIN}",ACOS:"%{BKY_MATH_TRIG_TOOLTIP_ACOS}",ATAN:"%{BKY_MATH_TRIG_TOOLTIP_ATAN}",SUM:"%{BKY_MATH_ONLIST_TOOLTIP_SUM}",MIN:"%{BKY_MATH_ONLIST_TOOLTIP_MIN}",MAX:"%{BKY_MATH_ONLIST_TOOLTIP_MAX}",AVERAGE:"%{BKY_MATH_ONLIST_TOOLTIP_AVERAGE}",MEDIAN:"%{BKY_MATH_ONLIST_TOOLTIP_MEDIAN}",MODE:"%{BKY_MATH_ONLIST_TOOLTIP_MODE}",STD_DEV:"%{BKY_MATH_ONLIST_TOOLTIP_STD_DEV}",RANDOM:"%{BKY_MATH_ONLIST_TOOLTIP_RANDOM}"};
|
||||
Blockly.Extensions.register("math_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Math.TOOLTIPS_BY_OP));
|
||||
Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation"),b="DIVISIBLE_BY"==this.getFieldValue("PROPERTY");a.setAttribute("divisor_input",b);return a},domToMutation:function(a){a="true"==a.getAttribute("divisor_input");this.updateShape_(a)},updateShape_:function(a){var b=this.getInput("DIVISOR");a?b||this.appendValueInput("DIVISOR").setCheck("Number"):b&&this.removeInput("DIVISOR")}};
|
||||
Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION=function(){this.getField("PROPERTY").setValidator(function(a){this.sourceBlock_.updateShape_("DIVISIBLE_BY"==a)})};Blockly.Extensions.registerMutator("math_is_divisibleby_mutator",Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);Blockly.Extensions.register("math_change_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_MATH_CHANGE_TOOLTIP}","VAR"));
|
||||
Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN={updateType_:function(a){"MODE"==a?this.outputConnection.setCheck("Array"):this.outputConnection.setCheck("Number")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("op",this.getFieldValue("OP"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("op"))}};Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION=function(){this.getField("OP").setValidator(function(a){this.updateType_(a)}.bind(this))};
|
||||
Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN={mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation"),b="DIVISIBLE_BY"==this.getFieldValue("PROPERTY");a.setAttribute("divisor_input",b);return a},domToMutation:function(a){a="true"==a.getAttribute("divisor_input");this.updateShape_(a)},updateShape_:function(a){var b=this.getInput("DIVISOR");a?b||this.appendValueInput("DIVISOR").setCheck("Number"):b&&this.removeInput("DIVISOR")}};
|
||||
Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION=function(){this.getField("PROPERTY").setValidator(function(a){a="DIVISIBLE_BY"==a;this.getSourceBlock().updateShape_(a)})};Blockly.Extensions.registerMutator("math_is_divisibleby_mutator",Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);Blockly.Extensions.register("math_change_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_MATH_CHANGE_TOOLTIP}","VAR"));
|
||||
Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN={updateType_:function(a){"MODE"==a?this.outputConnection.setCheck("Array"):this.outputConnection.setCheck("Number")},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("op",this.getFieldValue("OP"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("op"))}};Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION=function(){this.getField("OP").setValidator(function(a){this.updateType_(a)}.bind(this))};
|
||||
Blockly.Extensions.registerMutator("math_modes_of_list_mutator",Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN,Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION);Blockly.Blocks.procedures={};
|
||||
Blockly.Blocks.procedures_defnoreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);
|
||||
this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:function(a){this.hasStatements_!==a&&(a?(this.appendStatementInput("STACK").appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO),this.getInput("RETURN")&&this.moveInputBefore("STACK","RETURN")):this.removeInput("STACK",!0),this.hasStatements_=
|
||||
a)},updateParams_:function(){var a="";this.arguments_.length&&(a=Blockly.Msg.PROCEDURES_BEFORE_PARAMS+" "+this.arguments_.join(", "));Blockly.Events.disable();try{this.setFieldValue(a,"PARAMS")}finally{Blockly.Events.enable()}},mutationToDom:function(a){var b=document.createElement("mutation");a&&b.setAttribute("name",this.getFieldValue("NAME"));for(var c=0;c<this.argumentVarModels_.length;c++){var d=document.createElement("arg"),e=this.argumentVarModels_[c];d.setAttribute("name",e.name);d.setAttribute("varid",
|
||||
e.getId());a&&this.paramIds_&&d.setAttribute("paramId",this.paramIds_[c]);b.appendChild(d)}this.hasStatements_||b.setAttribute("statements","false");return b},domToMutation:function(a){this.arguments_=[];this.argumentVarModels_=[];for(var b=0,c;c=a.childNodes[b];b++)if("arg"==c.nodeName.toLowerCase()){var d=c.getAttribute("name");c=c.getAttribute("varid")||c.getAttribute("varId");this.arguments_.push(d);c=Blockly.Variables.getOrCreateVariablePackage(this.workspace,c,d,"");null!=c?this.argumentVarModels_.push(c):
|
||||
console.log("Failed to create a variable with name "+d+", ignoring.")}this.updateParams_();Blockly.Procedures.mutateCallers(this);this.setStatements_("false"!==a.getAttribute("statements"))},decompose:function(a){var b=a.newBlock("procedures_mutatorcontainer");b.initSvg();this.getInput("RETURN")?b.setFieldValue(this.hasStatements_?"TRUE":"FALSE","STATEMENTS"):b.getInput("STATEMENT_INPUT").setVisible(!1);for(var c=b.getInput("STACK").connection,d=0;d<this.arguments_.length;d++){var e=a.newBlock("procedures_mutatorarg");
|
||||
e.initSvg();e.setFieldValue(this.arguments_[d],"NAME");e.oldLocation=d;c.connect(e.previousConnection);c=e.nextConnection}Blockly.Procedures.mutateCallers(this);return b},compose:function(a){this.arguments_=[];this.paramIds_=[];this.argumentVarModels_=[];for(var b=a.getInputTargetBlock("STACK");b;){var c=b.getFieldValue("NAME");this.arguments_.push(c);var d=this.workspace.getVariable(c,"");null!=d?this.argumentVarModels_.push(d):console.log("Failed to get variable named "+c+", ignoring.");this.paramIds_.push(b.id);
|
||||
b=b.nextConnection&&b.nextConnection.targetBlock()}this.updateParams_();Blockly.Procedures.mutateCallers(this);a=a.getFieldValue("STATEMENTS");if(null!==a&&(a="TRUE"==a,this.hasStatements_!=a))if(a)this.setStatements_(!0),Blockly.Mutator.reconnect(this.statementConnection_,this,"STACK"),this.statementConnection_=null;else{a=this.getInput("STACK").connection;if(this.statementConnection_=a.targetConnection)a=a.targetBlock(),a.unplug(),a.bumpNeighbours_();this.setStatements_(!1)}},getProcedureDef:function(){return[this.getFieldValue("NAME"),
|
||||
this.arguments_,!1]},getVars:function(){return this.arguments_},getVarModels:function(){return this.argumentVarModels_},renameVarById:function(a,b){var c=this.workspace.getVariableById(a);if(""==c.type){c=c.name;for(var d=this.workspace.getVariableById(b),e=!1,f=0;f<this.argumentVarModels_.length;f++)this.argumentVarModels_[f].getId()==a&&(this.arguments_[f]=d.name,this.argumentVarModels_[f]=d,e=!0);e&&(this.displayRenamedVar_(c,d.name),Blockly.Procedures.mutateCallers(this))}},updateVarName:function(a){for(var b=
|
||||
a.name,c=!1,d=0;d<this.argumentVarModels_.length;d++)if(this.argumentVarModels_[d].getId()==a.getId()){var e=this.arguments_[d];this.arguments_[d]=b;c=!0}c&&(this.displayRenamedVar_(e,b),Blockly.Procedures.mutateCallers(this))},displayRenamedVar_:function(a,b){this.updateParams_();if(this.mutator.isVisible())for(var c=this.mutator.workspace_.getAllBlocks(!1),d=0,e;e=c[d];d++)"procedures_mutatorarg"==e.type&&Blockly.Names.equals(a,e.getFieldValue("NAME"))&&e.setFieldValue(b,"NAME")},customContextMenu:function(a){if(!this.isInFlyout){var b=
|
||||
{enabled:!0},c=this.getFieldValue("NAME");b.text=Blockly.Msg.PROCEDURES_CREATE_DO.replace("%1",c);var d=document.createElement("mutation");d.setAttribute("name",c);for(var e=0;e<this.arguments_.length;e++)c=document.createElement("arg"),c.setAttribute("name",this.arguments_[e]),d.appendChild(c);c=document.createElement("block");c.setAttribute("type",this.callType_);c.appendChild(d);b.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(b);if(!this.isCollapsed())for(e=0;e<this.argumentVarModels_.length;e++)b=
|
||||
{enabled:!0},d=this.argumentVarModels_[e],c=d.name,b.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c),d=Blockly.Variables.generateVariableFieldDom(d),c=document.createElement("block"),c.setAttribute("type","variables_get"),c.appendChild(d),b.callback=Blockly.ContextMenu.callbackFactory(this,c),a.push(b)}},callType_:"procedures_callnoreturn"};
|
||||
a)},updateParams_:function(){var a="";this.arguments_.length&&(a=Blockly.Msg.PROCEDURES_BEFORE_PARAMS+" "+this.arguments_.join(", "));Blockly.Events.disable();try{this.setFieldValue(a,"PARAMS")}finally{Blockly.Events.enable()}},mutationToDom:function(a){var b=Blockly.utils.xml.createElement("mutation");a&&b.setAttribute("name",this.getFieldValue("NAME"));for(var c=0;c<this.argumentVarModels_.length;c++){var d=Blockly.utils.xml.createElement("arg"),e=this.argumentVarModels_[c];d.setAttribute("name",
|
||||
e.name);d.setAttribute("varid",e.getId());a&&this.paramIds_&&d.setAttribute("paramId",this.paramIds_[c]);b.appendChild(d)}this.hasStatements_||b.setAttribute("statements","false");return b},domToMutation:function(a){this.arguments_=[];this.argumentVarModels_=[];for(var b=0,c;c=a.childNodes[b];b++)if("arg"==c.nodeName.toLowerCase()){var d=c.getAttribute("name");c=c.getAttribute("varid")||c.getAttribute("varId");this.arguments_.push(d);c=Blockly.Variables.getOrCreateVariablePackage(this.workspace,c,
|
||||
d,"");null!=c?this.argumentVarModels_.push(c):console.log("Failed to create a variable with name "+d+", ignoring.")}this.updateParams_();Blockly.Procedures.mutateCallers(this);this.setStatements_("false"!==a.getAttribute("statements"))},decompose:function(a){var b=Blockly.utils.xml.createElement("block");b.setAttribute("type","procedures_mutatorcontainer");var c=Blockly.utils.xml.createElement("statement");c.setAttribute("name","STACK");b.appendChild(c);for(var d=0;d<this.arguments_.length;d++){var e=
|
||||
Blockly.utils.xml.createElement("block");e.setAttribute("type","procedures_mutatorarg");var f=Blockly.utils.xml.createElement("field");f.setAttribute("name","NAME");var g=Blockly.utils.xml.createTextNode(this.arguments_[d]);f.appendChild(g);e.appendChild(f);f=Blockly.utils.xml.createElement("next");e.appendChild(f);c.appendChild(e);c=f}a=Blockly.Xml.domToBlock(b,a);"procedures_defreturn"==this.type?a.setFieldValue(this.hasStatements_,"STATEMENTS"):a.removeInput("STATEMENT_INPUT");Blockly.Procedures.mutateCallers(this);
|
||||
return a},compose:function(a){this.arguments_=[];this.paramIds_=[];this.argumentVarModels_=[];for(var b=a.getInputTargetBlock("STACK");b;){var c=b.getFieldValue("NAME");this.arguments_.push(c);c=this.workspace.getVariable(c,"");this.argumentVarModels_.push(c);this.paramIds_.push(b.id);b=b.nextConnection&&b.nextConnection.targetBlock()}this.updateParams_();Blockly.Procedures.mutateCallers(this);a=a.getFieldValue("STATEMENTS");if(null!==a&&(a="TRUE"==a,this.hasStatements_!=a))if(a)this.setStatements_(!0),
|
||||
Blockly.Mutator.reconnect(this.statementConnection_,this,"STACK"),this.statementConnection_=null;else{a=this.getInput("STACK").connection;if(this.statementConnection_=a.targetConnection)a=a.targetBlock(),a.unplug(),a.bumpNeighbours_();this.setStatements_(!1)}},getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!1]},getVars:function(){return this.arguments_},getVarModels:function(){return this.argumentVarModels_},renameVarById:function(a,b){var c=this.workspace.getVariableById(a);
|
||||
if(""==c.type){c=c.name;for(var d=this.workspace.getVariableById(b),e=!1,f=0;f<this.argumentVarModels_.length;f++)this.argumentVarModels_[f].getId()==a&&(this.arguments_[f]=d.name,this.argumentVarModels_[f]=d,e=!0);e&&(this.displayRenamedVar_(c,d.name),Blockly.Procedures.mutateCallers(this))}},updateVarName:function(a){for(var b=a.name,c=!1,d=0;d<this.argumentVarModels_.length;d++)if(this.argumentVarModels_[d].getId()==a.getId()){var e=this.arguments_[d];this.arguments_[d]=b;c=!0}c&&(this.displayRenamedVar_(e,
|
||||
b),Blockly.Procedures.mutateCallers(this))},displayRenamedVar_:function(a,b){this.updateParams_();if(this.mutator.isVisible())for(var c=this.mutator.workspace_.getAllBlocks(!1),d=0,e;e=c[d];d++)"procedures_mutatorarg"==e.type&&Blockly.Names.equals(a,e.getFieldValue("NAME"))&&e.setFieldValue(b,"NAME")},customContextMenu:function(a){if(!this.isInFlyout){var b={enabled:!0},c=this.getFieldValue("NAME");b.text=Blockly.Msg.PROCEDURES_CREATE_DO.replace("%1",c);var d=Blockly.utils.xml.createElement("mutation");
|
||||
d.setAttribute("name",c);for(c=0;c<this.arguments_.length;c++){var e=Blockly.utils.xml.createElement("arg");e.setAttribute("name",this.arguments_[c]);d.appendChild(e)}c=Blockly.utils.xml.createElement("block");c.setAttribute("type",this.callType_);c.appendChild(d);b.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(b);if(!this.isCollapsed())for(c=0;c<this.argumentVarModels_.length;c++)b={enabled:!0},d=this.argumentVarModels_[c],b.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",d.name),
|
||||
d=Blockly.Variables.generateVariableFieldDom(d),e=Blockly.utils.xml.createElement("block"),e.setAttribute("type","variables_get"),e.appendChild(d),b.callback=Blockly.ContextMenu.callbackFactory(this,e),a.push(b)}},callType_:"procedures_callnoreturn"};
|
||||
Blockly.Blocks.procedures_defreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFRETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.appendValueInput("RETURN").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&
|
||||
this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:Blockly.Blocks.procedures_defnoreturn.setStatements_,updateParams_:Blockly.Blocks.procedures_defnoreturn.updateParams_,
|
||||
mutationToDom:Blockly.Blocks.procedures_defnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_defnoreturn.domToMutation,decompose:Blockly.Blocks.procedures_defnoreturn.decompose,compose:Blockly.Blocks.procedures_defnoreturn.compose,getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!0]},getVars:Blockly.Blocks.procedures_defnoreturn.getVars,getVarModels:Blockly.Blocks.procedures_defnoreturn.getVarModels,renameVarById:Blockly.Blocks.procedures_defnoreturn.renameVarById,
|
||||
@@ -107,38 +108,38 @@ Blockly.Blocks.procedures_mutatorcontainer={init:function(){this.appendDummyInpu
|
||||
(a.type==Blockly.Events.BLOCK_DELETE||a.type==Blockly.Events.BLOCK_CREATE)){var b=this.workspace.getAllBlocks(),c=this.workspace.getAllVariables();if(a.type==Blockly.Events.BLOCK_DELETE){a=[];for(var d=0;d<b.length;d+=1)b[d].getFieldValue("NAME")&&a.push(b[d].getFieldValue("NAME"));for(b=0;b<c.length;b+=1)-1==a.indexOf(c[b].name)&&this.workspace.deleteVariableById(c[b].getId())}else if(a.type==Blockly.Events.BLOCK_CREATE&&(c=this.workspace.getBlockById(a.blockId),c.getField("NAME")&&(d=c.getFieldValue("NAME"),
|
||||
(a=this.workspace.getVariable(d))||(a=this.workspace.createVariable(d)),!c.previousConnection.isConnected()&&!c.nextConnection.isConnected())))for(d=0;d<b.length;d+=1)if(c.id!=b[d].id&&b[d].getFieldValue("NAME")==a.name){d=Blockly.Variables.generateUniqueName(this.workspace);a=this.workspace.createVariable(d);c.setFieldValue(a.name,"NAME");break}}}};
|
||||
Blockly.Blocks.procedures_mutatorarg={init:function(){var a=new Blockly.FieldTextInput("x",this.validator_);a.oldShowEditorFn_=a.showEditor_;a.showEditor_=function(){this.createdVariables_=[];this.oldShowEditorFn_()};this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORARG_TITLE).appendField(a,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP);this.contextMenu=!1;a.onFinishEditing_=
|
||||
this.deleteIntermediateVars_;a.createdVariables_=[];a.onFinishEditing_("x")},validator_:function(a){var b=Blockly.Mutator.findParentWs(this.sourceBlock_.workspace);a=a.replace(/[\s\xa0]+/g," ").replace(/^ | $/g,"");if(!a)return null;for(var c=this.sourceBlock_.workspace.getAllBlocks(),d=0;d<c.length;d+=1)if(c[d].id!=this.sourceBlock_.id&&c[d].getFieldValue("NAME")==a)return null;(c=b.getVariable(a,""))&&c.name!=a&&b.renameVarById(c.getId(),a);c||(c=b.createVariable(a,""))&&this.createdVariables_&&
|
||||
this.createdVariables_.push(c);return a},deleteIntermediateVars_:function(a){var b=Blockly.Mutator.findParentWs(this.sourceBlock_.workspace);if(b)for(var c=0;c<this.createdVariables_.length;c++){var d=this.createdVariables_[c];d.name!=a&&b.deleteVariableById(d.getId())}}};
|
||||
Blockly.Blocks.procedures_callnoreturn={init:function(){this.appendDummyInput("TOPROW").appendField(this.id,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousDisabledState_=!1},getProcedureCall:function(){return this.getFieldValue("NAME")},renameProcedure:function(a,b){Blockly.Names.equals(a,
|
||||
this.deleteIntermediateVars_;a.createdVariables_=[];a.onFinishEditing_("x")},validator_:function(a){var b=Blockly.Mutator.findParentWs(this.getSourceBlock().workspace);a=a.replace(/[\s\xa0]+/g," ").replace(/^ | $/g,"");if(!a)return null;for(var c=this.getSourceBlock().workspace.getAllBlocks(),d=0;d<c.length;d+=1)if(c[d].id!=this.getSourceBlock().id&&c[d].getFieldValue("NAME")==a)return null;(c=b.getVariable(a,""))&&c.name!=a&&b.renameVarById(c.getId(),a);c||(c=b.createVariable(a,""))&&this.createdVariables_&&
|
||||
this.createdVariables_.push(c);return a},deleteIntermediateVars_:function(a){var b=Blockly.Mutator.findParentWs(this.getSourceBlock().workspace);if(b)for(var c=0;c<this.createdVariables_.length;c++){var d=this.createdVariables_[c];d.name!=a&&b.deleteVariableById(d.getId())}}};
|
||||
Blockly.Blocks.procedures_callnoreturn={init:function(){this.appendDummyInput("TOPROW").appendField(this.id,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousEnabledState_=!0},getProcedureCall:function(){return this.getFieldValue("NAME")},renameProcedure:function(a,b){Blockly.Names.equals(a,
|
||||
this.getProcedureCall())&&(this.setFieldValue(b,"NAME"),this.setTooltip((this.outputConnection?Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP:Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP).replace("%1",b)))},setProcedureParameters_:function(a,b){var c=Blockly.Procedures.getDefinition(this.getProcedureCall(),this.workspace),d=c&&c.mutator&&c.mutator.isVisible();d||(this.quarkConnections_={},this.quarkIds_=null);if(b)if(a.join("\n")==this.arguments_.join("\n"))this.quarkIds_=b;else{if(b.length!=a.length)throw RangeError("paramNames and paramIds must be the same length.");
|
||||
this.setCollapsed(!1);this.quarkIds_||(this.quarkConnections_={},this.quarkIds_=[]);c=this.rendered;this.rendered=!1;for(var e=0;e<this.arguments_.length;e++){var f=this.getInput("ARG"+e);f&&(f=f.connection.targetConnection,this.quarkConnections_[this.quarkIds_[e]]=f,d&&f&&-1==b.indexOf(this.quarkIds_[e])&&(f.disconnect(),f.getSourceBlock().bumpNeighbours_()))}this.arguments_=[].concat(a);this.argumentVarModels_=[];for(e=0;e<this.arguments_.length;e++)d=Blockly.Variables.getOrCreateVariablePackage(this.workspace,
|
||||
null,this.arguments_[e],""),this.argumentVarModels_.push(d);this.updateShape_();if(this.quarkIds_=b)for(e=0;e<this.arguments_.length;e++)d=this.quarkIds_[e],d in this.quarkConnections_&&(f=this.quarkConnections_[d],Blockly.Mutator.reconnect(f,this,"ARG"+e)||delete this.quarkConnections_[d]);(this.rendered=c)&&this.render()}},updateShape_:function(){for(var a=0;a<this.arguments_.length;a++){var b=this.getField("ARGNAME"+a);if(b){Blockly.Events.disable();try{b.setValue(this.arguments_[a])}finally{Blockly.Events.enable()}}else b=
|
||||
new Blockly.FieldLabel(this.arguments_[a]),this.appendValueInput("ARG"+a).setAlign(Blockly.ALIGN_RIGHT).appendField(b,"ARGNAME"+a).init()}for(;this.getInput("ARG"+a);)this.removeInput("ARG"+a),a++;if(a=this.getInput("TOPROW"))this.arguments_.length?this.getField("WITH")||(a.appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS,"WITH"),a.init()):this.getField("WITH")&&a.removeField("WITH")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("name",this.getProcedureCall());
|
||||
for(var b=0;b<this.arguments_.length;b++){var c=document.createElement("arg");c.setAttribute("name",this.arguments_[b]);a.appendChild(c)}return a},domToMutation:function(a){var b=a.getAttribute("name");this.renameProcedure(this.getProcedureCall(),b);b=[];for(var c=[],d=0,e;e=a.childNodes[d];d++)"arg"==e.nodeName.toLowerCase()&&(b.push(e.getAttribute("name")),c.push(e.getAttribute("paramId")));this.setProcedureParameters_(b,c)},getVarModels:function(){return this.argumentVarModels_},onchange:function(a){if(this.workspace&&
|
||||
!this.workspace.isFlyout&&a.recordUndo)if(a.type==Blockly.Events.BLOCK_CREATE&&-1!=a.ids.indexOf(this.id)){var b=this.getProcedureCall();b=Blockly.Procedures.getDefinition(b,this.workspace);!b||b.type==this.defType_&&JSON.stringify(b.arguments_)==JSON.stringify(this.arguments_)||(b=null);if(!b){Blockly.Events.setGroup(a.group);a=document.createElement("xml");b=document.createElement("block");b.setAttribute("type",this.defType_);var c=this.getRelativeToSurfaceXY(),d=c.y+2*Blockly.SNAP_RADIUS;b.setAttribute("x",
|
||||
c.x+Blockly.SNAP_RADIUS*(this.RTL?-1:1));b.setAttribute("y",d);c=this.mutationToDom();b.appendChild(c);c=document.createElement("field");c.setAttribute("name","NAME");c.appendChild(document.createTextNode(this.getProcedureCall()));b.appendChild(c);a.appendChild(b);Blockly.Xml.domToWorkspace(a,this.workspace);Blockly.Events.setGroup(!1)}}else a.type==Blockly.Events.BLOCK_DELETE?(b=this.getProcedureCall(),b=Blockly.Procedures.getDefinition(b,this.workspace),b||(Blockly.Events.setGroup(a.group),this.dispose(!0,
|
||||
!1),Blockly.Events.setGroup(!1))):a.type==Blockly.Events.CHANGE&&"disabled"==a.element&&(b=this.getProcedureCall(),(b=Blockly.Procedures.getDefinition(b,this.workspace))&&b.id==a.blockId&&((b=Blockly.Events.getGroup())&&console.log("Saw an existing group while responding to a definition change"),Blockly.Events.setGroup(a.group),a.newValue?(this.previousDisabledState_=this.disabled,this.setDisabled(!0)):this.setDisabled(this.previousDisabledState_),Blockly.Events.setGroup(b)))},customContextMenu:function(a){if(this.workspace.isMovable()){var b=
|
||||
new Blockly.FieldLabel(this.arguments_[a]),this.appendValueInput("ARG"+a).setAlign(Blockly.ALIGN_RIGHT).appendField(b,"ARGNAME"+a).init()}for(;this.getInput("ARG"+a);)this.removeInput("ARG"+a),a++;if(a=this.getInput("TOPROW"))this.arguments_.length?this.getField("WITH")||(a.appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS,"WITH"),a.init()):this.getField("WITH")&&a.removeField("WITH")},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("name",this.getProcedureCall());
|
||||
for(var b=0;b<this.arguments_.length;b++){var c=Blockly.utils.xml.createElement("arg");c.setAttribute("name",this.arguments_[b]);a.appendChild(c)}return a},domToMutation:function(a){var b=a.getAttribute("name");this.renameProcedure(this.getProcedureCall(),b);b=[];for(var c=[],d=0,e;e=a.childNodes[d];d++)"arg"==e.nodeName.toLowerCase()&&(b.push(e.getAttribute("name")),c.push(e.getAttribute("paramId")));this.setProcedureParameters_(b,c)},getVarModels:function(){return this.argumentVarModels_},onchange:function(a){if(this.workspace&&
|
||||
!this.workspace.isFlyout&&a.recordUndo)if(a.type==Blockly.Events.BLOCK_CREATE&&-1!=a.ids.indexOf(this.id)){var b=this.getProcedureCall();b=Blockly.Procedures.getDefinition(b,this.workspace);!b||b.type==this.defType_&&JSON.stringify(b.arguments_)==JSON.stringify(this.arguments_)||(b=null);if(!b){Blockly.Events.setGroup(a.group);a=Blockly.utils.xml.createElement("xml");b=Blockly.utils.xml.createElement("block");b.setAttribute("type",this.defType_);var c=this.getRelativeToSurfaceXY(),d=c.y+2*Blockly.SNAP_RADIUS;
|
||||
b.setAttribute("x",c.x+Blockly.SNAP_RADIUS*(this.RTL?-1:1));b.setAttribute("y",d);c=this.mutationToDom();b.appendChild(c);c=Blockly.utils.xml.createElement("field");c.setAttribute("name","NAME");c.appendChild(Blockly.utils.xml.createTextNode(this.getProcedureCall()));b.appendChild(c);a.appendChild(b);Blockly.Xml.domToWorkspace(a,this.workspace);Blockly.Events.setGroup(!1)}}else a.type==Blockly.Events.BLOCK_DELETE?(b=this.getProcedureCall(),b=Blockly.Procedures.getDefinition(b,this.workspace),b||(Blockly.Events.setGroup(a.group),
|
||||
this.dispose(!0,!1),Blockly.Events.setGroup(!1))):a.type==Blockly.Events.CHANGE&&"disabled"==a.element&&(b=this.getProcedureCall(),(b=Blockly.Procedures.getDefinition(b,this.workspace))&&b.id==a.blockId&&((b=Blockly.Events.getGroup())&&console.log("Saw an existing group while responding to a definition change"),Blockly.Events.setGroup(a.group),a.newValue?(this.previousEnabledState_=this.isEnabled(),this.setEnabled(!1)):this.setEnabled(this.previousEnabledState_),Blockly.Events.setGroup(b)))},customContextMenu:function(a){if(this.workspace.isMovable()){var b=
|
||||
{enabled:!0};b.text=Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF;var c=this.getProcedureCall(),d=this.workspace;b.callback=function(){var a=Blockly.Procedures.getDefinition(c,d);a&&(d.centerOnBlock(a.id),a.select())};a.push(b)}},defType_:"procedures_defnoreturn"};
|
||||
Blockly.Blocks.procedures_callreturn={init:function(){this.appendDummyInput("TOPROW").appendField("","NAME");this.setOutput(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);this.arguments_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousDisabledState_=!1},getProcedureCall:Blockly.Blocks.procedures_callnoreturn.getProcedureCall,renameProcedure:Blockly.Blocks.procedures_callnoreturn.renameProcedure,setProcedureParameters_:Blockly.Blocks.procedures_callnoreturn.setProcedureParameters_,
|
||||
Blockly.Blocks.procedures_callreturn={init:function(){this.appendDummyInput("TOPROW").appendField("","NAME");this.setOutput(!0);this.setStyle("procedure_blocks");this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);this.arguments_=[];this.quarkConnections_={};this.quarkIds_=null;this.previousEnabledState_=!0},getProcedureCall:Blockly.Blocks.procedures_callnoreturn.getProcedureCall,renameProcedure:Blockly.Blocks.procedures_callnoreturn.renameProcedure,setProcedureParameters_:Blockly.Blocks.procedures_callnoreturn.setProcedureParameters_,
|
||||
updateShape_:Blockly.Blocks.procedures_callnoreturn.updateShape_,mutationToDom:Blockly.Blocks.procedures_callnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_callnoreturn.domToMutation,getVarModels:Blockly.Blocks.procedures_callnoreturn.getVarModels,onchange:Blockly.Blocks.procedures_callnoreturn.onchange,customContextMenu:Blockly.Blocks.procedures_callnoreturn.customContextMenu,defType_:"procedures_defreturn"};
|
||||
Blockly.Blocks.procedures_ifreturn={init:function(){this.appendValueInput("CONDITION").setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setStyle("procedure_blocks");this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_IFRETURN_HELPURL);this.hasReturnValue_=!0},mutationToDom:function(){var a=
|
||||
document.createElement("mutation");a.setAttribute("value",Number(this.hasReturnValue_));return a},domToMutation:function(a){this.hasReturnValue_=1==a.getAttribute("value");this.hasReturnValue_||(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN))},onchange:function(){if(this.workspace.isDragging&&!this.workspace.isDragging()){var a=!1,b=this;do{if(-1!=this.FUNCTION_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);a?("procedures_defnoreturn"==
|
||||
b.type&&this.hasReturnValue_?(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!1):"procedures_defreturn"!=b.type||this.hasReturnValue_||(this.removeInput("VALUE"),this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!0),this.setWarningText(null),this.isInFlyout||this.setDisabled(!1)):(this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING),this.isInFlyout||this.getInheritedDisabled()||
|
||||
this.setDisabled(!0))}},FUNCTION_TYPES:["procedures_defnoreturn","procedures_defreturn"]};Blockly.Blocks.texts={};Blockly.Constants.Text={};Blockly.Constants.Text.HUE=160;
|
||||
Blockly.utils.xml.createElement("mutation");a.setAttribute("value",Number(this.hasReturnValue_));return a},domToMutation:function(a){this.hasReturnValue_=1==a.getAttribute("value");this.hasReturnValue_||(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN))},onchange:function(a){if(this.workspace.isDragging&&!this.workspace.isDragging()){a=!1;var b=this;do{if(-1!=this.FUNCTION_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);
|
||||
a?("procedures_defnoreturn"==b.type&&this.hasReturnValue_?(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!1):"procedures_defreturn"!=b.type||this.hasReturnValue_||(this.removeInput("VALUE"),this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!0),this.setWarningText(null),this.isInFlyout||this.setEnabled(!0)):(this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING),
|
||||
this.isInFlyout||this.getInheritedDisabled()||this.setEnabled(!1))}},FUNCTION_TYPES:["procedures_defnoreturn","procedures_defreturn"]};Blockly.Blocks.texts={};Blockly.Constants.Text={};Blockly.Constants.Text.HUE=160;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"text",message0:"%1",args0:[{type:"field_input",name:"TEXT",text:""}],output:"String",style:"text_blocks",helpUrl:"%{BKY_TEXT_TEXT_HELPURL}",tooltip:"%{BKY_TEXT_TEXT_TOOLTIP}",extensions:["text_quotes","parent_tooltip_when_inline"]},{type:"text_join",message0:"",output:"String",style:"text_blocks",helpUrl:"%{BKY_TEXT_JOIN_HELPURL}",tooltip:"%{BKY_TEXT_JOIN_TOOLTIP}",mutator:"text_join_mutator"},{type:"text_create_join_container",message0:"%{BKY_TEXT_CREATE_JOIN_TITLE_JOIN} %1 %2",
|
||||
args0:[{type:"input_dummy"},{type:"input_statement",name:"STACK"}],style:"text_blocks",tooltip:"%{BKY_TEXT_CREATE_JOIN_TOOLTIP}",enableContextMenu:!1},{type:"text_create_join_item",message0:"%{BKY_TEXT_CREATE_JOIN_ITEM_TITLE_ITEM}",previousStatement:null,nextStatement:null,style:"text_blocks",tooltip:"%{BKY_TEXT_CREATE_JOIN_ITEM_TOOLTIP}",enableContextMenu:!1},{type:"text_append",message0:"%{BKY_TEXT_APPEND_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_TEXT_APPEND_VARIABLE}"},{type:"input_value",
|
||||
name:"TEXT"}],previousStatement:null,nextStatement:null,style:"text_blocks",extensions:["text_append_tooltip"]},{type:"text_length",message0:"%{BKY_TEXT_LENGTH_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",style:"text_blocks",tooltip:"%{BKY_TEXT_LENGTH_TOOLTIP}",helpUrl:"%{BKY_TEXT_LENGTH_HELPURL}"},{type:"text_isEmpty",message0:"%{BKY_TEXT_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Boolean",style:"text_blocks",
|
||||
tooltip:"%{BKY_TEXT_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_TEXT_ISEMPTY_HELPURL}"},{type:"text_indexOf",message0:"%{BKY_TEXT_INDEXOF_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"String"},{type:"field_dropdown",name:"END",options:[["%{BKY_TEXT_INDEXOF_OPERATOR_FIRST}","FIRST"],["%{BKY_TEXT_INDEXOF_OPERATOR_LAST}","LAST"]]},{type:"input_value",name:"FIND",check:"String"}],output:"Number",style:"text_blocks",helpUrl:"%{BKY_TEXT_INDEXOF_HELPURL}",inputsInline:!0,extensions:["text_indexOf_tooltip"]},
|
||||
{type:"text_charAt",message0:"%{BKY_TEXT_CHARAT_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"String"},{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",style:"text_blocks",helpUrl:"%{BKY_TEXT_CHARAT_HELPURL}",inputsInline:!0,mutator:"text_charAt_mutator"}]);
|
||||
Blockly.Blocks.text_getSubstring={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL);this.setStyle("text_blocks");
|
||||
this.appendValueInput("STRING").setCheck("String").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);this.setInputsInline(!0);this.setOutput(!0,"String");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation"),
|
||||
this.appendValueInput("STRING").setCheck("String").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);this.setInputsInline(!0);this.setOutput(!0,"String");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP)},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation"),
|
||||
b=this.getInput("AT1").type==Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
|
||||
this.appendDummyInput("AT"+a);2==a&&Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL));var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.sourceBlock_;f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&this.moveInputBefore("ORDINAL1",
|
||||
"AT2"))}};Blockly.Blocks.text_changeCase={init:function(){var a=[[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE,"UPPERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE,"LOWERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE,"TITLECASE"]];this.setHelpUrl(Blockly.Msg.TEXT_CHANGECASE_HELPURL);this.setStyle("text_blocks");this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"CASE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_CHANGECASE_TOOLTIP)}};
|
||||
this.appendDummyInput("AT"+a);2==a&&Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL));var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.getSourceBlock();f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&
|
||||
this.moveInputBefore("ORDINAL1","AT2"))}};Blockly.Blocks.text_changeCase={init:function(){var a=[[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE,"UPPERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE,"LOWERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE,"TITLECASE"]];this.setHelpUrl(Blockly.Msg.TEXT_CHANGECASE_HELPURL);this.setStyle("text_blocks");this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"CASE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_CHANGECASE_TOOLTIP)}};
|
||||
Blockly.Blocks.text_trim={init:function(){var a=[[Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH,"BOTH"],[Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT,"LEFT"],[Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT,"RIGHT"]];this.setHelpUrl(Blockly.Msg.TEXT_TRIM_HELPURL);this.setStyle("text_blocks");this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"MODE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_TRIM_TOOLTIP)}};
|
||||
Blockly.Blocks.text_print={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_PRINT_TITLE,args0:[{type:"input_value",name:"TEXT"}],previousStatement:null,nextStatement:null,style:"text_blocks",tooltip:Blockly.Msg.TEXT_PRINT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_PRINT_HELPURL})}};
|
||||
Blockly.Blocks.text_prompt_ext={init:function(){var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]];this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setStyle("text_blocks");var b=this;a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendValueInput("TEXT").appendField(a,"TYPE");this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},
|
||||
updateType_:function(a){this.outputConnection.setCheck("NUMBER"==a?"Number":"String")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("type",this.getFieldValue("TYPE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("type"))}};
|
||||
updateType_:function(a){this.outputConnection.setCheck("NUMBER"==a?"Number":"String")},mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("type",this.getFieldValue("TYPE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("type"))}};
|
||||
Blockly.Blocks.text_prompt={init:function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]],b=this;this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setStyle("text_blocks");a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendDummyInput().appendField(a,"TYPE").appendField(this.newQuote_(!0)).appendField(new Blockly.FieldTextInput(""),"TEXT").appendField(this.newQuote_(!1));
|
||||
this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},updateType_:Blockly.Blocks.text_prompt_ext.updateType_,mutationToDom:Blockly.Blocks.text_prompt_ext.mutationToDom,domToMutation:Blockly.Blocks.text_prompt_ext.domToMutation};
|
||||
Blockly.Blocks.text_count={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_COUNT_MESSAGE0,args0:[{type:"input_value",name:"SUB",check:"String"},{type:"input_value",name:"TEXT",check:"String"}],output:"Number",inputsInline:!0,style:"text_blocks",tooltip:Blockly.Msg.TEXT_COUNT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_COUNT_HELPURL})}};
|
||||
@@ -147,25 +148,24 @@ Blockly.Blocks.text_reverse={init:function(){this.jsonInit({message0:Blockly.Msg
|
||||
Blockly.Constants.Text.QUOTE_IMAGE_MIXIN={QUOTE_IMAGE_LEFT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC",QUOTE_IMAGE_RIGHT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==",
|
||||
QUOTE_IMAGE_WIDTH:12,QUOTE_IMAGE_HEIGHT:12,quoteField_:function(a){for(var b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)if(a==e.name){c.insertFieldAt(d,this.newQuote_(!0));c.insertFieldAt(d+2,this.newQuote_(!1));return}console.warn('field named "'+a+'" not found in '+this.toDevString())},newQuote_:function(a){a=this.RTL?!a:a;return new Blockly.FieldImage(a?this.QUOTE_IMAGE_LEFT_DATAURI:this.QUOTE_IMAGE_RIGHT_DATAURI,this.QUOTE_IMAGE_WIDTH,this.QUOTE_IMAGE_HEIGHT,a?"\u201c":"\u201d")}};
|
||||
Blockly.Constants.Text.TEXT_QUOTES_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.quoteField_("TEXT")};
|
||||
Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),10);this.updateShape_()},decompose:function(a){var b=a.newBlock("text_create_join_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("text_create_join_item");e.initSvg();c.connect(e.previousConnection);c=
|
||||
e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=
|
||||
Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN={mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),10);this.updateShape_()},decompose:function(a){var b=a.newBlock("text_create_join_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("text_create_join_item");e.initSvg();c.connect(e.previousConnection);
|
||||
c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=
|
||||
this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||this.appendDummyInput("EMPTY").appendField(this.newQuote_(!0)).appendField(this.newQuote_(!1));for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a);0==a&&b.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH)}for(;this.getInput("ADD"+
|
||||
a);)this.removeInput("ADD"+a),a++}};Blockly.Constants.Text.TEXT_JOIN_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.itemCount_=2;this.updateShape_();this.setMutator(new Blockly.Mutator(["text_create_join_item"]))};Blockly.Extensions.register("text_append_tooltip",Blockly.Extensions.buildTooltipWithFieldText("%{BKY_TEXT_APPEND_TOOLTIP}","VAR"));
|
||||
Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION=function(){var a=this;this.setTooltip(function(){return Blockly.Msg.TEXT_INDEXOF_TOOLTIP.replace("%1",a.workspace.options.oneBasedIndex?"0":"-1")})};
|
||||
Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("at",!!this.isAt_);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT",!0);this.removeInput("ORDINAL",!0);a&&(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX));Blockly.Msg.TEXT_CHARAT_TAIL&&
|
||||
Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN={mutationToDom:function(){var a=Blockly.utils.xml.createElement("mutation");a.setAttribute("at",!!this.isAt_);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT",!0);this.removeInput("ORDINAL",!0);a&&(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX));Blockly.Msg.TEXT_CHARAT_TAIL&&
|
||||
(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_CHARAT_TAIL));this.isAt_=a}};
|
||||
Blockly.Constants.Text.TEXT_CHARAT_EXTENSION=function(){this.getField("WHERE").setValidator(function(a){var b="FROM_START"==a||"FROM_END"==a;if(b!=this.isAt_){var d=this.sourceBlock_;d.updateAt_(b);d.setFieldValue(a,"WHERE");return null}});this.updateAt_(!0);var a=this;this.setTooltip(function(){var b=a.getFieldValue("WHERE"),c=Blockly.Msg.TEXT_CHARAT_TOOLTIP;("FROM_START"==b||"FROM_END"==b)&&(b="FROM_START"==b?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP)&&
|
||||
(c+=" "+b.replace("%1",a.workspace.options.oneBasedIndex?"#1":"#0"));return c})};Blockly.Extensions.register("text_indexOf_tooltip",Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION);Blockly.Extensions.register("text_quotes",Blockly.Constants.Text.TEXT_QUOTES_EXTENSION);Blockly.Extensions.registerMutator("text_join_mutator",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.Blocks.variables={};Blockly.Constants.Variables={};Blockly.Constants.Variables.HUE=330;
|
||||
Blockly.Constants.Text.TEXT_CHARAT_EXTENSION=function(){this.getField("WHERE").setValidator(function(a){a="FROM_START"==a||"FROM_END"==a;a!=this.isAt_&&this.getSourceBlock().updateAt_(a)});this.updateAt_(!0);var a=this;this.setTooltip(function(){var b=a.getFieldValue("WHERE"),c=Blockly.Msg.TEXT_CHARAT_TOOLTIP;("FROM_START"==b||"FROM_END"==b)&&(b="FROM_START"==b?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP)&&(c+=" "+b.replace("%1",a.workspace.options.oneBasedIndex?
|
||||
"#1":"#0"));return c})};Blockly.Extensions.register("text_indexOf_tooltip",Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION);Blockly.Extensions.register("text_quotes",Blockly.Constants.Text.TEXT_QUOTES_EXTENSION);Blockly.Extensions.registerMutator("text_join_mutator",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.Blocks.variables={};Blockly.Constants.Variables={};Blockly.Constants.Variables.HUE=330;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"variables_get",message0:"%1",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"}],output:null,style:"variable_blocks",helpUrl:"%{BKY_VARIABLES_GET_HELPURL}",tooltip:"%{BKY_VARIABLES_GET_TOOLTIP}",extensions:["contextMenu_variableSetterGetter"]},{type:"variables_set",message0:"%{BKY_VARIABLES_SET}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"},{type:"input_value",name:"VALUE"}],previousStatement:null,
|
||||
nextStatement:null,style:"variable_blocks",tooltip:"%{BKY_VARIABLES_SET_TOOLTIP}",helpUrl:"%{BKY_VARIABLES_SET_HELPURL}",extensions:["contextMenu_variableSetterGetter"]}]);
|
||||
Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){if("variables_get"==this.type)var b="variables_set",c=Blockly.Msg.VARIABLES_GET_CREATE_SET;else b="variables_get",c=Blockly.Msg.VARIABLES_SET_CREATE_GET;var d={enabled:0<this.workspace.remainingCapacity()},e=this.getField("VAR").getText();d.text=c.replace("%1",e);c=document.createElement("field");c.setAttribute("name","VAR");c.appendChild(document.createTextNode(e));e=document.createElement("block");
|
||||
e.setAttribute("type",b);e.appendChild(c);d.callback=Blockly.ContextMenu.callbackFactory(this,e);a.push(d)}else if("variables_get"==this.type||"variables_get_reporter"==this.type)b={text:Blockly.Msg.RENAME_VARIABLE,enabled:!0,callback:Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY(this)},e=this.getField("VAR").getText(),d={text:Blockly.Msg.DELETE_VARIABLE.replace("%1",e),enabled:!0,callback:Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY(this)},a.unshift(b),a.unshift(d)}};
|
||||
Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();Blockly.Variables.renameVariable(b,c)}};Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();b.deleteVariableById(c.getId());b.refreshToolboxSelection()}};Blockly.Extensions.registerMixin("contextMenu_variableSetterGetter",Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);
|
||||
Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){if("variables_get"==this.type)var b="variables_set",c=Blockly.Msg.VARIABLES_GET_CREATE_SET;else b="variables_get",c=Blockly.Msg.VARIABLES_SET_CREATE_GET;var d={enabled:0<this.workspace.remainingCapacity()},e=this.getField("VAR").getText();d.text=c.replace("%1",e);c=Blockly.utils.xml.createElement("field");c.setAttribute("name","VAR");c.appendChild(Blockly.utils.xml.createTextNode(e));
|
||||
e=Blockly.utils.xml.createElement("block");e.setAttribute("type",b);e.appendChild(c);d.callback=Blockly.ContextMenu.callbackFactory(this,e);a.push(d)}else if("variables_get"==this.type||"variables_get_reporter"==this.type)b={text:Blockly.Msg.RENAME_VARIABLE,enabled:!0,callback:Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY(this)},e=this.getField("VAR").getText(),d={text:Blockly.Msg.DELETE_VARIABLE.replace("%1",e),enabled:!0,callback:Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY(this)},
|
||||
a.unshift(b),a.unshift(d)}};Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();Blockly.Variables.renameVariable(b,c)}};Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();b.deleteVariableById(c.getId());b.refreshToolboxSelection()}};Blockly.Extensions.registerMixin("contextMenu_variableSetterGetter",Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);
|
||||
Blockly.Constants.VariablesDynamic={};Blockly.Constants.VariablesDynamic.HUE=310;
|
||||
Blockly.defineBlocksWithJsonArray([{type:"variables_get_dynamic",message0:"%1",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"}],output:null,style:"variable_dynamic_blocks",helpUrl:"%{BKY_VARIABLES_GET_HELPURL}",tooltip:"%{BKY_VARIABLES_GET_TOOLTIP}",extensions:["contextMenu_variableDynamicSetterGetter"]},{type:"variables_set_dynamic",message0:"%{BKY_VARIABLES_SET}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"},{type:"input_value",
|
||||
name:"VALUE"}],previousStatement:null,nextStatement:null,style:"variable_dynamic_blocks",tooltip:"%{BKY_VARIABLES_SET_TOOLTIP}",helpUrl:"%{BKY_VARIABLES_SET_HELPURL}",extensions:["contextMenu_variableDynamicSetterGetter"]}]);
|
||||
Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){var b=this.getFieldValue("VAR");var c=this.workspace.getVariableById(b).type;if("variables_get_dynamic"==this.type){b="variables_set_dynamic";var d=Blockly.Msg.VARIABLES_GET_CREATE_SET}else b="variables_get_dynamic",d=Blockly.Msg.VARIABLES_SET_CREATE_GET;var e={enabled:0<this.workspace.remainingCapacity()},f=this.getField("VAR").getText();e.text=d.replace("%1",f);
|
||||
d=document.createElement("field");d.setAttribute("name","VAR");d.setAttribute("variabletype",c);d.appendChild(document.createTextNode(f));f=document.createElement("block");f.setAttribute("type",b);f.appendChild(d);e.callback=Blockly.ContextMenu.callbackFactory(this,f);a.push(e)}else if("variables_get_dynamic"==this.type||"variables_get_reporter_dynamic"==this.type)b={text:Blockly.Msg.RENAME_VARIABLE,enabled:!0,callback:Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY(this)},f=this.getField("VAR").getText(),
|
||||
e={text:Blockly.Msg.DELETE_VARIABLE.replace("%1",f),enabled:!0,callback:Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY(this)},a.unshift(b),a.unshift(e)},onchange:function(){var a=this.getFieldValue("VAR");a=this.workspace.getVariableById(a);"variables_get_dynamic"==this.type?this.outputConnection.setCheck(a.type):this.getInput("VALUE").connection.setCheck(a.type)}};
|
||||
d=Blockly.utils.xml.createElement("field");d.setAttribute("name","VAR");d.setAttribute("variabletype",c);d.appendChild(Blockly.utils.xml.createTextNode(f));f=Blockly.utils.xml.createElement("block");f.setAttribute("type",b);f.appendChild(d);e.callback=Blockly.ContextMenu.callbackFactory(this,f);a.push(e)}else if("variables_get_dynamic"==this.type||"variables_get_reporter_dynamic"==this.type)b={text:Blockly.Msg.RENAME_VARIABLE,enabled:!0,callback:Blockly.Constants.Variables.RENAME_OPTION_CALLBACK_FACTORY(this)},
|
||||
f=this.getField("VAR").getText(),e={text:Blockly.Msg.DELETE_VARIABLE.replace("%1",f),enabled:!0,callback:Blockly.Constants.Variables.DELETE_OPTION_CALLBACK_FACTORY(this)},a.unshift(b),a.unshift(e)},onchange:function(a){a=this.getFieldValue("VAR");a=Blockly.Variables.getVariable(this.workspace,a);"variables_get_dynamic"==this.type?this.outputConnection.setCheck(a.type):this.getInput("VALUE").connection.setCheck(a.type)}};
|
||||
Blockly.Constants.VariablesDynamic.RENAME_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();Blockly.Variables.renameVariable(b,c)}};Blockly.Constants.VariablesDynamic.DELETE_OPTION_CALLBACK_FACTORY=function(a){return function(){var b=a.workspace,c=a.getField("VAR").getVariable();b.deleteVariableById(c.getId());b.refreshToolboxSelection()}};Blockly.Extensions.registerMixin("contextMenu_variableDynamicSetterGetter",Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);
|
||||
@@ -16,16 +16,13 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Usage: build.py <0 or more of accessible, core, generators, langfiles>
|
||||
# Usage: build.py <0 or more of core, generators, langfiles>
|
||||
# build.py with no parameters builds all files.
|
||||
# core builds blockly_compressed, blockly_uncompressed, and blocks_compressed.
|
||||
# accessible builds blockly_accessible_compressed,
|
||||
# blockly_accessible_uncompressed, and blocks_compressed.
|
||||
# generators builds every <language>_compressed.js.
|
||||
# langfiles builds every msg/js/<LANG>.js file.
|
||||
|
||||
# This script generates four versions of Blockly's core files. The first pair
|
||||
# are:
|
||||
# This script generates two versions of Blockly's core files:
|
||||
# blockly_compressed.js
|
||||
# blockly_uncompressed.js
|
||||
# The compressed file is a concatenation of all of Blockly's core files which
|
||||
@@ -37,11 +34,6 @@
|
||||
# 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:
|
||||
# blockly_accessible_compressed.js
|
||||
# blockly_accessible_uncompressed.js
|
||||
# These files are analogous to blockly_compressed and blockly_uncompressed,
|
||||
# but also include the visually-impaired module for Blockly.
|
||||
#
|
||||
# This script also generates:
|
||||
# blocks_compressed.js: The compressed Blockly language blocks.
|
||||
@@ -60,7 +52,7 @@ for arg in sys.argv[1:len(sys.argv)]:
|
||||
arg != 'generators' and
|
||||
arg != 'langfiles'):
|
||||
raise Exception("Invalid argument: \"" + arg + "\". Usage: build.py "
|
||||
"<0 or more of accessible, core, generators, langfiles>")
|
||||
"<0 or more of core, generators, langfiles>")
|
||||
|
||||
import errno, glob, json, os, re, subprocess, threading, codecs
|
||||
|
||||
@@ -153,7 +145,7 @@ this.BLOCKLY_BOOT = function(root) {
|
||||
# used on another, even if the directory name differs.
|
||||
m = re.search('[\\/]([^\\/]+)[\\/]core[\\/]blockly.js', add_dependency)
|
||||
add_dependency = re.sub('([\\/])' + re.escape(m.group(1)) +
|
||||
'([\\/](core|accessible)[\\/])', '\\1" + dir + "\\2', add_dependency)
|
||||
'([\\/](core)[\\/])', '\\1" + dir + "\\2', add_dependency)
|
||||
f.write(add_dependency + '\n')
|
||||
|
||||
provides = []
|
||||
@@ -204,9 +196,10 @@ class Gen_compressed(threading.Thread):
|
||||
self.gen_core()
|
||||
|
||||
if ('accessible' in self.bundles):
|
||||
self.gen_accessible()
|
||||
print("The Blockly accessibility demo has moved to https://github.com/google/blockly-experimental")
|
||||
return
|
||||
|
||||
if ('core' in self.bundles or 'accessible' in self.bundles):
|
||||
if ('core' in self.bundles):
|
||||
self.gen_blocks()
|
||||
|
||||
if ('generators' in self.bundles):
|
||||
@@ -244,35 +237,6 @@ class Gen_compressed(threading.Thread):
|
||||
|
||||
self.do_compile(params, target_filename, filenames, "")
|
||||
|
||||
def gen_accessible(self):
|
||||
target_filename = "blockly_accessible_compressed.js"
|
||||
# Define the parameters for the POST request.
|
||||
params = [
|
||||
("compilation_level", "SIMPLE_OPTIMIZATIONS"),
|
||||
("use_closure_library", "true"),
|
||||
("language_out", "ES5"),
|
||||
("output_format", "json"),
|
||||
("output_info", "compiled_code"),
|
||||
("output_info", "warnings"),
|
||||
("output_info", "errors"),
|
||||
("output_info", "statistics"),
|
||||
("warning_level", "DEFAULT"),
|
||||
]
|
||||
|
||||
# Read in all the source files.
|
||||
filenames = calcdeps.CalculateDependencies(self.search_paths,
|
||||
[os.path.join("accessible", "app.component.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 = codecs.open(filename, encoding="utf-8")
|
||||
params.append(("js_code", "".join(f.readlines()).encode("utf-8")))
|
||||
f.close()
|
||||
|
||||
self.do_compile(params, target_filename, filenames, "")
|
||||
|
||||
def gen_blocks(self):
|
||||
target_filename = "blocks_compressed.js"
|
||||
# Define the parameters for the POST request.
|
||||
@@ -314,8 +278,9 @@ class Gen_compressed(threading.Thread):
|
||||
]
|
||||
|
||||
# Read in all the source files.
|
||||
# Add Blockly.Generator to be compatible with the compiler.
|
||||
params.append(("js_code", "goog.provide('Blockly.Generator');"))
|
||||
# Add Blockly.Generator and Blockly.utils.string to be compatible
|
||||
# with the compiler.
|
||||
params.append(("js_code", "goog.provide('Blockly.Generator');goog.provide('Blockly.utils.string');"))
|
||||
filenames = glob.glob(
|
||||
os.path.join("generators", language, "*.js"))
|
||||
filenames.sort() # Deterministic build.
|
||||
@@ -326,8 +291,9 @@ class Gen_compressed(threading.Thread):
|
||||
f.close()
|
||||
filenames.insert(0, "[goog.provide]")
|
||||
|
||||
# Remove Blockly.Generator to be compatible with Blockly.
|
||||
remove = "var Blockly={Generator:{}};"
|
||||
# Remove Blockly.Generator and Blockly.utils.string to be compatible
|
||||
# with Blockly.
|
||||
remove = "var Blockly={Generator:{},utils:{}};Blockly.utils.string={};"
|
||||
self.do_compile(params, target_filename, filenames, remove)
|
||||
|
||||
def do_compile(self, params, target_filename, filenames, remove):
|
||||
@@ -390,29 +356,7 @@ class Gen_compressed(threading.Thread):
|
||||
|
||||
code = HEADER + "\n" + json_data["compiledCode"]
|
||||
code = code.replace(remove, "")
|
||||
|
||||
# Trim down Google's (and only Google's) Apache licences.
|
||||
# The Closure Compiler preserves these.
|
||||
LICENSE = re.compile("""/\\*
|
||||
|
||||
[\w ]+
|
||||
|
||||
Copyright \\d+ 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.
|
||||
\\*/""")
|
||||
code = re.sub(LICENSE, "", code)
|
||||
code = self.trim_licence(code)
|
||||
|
||||
stats = json_data["statistics"]
|
||||
original_b = stats["originalSize"]
|
||||
@@ -431,6 +375,40 @@ class Gen_compressed(threading.Thread):
|
||||
else:
|
||||
print("UNKNOWN ERROR")
|
||||
|
||||
def trim_licence(self, code):
|
||||
"""Strip out Google's and MIT's Apache licences.
|
||||
|
||||
JS Compiler preserves dozens of Apache licences in the Blockly code.
|
||||
Remove these if they belong to Google or MIT.
|
||||
MIT's permission to do this is logged in Blockly issue 2412.
|
||||
|
||||
Args:
|
||||
code: Large blob of compiled source code.
|
||||
|
||||
Returns:
|
||||
Code with Google's and MIT's Apache licences trimmed.
|
||||
"""
|
||||
apache2 = re.compile("""/\\*
|
||||
|
||||
[\\w: ]+
|
||||
|
||||
(Copyright \\d+ (Google Inc.|Massachusetts Institute of Technology))
|
||||
(https://developers.google.com/blockly/|All rights reserved.)
|
||||
|
||||
Licensed under the Apache License, Version 2.0 \\(the "License"\\);
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
\\*/""")
|
||||
return re.sub(apache2, "", code)
|
||||
|
||||
|
||||
class Gen_langfiles(threading.Thread):
|
||||
"""Generate JavaScript file for each natural language supported.
|
||||
@@ -538,11 +516,11 @@ developers.google.com/blockly/guides/modify/web/closure""")
|
||||
["core", os.path.join(os.path.pardir, "closure-library")])
|
||||
core_search_paths = sorted(core_search_paths) # Deterministic build.
|
||||
full_search_paths = calcdeps.ExpandDirectories(
|
||||
["accessible", "core", os.path.join(os.path.pardir, "closure-library")])
|
||||
["core", os.path.join(os.path.pardir, "closure-library")])
|
||||
full_search_paths = sorted(full_search_paths) # Deterministic build.
|
||||
|
||||
if (len(sys.argv) == 1):
|
||||
args = ['core', 'accessible', 'generators', 'defaultlangfiles']
|
||||
args = ['core', 'generators', 'defaultlangfiles']
|
||||
else:
|
||||
args = sys.argv
|
||||
|
||||
@@ -551,9 +529,6 @@ developers.google.com/blockly/guides/modify/web/closure""")
|
||||
if ('core' in args):
|
||||
Gen_uncompressed(core_search_paths, 'blockly_uncompressed.js').start()
|
||||
|
||||
if ('accessible' in args):
|
||||
Gen_uncompressed(full_search_paths, 'blockly_accessible_uncompressed.js').start()
|
||||
|
||||
# Compressed is limited by network and server speed.
|
||||
Gen_compressed(full_search_paths, args).start()
|
||||
|
||||
|
||||
+85
-23
@@ -29,6 +29,7 @@ goog.provide('Blockly.Block');
|
||||
goog.require('Blockly.Blocks');
|
||||
goog.require('Blockly.Comment');
|
||||
goog.require('Blockly.Connection');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
goog.require('Blockly.Events.BlockDelete');
|
||||
@@ -37,11 +38,11 @@ goog.require('Blockly.Extensions');
|
||||
goog.require('Blockly.Input');
|
||||
goog.require('Blockly.Mutator');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.string');
|
||||
goog.require('Blockly.Warning');
|
||||
goog.require('Blockly.Workspace');
|
||||
|
||||
goog.require('goog.math.Coordinate');
|
||||
|
||||
|
||||
/**
|
||||
* Class for one block.
|
||||
@@ -75,7 +76,10 @@ Blockly.Block = function(workspace, prototypeName, opt_id) {
|
||||
this.inputList = [];
|
||||
/** @type {boolean|undefined} */
|
||||
this.inputsInline = undefined;
|
||||
/** @type {boolean} */
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.disabled = false;
|
||||
/** @type {string|!Function} */
|
||||
this.tooltip = '';
|
||||
@@ -130,10 +134,10 @@ Blockly.Block = function(workspace, prototypeName, opt_id) {
|
||||
/**
|
||||
* The block's position in workspace units. (0, 0) is at the workspace's
|
||||
* origin; scale does not change this value.
|
||||
* @type {!goog.math.Coordinate}
|
||||
* @type {!Blockly.utils.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.xy_ = new goog.math.Coordinate(0, 0);
|
||||
this.xy_ = new Blockly.utils.Coordinate(0, 0);
|
||||
|
||||
/** @type {!Blockly.Workspace} */
|
||||
this.workspace = workspace;
|
||||
@@ -260,7 +264,6 @@ Blockly.Block.prototype.colourTertiary_ = null;
|
||||
*/
|
||||
Blockly.Block.prototype.styleName_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Dispose of this block.
|
||||
* @param {boolean} healStack If true, then try to heal any gap by connecting
|
||||
@@ -878,6 +881,44 @@ Blockly.Block.prototype.getColourTertiary = function() {
|
||||
return this.colourTertiary_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the shadow colour of a block.
|
||||
* @return {?string} #RRGGBB string.
|
||||
*/
|
||||
Blockly.Block.prototype.getColourShadow = function() {
|
||||
var colourSecondary = this.getColourSecondary();
|
||||
if (colourSecondary) {
|
||||
return colourSecondary;
|
||||
}
|
||||
return Blockly.utils.colour.blend('white', this.getColour(), 0.6);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the border colour(s) of a block.
|
||||
* @return {{colourDark, colourLight, colourBorder}} An object containing
|
||||
* colour values for the border(s) of the block. If the block is using a
|
||||
* style the colourBorder will be defined and equal to the tertiary colour
|
||||
* of the style (#RRGGBB string). Otherwise the colourDark and colourLight
|
||||
* attributes will be defined (#RRGGBB strings).
|
||||
* @package
|
||||
*/
|
||||
Blockly.Block.prototype.getColourBorder = function() {
|
||||
var colourTertiary = this.getColourTertiary();
|
||||
if (colourTertiary) {
|
||||
return {
|
||||
colourBorder: colourTertiary,
|
||||
colourLight: null,
|
||||
colourDark: null
|
||||
};
|
||||
}
|
||||
var colour = this.getColour();
|
||||
return {
|
||||
colourBorder: null,
|
||||
colourLight: Blockly.utils.colour.blend('white',colour, 0.3),
|
||||
colourDark: Blockly.utils.colour.blend('black', colour, 0.2)
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the name of the block style.
|
||||
* @return {?string} Name of the block style.
|
||||
@@ -887,8 +928,8 @@ Blockly.Block.prototype.getStyleName = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the HSV hue value of a block. Null if hue not set.
|
||||
* @return {?number} Hue value (0-360)
|
||||
* Get the HSV hue value of a block. Null if hue not set.
|
||||
* @return {?number} Hue value (0-360).
|
||||
*/
|
||||
Blockly.Block.prototype.getHue = function() {
|
||||
return this.hue_;
|
||||
@@ -906,18 +947,20 @@ Blockly.Block.prototype.setColour = function(colour) {
|
||||
var hue = Number(dereferenced);
|
||||
if (!isNaN(hue) && 0 <= hue && hue <= 360) {
|
||||
this.hue_ = hue;
|
||||
this.colour_ = Blockly.hueToRgb(hue);
|
||||
} else if ((typeof dereferenced == 'string') &&
|
||||
/^#[0-9a-fA-F]{6}$/.test(dereferenced)) {
|
||||
this.colour_ = dereferenced;
|
||||
// Only store hue if colour is set as a hue.
|
||||
this.hue_ = null;
|
||||
this.colour_ = Blockly.hueToHex(hue);
|
||||
} else {
|
||||
var errorMsg = 'Invalid colour: "' + dereferenced + '"';
|
||||
if (colour != dereferenced) {
|
||||
errorMsg += ' (from "' + colour + '")';
|
||||
var hex = Blockly.utils.colour.parse(dereferenced);
|
||||
if (hex) {
|
||||
this.colour_ = hex;
|
||||
// Only store hue if colour is set as a hue.
|
||||
this.hue_ = null;
|
||||
} else {
|
||||
var errorMsg = 'Invalid colour: "' + dereferenced + '"';
|
||||
if (colour != dereferenced) {
|
||||
errorMsg += ' (from "' + colour + '")';
|
||||
}
|
||||
throw Error(errorMsg);
|
||||
}
|
||||
throw Error(errorMsg);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1217,12 +1260,31 @@ Blockly.Block.prototype.getInputsInline = function() {
|
||||
/**
|
||||
* Set whether the block is disabled or not.
|
||||
* @param {boolean} disabled True if disabled.
|
||||
* @deprecated May 2019
|
||||
*/
|
||||
Blockly.Block.prototype.setDisabled = function(disabled) {
|
||||
if (this.disabled != disabled) {
|
||||
console.warn('Deprecated call to Blockly.Block.prototype.setDisabled, ' +
|
||||
'use Blockly.Block.prototype.setEnabled instead.');
|
||||
this.setEnabled(!disabled);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get whether this block is enabled or not.
|
||||
* @return {boolean} True if enabled.
|
||||
*/
|
||||
Blockly.Block.prototype.isEnabled = function() {
|
||||
return !this.disabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether the block is enabled or not.
|
||||
* @param {boolean} enabled True if enabled.
|
||||
*/
|
||||
Blockly.Block.prototype.setEnabled = function(enabled) {
|
||||
if (this.isEnabled() != enabled) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this, 'disabled', null, this.disabled, disabled));
|
||||
this.disabled = disabled;
|
||||
this, 'disabled', null, this.disabled, !enabled));
|
||||
this.disabled = !enabled;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1529,7 +1591,7 @@ Blockly.Block.prototype.interpolate_ = function(message, args, lastDummyAlign) {
|
||||
}
|
||||
// Add last dummy input if needed.
|
||||
if (elements.length && (typeof elements[elements.length - 1] == 'string' ||
|
||||
Blockly.utils.startsWith(
|
||||
Blockly.utils.string.startsWith(
|
||||
elements[elements.length - 1]['type'], 'field_'))) {
|
||||
var dummyInput = {type: 'input_dummy'};
|
||||
if (lastDummyAlign) {
|
||||
@@ -1784,7 +1846,7 @@ Blockly.Block.prototype.setMutator = function(_mutator) {
|
||||
/**
|
||||
* Return the coordinates of the top-left corner of this block relative to the
|
||||
* drawing surface's origin (0,0), in workspace units.
|
||||
* @return {!goog.math.Coordinate} Object with .x and .y properties.
|
||||
* @return {!Blockly.utils.Coordinate} Object with .x and .y properties.
|
||||
*/
|
||||
Blockly.Block.prototype.getRelativeToSurfaceXY = function() {
|
||||
return this.xy_;
|
||||
|
||||
+27
-27
@@ -24,9 +24,9 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.BlockAnimations');
|
||||
goog.provide('Blockly.blockAnimations');
|
||||
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
|
||||
/**
|
||||
@@ -34,21 +34,21 @@ goog.require('Blockly.utils');
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockAnimations.disconnectPid_ = 0;
|
||||
Blockly.blockAnimations.disconnectPid_ = 0;
|
||||
|
||||
/**
|
||||
* SVG group of wobbling block. There can only be one at a time.
|
||||
* @type {Element}
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockAnimations.disconnectGroup_ = null;
|
||||
Blockly.blockAnimations.disconnectGroup_ = null;
|
||||
|
||||
/**
|
||||
* Play some UI effects (sound, animation) when disposing of a block.
|
||||
* @param {!Blockly.BlockSvg} block The block being disposed of.
|
||||
* @package
|
||||
*/
|
||||
Blockly.BlockAnimations.disposeUiEffect = function(block) {
|
||||
Blockly.blockAnimations.disposeUiEffect = function(block) {
|
||||
var workspace = block.workspace;
|
||||
var svgGroup = block.getSvgRoot();
|
||||
workspace.getAudioManager().play('delete');
|
||||
@@ -62,7 +62,7 @@ Blockly.BlockAnimations.disposeUiEffect = function(block) {
|
||||
workspace.getParentSvg().appendChild(clone);
|
||||
clone.bBox_ = clone.getBBox();
|
||||
// Start the animation.
|
||||
Blockly.BlockAnimations.disposeUiStep_(clone, workspace.RTL, new Date,
|
||||
Blockly.blockAnimations.disposeUiStep_(clone, workspace.RTL, new Date,
|
||||
workspace.scale);
|
||||
};
|
||||
|
||||
@@ -76,12 +76,12 @@ Blockly.BlockAnimations.disposeUiEffect = function(block) {
|
||||
* @param {number} workspaceScale Scale of workspace.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockAnimations.disposeUiStep_ = function(clone, rtl, start,
|
||||
Blockly.blockAnimations.disposeUiStep_ = function(clone, rtl, start,
|
||||
workspaceScale) {
|
||||
var ms = new Date - start;
|
||||
var percent = ms / 150;
|
||||
if (percent > 1) {
|
||||
Blockly.utils.removeNode(clone);
|
||||
Blockly.utils.dom.removeNode(clone);
|
||||
} else {
|
||||
var x = clone.translateX_ +
|
||||
(rtl ? -1 : 1) * clone.bBox_.width * workspaceScale / 2 * percent;
|
||||
@@ -89,7 +89,7 @@ Blockly.BlockAnimations.disposeUiStep_ = function(clone, rtl, start,
|
||||
var scale = (1 - percent) * workspaceScale;
|
||||
clone.setAttribute('transform', 'translate(' + x + ',' + y + ')' +
|
||||
' scale(' + scale + ')');
|
||||
setTimeout(Blockly.BlockAnimations.disposeUiStep_, 10, clone, rtl, start,
|
||||
setTimeout(Blockly.blockAnimations.disposeUiStep_, 10, clone, rtl, start,
|
||||
workspaceScale);
|
||||
}
|
||||
};
|
||||
@@ -99,7 +99,7 @@ Blockly.BlockAnimations.disposeUiStep_ = function(clone, rtl, start,
|
||||
* @param {!Blockly.BlockSvg} block The block being connected.
|
||||
* @package
|
||||
*/
|
||||
Blockly.BlockAnimations.connectionUiEffect = function(block) {
|
||||
Blockly.blockAnimations.connectionUiEffect = function(block) {
|
||||
var workspace = block.workspace;
|
||||
var scale = workspace.scale;
|
||||
workspace.getAudioManager().play('click');
|
||||
@@ -116,7 +116,7 @@ Blockly.BlockAnimations.connectionUiEffect = function(block) {
|
||||
xy.x += (block.RTL ? -23 : 23) * scale;
|
||||
xy.y += 3 * scale;
|
||||
}
|
||||
var ripple = Blockly.utils.createSvgElement('circle',
|
||||
var ripple = Blockly.utils.dom.createSvgElement('circle',
|
||||
{
|
||||
'cx': xy.x,
|
||||
'cy': xy.y,
|
||||
@@ -127,7 +127,7 @@ Blockly.BlockAnimations.connectionUiEffect = function(block) {
|
||||
},
|
||||
workspace.getParentSvg());
|
||||
// Start the animation.
|
||||
Blockly.BlockAnimations.connectionUiStep_(ripple, new Date, scale);
|
||||
Blockly.blockAnimations.connectionUiStep_(ripple, new Date, scale);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -137,16 +137,16 @@ Blockly.BlockAnimations.connectionUiEffect = function(block) {
|
||||
* @param {number} scale Scale of workspace.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockAnimations.connectionUiStep_ = function(ripple, start, scale) {
|
||||
Blockly.blockAnimations.connectionUiStep_ = function(ripple, start, scale) {
|
||||
var ms = new Date - start;
|
||||
var percent = ms / 150;
|
||||
if (percent > 1) {
|
||||
Blockly.utils.removeNode(ripple);
|
||||
Blockly.utils.dom.removeNode(ripple);
|
||||
} else {
|
||||
ripple.setAttribute('r', percent * 25 * scale);
|
||||
ripple.style.opacity = 1 - percent;
|
||||
Blockly.BlockAnimations.disconnectPid_ = setTimeout(
|
||||
Blockly.BlockAnimations.connectionUiStep_, 10, ripple, start, scale);
|
||||
Blockly.blockAnimations.disconnectPid_ = setTimeout(
|
||||
Blockly.blockAnimations.connectionUiStep_, 10, ripple, start, scale);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -155,7 +155,7 @@ Blockly.BlockAnimations.connectionUiStep_ = function(ripple, start, scale) {
|
||||
* @param {!Blockly.BlockSvg} block The block being disconnected.
|
||||
* @package
|
||||
*/
|
||||
Blockly.BlockAnimations.disconnectUiEffect = function(block) {
|
||||
Blockly.blockAnimations.disconnectUiEffect = function(block) {
|
||||
block.workspace.getAudioManager().play('disconnect');
|
||||
if (block.workspace.scale < 1) {
|
||||
return; // Too small to care about visual effects.
|
||||
@@ -169,7 +169,7 @@ Blockly.BlockAnimations.disconnectUiEffect = function(block) {
|
||||
magnitude *= -1;
|
||||
}
|
||||
// Start the animation.
|
||||
Blockly.BlockAnimations.disconnectUiStep_(
|
||||
Blockly.blockAnimations.disconnectUiStep_(
|
||||
block.getSvgRoot(), magnitude, new Date);
|
||||
};
|
||||
/**
|
||||
@@ -179,7 +179,7 @@ Blockly.BlockAnimations.disconnectUiEffect = function(block) {
|
||||
* @param {!Date} start Date of animation's start.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockAnimations.disconnectUiStep_ = function(group, magnitude, start) {
|
||||
Blockly.blockAnimations.disconnectUiStep_ = function(group, magnitude, start) {
|
||||
var DURATION = 200; // Milliseconds.
|
||||
var WIGGLES = 3; // Half oscillations.
|
||||
|
||||
@@ -192,9 +192,9 @@ Blockly.BlockAnimations.disconnectUiStep_ = function(group, magnitude, start) {
|
||||
var skew = Math.round(
|
||||
Math.sin(percent * Math.PI * WIGGLES) * (1 - percent) * magnitude);
|
||||
group.skew_ = 'skewX(' + skew + ')';
|
||||
Blockly.BlockAnimations.disconnectGroup_ = group;
|
||||
Blockly.BlockAnimations.disconnectPid_ =
|
||||
setTimeout(Blockly.BlockAnimations.disconnectUiStep_, 10, group,
|
||||
Blockly.blockAnimations.disconnectGroup_ = group;
|
||||
Blockly.blockAnimations.disconnectPid_ =
|
||||
setTimeout(Blockly.blockAnimations.disconnectUiStep_, 10, group,
|
||||
magnitude, start);
|
||||
}
|
||||
group.setAttribute('transform', group.translate_ + group.skew_);
|
||||
@@ -204,12 +204,12 @@ Blockly.BlockAnimations.disconnectUiStep_ = function(group, magnitude, start) {
|
||||
* Stop the disconnect UI animation immediately.
|
||||
* @package
|
||||
*/
|
||||
Blockly.BlockAnimations.disconnectUiStop = function() {
|
||||
if (Blockly.BlockAnimations.disconnectGroup_) {
|
||||
clearTimeout(Blockly.BlockAnimations.disconnectPid_);
|
||||
var group = Blockly.BlockAnimations.disconnectGroup_;
|
||||
Blockly.blockAnimations.disconnectUiStop = function() {
|
||||
if (Blockly.blockAnimations.disconnectGroup_) {
|
||||
clearTimeout(Blockly.blockAnimations.disconnectPid_);
|
||||
var group = Blockly.blockAnimations.disconnectGroup_;
|
||||
group.skew_ = '';
|
||||
group.setAttribute('transform', group.translate_);
|
||||
Blockly.BlockAnimations.disconnectGroup_ = null;
|
||||
Blockly.blockAnimations.disconnectGroup_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
+13
-12
@@ -31,7 +31,8 @@
|
||||
|
||||
goog.provide('Blockly.BlockDragSurfaceSvg');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
|
||||
/**
|
||||
@@ -83,7 +84,7 @@ Blockly.BlockDragSurfaceSvg.prototype.scale_ = 1;
|
||||
* Cached value for the translation of the drag surface.
|
||||
* This translation is in pixel units, because the scale is applied to the
|
||||
* drag group rather than the top-level SVG.
|
||||
* @type {goog.math.Coordinate}
|
||||
* @type {Blockly.utils.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockDragSurfaceSvg.prototype.surfaceXY_ = null;
|
||||
@@ -95,14 +96,14 @@ Blockly.BlockDragSurfaceSvg.prototype.createDom = function() {
|
||||
if (this.SVG_) {
|
||||
return; // Already created.
|
||||
}
|
||||
this.SVG_ = Blockly.utils.createSvgElement('svg', {
|
||||
'xmlns': Blockly.SVG_NS,
|
||||
'xmlns:html': Blockly.HTML_NS,
|
||||
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
|
||||
this.SVG_ = Blockly.utils.dom.createSvgElement('svg', {
|
||||
'xmlns': Blockly.utils.dom.SVG_NS,
|
||||
'xmlns:html': Blockly.utils.dom.HTML_NS,
|
||||
'xmlns:xlink': Blockly.utils.dom.XLINK_NS,
|
||||
'version': '1.1',
|
||||
'class': 'blocklyBlockDragSurface'
|
||||
}, this.container_);
|
||||
this.dragGroup_ = Blockly.utils.createSvgElement('g', {}, this.SVG_);
|
||||
this.dragGroup_ = Blockly.utils.dom.createSvgElement('g', {}, this.SVG_);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -118,7 +119,7 @@ Blockly.BlockDragSurfaceSvg.prototype.setBlocksAndShow = function(blocks) {
|
||||
// appendChild removes the blocks from the previous parent
|
||||
this.dragGroup_.appendChild(blocks);
|
||||
this.SVG_.style.display = 'block';
|
||||
this.surfaceXY_ = new goog.math.Coordinate(0, 0);
|
||||
this.surfaceXY_ = new Blockly.utils.Coordinate(0, 0);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -152,7 +153,7 @@ Blockly.BlockDragSurfaceSvg.prototype.translateSurfaceInternal_ = function() {
|
||||
y = y.toFixed(0);
|
||||
this.SVG_.style.display = 'block';
|
||||
|
||||
Blockly.utils.setCssTransform(this.SVG_,
|
||||
Blockly.utils.dom.setCssTransform(this.SVG_,
|
||||
'translate3d(' + x + 'px, ' + y + 'px, 0px)');
|
||||
};
|
||||
|
||||
@@ -165,18 +166,18 @@ Blockly.BlockDragSurfaceSvg.prototype.translateSurfaceInternal_ = function() {
|
||||
* @param {number} y Y translation for the entire surface.
|
||||
*/
|
||||
Blockly.BlockDragSurfaceSvg.prototype.translateSurface = function(x, y) {
|
||||
this.surfaceXY_ = new goog.math.Coordinate(x * this.scale_, y * this.scale_);
|
||||
this.surfaceXY_ = new Blockly.utils.Coordinate(x * this.scale_, y * this.scale_);
|
||||
this.translateSurfaceInternal_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Reports the surface translation in scaled workspace coordinates.
|
||||
* Use this when finishing a drag to return blocks to the correct position.
|
||||
* @return {!goog.math.Coordinate} Current translation of the surface.
|
||||
* @return {!Blockly.utils.Coordinate} Current translation of the surface.
|
||||
*/
|
||||
Blockly.BlockDragSurfaceSvg.prototype.getSurfaceTranslation = function() {
|
||||
var xy = Blockly.utils.getRelativeXY(this.SVG_);
|
||||
return new goog.math.Coordinate(xy.x / this.scale_, xy.y / this.scale_);
|
||||
return new Blockly.utils.Coordinate(xy.x / this.scale_, xy.y / this.scale_);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+23
-22
@@ -26,11 +26,11 @@
|
||||
|
||||
goog.provide('Blockly.BlockDragger');
|
||||
|
||||
goog.require('Blockly.BlockAnimations');
|
||||
goog.require('Blockly.InsertionMarkerManager');
|
||||
goog.require('Blockly.blockAnimations');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('Blockly.InsertionMarkerManager');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ Blockly.BlockDragger = function(block, workspace) {
|
||||
/**
|
||||
* The location of the top left corner of the dragging block at the beginning
|
||||
* of the drag in workspace coordinates.
|
||||
* @type {!goog.math.Coordinate}
|
||||
* @type {!Blockly.utils.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.startXY_ = this.draggingBlock_.getRelativeToSurfaceXY();
|
||||
@@ -129,7 +129,7 @@ Blockly.BlockDragger.initIconData_ = function(block) {
|
||||
var icons = descendant.getIcons();
|
||||
for (var j = 0; j < icons.length; j++) {
|
||||
var data = {
|
||||
// goog.math.Coordinate with x and y properties (workspace coordinates).
|
||||
// Blockly.utils.Coordinate with x and y properties (workspace coordinates).
|
||||
location: icons[j].getIconLocation(),
|
||||
// Blockly.Icon
|
||||
icon: icons[j]
|
||||
@@ -142,7 +142,7 @@ Blockly.BlockDragger.initIconData_ = function(block) {
|
||||
|
||||
/**
|
||||
* Start dragging a block. This includes moving it to the drag surface.
|
||||
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* moved from the position at mouse down, in pixel units.
|
||||
* @param {boolean} healStack Whether or not to heal the stack after
|
||||
* disconnecting.
|
||||
@@ -166,17 +166,17 @@ Blockly.BlockDragger.prototype.startBlockDrag = function(currentDragDeltaXY,
|
||||
// Turn the cache on so we don't do spurious remeasures during the drag.
|
||||
Blockly.Field.startCache();
|
||||
this.workspace_.setResizesEnabled(false);
|
||||
Blockly.BlockAnimations.disconnectUiStop();
|
||||
Blockly.blockAnimations.disconnectUiStop();
|
||||
|
||||
if (this.draggingBlock_.getParent() ||
|
||||
(healStack && this.draggingBlock_.nextConnection &&
|
||||
this.draggingBlock_.nextConnection.targetBlock())) {
|
||||
this.draggingBlock_.unplug(healStack);
|
||||
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
|
||||
var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
|
||||
var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
|
||||
|
||||
this.draggingBlock_.translate(newLoc.x, newLoc.y);
|
||||
Blockly.BlockAnimations.disconnectUiEffect(this.draggingBlock_);
|
||||
Blockly.blockAnimations.disconnectUiEffect(this.draggingBlock_);
|
||||
}
|
||||
this.draggingBlock_.setDragging(true);
|
||||
// For future consideration: we may be able to put moveToDragSurface inside
|
||||
@@ -196,13 +196,13 @@ Blockly.BlockDragger.prototype.startBlockDrag = function(currentDragDeltaXY,
|
||||
* Execute a step of block dragging, based on the given event. Update the
|
||||
* display accordingly.
|
||||
* @param {!Event} e The most recent move event.
|
||||
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* moved from the position at the start of the drag, in pixel units.
|
||||
* @package
|
||||
*/
|
||||
Blockly.BlockDragger.prototype.dragBlock = function(e, currentDragDeltaXY) {
|
||||
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
|
||||
var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
|
||||
var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
|
||||
|
||||
this.draggingBlock_.moveDuringDrag(newLoc);
|
||||
this.dragIcons_(delta);
|
||||
@@ -216,7 +216,7 @@ Blockly.BlockDragger.prototype.dragBlock = function(e, currentDragDeltaXY) {
|
||||
/**
|
||||
* Finish a block drag and put the block back on the workspace.
|
||||
* @param {!Event} e The mouseup/touchend event.
|
||||
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* moved from the position at the start of the drag, in pixel units.
|
||||
* @package
|
||||
*/
|
||||
@@ -227,10 +227,10 @@ Blockly.BlockDragger.prototype.endBlockDrag = function(e, currentDragDeltaXY) {
|
||||
|
||||
Blockly.Field.stopCache();
|
||||
|
||||
Blockly.BlockAnimations.disconnectUiStop();
|
||||
Blockly.blockAnimations.disconnectUiStop();
|
||||
|
||||
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
|
||||
var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
|
||||
var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
|
||||
this.draggingBlock_.moveOffDragSurface_(newLoc);
|
||||
|
||||
var deleted = this.maybeDeleteBlock_();
|
||||
@@ -318,14 +318,15 @@ Blockly.BlockDragger.prototype.updateCursorDuringBlockDrag_ = function() {
|
||||
* correction for mutator workspaces.
|
||||
* This function does not consider differing origins. It simply scales the
|
||||
* input's x and y values.
|
||||
* @param {!goog.math.Coordinate} pixelCoord A coordinate with x and y values
|
||||
* in css pixel units.
|
||||
* @return {!goog.math.Coordinate} The input coordinate divided by the workspace
|
||||
* @param {!Blockly.utils.Coordinate} pixelCoord A coordinate with x and y values
|
||||
* in CSS pixel units.
|
||||
* @return {!Blockly.utils.Coordinate} The input coordinate divided by the workspace
|
||||
* scale.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
|
||||
var result = new goog.math.Coordinate(pixelCoord.x / this.workspace_.scale,
|
||||
var result = new Blockly.utils.Coordinate(
|
||||
pixelCoord.x / this.workspace_.scale,
|
||||
pixelCoord.y / this.workspace_.scale);
|
||||
if (this.workspace_.isMutator) {
|
||||
// If we're in a mutator, its scale is always 1, purely because of some
|
||||
@@ -333,14 +334,14 @@ Blockly.BlockDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
|
||||
// the scale on the parent workspace.
|
||||
// Fix that for dragging.
|
||||
var mainScale = this.workspace_.options.parentWorkspace.scale;
|
||||
result = result.scale(1 / mainScale);
|
||||
result.scale(1 / mainScale);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Move all of the icons connected to this drag.
|
||||
* @param {!goog.math.Coordinate} dxy How far to move the icons from their
|
||||
* @param {!Blockly.utils.Coordinate} dxy How far to move the icons from their
|
||||
* original positions, in workspace units.
|
||||
* @private
|
||||
*/
|
||||
@@ -348,7 +349,7 @@ Blockly.BlockDragger.prototype.dragIcons_ = function(dxy) {
|
||||
// Moving icons moves their associated bubbles.
|
||||
for (var i = 0; i < this.dragIconData_.length; i++) {
|
||||
var data = this.dragIconData_[i];
|
||||
data.icon.setIconLocation(goog.math.Coordinate.sum(data.location, dxy));
|
||||
data.icon.setIconLocation(Blockly.utils.Coordinate.sum(data.location, dxy));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+10
-12
@@ -36,9 +36,8 @@ goog.provide('Blockly.Events.Move'); // Deprecated.
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.Abstract');
|
||||
goog.require('Blockly.Xml.utils');
|
||||
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.xml');
|
||||
|
||||
|
||||
/**
|
||||
@@ -186,7 +185,7 @@ Blockly.Events.Change.prototype.run = function(forward) {
|
||||
block.setCollapsed(value);
|
||||
break;
|
||||
case 'disabled':
|
||||
block.setDisabled(value);
|
||||
block.setEnabled(!value);
|
||||
break;
|
||||
case 'inline':
|
||||
block.setInputsInline(value);
|
||||
@@ -198,9 +197,8 @@ Blockly.Events.Change.prototype.run = function(forward) {
|
||||
oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
|
||||
}
|
||||
if (block.domToMutation) {
|
||||
value = value || '<mutation></mutation>';
|
||||
var dom = Blockly.Xml.textToDom('<xml>' + value + '</xml>');
|
||||
block.domToMutation(dom.firstChild);
|
||||
var dom = Blockly.Xml.textToDom(value || '<mutation/>');
|
||||
block.domToMutation(dom);
|
||||
}
|
||||
Blockly.Events.fire(new Blockly.Events.Change(
|
||||
block, 'mutation', null, oldMutation, value));
|
||||
@@ -262,7 +260,7 @@ Blockly.Events.Create.prototype.toJson = function() {
|
||||
*/
|
||||
Blockly.Events.Create.prototype.fromJson = function(json) {
|
||||
Blockly.Events.Create.superClass_.fromJson.call(this, json);
|
||||
this.xml = Blockly.Xml.textToDom('<xml>' + json['xml'] + '</xml>').firstChild;
|
||||
this.xml = Blockly.Xml.textToDom(json['xml']);
|
||||
this.ids = json['ids'];
|
||||
};
|
||||
|
||||
@@ -273,7 +271,7 @@ Blockly.Events.Create.prototype.fromJson = function(json) {
|
||||
Blockly.Events.Create.prototype.run = function(forward) {
|
||||
var workspace = this.getEventWorkspace_();
|
||||
if (forward) {
|
||||
var xml = Blockly.Xml.utils.createElement('xml');
|
||||
var xml = Blockly.utils.xml.createElement('xml');
|
||||
xml.appendChild(this.xml);
|
||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||
} else {
|
||||
@@ -363,7 +361,7 @@ Blockly.Events.Delete.prototype.run = function(forward) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var xml = Blockly.Xml.utils.createElement('xml');
|
||||
var xml = Blockly.utils.xml.createElement('xml');
|
||||
xml.appendChild(this.oldXml);
|
||||
Blockly.Xml.domToWorkspace(xml, workspace);
|
||||
}
|
||||
@@ -431,7 +429,7 @@ Blockly.Events.Move.prototype.fromJson = function(json) {
|
||||
if (json['newCoordinate']) {
|
||||
var xy = json['newCoordinate'].split(',');
|
||||
this.newCoordinate =
|
||||
new goog.math.Coordinate(parseFloat(xy[0]), parseFloat(xy[1]));
|
||||
new Blockly.utils.Coordinate(parseFloat(xy[0]), parseFloat(xy[1]));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -475,7 +473,7 @@ Blockly.Events.Move.prototype.currentLocation_ = function() {
|
||||
Blockly.Events.Move.prototype.isNull = function() {
|
||||
return this.oldParentId == this.newParentId &&
|
||||
this.oldInputName == this.newInputName &&
|
||||
goog.math.Coordinate.equals(this.oldCoordinate, this.newCoordinate);
|
||||
Blockly.utils.Coordinate.equals(this.oldCoordinate, this.newCoordinate);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
goog.provide('Blockly.BlockSvg.render');
|
||||
|
||||
goog.require('Blockly.BlockSvg');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
|
||||
/**
|
||||
@@ -903,7 +904,7 @@ Blockly.BlockSvg.prototype.renderInlineRow_ = function(pathObject, row, cursor,
|
||||
var steps = pathObject.steps;
|
||||
var highlightSteps = pathObject.highlightSteps;
|
||||
|
||||
for (var x = 0, input; input = row[x]; x++) {
|
||||
for (var i = 0, input; input = row[i]; i++) {
|
||||
var fieldX = cursor.x;
|
||||
var fieldY = cursor.y;
|
||||
if (row.thicker) {
|
||||
@@ -1194,10 +1195,10 @@ Blockly.BlockSvg.prototype.positionNewBlock = function(newBlock, newConnection,
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.highlightForReplacement = function(add) {
|
||||
if (add) {
|
||||
Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
Blockly.utils.dom.addClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyReplaceable');
|
||||
} else {
|
||||
Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
Blockly.utils.dom.removeClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyReplaceable');
|
||||
}
|
||||
};
|
||||
|
||||
+149
-134
@@ -27,18 +27,20 @@
|
||||
goog.provide('Blockly.BlockSvg');
|
||||
|
||||
goog.require('Blockly.Block');
|
||||
goog.require('Blockly.BlockAnimations');
|
||||
goog.require('Blockly.blockAnimations');
|
||||
goog.require('Blockly.ContextMenu');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.Ui');
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
goog.require('Blockly.Grid');
|
||||
goog.require('Blockly.Msg');
|
||||
goog.require('Blockly.RenderedConnection');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
|
||||
goog.require('goog.color');
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
|
||||
|
||||
/**
|
||||
@@ -58,14 +60,14 @@ Blockly.BlockSvg = function(workspace, prototypeName, opt_id) {
|
||||
* @type {SVGElement}
|
||||
* @private
|
||||
*/
|
||||
this.svgGroup_ = Blockly.utils.createSvgElement('g', {}, null);
|
||||
this.svgGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null);
|
||||
this.svgGroup_.translate_ = '';
|
||||
|
||||
/**
|
||||
* @type {SVGElement}
|
||||
* @private
|
||||
*/
|
||||
this.svgPathDark_ = Blockly.utils.createSvgElement('path',
|
||||
this.svgPathDark_ = Blockly.utils.dom.createSvgElement('path',
|
||||
{'class': 'blocklyPathDark', 'transform': 'translate(1,1)'},
|
||||
this.svgGroup_);
|
||||
|
||||
@@ -73,14 +75,14 @@ Blockly.BlockSvg = function(workspace, prototypeName, opt_id) {
|
||||
* @type {SVGElement}
|
||||
* @private
|
||||
*/
|
||||
this.svgPath_ = Blockly.utils.createSvgElement('path',
|
||||
this.svgPath_ = Blockly.utils.dom.createSvgElement('path',
|
||||
{'class': 'blocklyPath'}, this.svgGroup_);
|
||||
|
||||
/**
|
||||
* @type {SVGElement}
|
||||
* @private
|
||||
*/
|
||||
this.svgPathLight_ = Blockly.utils.createSvgElement('path',
|
||||
this.svgPathLight_ = Blockly.utils.dom.createSvgElement('path',
|
||||
{'class': 'blocklyPathLight'}, this.svgGroup_);
|
||||
this.svgPath_.tooltip = this;
|
||||
|
||||
@@ -120,7 +122,7 @@ Blockly.BlockSvg.prototype.width = 0;
|
||||
|
||||
/**
|
||||
* Original location of block being dragged.
|
||||
* @type {goog.math.Coordinate}
|
||||
* @type {Blockly.utils.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.dragStartXY_ = null;
|
||||
@@ -300,7 +302,7 @@ Blockly.BlockSvg.prototype.setParent = function(newParent) {
|
||||
* If the block is on the workspace, (0, 0) is the origin of the workspace
|
||||
* coordinate system.
|
||||
* This does not change with workspace scale.
|
||||
* @return {!goog.math.Coordinate} Object with .x and .y properties in
|
||||
* @return {!Blockly.utils.Coordinate} Object with .x and .y properties in
|
||||
* workspace coordinates.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.getRelativeToSurfaceXY = function() {
|
||||
@@ -330,7 +332,7 @@ Blockly.BlockSvg.prototype.getRelativeToSurfaceXY = function() {
|
||||
} while (element && element != this.workspace.getCanvas() &&
|
||||
element != dragSurfaceGroup);
|
||||
}
|
||||
return new goog.math.Coordinate(x, y);
|
||||
return new Blockly.utils.Coordinate(x, y);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -392,7 +394,7 @@ Blockly.BlockSvg.prototype.moveToDragSurface_ = function() {
|
||||
* Move this block back to the workspace block canvas.
|
||||
* Generally should be called at the same time as setDragging_(false).
|
||||
* Does nothing if useDragSurface_ is false.
|
||||
* @param {!goog.math.Coordinate} newXY The position the block should take on
|
||||
* @param {!Blockly.utils.Coordinate} newXY The position the block should take on
|
||||
* on the workspace canvas, in workspace coordinates.
|
||||
* @private
|
||||
*/
|
||||
@@ -409,7 +411,7 @@ Blockly.BlockSvg.prototype.moveOffDragSurface_ = function(newXY) {
|
||||
* Move this block during a drag, taking into account whether we are using a
|
||||
* drag surface to translate blocks.
|
||||
* This block must be a top-level block.
|
||||
* @param {!goog.math.Coordinate} newLoc The location to translate to, in
|
||||
* @param {!Blockly.utils.Coordinate} newLoc The location to translate to, in
|
||||
* workspace coordinates.
|
||||
* @package
|
||||
*/
|
||||
@@ -429,7 +431,7 @@ Blockly.BlockSvg.prototype.moveDuringDrag = function(newLoc) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.clearTransformAttributes_ = function() {
|
||||
Blockly.utils.removeAttribute(this.getSvgRoot(), 'transform');
|
||||
this.getSvgRoot().removeAttribute('transform');
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -468,32 +470,29 @@ Blockly.BlockSvg.prototype.snapToGrid = function() {
|
||||
* Returns the coordinates of a bounding box describing the dimensions of this
|
||||
* block and any blocks stacked below it.
|
||||
* Coordinate system: workspace coordinates.
|
||||
* @return {!{topLeft: goog.math.Coordinate, bottomRight: goog.math.Coordinate}}
|
||||
* Object with top left and bottom right coordinates of the bounding box.
|
||||
* @return {!Blockly.utils.Rect} Object with coordinates of the bounding box.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.getBoundingRectangle = function() {
|
||||
var blockXY = this.getRelativeToSurfaceXY(this);
|
||||
var tab = this.outputConnection ? Blockly.BlockSvg.TAB_WIDTH : 0;
|
||||
var blockBounds = this.getHeightWidth();
|
||||
var topLeft;
|
||||
var bottomRight;
|
||||
var top = blockXY.y;
|
||||
var bottom = blockXY.y + blockBounds.height;
|
||||
var left, right;
|
||||
if (this.RTL) {
|
||||
// Width has the tab built into it already so subtract it here.
|
||||
topLeft = new goog.math.Coordinate(blockXY.x - (blockBounds.width - tab),
|
||||
blockXY.y);
|
||||
left = blockXY.x - (blockBounds.width - tab);
|
||||
// Add the width of the tab/puzzle piece knob to the x coordinate
|
||||
// since X is the corner of the rectangle, not the whole puzzle piece.
|
||||
bottomRight = new goog.math.Coordinate(blockXY.x + tab,
|
||||
blockXY.y + blockBounds.height);
|
||||
right = blockXY.x + tab;
|
||||
} else {
|
||||
// Subtract the width of the tab/puzzle piece knob to the x coordinate
|
||||
// since X is the corner of the rectangle, not the whole puzzle piece.
|
||||
topLeft = new goog.math.Coordinate(blockXY.x - tab, blockXY.y);
|
||||
left = blockXY.x - tab;
|
||||
// Width has the tab built into it already so subtract it here.
|
||||
bottomRight = new goog.math.Coordinate(blockXY.x + blockBounds.width - tab,
|
||||
blockXY.y + blockBounds.height);
|
||||
right = blockXY.x + blockBounds.width - tab;
|
||||
}
|
||||
return {topLeft: topLeft, bottomRight: bottomRight};
|
||||
return new Blockly.utils.Rect(top, bottom, left, right);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -635,76 +634,81 @@ Blockly.BlockSvg.prototype.showHelp_ = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the context menu for this block.
|
||||
* @param {!Event} e Mouse event.
|
||||
* @private
|
||||
* Generate the context menu for this block.
|
||||
* @protected
|
||||
* @returns {Array.<!Object>} Context menu options
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.showContextMenu_ = function(e) {
|
||||
Blockly.BlockSvg.prototype.generateContextMenu = function() {
|
||||
if (this.workspace.options.readOnly || !this.contextMenu) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
// Save the current block in a variable for use in closures.
|
||||
var block = this;
|
||||
var menuOptions = [];
|
||||
|
||||
if (this.isDeletable() && this.isMovable() && !block.isInFlyout) {
|
||||
menuOptions.push(Blockly.ContextMenu.blockDuplicateOption(block));
|
||||
if (this.isEditable() && !this.collapsed_ &&
|
||||
this.workspace.options.comments) {
|
||||
if (!this.isInFlyout) {
|
||||
if (this.isDeletable() && this.isMovable()) {
|
||||
menuOptions.push(Blockly.ContextMenu.blockDuplicateOption(block));
|
||||
}
|
||||
|
||||
if (this.workspace.options.comments && !this.collapsed_ &&
|
||||
this.isEditable()) {
|
||||
menuOptions.push(Blockly.ContextMenu.blockCommentOption(block));
|
||||
}
|
||||
|
||||
// Option to make block inline.
|
||||
if (!this.collapsed_) {
|
||||
for (var i = 1; i < this.inputList.length; i++) {
|
||||
if (this.inputList[i - 1].type != Blockly.NEXT_STATEMENT &&
|
||||
this.inputList[i].type != Blockly.NEXT_STATEMENT) {
|
||||
// Only display this option if there are two value or dummy inputs
|
||||
// next to each other.
|
||||
var inlineOption = {enabled: true};
|
||||
var isInline = this.getInputsInline();
|
||||
inlineOption.text = isInline ?
|
||||
Blockly.Msg['EXTERNAL_INPUTS'] : Blockly.Msg['INLINE_INPUTS'];
|
||||
inlineOption.callback = function() {
|
||||
block.setInputsInline(!isInline);
|
||||
if (this.isMovable()) {
|
||||
if (!this.collapsed_) {
|
||||
// Option to make block inline.
|
||||
for (var i = 1; i < this.inputList.length; i++) {
|
||||
if (this.inputList[i - 1].type != Blockly.NEXT_STATEMENT &&
|
||||
this.inputList[i].type != Blockly.NEXT_STATEMENT) {
|
||||
// Only display this option if there are two value or dummy inputs
|
||||
// next to each other.
|
||||
var inlineOption = {enabled: true};
|
||||
var isInline = this.getInputsInline();
|
||||
inlineOption.text = isInline ?
|
||||
Blockly.Msg['EXTERNAL_INPUTS'] : Blockly.Msg['INLINE_INPUTS'];
|
||||
inlineOption.callback = function() {
|
||||
block.setInputsInline(!isInline);
|
||||
};
|
||||
menuOptions.push(inlineOption);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Option to collapse block
|
||||
if (this.workspace.options.collapse) {
|
||||
var collapseOption = {enabled: true};
|
||||
collapseOption.text = Blockly.Msg['COLLAPSE_BLOCK'];
|
||||
collapseOption.callback = function() {
|
||||
block.setCollapsed(true);
|
||||
};
|
||||
menuOptions.push(inlineOption);
|
||||
break;
|
||||
menuOptions.push(collapseOption);
|
||||
}
|
||||
} else {
|
||||
// Option to expand block.
|
||||
if (this.workspace.options.collapse) {
|
||||
var expandOption = {enabled: true};
|
||||
expandOption.text = Blockly.Msg['EXPAND_BLOCK'];
|
||||
expandOption.callback = function() {
|
||||
block.setCollapsed(false);
|
||||
};
|
||||
menuOptions.push(expandOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.workspace.options.collapse) {
|
||||
// Option to collapse/expand block.
|
||||
if (this.collapsed_) {
|
||||
var expandOption = {enabled: true};
|
||||
expandOption.text = Blockly.Msg['EXPAND_BLOCK'];
|
||||
expandOption.callback = function() {
|
||||
block.setCollapsed(false);
|
||||
};
|
||||
menuOptions.push(expandOption);
|
||||
} else {
|
||||
var collapseOption = {enabled: true};
|
||||
collapseOption.text = Blockly.Msg['COLLAPSE_BLOCK'];
|
||||
collapseOption.callback = function() {
|
||||
block.setCollapsed(true);
|
||||
};
|
||||
menuOptions.push(collapseOption);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.workspace.options.disable) {
|
||||
if (this.workspace.options.disable && this.isEditable()) {
|
||||
// Option to disable/enable block.
|
||||
var disableOption = {
|
||||
text: this.disabled ?
|
||||
Blockly.Msg['ENABLE_BLOCK'] : Blockly.Msg['DISABLE_BLOCK'],
|
||||
text: this.isEnabled() ?
|
||||
Blockly.Msg['DISABLE_BLOCK'] : Blockly.Msg['ENABLE_BLOCK'],
|
||||
enabled: !this.getInheritedDisabled(),
|
||||
callback: function() {
|
||||
var group = Blockly.Events.getGroup();
|
||||
if (!group) {
|
||||
Blockly.Events.setGroup(true);
|
||||
}
|
||||
block.setDisabled(!block.disabled);
|
||||
block.setEnabled(!block.isEnabled());
|
||||
if (!group) {
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
@@ -713,7 +717,9 @@ Blockly.BlockSvg.prototype.showContextMenu_ = function(e) {
|
||||
menuOptions.push(disableOption);
|
||||
}
|
||||
|
||||
menuOptions.push(Blockly.ContextMenu.blockDeleteOption(block));
|
||||
if (this.isDeletable()) {
|
||||
menuOptions.push(Blockly.ContextMenu.blockDeleteOption(block));
|
||||
}
|
||||
}
|
||||
|
||||
menuOptions.push(Blockly.ContextMenu.blockHelpOption(block));
|
||||
@@ -723,8 +729,21 @@ Blockly.BlockSvg.prototype.showContextMenu_ = function(e) {
|
||||
this.customContextMenu(menuOptions);
|
||||
}
|
||||
|
||||
Blockly.ContextMenu.show(e, menuOptions, this.RTL);
|
||||
Blockly.ContextMenu.currentBlock = this;
|
||||
return menuOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the context menu for this block.
|
||||
* @param {!Event} e Mouse event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.showContextMenu_ = function(e) {
|
||||
var menuOptions = this.generateContextMenu();
|
||||
|
||||
if (menuOptions && menuOptions.length) {
|
||||
Blockly.ContextMenu.show(e, menuOptions, this.RTL);
|
||||
Blockly.ContextMenu.currentBlock = this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -769,11 +788,11 @@ Blockly.BlockSvg.prototype.setDragging = function(adding) {
|
||||
group.skew_ = '';
|
||||
Blockly.draggingConnections_ =
|
||||
Blockly.draggingConnections_.concat(this.getConnections_(true));
|
||||
Blockly.utils.addClass(
|
||||
Blockly.utils.dom.addClass(
|
||||
/** @type {!Element} */ (this.svgGroup_), 'blocklyDragging');
|
||||
} else {
|
||||
Blockly.draggingConnections_ = [];
|
||||
Blockly.utils.removeClass(
|
||||
Blockly.utils.dom.removeClass(
|
||||
/** @type {!Element} */ (this.svgGroup_), 'blocklyDragging');
|
||||
}
|
||||
// Recurse through all blocks attached under this one.
|
||||
@@ -787,10 +806,10 @@ Blockly.BlockSvg.prototype.setDragging = function(adding) {
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.updateMovable = function() {
|
||||
if (this.isMovable()) {
|
||||
Blockly.utils.addClass(
|
||||
Blockly.utils.dom.addClass(
|
||||
/** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable');
|
||||
} else {
|
||||
Blockly.utils.removeClass(
|
||||
Blockly.utils.dom.removeClass(
|
||||
/** @type {!Element} */ (this.svgGroup_), 'blocklyDraggable');
|
||||
}
|
||||
};
|
||||
@@ -838,7 +857,7 @@ Blockly.BlockSvg.prototype.setInsertionMarker = function(insertionMarker) {
|
||||
this.isInsertionMarker_ = insertionMarker;
|
||||
if (this.isInsertionMarker_) {
|
||||
this.setColour(Blockly.INSERTION_MARKER_COLOUR);
|
||||
Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
Blockly.utils.dom.addClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyInsertionMarker');
|
||||
}
|
||||
};
|
||||
@@ -880,7 +899,7 @@ Blockly.BlockSvg.prototype.dispose = function(healStack, animate) {
|
||||
|
||||
if (animate && this.rendered) {
|
||||
this.unplug(healStack);
|
||||
Blockly.BlockAnimations.disposeUiEffect(this);
|
||||
Blockly.blockAnimations.disposeUiEffect(this);
|
||||
}
|
||||
// Stop rerendering.
|
||||
this.rendered = false;
|
||||
@@ -916,7 +935,7 @@ Blockly.BlockSvg.prototype.dispose = function(healStack, animate) {
|
||||
Blockly.Events.fire(deleteEvent);
|
||||
}
|
||||
|
||||
Blockly.utils.removeNode(this.svgGroup_);
|
||||
Blockly.utils.dom.removeNode(this.svgGroup_);
|
||||
blockWorkspace.resizeContents();
|
||||
// Sever JavaScript to DOM connections.
|
||||
this.svgGroup_ = null;
|
||||
@@ -930,93 +949,78 @@ Blockly.BlockSvg.prototype.dispose = function(healStack, animate) {
|
||||
* Change the colour of a block.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.updateColour = function() {
|
||||
if (this.disabled) {
|
||||
if (!this.isEnabled()) {
|
||||
// Disabled blocks don't have colour.
|
||||
return;
|
||||
}
|
||||
var hexColour = this.getColour();
|
||||
var colourSecondary = this.getColourSecondary();
|
||||
var colourTertiary = this.getColourTertiary();
|
||||
var rgb = goog.color.hexToRgb(hexColour);
|
||||
|
||||
if (this.isShadow()) {
|
||||
hexColour = this.setShadowColour_(rgb, colourSecondary);
|
||||
this.setShadowColour_();
|
||||
} else {
|
||||
this.setBorderColour_(rgb, colourTertiary);
|
||||
this.setBorderColour_();
|
||||
this.svgPath_.setAttribute('fill', this.getColour());
|
||||
}
|
||||
this.svgPath_.setAttribute('fill', hexColour);
|
||||
|
||||
var icons = this.getIcons();
|
||||
for (var i = 0; i < icons.length; i++) {
|
||||
icons[i].updateColour();
|
||||
}
|
||||
|
||||
// Bump every dropdown to change its colour.
|
||||
// TODO (#1456)
|
||||
for (var x = 0, input; input = this.inputList[x]; x++) {
|
||||
for (var y = 0, field; field = input.fieldRow[y]; y++) {
|
||||
field.forceRerender();
|
||||
field.updateColour();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the colour of the border.
|
||||
* Removes the light and dark paths if a tertiary colour is defined.
|
||||
* @param {!string} rgb Colour of the block.
|
||||
* @param {?string} colourTertiary Colour of the border.
|
||||
* Removes the light and dark paths if a border colour is defined.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setBorderColour_ = function(rgb, colourTertiary) {
|
||||
if (colourTertiary) {
|
||||
this.svgPathLight_.setAttribute('stroke', 'none');
|
||||
this.svgPathDark_.setAttribute('fill', 'none');
|
||||
this.svgPath_.setAttribute('stroke', colourTertiary);
|
||||
Blockly.BlockSvg.prototype.setBorderColour_ = function() {
|
||||
var borderColours = this.getColourBorder();
|
||||
if (borderColours.colourBorder) {
|
||||
this.svgPathLight_.style.display = 'none';
|
||||
this.svgPathDark_.style.display = 'none';
|
||||
|
||||
this.svgPath_.setAttribute('stroke', borderColours.colourBorder);
|
||||
} else {
|
||||
this.svgPathLight_.style.display = '';
|
||||
var hexLight = goog.color.rgbArrayToHex(goog.color.lighten(rgb, 0.3));
|
||||
var hexDark = goog.color.rgbArrayToHex(goog.color.darken(rgb, 0.2));
|
||||
this.svgPathLight_.setAttribute('stroke', hexLight);
|
||||
this.svgPathDark_.setAttribute('fill', hexDark);
|
||||
this.svgPathDark_.style.display = '';
|
||||
this.svgPath_.setAttribute('stroke', 'none');
|
||||
|
||||
this.svgPathLight_.setAttribute('stroke', borderColours.colourLight);
|
||||
this.svgPathDark_.setAttribute('fill', borderColours.colourDark);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the colour of shadow blocks.
|
||||
* @param {!string} rgb Primary colour of the block.
|
||||
* @param {?string} colourSecondary Colour for shadow block.
|
||||
* @return {!string} The background colour of the block.
|
||||
* @return {?string} The background colour of the block.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setShadowColour_ = function(rgb, colourSecondary) {
|
||||
var hexColour;
|
||||
if (colourSecondary) {
|
||||
this.svgPathLight_.style.display = 'none';
|
||||
this.svgPathDark_.style.display = 'none';
|
||||
this.svgPath_.setAttribute('fill', colourSecondary);
|
||||
hexColour = colourSecondary;
|
||||
} else {
|
||||
rgb = goog.color.lighten(rgb, 0.6);
|
||||
hexColour = goog.color.rgbArrayToHex(rgb);
|
||||
this.svgPathLight_.style.display = 'none';
|
||||
this.svgPathDark_.setAttribute('fill', hexColour);
|
||||
}
|
||||
return hexColour;
|
||||
Blockly.BlockSvg.prototype.setShadowColour_ = function() {
|
||||
var shadowColour = this.getColourShadow();
|
||||
|
||||
this.svgPathLight_.style.display = 'none';
|
||||
this.svgPathDark_.setAttribute('fill', shadowColour);
|
||||
this.svgPath_.setAttribute('stroke', 'none');
|
||||
this.svgPath_.setAttribute('fill', shadowColour);
|
||||
return shadowColour;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable or disable a block.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.updateDisabled = function() {
|
||||
if (this.disabled || this.getInheritedDisabled()) {
|
||||
var added = Blockly.utils.addClass(
|
||||
if (!this.isEnabled() || this.getInheritedDisabled()) {
|
||||
var added = Blockly.utils.dom.addClass(
|
||||
/** @type {!Element} */ (this.svgGroup_), 'blocklyDisabled');
|
||||
if (added) {
|
||||
this.svgPath_.setAttribute('fill',
|
||||
'url(#' + this.workspace.options.disabledPatternId + ')');
|
||||
}
|
||||
} else {
|
||||
var removed = Blockly.utils.removeClass(
|
||||
var removed = Blockly.utils.dom.removeClass(
|
||||
/** @type {!Element} */ (this.svgGroup_), 'blocklyDisabled');
|
||||
if (removed) {
|
||||
this.updateColour();
|
||||
@@ -1167,10 +1171,21 @@ Blockly.BlockSvg.prototype.setMutator = function(mutator) {
|
||||
/**
|
||||
* Set whether the block is disabled or not.
|
||||
* @param {boolean} disabled True if disabled.
|
||||
* @deprecated May 2019
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setDisabled = function(disabled) {
|
||||
if (this.disabled != disabled) {
|
||||
Blockly.BlockSvg.superClass_.setDisabled.call(this, disabled);
|
||||
console.warn('Deprecated call to Blockly.BlockSvg.prototype.setDisabled, ' +
|
||||
'use Blockly.BlockSvg.prototype.setEnabled instead.');
|
||||
this.setEnabled(!disabled);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set whether the block is enabled or not.
|
||||
* @param {boolean} enabled True if enabled.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setEnabled = function(enabled) {
|
||||
if (this.isEnabled() != enabled) {
|
||||
Blockly.BlockSvg.superClass_.setEnabled.call(this, enabled);
|
||||
if (this.rendered) {
|
||||
this.updateDisabled();
|
||||
}
|
||||
@@ -1191,8 +1206,8 @@ Blockly.BlockSvg.prototype.setHighlighted = function(highlighted) {
|
||||
'url(#' + this.workspace.options.embossFilterId + ')');
|
||||
this.svgPathLight_.style.display = 'none';
|
||||
} else {
|
||||
Blockly.utils.removeAttribute(this.svgPath_, 'filter');
|
||||
delete this.svgPathLight_.style.display;
|
||||
this.svgPath_.setAttribute('filter', 'none');
|
||||
this.svgPathLight_.style.display = 'inline';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1200,7 +1215,7 @@ Blockly.BlockSvg.prototype.setHighlighted = function(highlighted) {
|
||||
* Select this block. Highlight it visually.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.addSelect = function() {
|
||||
Blockly.utils.addClass(
|
||||
Blockly.utils.dom.addClass(
|
||||
/** @type {!Element} */ (this.svgGroup_), 'blocklySelected');
|
||||
};
|
||||
|
||||
@@ -1208,7 +1223,7 @@ Blockly.BlockSvg.prototype.addSelect = function() {
|
||||
* Unselect this block. Remove its highlighting.
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.removeSelect = function() {
|
||||
Blockly.utils.removeClass(
|
||||
Blockly.utils.dom.removeClass(
|
||||
/** @type {!Element} */ (this.svgGroup_), 'blocklySelected');
|
||||
};
|
||||
|
||||
@@ -1220,10 +1235,10 @@ Blockly.BlockSvg.prototype.removeSelect = function() {
|
||||
*/
|
||||
Blockly.BlockSvg.prototype.setDeleteStyle = function(enable) {
|
||||
if (enable) {
|
||||
Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
Blockly.utils.dom.addClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyDraggingDelete');
|
||||
} else {
|
||||
Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
Blockly.utils.dom.removeClass(/** @type {!Element} */ (this.svgGroup_),
|
||||
'blocklyDraggingDelete');
|
||||
}
|
||||
};
|
||||
|
||||
+37
-36
@@ -32,6 +32,7 @@ goog.provide('Blockly');
|
||||
|
||||
goog.require('Blockly.BlockSvg.render');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.Ui');
|
||||
goog.require('Blockly.FieldAngle');
|
||||
goog.require('Blockly.FieldCheckbox');
|
||||
goog.require('Blockly.FieldColour');
|
||||
@@ -39,14 +40,15 @@ goog.require('Blockly.FieldColour');
|
||||
// Add it only if you need it.
|
||||
//goog.require('Blockly.FieldDate');
|
||||
goog.require('Blockly.FieldDropdown');
|
||||
goog.require('Blockly.FieldLabelSerializable');
|
||||
goog.require('Blockly.FieldImage');
|
||||
goog.require('Blockly.FieldTextInput');
|
||||
goog.require('Blockly.FieldNumber');
|
||||
goog.require('Blockly.FieldVariable');
|
||||
goog.require('Blockly.Generator');
|
||||
goog.require('Blockly.Msg');
|
||||
goog.require('Blockly.Procedures');
|
||||
goog.require('Blockly.Toolbox');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.WidgetDiv');
|
||||
goog.require('Blockly.WorkspaceSvg');
|
||||
@@ -55,8 +57,6 @@ goog.require('Blockly.inject');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.require('goog.color');
|
||||
|
||||
|
||||
// Turn off debugging when compiled.
|
||||
// Unused within the Blockly library, but used in Closure.
|
||||
@@ -107,7 +107,7 @@ Blockly.clipboardTypeCounts_ = null;
|
||||
|
||||
/**
|
||||
* Cached value for whether 3D is supported.
|
||||
* @type {!boolean}
|
||||
* @type {?boolean}
|
||||
* @private
|
||||
*/
|
||||
Blockly.cache3dSupported_ = null;
|
||||
@@ -119,16 +119,6 @@ Blockly.cache3dSupported_ = null;
|
||||
*/
|
||||
Blockly.theme_ = null;
|
||||
|
||||
/**
|
||||
* Convert a hue (HSV model) into an RGB hex triplet.
|
||||
* @param {number} hue Hue on a colour wheel (0-360).
|
||||
* @return {string} RGB code, e.g. '#5ba65b'.
|
||||
*/
|
||||
Blockly.hueToRgb = function(hue) {
|
||||
return goog.color.hsvToHex(hue, Blockly.HSV_SATURATION,
|
||||
Blockly.HSV_VALUE * 255);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the specified SVG image.
|
||||
* @param {!Element} svg SVG image.
|
||||
@@ -191,9 +181,9 @@ Blockly.svgResize = function(workspace) {
|
||||
// TODO (https://github.com/google/blockly/issues/1998) handle cases where there
|
||||
// are multiple workspaces and non-main workspaces are able to accept input.
|
||||
Blockly.onKeyDown_ = function(e) {
|
||||
var workspace = Blockly.mainWorkspace;
|
||||
if (workspace.options.readOnly || Blockly.utils.isTargetInput(e) ||
|
||||
(workspace.rendered && !workspace.isVisible())) {
|
||||
var mainWorkspace = Blockly.mainWorkspace;
|
||||
if (mainWorkspace.options.readOnly || Blockly.utils.isTargetInput(e) ||
|
||||
(mainWorkspace.rendered && !mainWorkspace.isVisible())) {
|
||||
// No key actions on readonly workspaces.
|
||||
// When focused on an HTML text input widget, don't trap any keys.
|
||||
// Ignore keypresses on rendered workspaces that have been explicitly
|
||||
@@ -257,7 +247,7 @@ Blockly.onKeyDown_ = function(e) {
|
||||
} else if (e.keyCode == 90) {
|
||||
// 'z' for undo 'Z' is for redo.
|
||||
Blockly.hideChaff();
|
||||
workspace.undo(e.shiftKey);
|
||||
mainWorkspace.undo(e.shiftKey);
|
||||
}
|
||||
}
|
||||
// Common code for delete and cut.
|
||||
@@ -280,7 +270,7 @@ Blockly.copy_ = function(toCopy) {
|
||||
if (toCopy.isComment) {
|
||||
var xml = toCopy.toXmlWithXY();
|
||||
} else {
|
||||
var xml = Blockly.Xml.blockToDom(toCopy);
|
||||
var xml = Blockly.Xml.blockToDom(toCopy, true);
|
||||
// Copy only the selected block and internal blocks.
|
||||
Blockly.Xml.deleteNext(xml);
|
||||
// Encode start position in XML.
|
||||
@@ -382,7 +372,7 @@ Blockly.getMainWorkspace = function() {
|
||||
* @param {function()=} opt_callback The callback when the alert is dismissed.
|
||||
*/
|
||||
Blockly.alert = function(message, opt_callback) {
|
||||
window.alert(message);
|
||||
alert(message);
|
||||
if (opt_callback) {
|
||||
opt_callback();
|
||||
}
|
||||
@@ -395,7 +385,7 @@ Blockly.alert = function(message, opt_callback) {
|
||||
* @param {!function(boolean)} callback The callback for handling user response.
|
||||
*/
|
||||
Blockly.confirm = function(message, callback) {
|
||||
callback(window.confirm(message));
|
||||
callback(confirm(message));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -408,7 +398,7 @@ Blockly.confirm = function(message, callback) {
|
||||
* @param {!function(string)} callback The callback for handling user response.
|
||||
*/
|
||||
Blockly.prompt = function(message, defaultValue, callback) {
|
||||
callback(window.prompt(message, defaultValue));
|
||||
callback(prompt(message, defaultValue));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -497,7 +487,8 @@ Blockly.bindEventWithChecks_ = function(node, name, thisObject, func,
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
if (goog.global.PointerEvent && (name in Blockly.Touch.TOUCH_MAP)) {
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; type = Blockly.Touch.TOUCH_MAP[name][i]; i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
@@ -549,8 +540,8 @@ Blockly.bindEvent_ = function(node, name, thisObject, func) {
|
||||
};
|
||||
|
||||
var bindData = [];
|
||||
var window = goog.global['window'];
|
||||
if (window && window.PointerEvent && (name in Blockly.Touch.TOUCH_MAP)) {
|
||||
if (Blockly.utils.global['PointerEvent'] &&
|
||||
(name in Blockly.Touch.TOUCH_MAP)) {
|
||||
for (var i = 0, type; type = Blockly.Touch.TOUCH_MAP[name][i]; i++) {
|
||||
node.addEventListener(type, wrapFunc, false);
|
||||
bindData.push([node, type, wrapFunc]);
|
||||
@@ -609,6 +600,16 @@ Blockly.isNumber = function(str) {
|
||||
return /^\s*-?\d+(\.\d+)?\s*$/.test(str);
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a hue (HSV model) into an RGB hex triplet.
|
||||
* @param {number} hue Hue on a colour wheel (0-360).
|
||||
* @return {string} RGB code, e.g. '#5ba65b'.
|
||||
*/
|
||||
Blockly.hueToHex = function(hue) {
|
||||
return Blockly.utils.colour.hsvToHex(hue, Blockly.HSV_SATURATION,
|
||||
Blockly.HSV_VALUE * 255);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks old colour constants are not overwritten by the host application.
|
||||
* If a constant is overwritten, it prints a console warning directing the
|
||||
@@ -688,11 +689,11 @@ Blockly.checkBlockColourConstant_ = function(
|
||||
* @param {!Blockly.Theme} theme Theme for Blockly.
|
||||
*/
|
||||
Blockly.setTheme = function(theme) {
|
||||
this.theme_ = theme;
|
||||
Blockly.theme_ = theme;
|
||||
var ws = Blockly.getMainWorkspace();
|
||||
|
||||
if (ws) {
|
||||
this.refreshTheme_(ws);
|
||||
Blockly.refreshTheme_(ws);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -703,15 +704,15 @@ Blockly.setTheme = function(theme) {
|
||||
*/
|
||||
Blockly.refreshTheme_ = function(ws) {
|
||||
// Update all blocks in workspace that have a style name.
|
||||
this.updateBlockStyles_(ws.getAllBlocks().filter(
|
||||
function(block){
|
||||
Blockly.updateBlockStyles_(ws.getAllBlocks().filter(
|
||||
function(block) {
|
||||
return block.getStyleName() !== undefined;
|
||||
}
|
||||
));
|
||||
|
||||
// Update blocks in the flyout.
|
||||
if (!ws.toolbox_ && ws.flyout_ && ws.flyout_.workspace_) {
|
||||
this.updateBlockStyles_(ws.flyout_.workspace_.getAllBlocks());
|
||||
Blockly.updateBlockStyles_(ws.flyout_.workspace_.getAllBlocks());
|
||||
} else {
|
||||
ws.refreshToolboxSelection();
|
||||
}
|
||||
@@ -735,7 +736,6 @@ Blockly.refreshTheme_ = function(ws) {
|
||||
Blockly.updateBlockStyles_ = function(blocks) {
|
||||
for (var i = 0, block; block = blocks[i]; i++) {
|
||||
var blockStyleName = block.getStyleName();
|
||||
|
||||
block.setStyle(blockStyleName);
|
||||
if (block.mutator) {
|
||||
block.mutator.updateBlockStyle(blockStyleName);
|
||||
@@ -748,12 +748,13 @@ Blockly.updateBlockStyles_ = function(blocks) {
|
||||
* @return {Blockly.Theme} Theme for Blockly.
|
||||
*/
|
||||
Blockly.getTheme = function() {
|
||||
return this.theme_;
|
||||
return Blockly.theme_;
|
||||
};
|
||||
|
||||
// Export symbols that would otherwise be renamed by Closure compiler.
|
||||
if (!goog.global['Blockly']) {
|
||||
goog.global['Blockly'] = {};
|
||||
if (!Blockly.utils.global['Blockly']) {
|
||||
Blockly.utils.global['Blockly'] = {};
|
||||
}
|
||||
goog.global['Blockly']['getMainWorkspace'] = Blockly.getMainWorkspace;
|
||||
goog.global['Blockly']['addChangeListener'] = Blockly.addChangeListener;
|
||||
Blockly.utils.global['Blockly']['getMainWorkspace'] = Blockly.getMainWorkspace;
|
||||
Blockly.utils.global['Blockly']['addChangeListener'] =
|
||||
Blockly.addChangeListener;
|
||||
|
||||
+1
-1
@@ -34,4 +34,4 @@ goog.provide('Blockly.Blocks');
|
||||
* A mapping of block type names to block prototype objects.
|
||||
* @type {!Object.<string,Object>}
|
||||
*/
|
||||
Blockly.Blocks = new Object(null);
|
||||
Blockly.Blocks = Object.create(null);
|
||||
|
||||
+26
-25
@@ -27,9 +27,12 @@
|
||||
goog.provide('Blockly.Bubble');
|
||||
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.math');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
goog.require('Blockly.Workspace');
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
@@ -38,8 +41,8 @@ goog.require('goog.userAgent');
|
||||
* bubble.
|
||||
* @param {!Element} content SVG content for the bubble.
|
||||
* @param {Element} shape SVG element to avoid eclipsing.
|
||||
* @param {!goog.math.Coordinate} anchorXY Absolute position of bubble's anchor
|
||||
* point.
|
||||
* @param {!Blockly.utils.Coordinate} anchorXY Absolute position of bubble's
|
||||
* anchor point.
|
||||
* @param {?number} bubbleWidth Width of bubble, or null if not resizable.
|
||||
* @param {?number} bubbleHeight Height of bubble, or null if not resizable.
|
||||
* @constructor
|
||||
@@ -54,7 +57,7 @@ Blockly.Bubble = function(workspace, content, shape, anchorXY,
|
||||
if (this.workspace_.RTL) {
|
||||
angle = -angle;
|
||||
}
|
||||
this.arrow_radians_ = Blockly.utils.toRadians(angle);
|
||||
this.arrow_radians_ = Blockly.utils.math.toRadians(angle);
|
||||
|
||||
var canvas = workspace.getBubbleCanvas();
|
||||
canvas.appendChild(this.createDom_(content, !!(bubbleWidth && bubbleHeight)));
|
||||
@@ -161,7 +164,7 @@ Blockly.Bubble.prototype.rendered_ = false;
|
||||
|
||||
/**
|
||||
* Absolute coordinate of anchor point, in workspace coordinates.
|
||||
* @type {goog.math.Coordinate}
|
||||
* @type {Blockly.utils.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.anchorXY_ = null;
|
||||
@@ -221,20 +224,18 @@ Blockly.Bubble.prototype.createDom_ = function(content, hasResize) {
|
||||
[...content goes here...]
|
||||
</g>
|
||||
*/
|
||||
this.bubbleGroup_ = Blockly.utils.createSvgElement('g', {}, null);
|
||||
this.bubbleGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null);
|
||||
var filter =
|
||||
{'filter': 'url(#' + this.workspace_.options.embossFilterId + ')'};
|
||||
if (goog.userAgent.getUserAgentString().indexOf('JavaFX') != -1) {
|
||||
// Multiple reports that JavaFX can't handle filters. UserAgent:
|
||||
// Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.44
|
||||
// (KHTML, like Gecko) JavaFX/8.0 Safari/537.44
|
||||
if (Blockly.utils.userAgent.JAVA_FX) {
|
||||
// Multiple reports that JavaFX can't handle filters.
|
||||
// https://github.com/google/blockly/issues/99
|
||||
filter = {};
|
||||
}
|
||||
var bubbleEmboss = Blockly.utils.createSvgElement('g',
|
||||
var bubbleEmboss = Blockly.utils.dom.createSvgElement('g',
|
||||
filter, this.bubbleGroup_);
|
||||
this.bubbleArrow_ = Blockly.utils.createSvgElement('path', {}, bubbleEmboss);
|
||||
this.bubbleBack_ = Blockly.utils.createSvgElement('rect',
|
||||
this.bubbleArrow_ = Blockly.utils.dom.createSvgElement('path', {}, bubbleEmboss);
|
||||
this.bubbleBack_ = Blockly.utils.dom.createSvgElement('rect',
|
||||
{
|
||||
'class': 'blocklyDraggable',
|
||||
'x': 0,
|
||||
@@ -244,21 +245,21 @@ Blockly.Bubble.prototype.createDom_ = function(content, hasResize) {
|
||||
},
|
||||
bubbleEmboss);
|
||||
if (hasResize) {
|
||||
this.resizeGroup_ = Blockly.utils.createSvgElement('g',
|
||||
this.resizeGroup_ = Blockly.utils.dom.createSvgElement('g',
|
||||
{'class': this.workspace_.RTL ?
|
||||
'blocklyResizeSW' : 'blocklyResizeSE'},
|
||||
this.bubbleGroup_);
|
||||
var resizeSize = 2 * Blockly.Bubble.BORDER_WIDTH;
|
||||
Blockly.utils.createSvgElement('polygon',
|
||||
Blockly.utils.dom.createSvgElement('polygon',
|
||||
{'points': '0,x x,x x,0'.replace(/x/g, resizeSize.toString())},
|
||||
this.resizeGroup_);
|
||||
Blockly.utils.createSvgElement('line',
|
||||
Blockly.utils.dom.createSvgElement('line',
|
||||
{
|
||||
'class': 'blocklyResizeLine',
|
||||
'x1': resizeSize / 3, 'y1': resizeSize - 1,
|
||||
'x2': resizeSize - 1, 'y2': resizeSize / 3
|
||||
}, this.resizeGroup_);
|
||||
Blockly.utils.createSvgElement('line',
|
||||
Blockly.utils.dom.createSvgElement('line',
|
||||
{
|
||||
'class': 'blocklyResizeLine',
|
||||
'x1': resizeSize * 2 / 3,
|
||||
@@ -336,7 +337,7 @@ Blockly.Bubble.prototype.resizeMouseDown_ = function(e) {
|
||||
return;
|
||||
}
|
||||
// Left-click (or middle click)
|
||||
this.workspace_.startDrag(e, new goog.math.Coordinate(
|
||||
this.workspace_.startDrag(e, new Blockly.utils.Coordinate(
|
||||
this.workspace_.RTL ? -this.width_ : this.width_, this.height_));
|
||||
|
||||
Blockly.Bubble.onMouseUpWrapper_ = Blockly.bindEventWithChecks_(document,
|
||||
@@ -373,7 +374,7 @@ Blockly.Bubble.prototype.registerResizeEvent = function(callback) {
|
||||
|
||||
/**
|
||||
* Move this bubble to the top of the stack.
|
||||
* @return {!boolean} Whether or not the bubble has been moved.
|
||||
* @return {boolean} Whether or not the bubble has been moved.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Bubble.prototype.promote_ = function() {
|
||||
@@ -388,7 +389,7 @@ Blockly.Bubble.prototype.promote_ = function() {
|
||||
/**
|
||||
* Notification that the anchor has moved.
|
||||
* Update the arrow and bubble accordingly.
|
||||
* @param {!goog.math.Coordinate} xy Absolute location.
|
||||
* @param {!Blockly.utils.Coordinate} xy Absolute location.
|
||||
*/
|
||||
Blockly.Bubble.prototype.setAnchorLocation = function(xy) {
|
||||
this.anchorXY_ = xy;
|
||||
@@ -759,7 +760,7 @@ Blockly.Bubble.prototype.setColour = function(hexColour) {
|
||||
Blockly.Bubble.prototype.dispose = function() {
|
||||
Blockly.Bubble.unbindDragEvents_();
|
||||
// Dispose of and unlink the bubble.
|
||||
Blockly.utils.removeNode(this.bubbleGroup_);
|
||||
Blockly.utils.dom.removeNode(this.bubbleGroup_);
|
||||
this.bubbleGroup_ = null;
|
||||
this.bubbleArrow_ = null;
|
||||
this.bubbleBack_ = null;
|
||||
@@ -774,7 +775,7 @@ Blockly.Bubble.prototype.dispose = function() {
|
||||
* a drag surface.
|
||||
* @param {Blockly.BlockDragSurfaceSvg} dragSurface The surface that carries
|
||||
* rendered items during a drag, or null if no drag surface is in use.
|
||||
* @param {!goog.math.Coordinate} newLoc The location to translate to, in
|
||||
* @param {!Blockly.utils.Coordinate} newLoc The location to translate to, in
|
||||
* workspace coordinates.
|
||||
* @package
|
||||
*/
|
||||
@@ -796,10 +797,10 @@ Blockly.Bubble.prototype.moveDuringDrag = function(dragSurface, newLoc) {
|
||||
/**
|
||||
* Return the coordinates of the top-left corner of this bubble's body relative
|
||||
* to the drawing surface's origin (0,0), in workspace units.
|
||||
* @return {!goog.math.Coordinate} Object with .x and .y properties.
|
||||
* @return {!Blockly.utils.Coordinate} Object with .x and .y properties.
|
||||
*/
|
||||
Blockly.Bubble.prototype.getRelativeToSurfaceXY = function() {
|
||||
return new goog.math.Coordinate(
|
||||
return new Blockly.utils.Coordinate(
|
||||
this.anchorXY_.x + this.relativeLeft_,
|
||||
this.anchorXY_.y + this.relativeTop_);
|
||||
};
|
||||
|
||||
+12
-12
@@ -27,12 +27,12 @@
|
||||
goog.provide('Blockly.BubbleDragger');
|
||||
|
||||
goog.require('Blockly.Bubble');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.CommentMove');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.WorkspaceCommentSvg');
|
||||
|
||||
goog.require('goog.math.Coordinate');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a bubble dragger. It moves things on the bubble canvas around the
|
||||
@@ -77,7 +77,7 @@ Blockly.BubbleDragger = function(bubble, workspace) {
|
||||
/**
|
||||
* The location of the top left corner of the dragging bubble's body at the
|
||||
* beginning of the drag, in workspace coordinates.
|
||||
* @type {!goog.math.Coordinate}
|
||||
* @type {!Blockly.utils.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.startXY_ = this.draggingBubble_.getRelativeToSurfaceXY();
|
||||
@@ -132,13 +132,13 @@ Blockly.BubbleDragger.prototype.startBubbleDrag = function() {
|
||||
* Execute a step of bubble dragging, based on the given event. Update the
|
||||
* display accordingly.
|
||||
* @param {!Event} e The most recent move event.
|
||||
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* moved from the position at the start of the drag, in pixel units.
|
||||
* @package
|
||||
*/
|
||||
Blockly.BubbleDragger.prototype.dragBubble = function(e, currentDragDeltaXY) {
|
||||
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
|
||||
var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
|
||||
var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
|
||||
|
||||
this.draggingBubble_.moveDuringDrag(this.dragSurface_, newLoc);
|
||||
|
||||
@@ -195,7 +195,7 @@ Blockly.BubbleDragger.prototype.updateCursorDuringBubbleDrag_ = function() {
|
||||
/**
|
||||
* Finish a bubble drag and put the bubble back on the workspace.
|
||||
* @param {!Event} e The mouseup/touchend event.
|
||||
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* moved from the position at the start of the drag, in pixel units.
|
||||
* @package
|
||||
*/
|
||||
@@ -205,7 +205,7 @@ Blockly.BubbleDragger.prototype.endBubbleDrag = function(
|
||||
this.dragBubble(e, currentDragDeltaXY);
|
||||
|
||||
var delta = this.pixelsToWorkspaceUnits_(currentDragDeltaXY);
|
||||
var newLoc = goog.math.Coordinate.sum(this.startXY_, delta);
|
||||
var newLoc = Blockly.utils.Coordinate.sum(this.startXY_, delta);
|
||||
|
||||
// Move the bubble to its final location.
|
||||
this.draggingBubble_.moveTo(newLoc.x, newLoc.y);
|
||||
@@ -250,14 +250,14 @@ Blockly.BubbleDragger.prototype.fireMoveEvent_ = function() {
|
||||
* correction for mutator workspaces.
|
||||
* This function does not consider differing origins. It simply scales the
|
||||
* input's x and y values.
|
||||
* @param {!goog.math.Coordinate} pixelCoord A coordinate with x and y values
|
||||
* in css pixel units.
|
||||
* @return {!goog.math.Coordinate} The input coordinate divided by the workspace
|
||||
* @param {!Blockly.utils.Coordinate} pixelCoord A coordinate with x and y values
|
||||
* in CSS pixel units.
|
||||
* @return {!Blockly.utils.Coordinate} The input coordinate divided by the workspace
|
||||
* scale.
|
||||
* @private
|
||||
*/
|
||||
Blockly.BubbleDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
|
||||
var result = new goog.math.Coordinate(pixelCoord.x / this.workspace_.scale,
|
||||
var result = new Blockly.utils.Coordinate(pixelCoord.x / this.workspace_.scale,
|
||||
pixelCoord.y / this.workspace_.scale);
|
||||
if (this.workspace_.isMutator) {
|
||||
// If we're in a mutator, its scale is always 1, purely because of some
|
||||
@@ -265,7 +265,7 @@ Blockly.BubbleDragger.prototype.pixelsToWorkspaceUnits_ = function(pixelCoord) {
|
||||
// the scale on the parent workspace.
|
||||
// Fix that for dragging.
|
||||
var mainScale = this.workspace_.options.parentWorkspace.scale;
|
||||
result = result.scale(1 / mainScale);
|
||||
result.scale(1 / mainScale);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
+12
-11
@@ -27,12 +27,12 @@
|
||||
goog.provide('Blockly.Comment');
|
||||
|
||||
goog.require('Blockly.Bubble');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Events.Ui');
|
||||
goog.require('Blockly.Icon');
|
||||
goog.require('Blockly.utils');
|
||||
|
||||
goog.require('goog.userAgent');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
@@ -72,13 +72,13 @@ Blockly.Comment.prototype.height_ = 80;
|
||||
*/
|
||||
Blockly.Comment.prototype.drawIcon_ = function(group) {
|
||||
// Circle.
|
||||
Blockly.utils.createSvgElement('circle',
|
||||
Blockly.utils.dom.createSvgElement('circle',
|
||||
{'class': 'blocklyIconShape', 'r': '8', 'cx': '8', 'cy': '8'},
|
||||
group);
|
||||
// Can't use a real '?' text character since different browsers and operating
|
||||
// systems render it differently.
|
||||
// Body of question mark.
|
||||
Blockly.utils.createSvgElement('path',
|
||||
Blockly.utils.dom.createSvgElement('path',
|
||||
{
|
||||
'class': 'blocklyIconSymbol',
|
||||
'd': 'm6.8,10h2c0.003,-0.617 0.271,-0.962 0.633,-1.266 2.875,-2.405' +
|
||||
@@ -86,7 +86,7 @@ Blockly.Comment.prototype.drawIcon_ = function(group) {
|
||||
'-1.201,0.998 -1.201,1.528 -1.204,2.19z'},
|
||||
group);
|
||||
// Dot of question mark.
|
||||
Blockly.utils.createSvgElement('rect',
|
||||
Blockly.utils.dom.createSvgElement('rect',
|
||||
{
|
||||
'class': 'blocklyIconSymbol',
|
||||
'x': '6.8',
|
||||
@@ -112,13 +112,13 @@ Blockly.Comment.prototype.createEditor_ = function() {
|
||||
</body>
|
||||
</foreignObject>
|
||||
*/
|
||||
this.foreignObject_ = Blockly.utils.createSvgElement('foreignObject',
|
||||
this.foreignObject_ = Blockly.utils.dom.createSvgElement('foreignObject',
|
||||
{'x': Blockly.Bubble.BORDER_WIDTH, 'y': Blockly.Bubble.BORDER_WIDTH},
|
||||
null);
|
||||
var body = document.createElementNS(Blockly.HTML_NS, 'body');
|
||||
body.setAttribute('xmlns', Blockly.HTML_NS);
|
||||
var body = document.createElementNS(Blockly.utils.dom.HTML_NS, 'body');
|
||||
body.setAttribute('xmlns', Blockly.utils.dom.HTML_NS);
|
||||
body.className = 'blocklyMinimalBody';
|
||||
var textarea = document.createElementNS(Blockly.HTML_NS, 'textarea');
|
||||
var textarea = document.createElementNS(Blockly.utils.dom.HTML_NS, 'textarea');
|
||||
textarea.className = 'blocklyCommentTextarea';
|
||||
textarea.setAttribute('dir', this.block_.RTL ? 'RTL' : 'LTR');
|
||||
body.appendChild(textarea);
|
||||
@@ -184,7 +184,8 @@ Blockly.Comment.prototype.setVisible = function(visible) {
|
||||
}
|
||||
Blockly.Events.fire(
|
||||
new Blockly.Events.Ui(this.block_, 'commentOpen', !visible, visible));
|
||||
if ((!this.block_.isEditable() && !this.textarea_) || goog.userAgent.IE) {
|
||||
if ((!this.block_.isEditable() && !this.textarea_) ||
|
||||
Blockly.utils.userAgent.IE) {
|
||||
// Steal the code from warnings to make an uneditable text bubble.
|
||||
// MSIE does not support foreignobject; textareas are impossible.
|
||||
// https://docs.microsoft.com/en-us/openspecs/ie_standards/ms-svg/56e6e04c-7c8c-44dd-8100-bd745ee42034
|
||||
|
||||
+20
-6
@@ -26,6 +26,7 @@
|
||||
|
||||
goog.provide('Blockly.Connection');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockMove');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
@@ -241,8 +242,6 @@ Blockly.Connection.prototype.dispose = function() {
|
||||
if (this.inDB_) {
|
||||
this.db_.removeConnection_(this);
|
||||
}
|
||||
this.db_ = null;
|
||||
this.dbOpposite_ = null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -445,6 +444,10 @@ Blockly.Connection.prototype.connect = function(otherConnection) {
|
||||
return;
|
||||
}
|
||||
this.checkConnection_(otherConnection);
|
||||
var eventGroup = Blockly.Events.getGroup();
|
||||
if (!eventGroup) {
|
||||
Blockly.Events.setGroup(true);
|
||||
}
|
||||
// Determine which block is superior (higher in the source stack).
|
||||
if (this.isSuperior()) {
|
||||
// Superior block.
|
||||
@@ -453,6 +456,9 @@ Blockly.Connection.prototype.connect = function(otherConnection) {
|
||||
// Inferior block.
|
||||
otherConnection.connect_(this);
|
||||
}
|
||||
if (!eventGroup) {
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -542,8 +548,16 @@ Blockly.Connection.prototype.disconnect = function() {
|
||||
childBlock = this.sourceBlock_;
|
||||
parentConnection = otherConnection;
|
||||
}
|
||||
|
||||
var eventGroup = Blockly.Events.getGroup();
|
||||
if (!eventGroup) {
|
||||
Blockly.Events.setGroup(true);
|
||||
}
|
||||
this.disconnectInternal_(parentBlock, childBlock);
|
||||
parentConnection.respawnShadow_();
|
||||
if (!eventGroup) {
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -656,8 +670,8 @@ Blockly.Connection.prototype.setCheck = function(check) {
|
||||
|
||||
/**
|
||||
* Get a connection's compatibility.
|
||||
* @return {Array} List of compatible value types. Null if
|
||||
* all types are compatible.
|
||||
* @return {Array} List of compatible value types.
|
||||
* Null if all types are compatible.
|
||||
* @public
|
||||
*/
|
||||
Blockly.Connection.prototype.getCheck = function() {
|
||||
@@ -688,11 +702,11 @@ Blockly.Connection.prototype.getShadowDom = function() {
|
||||
* and always return an empty list (the default).
|
||||
* {@link Blockly.RenderedConnection} overrides this behavior with a list
|
||||
* computed from the rendered positioning.
|
||||
* @param {number} maxLimit The maximum radius to another connection.
|
||||
* @param {number} _maxLimit The maximum radius to another connection.
|
||||
* @return {!Array.<!Blockly.Connection>} List of connections.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Connection.prototype.neighbours_ = function(/* maxLimit */) {
|
||||
Blockly.Connection.prototype.neighbours_ = function(_maxLimit) {
|
||||
return [];
|
||||
};
|
||||
|
||||
|
||||
@@ -226,16 +226,17 @@ Blockly.ConnectionDB.prototype.isInYRange_ = function(index, baseY, maxRadius) {
|
||||
* @param {!Blockly.Connection} conn The connection searching for a compatible
|
||||
* mate.
|
||||
* @param {number} maxRadius The maximum radius to another connection.
|
||||
* @param {!goog.math.Coordinate} dxy Offset between this connection's location
|
||||
* in the database and the current location (as a result of dragging).
|
||||
* @param {!Blockly.utils.Coordinate} dxy Offset between this connection's
|
||||
* location in the database and the current location (as a result of
|
||||
* dragging).
|
||||
* @return {!{connection: ?Blockly.Connection, radius: number}} Contains two
|
||||
* properties:' connection' which is either another connection or null,
|
||||
* and 'radius' which is the distance.
|
||||
*/
|
||||
Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius,
|
||||
dxy) {
|
||||
// Don't bother.
|
||||
if (!this.connections_.length) {
|
||||
// Don't bother.
|
||||
return {connection: null, radius: maxRadius};
|
||||
}
|
||||
|
||||
@@ -286,15 +287,15 @@ Blockly.ConnectionDB.prototype.searchForClosest = function(conn, maxRadius,
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize a set of connection DBs for a specified workspace.
|
||||
* @param {!Blockly.Workspace} workspace The workspace this DB is for.
|
||||
* Initialize a set of connection DBs for a workspace.
|
||||
* @return {!Array.<!Blockly.ConnectionDB>} Array of databases.
|
||||
*/
|
||||
Blockly.ConnectionDB.init = function(workspace) {
|
||||
Blockly.ConnectionDB.init = function() {
|
||||
// Create four databases, one for each connection type.
|
||||
var dbList = [];
|
||||
dbList[Blockly.INPUT_VALUE] = new Blockly.ConnectionDB();
|
||||
dbList[Blockly.OUTPUT_VALUE] = new Blockly.ConnectionDB();
|
||||
dbList[Blockly.NEXT_STATEMENT] = new Blockly.ConnectionDB();
|
||||
dbList[Blockly.PREVIOUS_STATEMENT] = new Blockly.ConnectionDB();
|
||||
workspace.connectionDBList = dbList;
|
||||
return dbList;
|
||||
};
|
||||
|
||||
@@ -129,18 +129,6 @@ Blockly.SPRITE = {
|
||||
|
||||
// Constants below this point are not intended to be changed.
|
||||
|
||||
/**
|
||||
* Required name space for SVG elements.
|
||||
* @const
|
||||
*/
|
||||
Blockly.SVG_NS = 'http://www.w3.org/2000/svg';
|
||||
|
||||
/**
|
||||
* Required name space for HTML elements.
|
||||
* @const
|
||||
*/
|
||||
Blockly.HTML_NS = 'http://www.w3.org/1999/xhtml';
|
||||
|
||||
/**
|
||||
* ENUM for a right-facing value input. E.g. 'set item to' or 'return'.
|
||||
* @const
|
||||
|
||||
+13
-11
@@ -30,16 +30,19 @@
|
||||
*/
|
||||
goog.provide('Blockly.ContextMenu');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
goog.require('Blockly.Msg');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.uiMenu');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('goog.ui.Menu');
|
||||
goog.require('goog.ui.MenuItem');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
@@ -154,7 +157,7 @@ Blockly.ContextMenu.createWidget_ = function(menu) {
|
||||
var div = Blockly.WidgetDiv.DIV;
|
||||
menu.render(div);
|
||||
var menuDom = menu.getElement();
|
||||
Blockly.utils.addClass(menuDom, 'blocklyContextMenu');
|
||||
Blockly.utils.dom.addClass(menuDom, 'blocklyContextMenu');
|
||||
// Prevent system context menu when right-clicking a Blockly context menu.
|
||||
Blockly.bindEventWithChecks_(
|
||||
menuDom, 'contextmenu', null, Blockly.utils.noEvent);
|
||||
@@ -280,7 +283,7 @@ Blockly.ContextMenu.blockDuplicateOption = function(block) {
|
||||
*/
|
||||
Blockly.ContextMenu.blockCommentOption = function(block) {
|
||||
var commentOption = {
|
||||
enabled: !goog.userAgent.IE
|
||||
enabled: !Blockly.utils.userAgent.IE
|
||||
};
|
||||
// If there's already a comment, add an option to delete it.
|
||||
if (block.comment) {
|
||||
@@ -360,7 +363,7 @@ Blockly.ContextMenu.workspaceCommentOption = function(ws, e) {
|
||||
var boundingRect = injectionDiv.getBoundingClientRect();
|
||||
|
||||
// The client coordinates offset by the injection div's upper left corner.
|
||||
var clientOffsetPixels = new goog.math.Coordinate(
|
||||
var clientOffsetPixels = new Blockly.utils.Coordinate(
|
||||
e.clientX - boundingRect.left, e.clientY - boundingRect.top);
|
||||
|
||||
// The offset in pixels between the main workspace's origin and the upper
|
||||
@@ -369,14 +372,13 @@ Blockly.ContextMenu.workspaceCommentOption = function(ws, e) {
|
||||
|
||||
// The position of the new comment in pixels relative to the origin of the
|
||||
// main workspace.
|
||||
var finalOffsetPixels = goog.math.Coordinate.difference(clientOffsetPixels,
|
||||
var finalOffset = Blockly.utils.Coordinate.difference(clientOffsetPixels,
|
||||
mainOffsetPixels);
|
||||
|
||||
// The position of the new comment in main workspace coordinates.
|
||||
var finalOffsetMainWs = finalOffsetPixels.scale(1 / ws.scale);
|
||||
finalOffset.scale(1 / ws.scale);
|
||||
|
||||
var commentX = finalOffsetMainWs.x;
|
||||
var commentY = finalOffsetMainWs.y;
|
||||
var commentX = finalOffset.x;
|
||||
var commentY = finalOffset.y;
|
||||
comment.moveBy(commentX, commentY);
|
||||
if (ws.rendered) {
|
||||
comment.initSvg();
|
||||
@@ -388,7 +390,7 @@ Blockly.ContextMenu.workspaceCommentOption = function(ws, e) {
|
||||
var wsCommentOption = {
|
||||
// Foreign objects don't work in IE. Don't let the user create comments
|
||||
// that they won't be able to edit.
|
||||
enabled: !goog.userAgent.IE
|
||||
enabled: !Blockly.utils.userAgent.IE
|
||||
};
|
||||
wsCommentOption.text = Blockly.Msg.ADD_COMMENT;
|
||||
wsCommentOption.callback = function() {
|
||||
|
||||
+10
-12
@@ -49,11 +49,11 @@ Blockly.Css.Cursor = {
|
||||
Blockly.Css.currentCursor_ = '';
|
||||
|
||||
/**
|
||||
* Large stylesheet added by Blockly.Css.inject.
|
||||
* @type {Element}
|
||||
* Has CSS already been injected?
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Css.styleSheet_ = null;
|
||||
Blockly.Css.injected_ = false;
|
||||
|
||||
/**
|
||||
* Path to media directory, with any trailing slash removed.
|
||||
@@ -74,13 +74,15 @@ Blockly.Css.mediaPath_ = '';
|
||||
*/
|
||||
Blockly.Css.inject = function(hasCss, pathToMedia) {
|
||||
// Only inject the CSS once.
|
||||
if (Blockly.Css.styleSheet_) {
|
||||
if (Blockly.Css.injected_) {
|
||||
return;
|
||||
}
|
||||
Blockly.Css.injected_ = true;
|
||||
// Placeholder for cursor rule. Must be first rule (index 0).
|
||||
var text = '.blocklyDraggable {}\n';
|
||||
if (hasCss) {
|
||||
text += Blockly.Css.CONTENT.join('\n');
|
||||
Blockly.Css.CONTENT = null; // Garbage collect 13 KB.
|
||||
if (Blockly.FieldDate) {
|
||||
text += Blockly.FieldDate.CSS.join('\n');
|
||||
}
|
||||
@@ -88,13 +90,12 @@ Blockly.Css.inject = function(hasCss, pathToMedia) {
|
||||
// Strip off any trailing slash (either Unix or Windows).
|
||||
Blockly.Css.mediaPath_ = pathToMedia.replace(/[\\\/]$/, '');
|
||||
text = text.replace(/<<<PATH>>>/g, Blockly.Css.mediaPath_);
|
||||
|
||||
// Inject CSS tag at start of head.
|
||||
var cssNode = document.createElement('style');
|
||||
document.head.insertBefore(cssNode, document.head.firstChild);
|
||||
|
||||
var cssTextNode = document.createTextNode(text);
|
||||
cssNode.appendChild(cssTextNode);
|
||||
Blockly.Css.styleSheet_ = cssNode.sheet;
|
||||
document.head.insertBefore(cssNode, document.head.firstChild);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -281,7 +282,7 @@ Blockly.Css.CONTENT = [
|
||||
'cursor: -webkit-grab;',
|
||||
'}',
|
||||
|
||||
'.blocklyDragging {',
|
||||
'.blocklyDragging {',
|
||||
/* backup for browsers (e.g. IE11) that don't support grabbing */
|
||||
'cursor: url("<<<PATH>>>/handclosed.cur"), auto;',
|
||||
'cursor: grabbing;',
|
||||
@@ -646,10 +647,9 @@ Blockly.Css.CONTENT = [
|
||||
'padding: 0 !important;',
|
||||
'}',
|
||||
|
||||
/* Override the default Closure URL. */
|
||||
'.blocklyWidgetDiv .goog-option-selected .goog-menuitem-checkbox,',
|
||||
'.blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon {',
|
||||
'background: url(<<<PATH>>>/sprites.png) no-repeat -48px -16px !important;',
|
||||
'background: url(<<<PATH>>>/sprites.png) no-repeat -48px -16px;',
|
||||
'}',
|
||||
|
||||
/* Category tree in Toolbox. */
|
||||
@@ -963,8 +963,6 @@ Blockly.Css.CONTENT = [
|
||||
'.blocklyWidgetDiv .goog-option-selected .goog-menuitem-icon, ',
|
||||
'.blocklyDropDownDiv .goog-option-selected .goog-menuitem-checkbox, ',
|
||||
'.blocklyDropDownDiv .goog-option-selected .goog-menuitem-icon {',
|
||||
/* Client apps may override the URL at which they serve the sprite. */
|
||||
'background: url(//ssl.gstatic.com/editor/editortoolbar.png) no-repeat -512px 0;',
|
||||
'position: static;', /* Scroll with the menu. */
|
||||
'float: left;',
|
||||
'margin-left: -24px;',
|
||||
|
||||
@@ -26,11 +26,9 @@
|
||||
|
||||
goog.provide('Blockly.DraggedConnectionManager');
|
||||
|
||||
goog.require('Blockly.BlockAnimations');
|
||||
goog.require('Blockly.blockAnimations');
|
||||
goog.require('Blockly.RenderedConnection');
|
||||
|
||||
goog.require('goog.math.Coordinate');
|
||||
|
||||
|
||||
/**
|
||||
* Class that controls updates to connections during drags. It is primarily
|
||||
@@ -151,7 +149,7 @@ Blockly.DraggedConnectionManager.prototype.applyConnections = function() {
|
||||
// Determine which connection is inferior (lower in the source stack).
|
||||
var inferiorConnection = this.localConnection_.isSuperior() ?
|
||||
this.closestConnection_ : this.localConnection_;
|
||||
Blockly.BlockAnimations.connectionUiEffect(
|
||||
Blockly.blockAnimations.connectionUiEffect(
|
||||
inferiorConnection.getSourceBlock());
|
||||
// Bring the just-edited stack to the front.
|
||||
var rootBlock = this.topBlock_.getRootBlock();
|
||||
@@ -163,7 +161,7 @@ Blockly.DraggedConnectionManager.prototype.applyConnections = function() {
|
||||
|
||||
/**
|
||||
* Update highlighted connections based on the most recent move location.
|
||||
* @param {!goog.math.Coordinate} dxy Position relative to drag start,
|
||||
* @param {!Blockly.utils.Coordinate} dxy Position relative to drag start,
|
||||
* in workspace units.
|
||||
* @param {?number} deleteArea One of {@link Blockly.DELETE_AREA_TRASH},
|
||||
* {@link Blockly.DELETE_AREA_TOOLBOX}, or {@link Blockly.DELETE_AREA_NONE}.
|
||||
@@ -236,7 +234,7 @@ Blockly.DraggedConnectionManager.prototype.initAvailableConnections_ = function(
|
||||
|
||||
/**
|
||||
* Find the new closest connection, and update internal state in response.
|
||||
* @param {!goog.math.Coordinate} dxy Position relative to the drag start,
|
||||
* @param {!Blockly.utils.Coordinate} dxy Position relative to the drag start,
|
||||
* in workspace units.
|
||||
* @return {boolean} Whether the closest connection has changed.
|
||||
* @private
|
||||
|
||||
+59
-45
@@ -28,11 +28,11 @@
|
||||
|
||||
goog.provide('Blockly.DropDownDiv');
|
||||
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.math');
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.style');
|
||||
|
||||
|
||||
/**
|
||||
* Class for drop-down div.
|
||||
* @constructor
|
||||
@@ -139,6 +139,8 @@ Blockly.DropDownDiv.createDom = function() {
|
||||
div.appendChild(arrow);
|
||||
Blockly.DropDownDiv.arrow_ = arrow;
|
||||
|
||||
Blockly.DropDownDiv.DIV_.style.opacity = 0;
|
||||
|
||||
// Transition animation for transform: translate() and opacity.
|
||||
Blockly.DropDownDiv.DIV_.style.transition = 'transform ' +
|
||||
Blockly.DropDownDiv.ANIMATION_TIME + 's, ' +
|
||||
@@ -228,10 +230,10 @@ Blockly.DropDownDiv.showPositionedByBlock = function(field, block,
|
||||
* by a particular field. The primary position will be below the field,
|
||||
* and the secondary position above the field. Drop-down will be
|
||||
* constrained to the block's workspace.
|
||||
* @param {Object} owner The object showing the drop-down.
|
||||
* @param {!Object} owner The object showing the drop-down.
|
||||
* @param {Function=} opt_onHide Optional callback for when the drop-down is
|
||||
* hidden.
|
||||
* @param {number} opt_secondaryYOffset Optional Y offset for above-block
|
||||
* @param {number=} opt_secondaryYOffset Optional Y offset for above-block
|
||||
* positioning.
|
||||
* @return {boolean} True if the menu rendered below block; false if above.
|
||||
*/
|
||||
@@ -250,7 +252,7 @@ Blockly.DropDownDiv.showPositionedByField = function(owner,
|
||||
// Set bounds to workspace; show the drop-down.
|
||||
Blockly.DropDownDiv.positionToField_ = true;
|
||||
Blockly.DropDownDiv.setBoundsElement(
|
||||
owner.sourceBlock_.workspace.getParentSvg().parentNode);
|
||||
owner.getSourceBlock().workspace.getParentSvg().parentNode);
|
||||
return Blockly.DropDownDiv.show(
|
||||
owner, primaryX, primaryY, secondaryX, secondaryY, opt_onHide);
|
||||
};
|
||||
@@ -272,17 +274,18 @@ Blockly.DropDownDiv.showPositionedByField = function(owner,
|
||||
* @param {Function=} opt_onHide Optional callback for when the drop-down is hidden
|
||||
* @return {boolean} True if the menu rendered at the primary origin point.
|
||||
*/
|
||||
Blockly.DropDownDiv.show = function(owner, primaryX, primaryY, secondaryX, secondaryY, opt_onHide) {
|
||||
Blockly.DropDownDiv.show = function(owner, primaryX, primaryY,
|
||||
secondaryX, secondaryY, opt_onHide) {
|
||||
Blockly.DropDownDiv.owner_ = owner;
|
||||
Blockly.DropDownDiv.onHide_ = opt_onHide;
|
||||
var metrics = Blockly.DropDownDiv.getPositionMetrics(primaryX, primaryY, secondaryX, secondaryY);
|
||||
// Update arrow CSS
|
||||
var metrics = Blockly.DropDownDiv.getPositionMetrics(primaryX, primaryY,
|
||||
secondaryX, secondaryY);
|
||||
// Update arrow CSS.
|
||||
Blockly.DropDownDiv.arrow_.style.transform = 'translate(' +
|
||||
metrics.arrowX + 'px,' + metrics.arrowY + 'px) rotate(45deg)';
|
||||
Blockly.DropDownDiv.arrow_.setAttribute('class',
|
||||
metrics.arrowAtTop ? 'blocklyDropDownArrow arrowTop' : 'blocklyDropDownArrow arrowBottom');
|
||||
Blockly.DropDownDiv.arrow_.style.display =
|
||||
metrics.arrowVisible ? '' : 'none';
|
||||
metrics.arrowX + 'px,' + metrics.arrowY + 'px) rotate(45deg)';
|
||||
Blockly.DropDownDiv.arrow_.setAttribute('class', metrics.arrowAtTop ?
|
||||
'blocklyDropDownArrow arrowTop' : 'blocklyDropDownArrow arrowBottom');
|
||||
Blockly.DropDownDiv.arrow_.style.display = metrics.arrowVisible ? '' : 'none';
|
||||
|
||||
// When we change `translate` multiple times in close succession,
|
||||
// Chrome may choose to wait and apply them all at once.
|
||||
@@ -328,7 +331,8 @@ Blockly.DropDownDiv.getBoundsInfo_ = function() {
|
||||
* @param {number} secondaryY Secondary/alternative origin point y, in absolute px
|
||||
* @return {Object} Various final metrics, including rendered positions for drop-down and arrow.
|
||||
*/
|
||||
Blockly.DropDownDiv.getPositionMetrics = function(primaryX, primaryY, secondaryX, secondaryY) {
|
||||
Blockly.DropDownDiv.getPositionMetrics = function(primaryX, primaryY,
|
||||
secondaryX, secondaryY) {
|
||||
var boundsInfo = Blockly.DropDownDiv.getBoundsInfo_();
|
||||
var div = Blockly.DropDownDiv.DIV_;
|
||||
var divSize = goog.style.getSize(div);
|
||||
@@ -364,14 +368,14 @@ Blockly.DropDownDiv.getPositionMetrics = function(primaryX, primaryY, secondaryX
|
||||
// dropdown should appear centered relative to the desired origin point.
|
||||
renderX -= divSize.width / 2;
|
||||
// Fit horizontally in the bounds.
|
||||
renderX = Blockly.utils.clampNumber(
|
||||
renderX = Blockly.utils.math.clamp(
|
||||
boundsInfo.left, renderX, boundsInfo.right - divSize.width);
|
||||
|
||||
// Calculate the absolute arrow X. The arrow wants to be as close to the
|
||||
// origin point as possible. The arrow may not be centered in the dropdown div.
|
||||
var absoluteArrowX = centerX - Blockly.DropDownDiv.ARROW_SIZE / 2;
|
||||
// Keep in overall bounds
|
||||
absoluteArrowX = Blockly.utils.clampNumber(
|
||||
absoluteArrowX = Blockly.utils.math.clamp(
|
||||
boundsInfo.left, absoluteArrowX, boundsInfo.right);
|
||||
|
||||
// Convert the arrow position to be relative to the top left corner of the div.
|
||||
@@ -379,7 +383,7 @@ Blockly.DropDownDiv.getPositionMetrics = function(primaryX, primaryY, secondaryX
|
||||
|
||||
// Pad the arrow by some pixels, primarily so that it doesn't render on top
|
||||
// of a rounded border.
|
||||
relativeArrowX = Blockly.utils.clampNumber(
|
||||
relativeArrowX = Blockly.utils.math.clamp(
|
||||
Blockly.DropDownDiv.ARROW_HORIZONTAL_PADDING,
|
||||
relativeArrowX,
|
||||
divSize.width - Blockly.DropDownDiv.ARROW_HORIZONTAL_PADDING -
|
||||
@@ -456,8 +460,19 @@ Blockly.DropDownDiv.hideWithoutAnimation = function() {
|
||||
if (!Blockly.DropDownDiv.isVisible()) {
|
||||
return;
|
||||
}
|
||||
Blockly.DropDownDiv.animateOutTimer_ && window.clearTimeout(Blockly.DropDownDiv.animateOutTimer_);
|
||||
Blockly.DropDownDiv.positionInternal_();
|
||||
if (Blockly.DropDownDiv.animateOutTimer_) {
|
||||
clearTimeout(Blockly.DropDownDiv.animateOutTimer_);
|
||||
}
|
||||
|
||||
// Reset style properties in case this gets called directly
|
||||
// instead of hide() - see discussion on #2551.
|
||||
var div = Blockly.DropDownDiv.DIV_;
|
||||
div.style.transform = '';
|
||||
div.style.left = '';
|
||||
div.style.top = '';
|
||||
div.style.opacity = 0;
|
||||
div.style.display = 'none';
|
||||
|
||||
Blockly.DropDownDiv.clearContent();
|
||||
Blockly.DropDownDiv.owner_ = null;
|
||||
if (Blockly.DropDownDiv.onHide_) {
|
||||
@@ -469,37 +484,36 @@ Blockly.DropDownDiv.hideWithoutAnimation = function() {
|
||||
|
||||
/**
|
||||
* Set the dropdown div's position.
|
||||
* @param {number} initialX Initial Horizontal location (window coordinates, not body).
|
||||
* @param {number} initialY Initial Vertical location (window coordinates, not body).
|
||||
* @param {number} finalX Final Horizontal location (window coordinates, not body).
|
||||
* @param {number} finalY Final Vertical location (window coordinates, not body).
|
||||
* @param {number} initialX Initial Horizontal location
|
||||
* (window coordinates, not body).
|
||||
* @param {number} initialY Initial Vertical location
|
||||
* (window coordinates, not body).
|
||||
* @param {number} finalX Final Horizontal location
|
||||
* (window coordinates, not body).
|
||||
* @param {number} finalY Final Vertical location
|
||||
* (window coordinates, not body).
|
||||
* @private
|
||||
*/
|
||||
Blockly.DropDownDiv.positionInternal_ = function(initialX, initialY, finalX, finalY) {
|
||||
initialX = initialX == null ? initialX : Math.floor(initialX);
|
||||
initialY = initialY == null ? initialY : Math.floor(initialY);
|
||||
finalX = finalX == null ? finalX : Math.floor(finalX);
|
||||
finalY = finalY == null ? finalY : Math.floor(finalY);
|
||||
initialX = Math.floor(initialX);
|
||||
initialY = Math.floor(initialY);
|
||||
finalX = Math.floor(finalX);
|
||||
finalY = Math.floor(finalY);
|
||||
|
||||
var div = Blockly.DropDownDiv.DIV_;
|
||||
// First apply initial translation.
|
||||
div.style.left = initialX != null ? initialX + 'px' : '';
|
||||
div.style.top = initialY != null ? initialY + 'px' : '';
|
||||
if (finalX != null) {
|
||||
// Show the div.
|
||||
div.style.display = 'block';
|
||||
div.style.opacity = 1;
|
||||
// Add final translate, animated through `transition`.
|
||||
// Coordinates are relative to (initialX, initialY),
|
||||
// where the drop-down is absolutely positioned.
|
||||
var dx = (finalX - initialX);
|
||||
var dy = (finalY - initialY);
|
||||
div.style.transform = 'translate(' + dx + 'px,' + dy + 'px)';
|
||||
} else {
|
||||
// Hide the div.
|
||||
div.style.display = 'none';
|
||||
div.style.transform = '';
|
||||
}
|
||||
div.style.left = initialX + 'px';
|
||||
div.style.top = initialY + 'px';
|
||||
|
||||
// Show the div.
|
||||
div.style.display = 'block';
|
||||
div.style.opacity = 1;
|
||||
// Add final translate, animated through `transition`.
|
||||
// Coordinates are relative to (initialX, initialY),
|
||||
// where the drop-down is absolutely positioned.
|
||||
var dx = finalX - initialX;
|
||||
var dy = finalY - initialY;
|
||||
div.style.transform = 'translate(' + dx + 'px,' + dy + 'px)';
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -512,7 +526,7 @@ Blockly.DropDownDiv.repositionForWindowResize = function() {
|
||||
// when a field is focused, the soft keyboard opens triggering a window resize
|
||||
// event and we want the dropdown div to stick around so users can type into it.
|
||||
if (Blockly.DropDownDiv.owner_) {
|
||||
var block = Blockly.DropDownDiv.owner_.sourceBlock_;
|
||||
var block = Blockly.DropDownDiv.owner_.getSourceBlock();
|
||||
var scale = block.workspace.scale;
|
||||
var bBox = {
|
||||
width: Blockly.DropDownDiv.positionToField_ ?
|
||||
|
||||
+5
-4
@@ -402,7 +402,7 @@ Blockly.Events.fromJson = function(json, workspace) {
|
||||
* Enable/disable a block depending on whether it is properly connected.
|
||||
* Use this on applications where all blocks should be connected to a top block.
|
||||
* Recommend setting the 'disable' option to 'false' in the config so that
|
||||
* users don't try to reenable disabled orphan blocks.
|
||||
* users don't try to re-enable disabled orphan blocks.
|
||||
* @param {!Blockly.Events.Abstract} event Custom data for event.
|
||||
*/
|
||||
Blockly.Events.disableOrphans = function(event) {
|
||||
@@ -411,15 +411,16 @@ Blockly.Events.disableOrphans = function(event) {
|
||||
var workspace = Blockly.Workspace.getById(event.workspaceId);
|
||||
var block = workspace.getBlockById(event.blockId);
|
||||
if (block) {
|
||||
if (block.getParent() && !block.getParent().disabled) {
|
||||
var parent = block.getParent();
|
||||
if (parent && parent.isEnabled()) {
|
||||
var children = block.getDescendants(false);
|
||||
for (var i = 0, child; child = children[i]; i++) {
|
||||
child.setDisabled(false);
|
||||
child.setEnabled(true);
|
||||
}
|
||||
} else if ((block.outputConnection || block.previousConnection) &&
|
||||
!workspace.isDragging()) {
|
||||
do {
|
||||
block.setDisabled(true);
|
||||
block.setEnabled(false);
|
||||
block = block.getNextBlock();
|
||||
} while (block);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ goog.provide('Blockly.Events.Abstract');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
|
||||
|
||||
/**
|
||||
* Abstract class for an event.
|
||||
* @constructor
|
||||
|
||||
+2
-1
@@ -36,6 +36,7 @@ goog.provide('Blockly.Extensions');
|
||||
goog.require('Blockly.Mutator');
|
||||
goog.require('Blockly.utils');
|
||||
|
||||
|
||||
/**
|
||||
* The set of all registered extensions, keyed by extension name/id.
|
||||
* @private
|
||||
@@ -73,7 +74,7 @@ Blockly.Extensions.register = function(name, initFn) {
|
||||
* registered.
|
||||
*/
|
||||
Blockly.Extensions.registerMixin = function(name, mixinObj) {
|
||||
if (!mixinObj || typeof mixinObj != 'object'){
|
||||
if (!mixinObj || typeof mixinObj != 'object') {
|
||||
throw Error('Error: Mixin "' + name + '" must be a object');
|
||||
}
|
||||
Blockly.Extensions.register(name, function() {
|
||||
|
||||
+362
-89
@@ -28,25 +28,27 @@
|
||||
|
||||
goog.provide('Blockly.Field');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Gesture');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
goog.require('goog.math.Size');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* Abstract class for an editable field.
|
||||
* @param {string} text The initial content of the field.
|
||||
* @param {function(string):(string|null|undefined)=} opt_validator An optional
|
||||
* function that is called to validate user input. See setValidator().
|
||||
* @param {*} value The initial value of the field.
|
||||
* @param {Function=} opt_validator A function that is called to validate
|
||||
* changes to the field's value. Takes in a value & returns a validated
|
||||
* value, or null to abort the change.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.Field = function(text, opt_validator) {
|
||||
Blockly.Field = function(value, opt_validator) {
|
||||
this.size_ = new goog.math.Size(0, Blockly.BlockSvg.MIN_BLOCK_Y);
|
||||
this.setValue(text);
|
||||
this.setValue(value);
|
||||
this.setValidator(opt_validator);
|
||||
};
|
||||
|
||||
@@ -109,7 +111,6 @@ Blockly.Field.cacheWidths_ = null;
|
||||
*/
|
||||
Blockly.Field.cacheReference_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Name of field. Unique within each block.
|
||||
* Static labels are usually unnamed.
|
||||
@@ -124,12 +125,30 @@ Blockly.Field.prototype.name = undefined;
|
||||
Blockly.Field.prototype.maxDisplayLength = 50;
|
||||
|
||||
/**
|
||||
* Visible text to display.
|
||||
* @type {string}
|
||||
* A generic value possessed by the field.
|
||||
* Should generally be non-null, only null when the field is created.
|
||||
* @type {*}
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.value_ = null;
|
||||
|
||||
/**
|
||||
* Text representation of the field's value. Maintained for backwards
|
||||
* compatibility reasons.
|
||||
* @type {string}
|
||||
* @protected
|
||||
* @deprecated Use or override getText instead.
|
||||
*/
|
||||
Blockly.Field.prototype.text_ = '';
|
||||
|
||||
/**
|
||||
* Used to cache the field's tooltip value if setTooltip is called when the
|
||||
* field is not yet initialized. Is *not* guaranteed to be accurate.
|
||||
* @type {?string}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Field.prototype.tooltip_ = null;
|
||||
|
||||
/**
|
||||
* Block this field is attached to. Starts as null, then set in init.
|
||||
* @type {Blockly.Block}
|
||||
@@ -137,6 +156,13 @@ Blockly.Field.prototype.text_ = '';
|
||||
*/
|
||||
Blockly.Field.prototype.sourceBlock_ = null;
|
||||
|
||||
/**
|
||||
* Does this block need to be re-rendered?
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
Blockly.Field.prototype.isDirty_ = true;
|
||||
|
||||
/**
|
||||
* Is the field visible, or hidden due to the block being collapsed?
|
||||
* @type {boolean}
|
||||
@@ -165,10 +191,24 @@ Blockly.Field.prototype.clickTarget_ = null;
|
||||
Blockly.Field.NBSP = '\u00A0';
|
||||
|
||||
/**
|
||||
* Editable fields are saved by the XML renderer, non-editable fields are not.
|
||||
* Editable fields usually show some sort of UI indicating they are editable.
|
||||
* They will also be saved by the XML renderer.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
* @default
|
||||
*/
|
||||
Blockly.Field.prototype.EDITABLE = true;
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable. This is not the
|
||||
* case by default so that SERIALIZABLE is backwards compatible.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
* @default
|
||||
*/
|
||||
Blockly.Field.prototype.SERIALIZABLE = false;
|
||||
|
||||
/**
|
||||
* Attach this field to a block.
|
||||
* @param {!Blockly.Block} block The block containing this field.
|
||||
@@ -181,63 +221,136 @@ Blockly.Field.prototype.setSourceBlock = function(block) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Install this field on a block.
|
||||
* Get the block this field is attached to.
|
||||
* @return {Blockly.Block} The block containing this field.
|
||||
*/
|
||||
Blockly.Field.prototype.getSourceBlock = function() {
|
||||
return this.sourceBlock_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize everything to render this field. Override
|
||||
* methods initModel and initView rather than this method.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.init = function() {
|
||||
if (this.fieldGroup_) {
|
||||
// Field has already been initialized once.
|
||||
return;
|
||||
}
|
||||
// Build the DOM.
|
||||
this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null);
|
||||
if (!this.visible_) {
|
||||
this.fieldGroup_ = Blockly.utils.dom.createSvgElement('g', {}, null);
|
||||
if (!this.isVisible()) {
|
||||
this.fieldGroup_.style.display = 'none';
|
||||
}
|
||||
this.borderRect_ = Blockly.utils.createSvgElement('rect',
|
||||
this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
|
||||
this.initView();
|
||||
this.updateEditable();
|
||||
this.setTooltip(this.tooltip_);
|
||||
this.bindEvents_();
|
||||
this.initModel();
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the block UI for this field.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.initView = function() {
|
||||
this.createBorderRect_();
|
||||
this.createTextElement_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a field border rect element. Not to be overridden by subclasses.
|
||||
* Instead modify the result of the function inside initView, or create a
|
||||
* separate function to call.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.createBorderRect_ = function() {
|
||||
this.borderRect_ = Blockly.utils.dom.createSvgElement('rect',
|
||||
{
|
||||
'rx': 4,
|
||||
'ry': 4,
|
||||
'x': -Blockly.BlockSvg.SEP_SPACE_X / 2,
|
||||
'y': 0,
|
||||
'height': 16
|
||||
'height': 16,
|
||||
'width': this.size_.width + Blockly.BlockSvg.SEP_SPACE_X
|
||||
}, this.fieldGroup_);
|
||||
/** @type {!Element} */
|
||||
this.textElement_ = Blockly.utils.createSvgElement('text',
|
||||
{'class': 'blocklyText', 'y': this.size_.height - 12.5},
|
||||
this.fieldGroup_);
|
||||
};
|
||||
|
||||
this.updateEditable();
|
||||
/**
|
||||
* Create a field text element. Not to be overridden by subclasses. Instead
|
||||
* modify the result of the function inside initView, or create a separate
|
||||
* function to call.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.createTextElement_ = function() {
|
||||
this.textElement_ = Blockly.utils.dom.createSvgElement('text',
|
||||
{
|
||||
'class': 'blocklyText',
|
||||
'y': this.size_.height - 12.5
|
||||
}, this.fieldGroup_);
|
||||
this.textContent_ = document.createTextNode('');
|
||||
this.textElement_.appendChild(this.textContent_);
|
||||
};
|
||||
|
||||
this.clickTarget_ = this.getSvgRoot();
|
||||
this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
|
||||
/**
|
||||
* Bind events to the field. Can be overridden by subclasses if they need to do
|
||||
* custom input handling.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.bindEvents_ = function() {
|
||||
Blockly.Tooltip.bindMouseEvents(this.getClickTarget_());
|
||||
this.mouseDownWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.clickTarget_, 'mousedown', this, this.onMouseDown_);
|
||||
this.getClickTarget_(), 'mousedown', this, this.onMouseDown_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the model of the field after it has been installed on a block.
|
||||
* No-op by default.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.initModel = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of all DOM objects belonging to this editable field.
|
||||
* Sets the field's value based on the given XML element. Should only be
|
||||
* called by Blockly.Xml.
|
||||
* @param {!Element} fieldElement The element containing info about the
|
||||
* field's state.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.fromXml = function(fieldElement) {
|
||||
this.setValue(fieldElement.textContent);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializes this field's value to XML. Should only be called by Blockly.Xml.
|
||||
* @param {!Element} fieldElement The element to populate with info about the
|
||||
* field's state.
|
||||
* @return {!Element} The element containing info about the field's state.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.toXml = function(fieldElement) {
|
||||
fieldElement.textContent = this.getValue();
|
||||
return fieldElement;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of all DOM objects and events belonging to this editable field.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.dispose = function() {
|
||||
Blockly.DropDownDiv.hideIfOwner(this);
|
||||
Blockly.WidgetDiv.hideIfOwner(this);
|
||||
|
||||
if (this.mouseDownWrapper_) {
|
||||
Blockly.unbindEvent_(this.mouseDownWrapper_);
|
||||
this.mouseDownWrapper_ = null;
|
||||
}
|
||||
this.sourceBlock_ = null;
|
||||
if (this.fieldGroup_) {
|
||||
Blockly.utils.removeNode(this.fieldGroup_);
|
||||
this.fieldGroup_ = null;
|
||||
}
|
||||
this.textElement_ = null;
|
||||
this.borderRect_ = null;
|
||||
this.validator_ = null;
|
||||
|
||||
Blockly.utils.dom.removeNode(this.fieldGroup_);
|
||||
|
||||
this.disposed = true;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -249,20 +362,28 @@ Blockly.Field.prototype.updateEditable = function() {
|
||||
return;
|
||||
}
|
||||
if (this.sourceBlock_.isEditable()) {
|
||||
Blockly.utils.addClass(group, 'blocklyEditableText');
|
||||
Blockly.utils.removeClass(group, 'blocklyNonEditableText');
|
||||
Blockly.utils.dom.addClass(group, 'blocklyEditableText');
|
||||
Blockly.utils.dom.removeClass(group, 'blocklyNonEditableText');
|
||||
group.style.cursor = this.CURSOR;
|
||||
} else {
|
||||
Blockly.utils.addClass(group, 'blocklyNonEditableText');
|
||||
Blockly.utils.removeClass(group, 'blocklyEditableText');
|
||||
Blockly.utils.dom.addClass(group, 'blocklyNonEditableText');
|
||||
Blockly.utils.dom.removeClass(group, 'blocklyEditableText');
|
||||
group.style.cursor = '';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether this field defines the showEditor_ function.
|
||||
* @return {boolean} Whether this field is clickable.
|
||||
*/
|
||||
Blockly.Field.prototype.isClickable = function() {
|
||||
return !!this.sourceBlock_ && this.sourceBlock_.isEditable() &&
|
||||
!!this.showEditor_ && (typeof this.showEditor_ === 'function');
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether this field is currently editable. Some fields are never
|
||||
* editable (e.g. text labels). Those fields are not serialized to XML. Other
|
||||
* fields may be editable, and therefore serialized, but may exist on
|
||||
* EDITABLE (e.g. text labels). Other fields may be EDITABLE but may exist on
|
||||
* non-editable blocks.
|
||||
* @return {boolean} Whether this field is editable and on an editable block
|
||||
*/
|
||||
@@ -270,6 +391,26 @@ Blockly.Field.prototype.isCurrentlyEditable = function() {
|
||||
return this.EDITABLE && !!this.sourceBlock_ && this.sourceBlock_.isEditable();
|
||||
};
|
||||
|
||||
/**
|
||||
* Check whether this field should be serialized by the XML renderer.
|
||||
* Handles the logic for backwards compatibility and incongruous states.
|
||||
* @return {boolean} Whether this field should be serialized or not.
|
||||
*/
|
||||
Blockly.Field.prototype.isSerializable = function() {
|
||||
var isSerializable = false;
|
||||
if (this.name) {
|
||||
if (this.SERIALIZABLE) {
|
||||
isSerializable = true;
|
||||
} else if (this.EDITABLE) {
|
||||
console.warn('Detected an editable field that was not serializable.' +
|
||||
' Please define SERIALIZABLE property as true on all editable custom' +
|
||||
' fields. Proceeding with serialization.');
|
||||
isSerializable = true;
|
||||
}
|
||||
}
|
||||
return isSerializable;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets whether this editable field is visible or not.
|
||||
* @return {boolean} True if visible.
|
||||
@@ -279,8 +420,10 @@ Blockly.Field.prototype.isVisible = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets whether this editable field is visible or not.
|
||||
* Sets whether this editable field is visible or not. Should only be called
|
||||
* by input.setVisible.
|
||||
* @param {boolean} visible True if visible.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.setVisible = function(visible) {
|
||||
if (this.visible_ == visible) {
|
||||
@@ -290,7 +433,6 @@ Blockly.Field.prototype.setVisible = function(visible) {
|
||||
var root = this.getSvgRoot();
|
||||
if (root) {
|
||||
root.style.display = visible ? 'block' : 'none';
|
||||
this.render_();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -298,14 +440,15 @@ Blockly.Field.prototype.setVisible = function(visible) {
|
||||
* Sets a new validation function for editable fields, or clears a previously
|
||||
* set validator.
|
||||
*
|
||||
* The validator function takes in the text form of the users input, and
|
||||
* optionally returns the accepted field text. Alternatively, if the function
|
||||
* returns null, the field value change aborts. If the function does not return
|
||||
* anything (or returns undefined), the input value is accepted as valid. This
|
||||
* is a shorthand for fields using the validator function call as a field-level
|
||||
* change event notification.
|
||||
* The validator function takes in the new field value, and returns
|
||||
* validated value. The validated value could be the input value, a modified
|
||||
* version of the input value, or null to abort the change.
|
||||
*
|
||||
* @param {?function(string):(string|null|undefined)} handler The validator
|
||||
* If the function does not return anything (or returns undefined) the new
|
||||
* value is accepted as valid. This is to allow for fields using the
|
||||
* validated founction as a field-level change event notification.
|
||||
*
|
||||
* @param {Function=} handler The validator
|
||||
* function or null to clear a previous validator.
|
||||
*/
|
||||
Blockly.Field.prototype.setValidator = function(handler) {
|
||||
@@ -324,6 +467,8 @@ Blockly.Field.prototype.getValidator = function() {
|
||||
* Validates a change. Does nothing. Subclasses may override this.
|
||||
* @param {string} text The user's text.
|
||||
* @return {string} No change needed.
|
||||
* @deprecated May 2019. Override doClassValidation and other relevant 'do'
|
||||
* functions instead.
|
||||
*/
|
||||
Blockly.Field.prototype.classValidator = function(text) {
|
||||
return text;
|
||||
@@ -334,6 +479,7 @@ Blockly.Field.prototype.classValidator = function(text) {
|
||||
* function for the field's class and its parents.
|
||||
* @param {string} text Proposed text.
|
||||
* @return {?string} Revised text, or null if invalid.
|
||||
* @deprecated May 2019. setValue now contains all relevant logic.
|
||||
*/
|
||||
Blockly.Field.prototype.callValidator = function(text) {
|
||||
var classResult = this.classValidator(text);
|
||||
@@ -366,27 +512,45 @@ Blockly.Field.prototype.getSvgRoot = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Draws the border with the correct width.
|
||||
* Saves the computed width in a property.
|
||||
* @protected
|
||||
* Updates the field to match the colour/style of the block. Should only be
|
||||
* called by BlockSvg.updateColour().
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.render_ = function() {
|
||||
if (!this.visible_) {
|
||||
this.size_.width = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Replace the text.
|
||||
this.textElement_.textContent = this.getDisplayText_();
|
||||
this.updateWidth();
|
||||
Blockly.Field.prototype.updateColour = function() {
|
||||
// Non-abstract sub-classes may wish to implement this. See FieldDropdown.
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the width of the field. This calls getCachedWidth which won't cache
|
||||
* the approximated width on IE/Edge when `getComputedTextLength` fails. Once
|
||||
* it eventually does succeed, the result will be cached.
|
||||
* Used by getSize() to move/resize any dom elements, and get the new size.
|
||||
*
|
||||
* All rendering that has an effect on the size/shape of the block should be
|
||||
* done here, and should be triggered by getSize().
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.render_ = function() {
|
||||
this.textContent_.nodeValue = this.getDisplayText_();
|
||||
this.updateSize_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the width of the field. Redirects to updateSize_().
|
||||
* @deprecated May 2019 Use Blockly.Field.updateSize_() to force an update
|
||||
* to the size of the field, or Blockly.Field.getCachedWidth() to check the
|
||||
* size of the field..
|
||||
*/
|
||||
Blockly.Field.prototype.updateWidth = function() {
|
||||
console.warn('Deprecated call to updateWidth, call' +
|
||||
' Blockly.Field.updateSize_ to force an update to the size of the' +
|
||||
' field, or Blockly.Field.getCachedWidth() to check the size of the' +
|
||||
' field.');
|
||||
this.updateSize_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the size of the field based on the text.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.updateSize_ = function() {
|
||||
var width = Blockly.Field.getCachedWidth(this.textElement_);
|
||||
if (this.borderRect_) {
|
||||
this.borderRect_.setAttribute('width',
|
||||
@@ -414,7 +578,7 @@ Blockly.Field.getCachedWidth = function(textElement) {
|
||||
|
||||
// Attempt to compute fetch the width of the SVG text element.
|
||||
try {
|
||||
if (goog.userAgent.IE || goog.userAgent.EDGE) {
|
||||
if (Blockly.utils.userAgent.IE || Blockly.utils.userAgent.EDGE) {
|
||||
width = textElement.getBBox().width;
|
||||
} else {
|
||||
width = textElement.getComputedTextLength();
|
||||
@@ -458,10 +622,23 @@ Blockly.Field.stopCache = function() {
|
||||
|
||||
/**
|
||||
* Returns the height and width of the field.
|
||||
*
|
||||
* This should *in general* be the only place render_ gets called from.
|
||||
* @return {!goog.math.Size} Height and width.
|
||||
*/
|
||||
Blockly.Field.prototype.getSize = function() {
|
||||
if (!this.size_.width) {
|
||||
if (!this.isVisible()) {
|
||||
return new goog.math.Size(0, 0);
|
||||
}
|
||||
|
||||
if (this.isDirty_) {
|
||||
this.render_();
|
||||
this.isDirty_ = false;
|
||||
} else if (this.visible_ && this.size_.width == 0) {
|
||||
// If the field is not visible the width will be 0 as well, one of the
|
||||
// problems with the old system.
|
||||
console.warn('Deprecated use of setting size_.width to 0 to rerender a' +
|
||||
' field. Set field.isDirty_ to true instead.');
|
||||
this.render_();
|
||||
}
|
||||
return this.size_;
|
||||
@@ -546,9 +723,7 @@ Blockly.Field.prototype.setText = function(newText) {
|
||||
* @package
|
||||
*/
|
||||
Blockly.Field.prototype.forceRerender = function() {
|
||||
// Set width to 0 to force a rerender of this field.
|
||||
this.size_.width = 0;
|
||||
|
||||
this.isDirty_ = true;
|
||||
if (this.sourceBlock_ && this.sourceBlock_.rendered) {
|
||||
this.sourceBlock_.render();
|
||||
this.sourceBlock_.bumpNeighbours_();
|
||||
@@ -556,33 +731,120 @@ Blockly.Field.prototype.forceRerender = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* By default there is no difference between the human-readable text and
|
||||
* the language-neutral values. Subclasses (such as dropdown) may define this.
|
||||
* @return {string} Current value.
|
||||
*/
|
||||
Blockly.Field.prototype.getValue = function() {
|
||||
return this.getText();
|
||||
};
|
||||
|
||||
/**
|
||||
* By default there is no difference between the human-readable text and
|
||||
* the language-neutral values. Subclasses (such as dropdown) may define this.
|
||||
* @param {string} newValue New value.
|
||||
* Used to change the value of the field. Handles validation and events.
|
||||
* Subclasses should override doClassValidation_ and doValueUpdate_ rather
|
||||
* than this method.
|
||||
* @param {*} newValue New value.
|
||||
*/
|
||||
Blockly.Field.prototype.setValue = function(newValue) {
|
||||
var doLogging = false;
|
||||
if (newValue === null) {
|
||||
// No change if null.
|
||||
doLogging && console.log('null, return');
|
||||
// Not a valid value to check.
|
||||
return;
|
||||
}
|
||||
|
||||
var validatedValue = this.doClassValidation_(newValue);
|
||||
// Class validators might accidentally forget to return, we'll ignore that.
|
||||
newValue = this.processValidation_(newValue, validatedValue);
|
||||
if (newValue instanceof Error) {
|
||||
doLogging && console.log('invalid class validation, return');
|
||||
return;
|
||||
}
|
||||
|
||||
var localValidator = this.getValidator();
|
||||
if (localValidator) {
|
||||
validatedValue = localValidator.call(this, newValue);
|
||||
// Local validators might accidentally forget to return, we'll ignore that.
|
||||
newValue = this.processValidation_(newValue, validatedValue);
|
||||
if (newValue instanceof Error) {
|
||||
doLogging && console.log('invalid local validation, return');
|
||||
return;
|
||||
}
|
||||
}
|
||||
var oldValue = this.getValue();
|
||||
if (oldValue == newValue) {
|
||||
if (oldValue === newValue) {
|
||||
doLogging && console.log('same, return');
|
||||
// No change.
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, oldValue, newValue));
|
||||
}
|
||||
this.setText(newValue);
|
||||
this.doValueUpdate_(newValue);
|
||||
if (this.isDirty_) {
|
||||
this.forceRerender();
|
||||
}
|
||||
doLogging && console.log(this.value_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Process the result of validation.
|
||||
* @param {*} newValue New value.
|
||||
* @param {*} validatedValue Validated value.
|
||||
* @return {*} New value, or an Error object.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Field.prototype.processValidation_ = function(newValue,
|
||||
validatedValue) {
|
||||
if (validatedValue === null) {
|
||||
this.doValueInvalid_(newValue);
|
||||
if (this.isDirty_) {
|
||||
this.forceRerender();
|
||||
}
|
||||
return Error();
|
||||
}
|
||||
if (validatedValue !== undefined) {
|
||||
newValue = validatedValue;
|
||||
}
|
||||
return newValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current value of the field.
|
||||
* @return {*} Current value.
|
||||
*/
|
||||
Blockly.Field.prototype.getValue = function() {
|
||||
return this.value_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to validate a value. Returns input by default. Can be overridden by
|
||||
* subclasses, see FieldDropdown.
|
||||
* @param {*} newValue The value to be validated.
|
||||
* @return {*} The validated value, same as input by default.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.doClassValidation_ = function(newValue) {
|
||||
// For backwards compatibility.
|
||||
newValue = this.classValidator(newValue);
|
||||
return newValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to update the value of a field. Can be overridden by subclasses to do
|
||||
* custom storage of values/updating of external things.
|
||||
* @param {*} newValue The value to be saved.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.doValueUpdate_ = function(newValue) {
|
||||
this.value_ = newValue;
|
||||
this.isDirty_ = true;
|
||||
// For backwards compatibility.
|
||||
this.text_ = String(newValue);
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to notify the field an invalid value was input. Can be overidden by
|
||||
* subclasses, see FieldTextInput.
|
||||
* No-op by default.
|
||||
* @param {*} _invalidValue The input value that was determined to be invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Field.prototype.doValueInvalid_ = function(_invalidValue) {
|
||||
// NOP
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -602,11 +864,22 @@ 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.
|
||||
* @param {string|function|!Element} newTip Text for tooltip or a parent
|
||||
* element to link to for its tooltip.
|
||||
*/
|
||||
Blockly.Field.prototype.setTooltip = function(_newTip) {
|
||||
// Non-abstract sub-classes may wish to implement this. See FieldLabel.
|
||||
Blockly.Field.prototype.setTooltip = function(newTip) {
|
||||
var clickTarget = this.getClickTarget_();
|
||||
if (!clickTarget) {
|
||||
// Field has not been initialized yet.
|
||||
this.tooltip_ = newTip;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newTip && newTip !== '') { // If null or undefined.
|
||||
clickTarget.tooltip = this.sourceBlock_;
|
||||
} else {
|
||||
clickTarget.tooltip = newTip;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+121
-115
@@ -28,28 +28,26 @@ goog.provide('Blockly.FieldAngle');
|
||||
|
||||
goog.require('Blockly.DropDownDiv');
|
||||
goog.require('Blockly.FieldTextInput');
|
||||
goog.require('Blockly.utils');
|
||||
|
||||
goog.require('goog.userAgent');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.math');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an editable angle field.
|
||||
* @param {(string|number)=} opt_value The initial content of the field. The
|
||||
* value should cast to a number, and if it does not, '0' will be used.
|
||||
* @param {Function=} opt_validator An optional function that is called
|
||||
* to validate any constraints on what the user entered. Takes the new
|
||||
* text as an argument and returns the accepted text or null to abort
|
||||
* the change.
|
||||
* @param {string|number=} opt_value The initial value of the field. Should cast
|
||||
* to a number. Defaults to 0.
|
||||
* @param {Function=} opt_validator A function that is called to validate
|
||||
* changes to the field's value. Takes in a number & returns a
|
||||
* validated number, or null to abort the change.
|
||||
* @extends {Blockly.FieldTextInput}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.FieldAngle = function(opt_value, opt_validator) {
|
||||
// Add degree symbol: '360°' (LTR) or '°360' (RTL)
|
||||
this.symbol_ = Blockly.utils.createSvgElement('tspan', {}, null);
|
||||
this.symbol_.appendChild(document.createTextNode('\u00B0'));
|
||||
|
||||
opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : '0';
|
||||
opt_value = this.doClassValidation_(opt_value);
|
||||
if (opt_value === null) {
|
||||
opt_value = 0;
|
||||
}
|
||||
Blockly.FieldAngle.superClass_.constructor.call(
|
||||
this, opt_value, opt_validator);
|
||||
};
|
||||
@@ -66,6 +64,14 @@ Blockly.FieldAngle.fromJson = function(options) {
|
||||
return new Blockly.FieldAngle(options['angle']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.SERIALIZABLE = true;
|
||||
|
||||
/**
|
||||
* Round angles to the nearest 15 degrees when using mouse.
|
||||
* Set to 0 to disable rounding.
|
||||
@@ -113,89 +119,82 @@ Blockly.FieldAngle.WRAP = 360;
|
||||
Blockly.FieldAngle.RADIUS = Blockly.FieldAngle.HALF - 1;
|
||||
|
||||
/**
|
||||
* Adds degree symbol and recalculates width.
|
||||
* Saves the computed width in a property.
|
||||
* Create the block UI for this field.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.initView = function() {
|
||||
Blockly.FieldAngle.superClass_.initView.call(this);
|
||||
// Add the degree symbol to the left of the number, even in RTL (issue #2380)
|
||||
this.symbol_ = Blockly.utils.dom.createSvgElement('tspan', {}, null);
|
||||
this.symbol_.appendChild(document.createTextNode('\u00B0'));
|
||||
this.textElement_.appendChild(this.symbol_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the graph when the field rerenders.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.render_ = function() {
|
||||
if (!this.visible_) {
|
||||
this.size_.width = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.updateWidth();
|
||||
Blockly.FieldAngle.superClass_.render_.call(this);
|
||||
this.updateGraph_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Clean up this FieldAngle, as well as the inherited FieldTextInput.
|
||||
* @return {!Function} Closure to call on destruction of the WidgetDiv.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.dispose_ = function() {
|
||||
var thisField = this;
|
||||
return function() {
|
||||
Blockly.FieldAngle.superClass_.dispose_.call(thisField)();
|
||||
thisField.gauge_ = null;
|
||||
if (thisField.clickWrapper_) {
|
||||
Blockly.unbindEvent_(thisField.clickWrapper_);
|
||||
}
|
||||
if (thisField.moveWrapper1_) {
|
||||
Blockly.unbindEvent_(thisField.moveWrapper1_);
|
||||
}
|
||||
if (thisField.moveWrapper2_) {
|
||||
Blockly.unbindEvent_(thisField.moveWrapper2_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Show the inline free-text editor on top of the text.
|
||||
* Create and show the angle field's editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.showEditor_ = function() {
|
||||
var noFocus =
|
||||
goog.userAgent.MOBILE || goog.userAgent.ANDROID || goog.userAgent.IPAD;
|
||||
// Mobile browsers have issues with in-line textareas (focus & keyboards).
|
||||
var noFocus =
|
||||
Blockly.utils.userAgent.MOBILE ||
|
||||
Blockly.utils.userAgent.ANDROID ||
|
||||
Blockly.utils.userAgent.IPAD;
|
||||
Blockly.FieldAngle.superClass_.showEditor_.call(this, noFocus);
|
||||
|
||||
// If there is an existing drop-down someone else owns, hide it immediately and clear it.
|
||||
Blockly.DropDownDiv.hideWithoutAnimation();
|
||||
Blockly.DropDownDiv.clearContent();
|
||||
var div = Blockly.DropDownDiv.getContentDiv();
|
||||
var editor = this.dropdownCreate_();
|
||||
Blockly.DropDownDiv.getContentDiv().appendChild(editor);
|
||||
|
||||
// Build the SVG DOM.
|
||||
var svg = Blockly.utils.createSvgElement('svg', {
|
||||
'xmlns': 'http://www.w3.org/2000/svg',
|
||||
'xmlns:html': 'http://www.w3.org/1999/xhtml',
|
||||
'xmlns:xlink': 'http://www.w3.org/1999/xlink',
|
||||
var border = this.sourceBlock_.getColourBorder();
|
||||
border = border.colourBorder || border.colourLight;
|
||||
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), border);
|
||||
|
||||
Blockly.DropDownDiv.showPositionedByField(
|
||||
this, this.dropdownDispose_.bind(this));
|
||||
|
||||
this.updateGraph_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the angle dropdown editor.
|
||||
* @return {!Element} The newly created angle picker.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.dropdownCreate_ = function() {
|
||||
var svg = Blockly.utils.dom.createSvgElement('svg', {
|
||||
'xmlns': Blockly.utils.dom.SVG_NS,
|
||||
'xmlns:html': Blockly.utils.dom.HTML_NS,
|
||||
'xmlns:xlink': Blockly.utils.dom.XLINK_NS,
|
||||
'version': '1.1',
|
||||
'height': (Blockly.FieldAngle.HALF * 2) + 'px',
|
||||
'width': (Blockly.FieldAngle.HALF * 2) + 'px'
|
||||
}, div);
|
||||
var circle = Blockly.utils.createSvgElement('circle', {
|
||||
'cx': Blockly.FieldAngle.HALF, 'cy': Blockly.FieldAngle.HALF,
|
||||
}, null);
|
||||
var circle = Blockly.utils.dom.createSvgElement('circle', {
|
||||
'cx': Blockly.FieldAngle.HALF,
|
||||
'cy': Blockly.FieldAngle.HALF,
|
||||
'r': Blockly.FieldAngle.RADIUS,
|
||||
'class': 'blocklyAngleCircle'
|
||||
}, svg);
|
||||
this.gauge_ = Blockly.utils.createSvgElement('path',
|
||||
{'class': 'blocklyAngleGauge'}, svg);
|
||||
this.line_ = Blockly.utils.createSvgElement('line', {
|
||||
this.gauge_ = Blockly.utils.dom.createSvgElement('path', {
|
||||
'class': 'blocklyAngleGauge'
|
||||
}, svg);
|
||||
this.line_ = Blockly.utils.dom.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', {
|
||||
Blockly.utils.dom.createSvgElement('line', {
|
||||
'x1': Blockly.FieldAngle.HALF + Blockly.FieldAngle.RADIUS,
|
||||
'y1': Blockly.FieldAngle.HALF,
|
||||
'x2': Blockly.FieldAngle.HALF + Blockly.FieldAngle.RADIUS -
|
||||
@@ -207,31 +206,35 @@ Blockly.FieldAngle.prototype.showEditor_ = function() {
|
||||
}, svg);
|
||||
}
|
||||
|
||||
|
||||
Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(),
|
||||
this.sourceBlock_.getColour());
|
||||
Blockly.DropDownDiv.showPositionedByField(this);
|
||||
// The angle picker is different from other fields in that it updates on
|
||||
// mousemove even if it's not in the middle of a drag. In future we may
|
||||
// change this behaviour. For now, using bindEvent_ instead of
|
||||
// bindEventWithChecks_ allows it to work without a mousedown/touchstart.
|
||||
this.clickWrapper_ =
|
||||
Blockly.bindEvent_(svg, 'click', this, this.hide_.bind(this));
|
||||
Blockly.bindEvent_(svg, 'click', this, this.hide_);
|
||||
this.moveWrapper1_ =
|
||||
Blockly.bindEvent_(circle, 'mousemove', this, this.onMouseMove);
|
||||
this.moveWrapper2_ =
|
||||
Blockly.bindEvent_(this.gauge_, 'mousemove', this, this.onMouseMove);
|
||||
this.updateGraph_();
|
||||
|
||||
return svg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the editor and unbind event listeners.
|
||||
* Dispose of events belonging to the angle editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.dropdownDispose_ = function() {
|
||||
Blockly.unbindEvent_(this.clickWrapper_);
|
||||
Blockly.unbindEvent_(this.moveWrapper1_);
|
||||
Blockly.unbindEvent_(this.moveWrapper2_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.hide_ = function() {
|
||||
Blockly.unbindEvent_(this.moveWrapper1_);
|
||||
Blockly.unbindEvent_(this.moveWrapper2_);
|
||||
Blockly.unbindEvent_(this.clickWrapper_);
|
||||
Blockly.DropDownDiv.hideIfOwner(this);
|
||||
Blockly.WidgetDiv.hide();
|
||||
};
|
||||
@@ -241,6 +244,7 @@ Blockly.FieldAngle.prototype.hide_ = function() {
|
||||
* @param {!Event} e Mouse move event.
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.onMouseMove = function(e) {
|
||||
// Calculate angle.
|
||||
var bBox = this.gauge_.ownerSVGElement.getBoundingClientRect();
|
||||
var dx = e.clientX - bBox.left - Blockly.FieldAngle.HALF;
|
||||
var dy = e.clientY - bBox.top - Blockly.FieldAngle.HALF;
|
||||
@@ -249,42 +253,44 @@ Blockly.FieldAngle.prototype.onMouseMove = function(e) {
|
||||
// This shouldn't happen, but let's not let this error propagate further.
|
||||
return;
|
||||
}
|
||||
angle = Blockly.utils.toDegrees(angle);
|
||||
angle = Blockly.utils.math.toDegrees(angle);
|
||||
// 0: East, 90: North, 180: West, 270: South.
|
||||
if (dx < 0) {
|
||||
angle += 180;
|
||||
} else if (dy > 0) {
|
||||
angle += 360;
|
||||
}
|
||||
|
||||
// Do offsetting.
|
||||
if (Blockly.FieldAngle.CLOCKWISE) {
|
||||
angle = Blockly.FieldAngle.OFFSET + 360 - angle;
|
||||
} else {
|
||||
angle -= Blockly.FieldAngle.OFFSET;
|
||||
angle = 360 - (Blockly.FieldAngle.OFFSET - angle);
|
||||
}
|
||||
if (angle > 360) {
|
||||
angle -= 360;
|
||||
}
|
||||
|
||||
// Do rounding.
|
||||
if (Blockly.FieldAngle.ROUND) {
|
||||
angle = Math.round(angle / Blockly.FieldAngle.ROUND) *
|
||||
Blockly.FieldAngle.ROUND;
|
||||
}
|
||||
angle = this.callValidator(angle);
|
||||
Blockly.FieldTextInput.htmlInput_.value = angle;
|
||||
this.setValue(angle);
|
||||
this.validate_();
|
||||
this.resizeEditor_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Insert a degree symbol.
|
||||
* @param {?string} text New text.
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.setText = function(text) {
|
||||
Blockly.FieldAngle.superClass_.setText.call(this, text);
|
||||
if (!this.textElement_) {
|
||||
// Not rendered yet.
|
||||
return;
|
||||
// Do wrapping.
|
||||
if (angle > Blockly.FieldAngle.WRAP) {
|
||||
angle -= 360;
|
||||
}
|
||||
|
||||
// Update value.
|
||||
var angleString = String(angle);
|
||||
if (angleString != this.text_) {
|
||||
this.htmlInput_.value = angle;
|
||||
this.setValue(angle);
|
||||
// Always render the input angle.
|
||||
this.text_ = angleString;
|
||||
this.forceRerender();
|
||||
}
|
||||
this.updateGraph_();
|
||||
// Cached width is obsolete. Clear it.
|
||||
this.size_.width = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -295,13 +301,15 @@ Blockly.FieldAngle.prototype.updateGraph_ = function() {
|
||||
if (!this.gauge_) {
|
||||
return;
|
||||
}
|
||||
// Always display the input (i.e. getText) even if it is invalid.
|
||||
var angleDegrees = Number(this.getText()) + Blockly.FieldAngle.OFFSET;
|
||||
var angleRadians = Blockly.utils.toRadians(angleDegrees);
|
||||
angleDegrees %= 360;
|
||||
var angleRadians = Blockly.utils.math.toRadians(angleDegrees);
|
||||
var path = ['M ', Blockly.FieldAngle.HALF, ',', Blockly.FieldAngle.HALF];
|
||||
var x2 = Blockly.FieldAngle.HALF;
|
||||
var y2 = Blockly.FieldAngle.HALF;
|
||||
if (!isNaN(angleRadians)) {
|
||||
var angle1 = Blockly.utils.toRadians(Blockly.FieldAngle.OFFSET);
|
||||
var angle1 = Blockly.utils.math.toRadians(Blockly.FieldAngle.OFFSET);
|
||||
var x1 = Math.cos(angle1) * Blockly.FieldAngle.RADIUS;
|
||||
var y1 = Math.sin(angle1) * -Blockly.FieldAngle.RADIUS;
|
||||
if (Blockly.FieldAngle.CLOCKWISE) {
|
||||
@@ -325,26 +333,24 @@ Blockly.FieldAngle.prototype.updateGraph_ = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure that only an angle may be entered.
|
||||
* @param {string} text The user's text.
|
||||
* @return {?string} A string representing a valid angle, or null if invalid.
|
||||
* Ensure that the input value is a valid angle.
|
||||
* @param {string|number=} newValue The input value.
|
||||
* @return {?number} A valid angle, or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldAngle.prototype.classValidator = function(text) {
|
||||
if (text === null) {
|
||||
Blockly.FieldAngle.prototype.doClassValidation_ = function(newValue) {
|
||||
if (isNaN(newValue)) {
|
||||
return null;
|
||||
}
|
||||
var n = parseFloat(text || 0);
|
||||
if (isNaN(n)) {
|
||||
return null;
|
||||
}
|
||||
n = n % 360;
|
||||
var n = parseFloat(newValue || 0);
|
||||
n %= 360;
|
||||
if (n < 0) {
|
||||
n += 360;
|
||||
}
|
||||
if (n > Blockly.FieldAngle.WRAP) {
|
||||
n -= 360;
|
||||
}
|
||||
return String(n);
|
||||
return n;
|
||||
};
|
||||
|
||||
Blockly.Field.register('field_angle', Blockly.FieldAngle);
|
||||
|
||||
+144
-65
@@ -26,24 +26,30 @@
|
||||
|
||||
goog.provide('Blockly.FieldCheckbox');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a checkbox field.
|
||||
* @param {string} state The initial state of the field ('TRUE' or 'FALSE').
|
||||
* @param {Function=} opt_validator A function that is executed when a new
|
||||
* option is selected. Its sole argument is the new checkbox state. If
|
||||
* it returns a value, this becomes the new checkbox state, unless the
|
||||
* value is null, in which case the change is aborted.
|
||||
* @param {string|boolean=} opt_value The initial value of the field. Should
|
||||
* either be 'TRUE', 'FALSE' or a boolean. Defaults to 'FALSE'.
|
||||
* @param {Function=} opt_validator A function that is called to validate
|
||||
* changes to the field's value. Takes in a value ('TRUE' or 'FALSE') &
|
||||
* returns a validated value ('TRUE' or 'FALSE'), or null to abort the
|
||||
* change.
|
||||
* @extends {Blockly.Field}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.FieldCheckbox = function(state, opt_validator) {
|
||||
Blockly.FieldCheckbox.superClass_.constructor.call(this, '', opt_validator);
|
||||
// Set the initial state.
|
||||
this.setValue(state);
|
||||
Blockly.FieldCheckbox = function(opt_value, opt_validator) {
|
||||
opt_value = this.doClassValidation_(opt_value);
|
||||
if (opt_value === null) {
|
||||
opt_value = 'FALSE';
|
||||
}
|
||||
Blockly.FieldCheckbox.superClass_.constructor.call(this, opt_value, opt_validator);
|
||||
this.size_.width = Blockly.FieldCheckbox.WIDTH;
|
||||
};
|
||||
goog.inherits(Blockly.FieldCheckbox, Blockly.Field);
|
||||
|
||||
@@ -55,78 +61,151 @@ goog.inherits(Blockly.FieldCheckbox, Blockly.Field);
|
||||
* @nocollapse
|
||||
*/
|
||||
Blockly.FieldCheckbox.fromJson = function(options) {
|
||||
return new Blockly.FieldCheckbox(options['checked'] ? 'TRUE' : 'FALSE');
|
||||
return new Blockly.FieldCheckbox(options['checked']);
|
||||
};
|
||||
|
||||
/**
|
||||
* The width of a checkbox field.
|
||||
* @type {number}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldCheckbox.WIDTH = 5;
|
||||
|
||||
/**
|
||||
* Character for the checkmark.
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldCheckbox.CHECK_CHAR = '\u2713';
|
||||
|
||||
/**
|
||||
* Used to correctly position the check mark.
|
||||
* @type {number}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldCheckbox.CHECK_X_OFFSET = -3;
|
||||
|
||||
/**
|
||||
* Used to correctly position the check mark.
|
||||
* @type {number}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldCheckbox.CHECK_Y_OFFSET = 14;
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.SERIALIZABLE = true;
|
||||
|
||||
/**
|
||||
* Mouse cursor style when over the hotspot that initiates editability.
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.CURSOR = 'default';
|
||||
|
||||
/**
|
||||
* Install this checkbox on a block.
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.init = function() {
|
||||
if (this.fieldGroup_) {
|
||||
// Checkbox has already been initialized once.
|
||||
return;
|
||||
}
|
||||
Blockly.FieldCheckbox.superClass_.init.call(this);
|
||||
// The checkbox doesn't use the inherited text element.
|
||||
// Instead it uses a custom checkmark element that is either visible or not.
|
||||
this.checkElement_ = Blockly.utils.createSvgElement('text',
|
||||
{'class': 'blocklyText blocklyCheckbox', 'x': -3, 'y': 14},
|
||||
this.fieldGroup_);
|
||||
var textNode = document.createTextNode(Blockly.FieldCheckbox.CHECK_CHAR);
|
||||
this.checkElement_.appendChild(textNode);
|
||||
this.checkElement_.style.display = this.state_ ? 'block' : 'none';
|
||||
};
|
||||
|
||||
/**
|
||||
* Return 'TRUE' if the checkbox is checked, 'FALSE' otherwise.
|
||||
* @return {string} Current state.
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.getValue = function() {
|
||||
return String(this.state_).toUpperCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the checkbox to be checked if newBool is 'TRUE' or true,
|
||||
* unchecks otherwise.
|
||||
* @param {string|boolean} newBool New state.
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.setValue = function(newBool) {
|
||||
var newState = (typeof newBool == 'string') ?
|
||||
(newBool.toUpperCase() == 'TRUE') : !!newBool;
|
||||
if (this.state_ !== newState) {
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, this.state_, newState));
|
||||
}
|
||||
this.state_ = newState;
|
||||
if (this.checkElement_) {
|
||||
this.checkElement_.style.display = newState ? 'block' : 'none';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle the state of the checkbox.
|
||||
* Used to tell if the field needs to be rendered the next time the block is
|
||||
* rendered. Checkbox fields are statically sized, and only need to be
|
||||
* rendered at initialization.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.isDirty_ = false;
|
||||
|
||||
/**
|
||||
* Create the block UI for this checkbox.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.initView = function() {
|
||||
Blockly.FieldCheckbox.superClass_.initView.call(this);
|
||||
|
||||
this.textElement_.setAttribute('x', Blockly.FieldCheckbox.CHECK_X_OFFSET);
|
||||
this.textElement_.setAttribute('y', Blockly.FieldCheckbox.CHECK_Y_OFFSET);
|
||||
Blockly.utils.dom.addClass(this.textElement_, 'blocklyCheckbox');
|
||||
|
||||
var textNode = document.createTextNode(Blockly.FieldCheckbox.CHECK_CHAR);
|
||||
this.textElement_.appendChild(textNode);
|
||||
this.textElement_.style.display = this.value_ ? 'block' : 'none';
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle the state of the checkbox on click.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.showEditor_ = function() {
|
||||
var newState = !this.state_;
|
||||
if (this.sourceBlock_) {
|
||||
// Call any validation function, and allow it to override.
|
||||
newState = this.callValidator(newState);
|
||||
this.setValue(!this.value_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure that the input value is valid ('TRUE' or 'FALSE').
|
||||
* @param {string|boolean=} newValue The input value.
|
||||
* @return {?string} A valid value ('TRUE' or 'FALSE), or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.doClassValidation_ = function(newValue) {
|
||||
if (newValue === true || newValue === 'TRUE') {
|
||||
return 'TRUE';
|
||||
}
|
||||
if (newState !== null) {
|
||||
this.setValue(String(newState).toUpperCase());
|
||||
if (newValue === false || newValue === 'FALSE') {
|
||||
return 'FALSE';
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the value of the field, and update the checkElement.
|
||||
* @param {string} newValue The new value ('TRUE' or 'FALSE') of the field.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.doValueUpdate_ = function(newValue) {
|
||||
this.value_ = this.convertValueToBool_(newValue);
|
||||
// Update visual.
|
||||
if (this.textElement_) {
|
||||
this.textElement_.style.display = this.value_ ? 'block' : 'none';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the value of this field, either 'TRUE' or 'FALSE'.
|
||||
* @return {string} The value of this field.
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.getValue = function() {
|
||||
return this.value_ ? 'TRUE' : 'FALSE';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the boolean value of this field.
|
||||
* @return {string} The boolean value of this field.
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.getValueBoolean = function() {
|
||||
return this.value_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text of this field. Used when the block is collapsed.
|
||||
* @return {string} Text representing the value of this field
|
||||
* ('true' or 'false').
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.getText = function() {
|
||||
return String(this.convertValueToBool_(this.value_));
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a value into a pure boolean.
|
||||
*
|
||||
* Converts 'TRUE' to true and 'FALSE' to false correctly, everything else
|
||||
* is cast to a boolean.
|
||||
* @param {*} value The value to convert.
|
||||
* @return {boolean} The converted value.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldCheckbox.prototype.convertValueToBool_ = function(value) {
|
||||
if (typeof value == 'string') {
|
||||
return value == 'TRUE';
|
||||
} else {
|
||||
return !!value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+78
-97
@@ -27,26 +27,31 @@
|
||||
goog.provide('Blockly.FieldColour');
|
||||
|
||||
goog.require('Blockly.DropDownDiv');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.colour');
|
||||
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.math.Size');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a colour input field.
|
||||
* @param {string} colour The initial colour in '#rrggbb' format.
|
||||
* @param {Function=} opt_validator A function that is executed when a new
|
||||
* colour is selected. Its sole argument is the new colour value. Its
|
||||
* return value becomes the selected colour, unless it is undefined, in
|
||||
* which case the new colour stands, or it is null, in which case the change
|
||||
* is aborted.
|
||||
* @param {string=} opt_value The initial value of the field. Should be in
|
||||
* '#rrggbb' format. Defaults to the first value in the default colour array.
|
||||
* @param {Function=} opt_validator A function that is called to validate
|
||||
* changes to the field's value. Takes in a colour string & returns a
|
||||
* validated colour string ('#rrggbb' format), or null to abort the change.
|
||||
* @extends {Blockly.Field}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.FieldColour = function(colour, opt_validator) {
|
||||
Blockly.FieldColour.superClass_.constructor.call(this, colour, opt_validator);
|
||||
this.setText(Blockly.Field.NBSP + Blockly.Field.NBSP + Blockly.Field.NBSP);
|
||||
Blockly.FieldColour = function(opt_value, opt_validator) {
|
||||
opt_value = this.doClassValidation_(opt_value);
|
||||
if (opt_value === null) {
|
||||
opt_value = Blockly.FieldColour.COLOURS[0];
|
||||
}
|
||||
Blockly.FieldColour.superClass_.constructor.call(
|
||||
this, opt_value, opt_validator);
|
||||
};
|
||||
goog.inherits(Blockly.FieldColour, Blockly.Field);
|
||||
|
||||
@@ -77,6 +82,28 @@ Blockly.FieldColour.DEFAULT_WIDTH = 16;
|
||||
*/
|
||||
Blockly.FieldColour.DEFAULT_HEIGHT = 12;
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldColour.prototype.SERIALIZABLE = true;
|
||||
|
||||
/**
|
||||
* Mouse cursor style when over the hotspot that initiates the editor.
|
||||
*/
|
||||
Blockly.FieldColour.prototype.CURSOR = 'default';
|
||||
|
||||
/**
|
||||
* Used to tell if the field needs to be rendered the next time the block is
|
||||
* rendered. Colour fields are statically sized, and only need to be
|
||||
* rendered at initialization.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldColour.prototype.isDirty_ = false;
|
||||
|
||||
/**
|
||||
* Array of colours used by this field. If null, use the global list.
|
||||
* @type {Array.<string>}
|
||||
@@ -116,88 +143,51 @@ Blockly.FieldColour.prototype.DROPDOWN_BORDER_COLOUR = 'silver';
|
||||
Blockly.FieldColour.prototype.DROPDOWN_BACKGROUND_COLOUR = 'white';
|
||||
|
||||
/**
|
||||
* Install this field on a block.
|
||||
* Create the block UI for this colour field.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldColour.prototype.init = function() {
|
||||
Blockly.FieldColour.superClass_.init.call(this);
|
||||
this.borderRect_.style['fillOpacity'] = 1;
|
||||
Blockly.FieldColour.prototype.initView = function() {
|
||||
this.size_ = new goog.math.Size(Blockly.FieldColour.DEFAULT_WIDTH,
|
||||
Blockly.FieldColour.DEFAULT_HEIGHT);
|
||||
this.setValue(this.getValue());
|
||||
this.createBorderRect_();
|
||||
this.borderRect_.style['fillOpacity'] = 1;
|
||||
this.borderRect_.style.fill = this.value_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mouse cursor style when over the hotspot that initiates the editor.
|
||||
* Ensure that the input value is a valid colour.
|
||||
* @param {string=} newValue The input value.
|
||||
* @return {?string} A valid colour, or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldColour.prototype.CURSOR = 'default';
|
||||
|
||||
/**
|
||||
* Close the colour picker if this input is being deleted.
|
||||
*/
|
||||
Blockly.FieldColour.prototype.dispose = function() {
|
||||
Blockly.WidgetDiv.hideIfOwner(this);
|
||||
Blockly.FieldColour.superClass_.dispose.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the current colour.
|
||||
* @return {string} Current colour in '#rrggbb' format.
|
||||
*/
|
||||
Blockly.FieldColour.prototype.getValue = function() {
|
||||
return this.colour_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the size, and rerender if necessary.
|
||||
* @return {!goog.math.Size} Height and width.
|
||||
*/
|
||||
Blockly.FieldColour.prototype.getSize = function() {
|
||||
if (!this.size_.width) {
|
||||
this.render_();
|
||||
Blockly.FieldColour.prototype.doClassValidation_ = function(newValue) {
|
||||
if (typeof newValue != 'string') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.size_;
|
||||
return Blockly.utils.colour.parse(newValue);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the width of the field. Colour fields have a constant width, but
|
||||
* the width is sometimes reset to force a rerender.
|
||||
* Update the value of this colour field, and update the displayed colour.
|
||||
* @param {string} newValue The new colour in '#rrggbb' format.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldColour.prototype.updateWidth = function() {
|
||||
var width = Blockly.FieldColour.DEFAULT_WIDTH;
|
||||
Blockly.FieldColour.prototype.doValueUpdate_ = function(newValue) {
|
||||
this.value_ = newValue;
|
||||
if (this.borderRect_) {
|
||||
this.borderRect_.setAttribute('width',
|
||||
width + Blockly.BlockSvg.SEP_SPACE_X);
|
||||
}
|
||||
this.size_.width = width;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the colour.
|
||||
* @param {string} colour The new colour in '#rrggbb' format.
|
||||
*/
|
||||
Blockly.FieldColour.prototype.setValue = function(colour) {
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled() &&
|
||||
this.colour_ != colour) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, this.colour_, colour));
|
||||
}
|
||||
this.colour_ = colour;
|
||||
if (this.borderRect_) {
|
||||
this.borderRect_.style.fill = colour;
|
||||
this.borderRect_.style.fill = newValue;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text from this field. Used when the block is collapsed.
|
||||
* @return {string} Current text.
|
||||
* Get the text for this field. Used when the block is collapsed.
|
||||
* @return {string} Text representing the value of this field.
|
||||
*/
|
||||
Blockly.FieldColour.prototype.getText = function() {
|
||||
var colour = this.colour_;
|
||||
var colour = this.value_;
|
||||
// Try to use #rgb format if possible, rather than #rrggbb.
|
||||
var m = colour.match(/^#(.)\1(.)\2(.)\3$/);
|
||||
if (m) {
|
||||
colour = '#' + m[1] + m[2] + m[3];
|
||||
if (/^#(.)\1(.)\2(.)\3$/.test(colour)) {
|
||||
colour = '#' + colour[1] + colour[3] + colour[5];
|
||||
}
|
||||
return colour;
|
||||
};
|
||||
@@ -273,24 +263,18 @@ Blockly.FieldColour.prototype.setColumns = function(columns) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a palette under the colour field.
|
||||
* Create and show the colour field's editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldColour.prototype.showEditor_ = function() {
|
||||
|
||||
Blockly.DropDownDiv.hideWithoutAnimation();
|
||||
Blockly.DropDownDiv.clearContent();
|
||||
|
||||
var picker = this.createWidget_();
|
||||
var picker = this.dropdownCreate_();
|
||||
Blockly.DropDownDiv.getContentDiv().appendChild(picker);
|
||||
|
||||
Blockly.DropDownDiv.setColour(
|
||||
this.DROPDOWN_BACKGROUND_COLOUR, this.DROPDOWN_BORDER_COLOUR);
|
||||
|
||||
Blockly.DropDownDiv.showPositionedByField(this);
|
||||
|
||||
// Configure event handler on the table to listen for any event in a cell.
|
||||
Blockly.FieldColour.onUpWrapper_ = Blockly.bindEvent_(picker,
|
||||
'mouseup', this, this.onClick_);
|
||||
Blockly.DropDownDiv.showPositionedByField(
|
||||
this, this.dropdownDispose_.bind(this));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -305,22 +289,18 @@ Blockly.FieldColour.prototype.onClick_ = function(e) {
|
||||
cell = cell.parentNode;
|
||||
}
|
||||
var colour = cell && cell.label;
|
||||
Blockly.WidgetDiv.hide();
|
||||
if (this.sourceBlock_) {
|
||||
// Call any validation function, and allow it to override.
|
||||
colour = this.callValidator(colour);
|
||||
}
|
||||
if (colour !== null) {
|
||||
this.setValue(colour);
|
||||
Blockly.DropDownDiv.hideIfOwner(this);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a colour picker widget.
|
||||
* Create a colour picker dropdown editor.
|
||||
* @return {!Element} The newly created colour picker.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldColour.prototype.createWidget_ = function() {
|
||||
Blockly.FieldColour.prototype.dropdownCreate_ = function() {
|
||||
var columns = this.columns_ || Blockly.FieldColour.COLUMNS;
|
||||
var colours = this.colours_ || Blockly.FieldColour.COLOURS;
|
||||
var titles = this.titles_ || Blockly.FieldColour.TITLES;
|
||||
@@ -345,18 +325,19 @@ Blockly.FieldColour.prototype.createWidget_ = function() {
|
||||
div.className = 'blocklyColourSelected';
|
||||
}
|
||||
}
|
||||
|
||||
// Configure event handler on the table to listen for any event in a cell.
|
||||
this.onUpWrapper_ = Blockly.bindEvent_(table, 'mouseup', this, this.onClick_);
|
||||
|
||||
return table;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the colour picker widget.
|
||||
* Dispose of events belonging to the colour editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldColour.widgetDispose_ = function() {
|
||||
if (Blockly.FieldColour.onUpWrapper_) {
|
||||
Blockly.unbindEvent_(Blockly.FieldColour.onUpWrapper_);
|
||||
}
|
||||
Blockly.Events.setGroup(false);
|
||||
Blockly.FieldColour.prototype.dropdownDispose_ = function() {
|
||||
Blockly.unbindEvent_(this.onUpWrapper_);
|
||||
};
|
||||
|
||||
Blockly.Field.register('field_colour', Blockly.FieldColour);
|
||||
|
||||
+181
-206
@@ -26,35 +26,35 @@
|
||||
|
||||
goog.provide('Blockly.FieldDate');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.string');
|
||||
|
||||
goog.require('goog.date');
|
||||
goog.require('goog.date.DateTime');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.i18n.DateTimeSymbols');
|
||||
goog.require('goog.i18n.DateTimeSymbols_he');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.ui.DatePicker');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a date input field.
|
||||
* @param {string} date The initial date.
|
||||
* @param {Function=} opt_validator A function that is executed when a new
|
||||
* date is selected. Its sole argument is the new date value. Its
|
||||
* return value becomes the selected date, unless it is undefined, in
|
||||
* which case the new date stands, or it is null, in which case the change
|
||||
* is aborted.
|
||||
* @param {string=} opt_value The initial value of the field. Should be in
|
||||
* 'YYYY-MM-DD' format. Defaults to the current date.
|
||||
* @param {Function=} opt_validator A function that is called to validate
|
||||
* changes to the field's value. Takes in a date string & returns a
|
||||
* validated date string ('YYYY-MM-DD' format), or null to abort the change.
|
||||
* @extends {Blockly.Field}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.FieldDate = function(date, opt_validator) {
|
||||
if (!date) {
|
||||
date = new goog.date.Date().toIsoString(true);
|
||||
Blockly.FieldDate = function(opt_value, opt_validator) {
|
||||
opt_value = this.doClassValidation_(opt_value);
|
||||
if (!opt_value) {
|
||||
opt_value = new goog.date.Date().toIsoString(true);
|
||||
}
|
||||
Blockly.FieldDate.superClass_.constructor.call(this, date, opt_validator);
|
||||
this.setValue(date);
|
||||
Blockly.FieldDate.superClass_.constructor.call(this, opt_value, opt_validator);
|
||||
};
|
||||
goog.inherits(Blockly.FieldDate, Blockly.Field);
|
||||
|
||||
@@ -69,105 +69,178 @@ Blockly.FieldDate.fromJson = function(options) {
|
||||
return new Blockly.FieldDate(options['date']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldDate.prototype.SERIALIZABLE = true;
|
||||
|
||||
/**
|
||||
* Mouse cursor style when over the hotspot that initiates the editor.
|
||||
*/
|
||||
Blockly.FieldDate.prototype.CURSOR = 'text';
|
||||
|
||||
/**
|
||||
* Close the colour picker if this input is being deleted.
|
||||
* Border colour for the dropdown div showing the date picker. Must be a CSS
|
||||
* string.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDate.prototype.dispose = function() {
|
||||
Blockly.WidgetDiv.hideIfOwner(this);
|
||||
Blockly.FieldDate.superClass_.dispose.call(this);
|
||||
};
|
||||
Blockly.FieldDate.prototype.DROPDOWN_BORDER_COLOUR = 'silver';
|
||||
|
||||
/**
|
||||
* Return the current date.
|
||||
* @return {string} Current date.
|
||||
* Background colour for the dropdown div showing the date picker. Must be a
|
||||
* CSS string.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDate.prototype.getValue = function() {
|
||||
return this.date_;
|
||||
};
|
||||
Blockly.FieldDate.prototype.DROPDOWN_BACKGROUND_COLOUR = 'white';
|
||||
|
||||
/**
|
||||
* Set the date.
|
||||
* @param {string} date The new date.
|
||||
* Ensure that the input value is a valid date.
|
||||
* @param {string=} newValue The input value.
|
||||
* @return {?string} A valid date, or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldDate.prototype.setValue = function(date) {
|
||||
if (this.sourceBlock_) {
|
||||
var validated = this.callValidator(date);
|
||||
// If the new date is invalid, validation returns null.
|
||||
// In this case we still want to display the illegal result.
|
||||
if (validated !== null) {
|
||||
date = validated;
|
||||
}
|
||||
Blockly.FieldDate.prototype.doClassValidation_ = function(newValue) {
|
||||
if (!newValue) {
|
||||
return null;
|
||||
}
|
||||
this.date_ = date;
|
||||
Blockly.Field.prototype.setText.call(this, date);
|
||||
// Check if the new value is parsable or not.
|
||||
var date = goog.date.Date.fromIsoString(newValue);
|
||||
if (!date || date.toIsoString(true) != newValue) {
|
||||
return null;
|
||||
}
|
||||
return newValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a date picker under the date field.
|
||||
* Render the field. If the picker is shown make sure it has the current
|
||||
* date selected.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldDate.prototype.render_ = function() {
|
||||
Blockly.FieldDate.superClass_.render_.call(this);
|
||||
if (this.picker_) {
|
||||
this.picker_.setDate(goog.date.Date.fromIsoString(this.getValue()));
|
||||
this.updateEditor_();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the field's colours to match those of the block.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldDate.prototype.updateColour = function() {
|
||||
this.todayColour_ = this.sourceBlock_.getColour();
|
||||
this.selectedColour_ = this.sourceBlock_.getColourShadow();
|
||||
this.updateEditor_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the picker to show the current date and currently selected date.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDate.prototype.updateEditor_ = function() {
|
||||
if (!this.picker_) {
|
||||
// Nothing to update.
|
||||
return;
|
||||
}
|
||||
|
||||
// Updating today should come before updating selected, so that if the
|
||||
// current day is selected, it will appear so.
|
||||
if (this.oldTodayElement_) {
|
||||
this.oldTodayElement_.style.backgroundColor = null;
|
||||
this.oldTodayElement_.style.color = null;
|
||||
}
|
||||
var today = this.picker_.getElementByClass('goog-date-picker-today');
|
||||
this.oldTodayElement_ = today;
|
||||
if (today) {
|
||||
today.style.backgroundColor = this.todayColour_;
|
||||
today.style.color = 'white';
|
||||
}
|
||||
|
||||
if (this.oldSelectedElement_ && this.oldSelectedElement_ != today) {
|
||||
this.oldSelectedElement_.style.backgroundColor = null;
|
||||
this.oldSelectedElement_.style.color = null;
|
||||
}
|
||||
var selected = this.picker_.getElementByClass('goog-date-picker-selected');
|
||||
this.oldSelectedElement_ = selected;
|
||||
if (selected) {
|
||||
selected.style.backgroundColor = this.selectedColour_;
|
||||
selected.style.color = this.todayColour_;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create and show the date field's editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDate.prototype.showEditor_ = function() {
|
||||
Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL,
|
||||
Blockly.FieldDate.widgetDispose_);
|
||||
this.picker_ = this.dropdownCreate_();
|
||||
this.picker_.render(Blockly.DropDownDiv.getContentDiv());
|
||||
Blockly.utils.dom.addClass(this.picker_.getElement(), 'blocklyDatePicker');
|
||||
Blockly.DropDownDiv.setColour(
|
||||
this.DROPDOWN_BACKGROUND_COLOUR, this.DROPDOWN_BORDER_COLOUR);
|
||||
|
||||
// Record viewport dimensions before adding the picker.
|
||||
var viewportBBox = Blockly.utils.getViewportBBox();
|
||||
var anchorBBox = this.getScaledBBox_();
|
||||
Blockly.DropDownDiv.showPositionedByField(
|
||||
this, this.dropdownDispose_.bind(this));
|
||||
|
||||
// Create and add the date picker, then record the size.
|
||||
var picker = this.createWidget_();
|
||||
var pickerSize = goog.style.getSize(picker.getElement());
|
||||
|
||||
// Position the picker to line up with the field.
|
||||
Blockly.WidgetDiv.positionWithAnchor(viewportBBox, anchorBBox, pickerSize,
|
||||
this.sourceBlock_.RTL);
|
||||
|
||||
// Configure event handler.
|
||||
var thisField = this;
|
||||
Blockly.FieldDate.changeEventKey_ = goog.events.listen(picker,
|
||||
goog.ui.DatePicker.Events.CHANGE,
|
||||
function(event) {
|
||||
var date = event.date ? event.date.toIsoString(true) : '';
|
||||
Blockly.WidgetDiv.hide();
|
||||
if (thisField.sourceBlock_) {
|
||||
// Call any validation function, and allow it to override.
|
||||
date = thisField.callValidator(date);
|
||||
}
|
||||
thisField.setValue(date);
|
||||
});
|
||||
this.updateEditor_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a date picker widget and render it inside the widget div.
|
||||
* Create the date dropdown editor.
|
||||
* @return {!goog.ui.DatePicker} The newly created date picker.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDate.prototype.createWidget_ = function() {
|
||||
Blockly.FieldDate.prototype.dropdownCreate_ = function() {
|
||||
// Create the date picker using Closure.
|
||||
Blockly.FieldDate.loadLanguage_();
|
||||
var picker = new goog.ui.DatePicker();
|
||||
picker.setAllowNone(false);
|
||||
picker.setShowWeekNum(false);
|
||||
var div = Blockly.WidgetDiv.DIV;
|
||||
picker.render(div);
|
||||
picker.setUseNarrowWeekdayNames(true);
|
||||
picker.setUseSimpleNavigationMenu(true);
|
||||
picker.setDate(goog.date.DateTime.fromIsoString(this.getValue()));
|
||||
|
||||
this.changeEventKey_ = goog.events.listen(
|
||||
picker,
|
||||
goog.ui.DatePicker.Events.CHANGE,
|
||||
this.onDateSelected_,
|
||||
null,
|
||||
this);
|
||||
this.activeMonthEventKey_ = goog.events.listen(
|
||||
picker,
|
||||
goog.ui.DatePicker.Events.CHANGE_ACTIVE_MONTH,
|
||||
this.updateEditor_,
|
||||
null,
|
||||
this);
|
||||
|
||||
return picker;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hide the date picker.
|
||||
* Dispose of references to DOM elements and events belonging
|
||||
* to the date editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDate.widgetDispose_ = function() {
|
||||
if (Blockly.FieldDate.changeEventKey_) {
|
||||
goog.events.unlistenByKey(Blockly.FieldDate.changeEventKey_);
|
||||
}
|
||||
Blockly.Events.setGroup(false);
|
||||
Blockly.FieldDate.prototype.dropdownDispose_ = function() {
|
||||
goog.events.unlistenByKey(this.changeEventKey_);
|
||||
goog.events.unlistenByKey(this.activeMonthEventKey_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle a CHANGE event in the date picker.
|
||||
* @param {!Event} event The CHANGE event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDate.prototype.onDateSelected_ = function(event) {
|
||||
var date = event.date ? event.date.toIsoString(true) : '';
|
||||
this.setValue(date);
|
||||
Blockly.DropDownDiv.hideIfOwner(this);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -176,13 +249,13 @@ Blockly.FieldDate.widgetDispose_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDate.loadLanguage_ = function() {
|
||||
var reg = /^DateTimeSymbols_(.+)$/;
|
||||
for (var prop in goog.i18n) {
|
||||
var m = prop.match(reg);
|
||||
if (m) {
|
||||
var lang = m[1].toLowerCase().replace('_', '.'); // E.g. 'pt.br'
|
||||
if (Blockly.utils.string.startsWith(prop, 'DateTimeSymbols_')) {
|
||||
var lang = prop.substr(16).toLowerCase().replace('_', '.');
|
||||
// E.g. 'DateTimeSymbols_pt_BR' -> 'pt.br'
|
||||
if (goog.getObjectByName(lang, Blockly.Msg)) {
|
||||
goog.i18n.DateTimeSymbols = goog.i18n[prop];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,159 +265,61 @@ Blockly.FieldDate.loadLanguage_ = function() {
|
||||
* CSS for date picker. See css.js for use.
|
||||
*/
|
||||
Blockly.FieldDate.CSS = [
|
||||
/* Copied from: goog/css/datepicker.css */
|
||||
/**
|
||||
* Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by the Apache License, Version 2.0.
|
||||
* See the COPYING file for details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Standard styling for a goog.ui.DatePicker.
|
||||
*
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker,',
|
||||
'.blocklyWidgetDiv .goog-date-picker th,',
|
||||
'.blocklyWidgetDiv .goog-date-picker td {',
|
||||
'.blocklyDatePicker,',
|
||||
'.blocklyDatePicker th,',
|
||||
'.blocklyDatePicker td {',
|
||||
' font: 13px Arial, sans-serif;',
|
||||
' color: #3c4043;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker {',
|
||||
' -moz-user-focus: normal;',
|
||||
' -moz-user-select: none;',
|
||||
' position: relative;',
|
||||
' border: 1px solid #000;',
|
||||
' float: left;',
|
||||
' padding: 2px;',
|
||||
' color: #000;',
|
||||
' background: #c3d9ff;',
|
||||
' cursor: default;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker th {',
|
||||
' text-align: center;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker td {',
|
||||
'.blocklyDatePicker th,',
|
||||
'.blocklyDatePicker td {',
|
||||
' text-align: center;',
|
||||
' vertical-align: middle;',
|
||||
' padding: 1px 3px;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-menu {',
|
||||
' position: absolute;',
|
||||
' background: threedface;',
|
||||
' border: 1px solid gray;',
|
||||
' -moz-user-focus: normal;',
|
||||
' z-index: 1;',
|
||||
' outline: none;',
|
||||
'.blocklyDatePicker .goog-date-picker-wday,',
|
||||
'.blocklyDatePicker .goog-date-picker-date {',
|
||||
' padding: 6px 6px;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-menu ul {',
|
||||
' list-style: none;',
|
||||
' margin: 0px;',
|
||||
' padding: 0px;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-menu ul li {',
|
||||
' cursor: default;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-menu-selected {',
|
||||
' background: #ccf;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker th {',
|
||||
' font-size: .9em;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker td div {',
|
||||
' float: left;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker button {',
|
||||
' padding: 0px;',
|
||||
'.blocklyDatePicker button {',
|
||||
' cursor: pointer;',
|
||||
' padding: 6px 6px;',
|
||||
' margin: 1px 0;',
|
||||
' border: 0;',
|
||||
' color: #20c;',
|
||||
' color: #3c4043;',
|
||||
' font-weight: bold;',
|
||||
' background: transparent;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-date {',
|
||||
' background: #fff;',
|
||||
'.blocklyDatePicker .goog-date-picker-previousMonth,',
|
||||
'.blocklyDatePicker .goog-date-picker-nextMonth {',
|
||||
' height: 24px;',
|
||||
' width: 24px;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-week,',
|
||||
'.blocklyWidgetDiv .goog-date-picker-wday {',
|
||||
' padding: 1px 3px;',
|
||||
' border: 0;',
|
||||
' border-color: #a2bbdd;',
|
||||
' border-style: solid;',
|
||||
'.blocklyDatePicker .goog-date-picker-monthyear {',
|
||||
' font-weight: bold;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-week {',
|
||||
' border-right-width: 1px;',
|
||||
'.blocklyDatePicker .goog-date-picker-wday, ',
|
||||
'.blocklyDatePicker .goog-date-picker-other-month {',
|
||||
' color: #70757a;',
|
||||
' border-radius: 12px;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-wday {',
|
||||
' border-bottom-width: 1px;',
|
||||
'.blocklyDatePicker button,',
|
||||
'.blocklyDatePicker .goog-date-picker-date {',
|
||||
' cursor: pointer;',
|
||||
' background-color: rgb(218, 220, 224, 0);',
|
||||
' border-radius: 12px;',
|
||||
' transition: background-color,opacity 100ms linear;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-head td {',
|
||||
' text-align: center;',
|
||||
'}',
|
||||
|
||||
/** Use td.className instead of !important */
|
||||
'.blocklyWidgetDiv td.goog-date-picker-today-cont {',
|
||||
' text-align: center;',
|
||||
'}',
|
||||
|
||||
/** Use td.className instead of !important */
|
||||
'.blocklyWidgetDiv td.goog-date-picker-none-cont {',
|
||||
' text-align: center;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-month {',
|
||||
' min-width: 11ex;',
|
||||
' white-space: nowrap;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-year {',
|
||||
' min-width: 6ex;',
|
||||
' white-space: nowrap;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-monthyear {',
|
||||
' white-space: nowrap;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker table {',
|
||||
' border-collapse: collapse;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-other-month {',
|
||||
' color: #888;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-wkend-start,',
|
||||
'.blocklyWidgetDiv .goog-date-picker-wkend-end {',
|
||||
' background: #eee;',
|
||||
'}',
|
||||
|
||||
/** Use td.className instead of !important */
|
||||
'.blocklyWidgetDiv td.goog-date-picker-selected {',
|
||||
' background: #c3d9ff;',
|
||||
'}',
|
||||
|
||||
'.blocklyWidgetDiv .goog-date-picker-today {',
|
||||
' background: #9ab;',
|
||||
' font-weight: bold !important;',
|
||||
' border-color: #246 #9bd #9bd #246;',
|
||||
' color: #fff;',
|
||||
'.blocklyDatePicker button:hover,',
|
||||
'.blocklyDatePicker .goog-date-picker-date:hover {',
|
||||
' background-color: rgb(218, 220, 224, .5);',
|
||||
'}'
|
||||
];
|
||||
|
||||
|
||||
+153
-178
@@ -28,25 +28,28 @@
|
||||
|
||||
goog.provide('Blockly.FieldDropdown');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.string');
|
||||
goog.require('Blockly.utils.uiMenu');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.ui.Menu');
|
||||
goog.require('goog.ui.MenuItem');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an editable dropdown field.
|
||||
* @param {(!Array.<!Array>|!Function)} menuGenerator An array of options
|
||||
* for a dropdown list, or a function which generates these options.
|
||||
* @param {Function=} opt_validator A function that is executed when a new
|
||||
* option is selected, with the newly selected value as its sole argument.
|
||||
* If it returns a value, that value (which must be one of the options) will
|
||||
* become selected in place of the newly selected option, unless the return
|
||||
* value is null, in which case the change is aborted.
|
||||
* @param {Function=} opt_validator A function that is called to validate
|
||||
* changes to the field's value. Takes in a language-neutral dropdown
|
||||
* option & returns a validated language-neutral dropdown option, or null to
|
||||
* abort the change.
|
||||
* @extends {Blockly.Field}
|
||||
* @constructor
|
||||
*/
|
||||
@@ -76,6 +79,14 @@ Blockly.FieldDropdown.fromJson = function(options) {
|
||||
return new Blockly.FieldDropdown(options['options']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.SERIALIZABLE = true;
|
||||
|
||||
/**
|
||||
* Horizontal distance that a checkmark overhangs the dropdown.
|
||||
*/
|
||||
@@ -86,23 +97,24 @@ Blockly.FieldDropdown.CHECKMARK_OVERHANG = 25;
|
||||
*/
|
||||
Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH = 0.45;
|
||||
|
||||
/**
|
||||
* Used to position the imageElement_ correctly.
|
||||
* @type {number}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldDropdown.IMAGE_Y_OFFSET = 5;
|
||||
|
||||
/**
|
||||
* Android can't (in 2014) display "▾", so use "▼" instead.
|
||||
*/
|
||||
Blockly.FieldDropdown.ARROW_CHAR = goog.userAgent.ANDROID ? '\u25BC' : '\u25BE';
|
||||
Blockly.FieldDropdown.ARROW_CHAR =
|
||||
Blockly.utils.userAgent.ANDROID ? '\u25BC' : '\u25BE';
|
||||
|
||||
/**
|
||||
* Mouse cursor style when over the hotspot that initiates the editor.
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.CURSOR = 'default';
|
||||
|
||||
/**
|
||||
* Language-neutral currently selected string or image object.
|
||||
* @type {string|!Object}
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.value_ = '';
|
||||
|
||||
/**
|
||||
* SVG image element if currently selected option is an image, or null.
|
||||
* @type {SVGElement}
|
||||
@@ -119,20 +131,27 @@ Blockly.FieldDropdown.prototype.imageElement_ = null;
|
||||
Blockly.FieldDropdown.prototype.imageJson_ = null;
|
||||
|
||||
/**
|
||||
* Install this dropdown on a block.
|
||||
* Create the block UI for this dropdown.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.init = function() {
|
||||
if (this.fieldGroup_) {
|
||||
// Dropdown has already been initialized once.
|
||||
return;
|
||||
}
|
||||
// Add dropdown arrow: "option ▾" (LTR) or "▾ אופציה" (RTL)
|
||||
this.arrow_ = Blockly.utils.createSvgElement('tspan', {}, null);
|
||||
this.arrow_.appendChild(document.createTextNode(this.sourceBlock_.RTL ?
|
||||
Blockly.FieldDropdown.prototype.initView = function() {
|
||||
Blockly.FieldDropdown.superClass_.initView.call(this);
|
||||
|
||||
this.imageElement_ = Blockly.utils.dom.createSvgElement( 'image',
|
||||
{
|
||||
'y': Blockly.FieldDropdown.IMAGE_Y_OFFSET
|
||||
}, this.fieldGroup_);
|
||||
|
||||
this.arrow_ = Blockly.utils.dom.createSvgElement('tspan', {}, this.textElement_);
|
||||
this.arrow_.appendChild(document.createTextNode(
|
||||
this.sourceBlock_.RTL ?
|
||||
Blockly.FieldDropdown.ARROW_CHAR + ' ' :
|
||||
' ' + Blockly.FieldDropdown.ARROW_CHAR));
|
||||
|
||||
Blockly.FieldDropdown.superClass_.init.call(this);
|
||||
if (this.sourceBlock_.RTL) {
|
||||
this.textElement_.insertBefore(this.arrow_, this.textContent_);
|
||||
} else {
|
||||
this.textElement_.appendChild(this.arrow_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -140,42 +159,32 @@ Blockly.FieldDropdown.prototype.init = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.showEditor_ = function() {
|
||||
Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, null);
|
||||
var menu = this.createMenu_();
|
||||
this.addActionListener_(menu);
|
||||
this.positionMenu_(menu);
|
||||
Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL,
|
||||
this.widgetDispose_.bind(this));
|
||||
this.menu_ = this.widgetCreate_();
|
||||
|
||||
this.menu_.render(Blockly.WidgetDiv.DIV);
|
||||
// Element gets created in render.
|
||||
Blockly.utils.dom.addClass(this.menu_.getElement(), 'blocklyDropdownMenu');
|
||||
|
||||
this.positionMenu_(this.menu_);
|
||||
|
||||
// Focusing needs to be handled after the menu is rendered and positioned.
|
||||
// Otherwise it will cause a page scroll to get the misplaced menu in
|
||||
// view. See issue #1329.
|
||||
this.menu_.setAllowAutoFocus(true);
|
||||
this.menu_.getElement().focus();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a listener for mouse and keyboard events in the menu and its items.
|
||||
* @param {!goog.ui.Menu} menu The menu to add listeners to.
|
||||
* Create the dropdown editor widget.
|
||||
* @return {goog.ui.Menu} The newly created dropdown menu.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.addActionListener_ = function(menu) {
|
||||
var thisField = this;
|
||||
|
||||
function callback(e) {
|
||||
var menu = this;
|
||||
var menuItem = e.target;
|
||||
if (menuItem) {
|
||||
thisField.onItemSelected(menu, menuItem);
|
||||
}
|
||||
Blockly.WidgetDiv.hideIfOwner(thisField);
|
||||
Blockly.Events.setGroup(false);
|
||||
}
|
||||
// Listen for mouse/keyboard events.
|
||||
goog.events.listen(menu, goog.ui.Component.EventType.ACTION, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create and populate the menu and menu items for this dropdown, based on
|
||||
* the options list.
|
||||
* @return {!goog.ui.Menu} The populated dropdown menu.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.createMenu_ = function() {
|
||||
Blockly.FieldDropdown.prototype.widgetCreate_ = function() {
|
||||
var menu = new goog.ui.Menu();
|
||||
menu.setRightToLeft(this.sourceBlock_.RTL);
|
||||
|
||||
var options = this.getOptions();
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
var content = options[i][0]; // Human-readable text or image.
|
||||
@@ -194,9 +203,35 @@ Blockly.FieldDropdown.prototype.createMenu_ = function() {
|
||||
menu.addChild(menuItem, true);
|
||||
menuItem.setChecked(value == this.value_);
|
||||
}
|
||||
|
||||
this.menuActionEventKey_ = goog.events.listen(
|
||||
menu,
|
||||
goog.ui.Component.EventType.ACTION,
|
||||
this.handleMenuActionEvent_,
|
||||
false,
|
||||
this);
|
||||
|
||||
return menu;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of events belonging to the dropdown editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.widgetDispose_ = function() {
|
||||
goog.events.unlistenByKey(this.menuActionEventKey_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle an ACTION event in the dropdown menu.
|
||||
* @param {!Event} event The CHANGE event.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.handleMenuActionEvent_ = function(event) {
|
||||
Blockly.WidgetDiv.hideIfOwner(this);
|
||||
this.onItemSelected(this.menu_, event.target);
|
||||
};
|
||||
|
||||
/**
|
||||
* Place the menu correctly on the screen, taking into account the dimensions
|
||||
* of the menu and the dimensions of the screen so that it doesn't run off any
|
||||
@@ -205,11 +240,9 @@ Blockly.FieldDropdown.prototype.createMenu_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.positionMenu_ = function(menu) {
|
||||
// Record viewport dimensions before adding the dropdown.
|
||||
var viewportBBox = Blockly.utils.getViewportBBox();
|
||||
var anchorBBox = this.getAnchorDimensions_();
|
||||
|
||||
this.createWidget_(menu);
|
||||
var menuSize = Blockly.utils.uiMenu.getSize(menu);
|
||||
|
||||
var menuMaxHeightPx = Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH
|
||||
@@ -221,26 +254,8 @@ Blockly.FieldDropdown.prototype.positionMenu_ = function(menu) {
|
||||
if (this.sourceBlock_.RTL) {
|
||||
Blockly.utils.uiMenu.adjustBBoxesForRTL(viewportBBox, anchorBBox, menuSize);
|
||||
}
|
||||
// Position the menu.
|
||||
Blockly.WidgetDiv.positionWithAnchor(viewportBBox, anchorBBox, menuSize,
|
||||
this.sourceBlock_.RTL);
|
||||
// Calling menuDom.focus() has to wait until after the menu has been placed
|
||||
// correctly. Otherwise it will cause a page scroll to get the misplaced menu
|
||||
// in view. See issue #1329.
|
||||
menu.getElement().focus();
|
||||
};
|
||||
|
||||
/**
|
||||
* Create and render the menu widget inside Blockly's widget div.
|
||||
* @param {!goog.ui.Menu} menu The menu to add to the widget div.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.createWidget_ = function(menu) {
|
||||
var div = Blockly.WidgetDiv.DIV;
|
||||
menu.render(div);
|
||||
Blockly.utils.addClass(menu.getElement(), 'blocklyDropdownMenu');
|
||||
// Enable autofocus after the initial render to avoid issue #1329.
|
||||
menu.setAllowAutoFocus(true);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -270,14 +285,7 @@ Blockly.FieldDropdown.prototype.getAnchorDimensions_ = function() {
|
||||
* @param {!goog.ui.MenuItem} menuItem The MenuItem selected within menu.
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.onItemSelected = function(menu, menuItem) {
|
||||
var value = menuItem.getValue();
|
||||
if (this.sourceBlock_) {
|
||||
// Call any validation function, and allow it to override.
|
||||
value = this.callValidator(value);
|
||||
}
|
||||
if (value !== null) {
|
||||
this.setValue(value);
|
||||
}
|
||||
this.setValue(menuItem.getValue());
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -313,9 +321,9 @@ Blockly.FieldDropdown.prototype.trimOptions_ = function() {
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
strings.push(options[i][0]);
|
||||
}
|
||||
var shortest = Blockly.utils.shortestStringLength(strings);
|
||||
var prefixLength = Blockly.utils.commonWordPrefix(strings, shortest);
|
||||
var suffixLength = Blockly.utils.commonWordSuffix(strings, shortest);
|
||||
var shortest = Blockly.utils.string.shortestStringLength(strings);
|
||||
var prefixLength = Blockly.utils.string.commonWordPrefix(strings, shortest);
|
||||
var suffixLength = Blockly.utils.string.commonWordSuffix(strings, shortest);
|
||||
if (!prefixLength && !suffixLength) {
|
||||
return;
|
||||
}
|
||||
@@ -380,32 +388,43 @@ Blockly.FieldDropdown.prototype.getOptions = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the language-neutral value from this dropdown menu.
|
||||
* @return {string} Current text.
|
||||
* Ensure that the input value is a valid language-neutral option.
|
||||
* @param {string=} newValue The input value.
|
||||
* @return {?string} A valid language-neutral option, or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.getValue = function() {
|
||||
return this.value_;
|
||||
Blockly.FieldDropdown.prototype.doClassValidation_ = function(newValue) {
|
||||
var isValueValid = false;
|
||||
var options = this.getOptions();
|
||||
for (var i = 0, option; option = options[i]; i++) {
|
||||
// Options are tuples of human-readable text and language-neutral values.
|
||||
if (option[1] == newValue) {
|
||||
isValueValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValueValid) {
|
||||
if (this.sourceBlock_) {
|
||||
console.warn('Cannot set the dropdown\'s value to an unavailable option.' +
|
||||
' Block type: ' + this.sourceBlock_.type + ', Field name: ' + this.name +
|
||||
', Value: ' + newValue);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return newValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the language-neutral value for this dropdown menu.
|
||||
* @param {string} newValue New value to set.
|
||||
* Update the value of this dropdown field.
|
||||
* @param {string} newValue The new language-enutral value.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.setValue = function(newValue) {
|
||||
if (newValue === null || (newValue === this.value_ && this.text_)) {
|
||||
return; // No change if null and text_ was initialized.
|
||||
}
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, this.value_, newValue));
|
||||
}
|
||||
this.value_ = newValue;
|
||||
// Look up and display the human-readable text.
|
||||
Blockly.FieldDropdown.prototype.doValueUpdate_ = function(newValue) {
|
||||
Blockly.FieldDropdown.superClass_.doValueUpdate_.call(this, newValue);
|
||||
var options = this.getOptions();
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
// Options are tuples of human-readable text and language-neutral values.
|
||||
if (options[i][1] == newValue) {
|
||||
var content = options[i][0];
|
||||
for (var i = 0, option; option = options[i]; i++) {
|
||||
if (option[1] == this.value_) {
|
||||
var content = option[0];
|
||||
if (typeof content == 'object') {
|
||||
this.imageJson_ = content;
|
||||
this.text_ = content.alt;
|
||||
@@ -413,15 +432,23 @@ Blockly.FieldDropdown.prototype.setValue = function(newValue) {
|
||||
this.imageJson_ = null;
|
||||
this.text_ = content;
|
||||
}
|
||||
// Always rerender if either the value or the text has changed.
|
||||
this.forceRerender();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Value not found. Add it, maybe it will become valid once set
|
||||
// (like variable names).
|
||||
this.text_ = newValue;
|
||||
this.forceRerender();
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the dropdown arrow to match the colour/style of the block.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.updateColour = function() {
|
||||
// Update arrow's colour.
|
||||
if (this.sourceBlock_ && this.arrow_) {
|
||||
if (this.sourceBlock_.isShadow()) {
|
||||
this.arrow_.style.fill = this.sourceBlock_.getColourShadow();
|
||||
} else {
|
||||
this.arrow_.style.fill = this.sourceBlock_.getColour();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -429,23 +456,11 @@ Blockly.FieldDropdown.prototype.setValue = function(newValue) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.render_ = function() {
|
||||
if (!this.visible_) {
|
||||
this.size_.width = 0;
|
||||
return;
|
||||
}
|
||||
if (this.sourceBlock_ && this.arrow_) {
|
||||
// Update arrow's colour.
|
||||
this.arrow_.style.fill = this.sourceBlock_.getColour();
|
||||
}
|
||||
var child;
|
||||
while ((child = this.textElement_.firstChild)) {
|
||||
this.textElement_.removeChild(child);
|
||||
}
|
||||
if (this.imageElement_) {
|
||||
Blockly.utils.removeNode(this.imageElement_);
|
||||
this.imageElement_ = null;
|
||||
}
|
||||
// Hide both elements.
|
||||
this.textContent_.nodeValue = '';
|
||||
this.imageElement_.style.display = 'none';
|
||||
|
||||
// Show correct element.
|
||||
if (this.imageJson_) {
|
||||
this.renderSelectedImage_();
|
||||
} else {
|
||||
@@ -461,20 +476,19 @@ Blockly.FieldDropdown.prototype.render_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.renderSelectedImage_ = function() {
|
||||
// Image option is selected.
|
||||
this.imageElement_ = Blockly.utils.createSvgElement('image',
|
||||
{
|
||||
'y': 5,
|
||||
'height': this.imageJson_.height + 'px',
|
||||
'width': this.imageJson_.width + 'px'
|
||||
}, this.fieldGroup_);
|
||||
this.imageElement_.style.display = '';
|
||||
this.imageElement_.setAttributeNS(
|
||||
'http://www.w3.org/1999/xlink', 'xlink:href', this.imageJson_.src);
|
||||
// Insert dropdown arrow.
|
||||
this.textElement_.appendChild(this.arrow_);
|
||||
Blockly.utils.dom.XLINK_NS, 'xlink:href', this.imageJson_.src);
|
||||
this.imageElement_.setAttribute('height', this.imageJson_.height);
|
||||
this.imageElement_.setAttribute('width', this.imageJson_.width);
|
||||
|
||||
var arrowWidth = Blockly.Field.getCachedWidth(this.arrow_);
|
||||
// TODO: Standardize sizing, need to talk to rachel and abby about rendering
|
||||
// redux.
|
||||
// I think really this means plus 10?
|
||||
this.size_.height = Number(this.imageJson_.height) + 19;
|
||||
this.size_.width = Number(this.imageJson_.width) + arrowWidth;
|
||||
|
||||
if (this.sourceBlock_.RTL) {
|
||||
this.imageElement_.setAttribute('x', arrowWidth);
|
||||
this.textElement_.setAttribute('x', -1);
|
||||
@@ -489,52 +503,13 @@ Blockly.FieldDropdown.prototype.renderSelectedImage_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.renderSelectedText_ = function() {
|
||||
// Text option is selected.
|
||||
// Replace the text.
|
||||
var textNode = document.createTextNode(this.getDisplayText_());
|
||||
this.textElement_.appendChild(textNode);
|
||||
// Insert dropdown arrow.
|
||||
if (this.sourceBlock_.RTL) {
|
||||
this.textElement_.insertBefore(this.arrow_, this.textElement_.firstChild);
|
||||
} else {
|
||||
this.textElement_.appendChild(this.arrow_);
|
||||
}
|
||||
this.textContent_.nodeValue = this.getDisplayText_();
|
||||
this.textElement_.setAttribute('text-anchor', 'start');
|
||||
this.textElement_.setAttribute('x', 0);
|
||||
|
||||
this.size_.height = Blockly.BlockSvg.MIN_BLOCK_Y;
|
||||
this.size_.width = Blockly.Field.getCachedWidth(this.textElement_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the width of the field. Overrides field.prototype.updateWidth to
|
||||
* deal with image selections on IE and Edge. If the selected item is not an
|
||||
* image, or if the browser is not IE / Edge, this simply calls the parent
|
||||
* implementation.
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.updateWidth = function() {
|
||||
if (this.imageJson_ && (goog.userAgent.IE || goog.userAgent.EDGE)) {
|
||||
// Recalculate the full width.
|
||||
var arrowWidth = Blockly.Field.getCachedWidth(this.arrow_);
|
||||
var width = Number(this.imageJson_.width) + arrowWidth +
|
||||
Blockly.BlockSvg.SEP_SPACE_X;
|
||||
if (this.borderRect_) {
|
||||
this.borderRect_.setAttribute('width', width);
|
||||
}
|
||||
this.size_.width = width;
|
||||
} else {
|
||||
Blockly.Field.prototype.updateWidth.call(this);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Close the dropdown menu if this input is being deleted.
|
||||
*/
|
||||
Blockly.FieldDropdown.prototype.dispose = function() {
|
||||
Blockly.WidgetDiv.hideIfOwner(this);
|
||||
Blockly.FieldDropdown.superClass_.dispose.call(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates the data structure to be processed as an options list.
|
||||
* @param {?} options The proposed dropdown options.
|
||||
|
||||
+54
-109
@@ -27,16 +27,18 @@
|
||||
goog.provide('Blockly.FieldImage');
|
||||
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
goog.require('goog.math.Size');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an image on a block.
|
||||
* @param {string} src The URL of the image.
|
||||
* @param {number} width Width of the image.
|
||||
* @param {number} height Height of the image.
|
||||
* @param {string=} src The URL of the image. Defaults to an empty string.
|
||||
* @param {!(string|number)} width Width of the image.
|
||||
* @param {!(string|number)} height Height of the image.
|
||||
* @param {string=} opt_alt Optional alt text for when block is collapsed.
|
||||
* @param {Function=} opt_onClick Optional function to be called when the image
|
||||
* is clicked. If opt_onClick is defined, opt_alt must also be defined.
|
||||
@@ -48,15 +50,25 @@ Blockly.FieldImage = function(src, width, height,
|
||||
opt_alt, opt_onClick, opt_flipRtl) {
|
||||
this.sourceBlock_ = null;
|
||||
|
||||
|
||||
if (isNaN(height) || isNaN(width)) {
|
||||
throw Error('Height and width values of an image field must cast to' +
|
||||
' numbers.');
|
||||
}
|
||||
|
||||
// Ensure height and width are numbers. Strings are bad at math.
|
||||
this.height_ = Number(height);
|
||||
this.width_ = Number(width);
|
||||
if (this.height_ <= 0 || this.width_ <= 0) {
|
||||
throw Error('Height and width values of an image field must be greater' +
|
||||
' than 0.');
|
||||
}
|
||||
this.size_ = new goog.math.Size(this.width_,
|
||||
this.height_ + 2 * Blockly.BlockSvg.INLINE_PADDING_Y);
|
||||
|
||||
this.flipRtl_ = opt_flipRtl;
|
||||
this.tooltip_ = '';
|
||||
this.setValue(src);
|
||||
this.setText(opt_alt);
|
||||
this.text_ = opt_alt || '';
|
||||
this.setValue(src || '');
|
||||
|
||||
if (typeof opt_onClick == 'function') {
|
||||
this.clickHandler_ = opt_onClick;
|
||||
@@ -84,106 +96,62 @@ Blockly.FieldImage.fromJson = function(options) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Editable fields are saved by the XML renderer, non-editable fields are not.
|
||||
* Editable fields usually show some sort of UI indicating they are
|
||||
* editable. This field should not.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldImage.prototype.EDITABLE = false;
|
||||
|
||||
/**
|
||||
* Install this image on a block.
|
||||
* Used to tell if the field needs to be rendered the next time the block is
|
||||
* rendered. Image fields are statically sized, and only need to be
|
||||
* rendered at initialization.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldImage.prototype.init = function() {
|
||||
if (this.fieldGroup_) {
|
||||
// Image has already been initialized once.
|
||||
return;
|
||||
}
|
||||
// Build the DOM.
|
||||
/** @type {SVGElement} */
|
||||
this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null);
|
||||
if (!this.visible_) {
|
||||
this.fieldGroup_.style.display = 'none';
|
||||
}
|
||||
/** @type {SVGElement} */
|
||||
this.imageElement_ = Blockly.utils.createSvgElement(
|
||||
Blockly.FieldImage.prototype.isDirty_ = false;
|
||||
|
||||
/**
|
||||
* Create the block UI for this image.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldImage.prototype.initView = function() {
|
||||
this.imageElement_ = Blockly.utils.dom.createSvgElement(
|
||||
'image',
|
||||
{
|
||||
'height': this.height_ + 'px',
|
||||
'width': this.width_ + 'px'
|
||||
'width': this.width_ + 'px',
|
||||
'alt': this.text_
|
||||
},
|
||||
this.fieldGroup_);
|
||||
this.setValue(this.src_);
|
||||
this.setText(this.text_);
|
||||
this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_);
|
||||
|
||||
if (this.tooltip_) {
|
||||
this.imageElement_.tooltip = this.tooltip_;
|
||||
} else {
|
||||
// Configure the field to be transparent with respect to tooltips.
|
||||
this.setTooltip(this.sourceBlock_);
|
||||
}
|
||||
Blockly.Tooltip.bindMouseEvents(this.imageElement_);
|
||||
|
||||
this.maybeAddClickHandler_();
|
||||
this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,
|
||||
'xlink:href', this.value_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of all DOM objects belonging to this text.
|
||||
* Ensure that the input value (the source URL) is a string.
|
||||
* @param {string=} newValue The input value
|
||||
* @return {?string} A string, or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldImage.prototype.dispose = function() {
|
||||
if (this.fieldGroup_) {
|
||||
Blockly.utils.removeNode(this.fieldGroup_);
|
||||
this.fieldGroup_ = null;
|
||||
Blockly.FieldImage.prototype.doClassValidation_ = function(newValue) {
|
||||
if (typeof newValue != 'string') {
|
||||
return null;
|
||||
}
|
||||
this.imageElement_ = null;
|
||||
return newValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind events for a mouse down on the image, but only if a click handler has
|
||||
* been defined.
|
||||
* @private
|
||||
* Update the value of this image field, and update the displayed image.
|
||||
* @param {string} newValue The new image src.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldImage.prototype.maybeAddClickHandler_ = function() {
|
||||
if (this.clickHandler_) {
|
||||
this.mouseDownWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
this.fieldGroup_, 'mousedown', this, this.clickHandler_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.FieldImage.prototype.setTooltip = function(newTip) {
|
||||
this.tooltip_ = newTip;
|
||||
Blockly.FieldImage.prototype.doValueUpdate_ = function(newValue) {
|
||||
this.value_ = newValue;
|
||||
if (this.imageElement_) {
|
||||
this.imageElement_.tooltip = newTip;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the source URL of this image.
|
||||
* @return {string} Current text.
|
||||
* @override
|
||||
*/
|
||||
Blockly.FieldImage.prototype.getValue = function() {
|
||||
return this.src_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the source URL of this image.
|
||||
* @param {?string} src New source.
|
||||
* @override
|
||||
*/
|
||||
Blockly.FieldImage.prototype.setValue = function(src) {
|
||||
if (src === null) {
|
||||
// No change if null.
|
||||
return;
|
||||
}
|
||||
this.src_ = src;
|
||||
if (this.imageElement_) {
|
||||
this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink',
|
||||
'xlink:href', src || '');
|
||||
this.imageElement_.setAttributeNS(Blockly.utils.dom.XLINK_NS,
|
||||
'xlink:href', this.value_ || '');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -211,29 +179,6 @@ Blockly.FieldImage.prototype.setText = function(alt) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Images are fixed width, no need to render.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldImage.prototype.render_ = function() {
|
||||
// NOP
|
||||
};
|
||||
|
||||
/**
|
||||
* Images are fixed width, no need to render even if forced.
|
||||
*/
|
||||
Blockly.FieldImage.prototype.forceRerender = function() {
|
||||
// NOP
|
||||
};
|
||||
|
||||
/**
|
||||
* Images are fixed width, no need to update.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldImage.prototype.updateWidth = function() {
|
||||
// NOP
|
||||
};
|
||||
|
||||
/**
|
||||
* If field click is called, and click handler defined,
|
||||
* call the handler.
|
||||
|
||||
+30
-57
@@ -19,7 +19,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Non-editable text field. Used for titles, labels, etc.
|
||||
* @fileoverview Non-editable, non-serializable text field. Used for titles,
|
||||
* labels, etc.
|
||||
* @author fraser@google.com (Neil Fraser)
|
||||
*/
|
||||
'use strict';
|
||||
@@ -29,22 +30,27 @@ goog.provide('Blockly.FieldLabel');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
goog.require('goog.math.Size');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a non-editable field.
|
||||
* @param {string} text The initial content of the field.
|
||||
* Class for a non-editable, non-serializable text field.
|
||||
* @param {string=} opt_value The initial value of the field. Should cast to a
|
||||
* string. Defaults to an empty string if null or undefined.
|
||||
* @param {string=} opt_class Optional CSS class for the field's text.
|
||||
* @extends {Blockly.Field}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.FieldLabel = function(text, opt_class) {
|
||||
Blockly.FieldLabel = function(opt_value, opt_class) {
|
||||
this.size_ = new goog.math.Size(0, 17.5);
|
||||
this.class_ = opt_class;
|
||||
this.setValue(text);
|
||||
this.tooltip_ = '';
|
||||
opt_value = this.doClassValidation_(opt_value);
|
||||
if (opt_value === null) {
|
||||
opt_value = '';
|
||||
}
|
||||
this.setValue(opt_value);
|
||||
};
|
||||
goog.inherits(Blockly.FieldLabel, Blockly.Field);
|
||||
|
||||
@@ -62,69 +68,36 @@ Blockly.FieldLabel.fromJson = function(options) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Editable fields are saved by the XML renderer, non-editable fields are not.
|
||||
* Editable fields usually show some sort of UI indicating they are
|
||||
* editable. This field should not.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldLabel.prototype.EDITABLE = false;
|
||||
|
||||
/**
|
||||
* Install this text on a block.
|
||||
* Create block UI for this label.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FieldLabel.prototype.init = function() {
|
||||
if (this.textElement_) {
|
||||
// Text has already been initialized once.
|
||||
return;
|
||||
}
|
||||
// Build the DOM.
|
||||
this.textElement_ = Blockly.utils.createSvgElement('text',
|
||||
{'class': 'blocklyText', 'y': this.size_.height - 5}, null);
|
||||
Blockly.FieldLabel.prototype.initView = function() {
|
||||
this.createTextElement_();
|
||||
this.textElement_.setAttribute('y', this.size_.height - 5);
|
||||
if (this.class_) {
|
||||
Blockly.utils.addClass(this.textElement_, this.class_);
|
||||
}
|
||||
if (!this.visible_) {
|
||||
this.textElement_.style.display = 'none';
|
||||
}
|
||||
this.sourceBlock_.getSvgRoot().appendChild(this.textElement_);
|
||||
|
||||
if (this.tooltip_) {
|
||||
this.textElement_.tooltip = this.tooltip_;
|
||||
} else {
|
||||
// Configure the field to be transparent with respect to tooltips.
|
||||
this.textElement_.tooltip = this.sourceBlock_;
|
||||
}
|
||||
Blockly.Tooltip.bindMouseEvents(this.textElement_);
|
||||
// Force a render.
|
||||
this.render_();
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of all DOM objects belonging to this text.
|
||||
*/
|
||||
Blockly.FieldLabel.prototype.dispose = function() {
|
||||
if (this.textElement_) {
|
||||
Blockly.utils.removeNode(this.textElement_);
|
||||
this.textElement_ = null;
|
||||
Blockly.utils.dom.addClass(this.textElement_, this.class_);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the group element for this field.
|
||||
* Used for measuring the size and for positioning.
|
||||
* @return {!Element} The group element.
|
||||
* Ensure that the input value casts to a valid string.
|
||||
* @param {string=} newValue The input value.
|
||||
* @return {?string} A valid string, or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldLabel.prototype.getSvgRoot = function() {
|
||||
return /** @type {!Element} */ (this.textElement_);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.FieldLabel.prototype.setTooltip = function(newTip) {
|
||||
this.tooltip_ = newTip;
|
||||
if (this.textElement_) {
|
||||
this.textElement_.tooltip = newTip;
|
||||
Blockly.FieldLabel.prototype.doClassValidation_ = function(newValue) {
|
||||
if (newValue === null || newValue === undefined) {
|
||||
return null;
|
||||
}
|
||||
return String(newValue);
|
||||
};
|
||||
|
||||
Blockly.Field.register('field_label', Blockly.FieldLabel);
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @license
|
||||
* Visual Blocks Editor
|
||||
*
|
||||
* Copyright 2019 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 Non-editable, serializable text field. Behaves like a
|
||||
* normal label but is serialized to XML. It may only be
|
||||
* edited programmatically.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.FieldLabelSerializable');
|
||||
|
||||
goog.require('Blockly.FieldLabel');
|
||||
goog.require('Blockly.utils');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a non-editable, serializable text field.
|
||||
* @param {*} opt_value The initial value of the field. Should cast to a
|
||||
* string. Defaults to an empty string if null or undefined.
|
||||
* @param {string=} opt_class Optional CSS class for the field's text.
|
||||
* @extends {Blockly.FieldLabel}
|
||||
* @constructor
|
||||
*
|
||||
*/
|
||||
Blockly.FieldLabelSerializable = function(opt_value, opt_class) {
|
||||
Blockly.FieldLabelSerializable.superClass_.constructor.call(this, opt_value,
|
||||
opt_class);
|
||||
};
|
||||
goog.inherits(Blockly.FieldLabelSerializable, Blockly.FieldLabel);
|
||||
|
||||
/**
|
||||
* Construct a FieldLabelSerializable from a JSON arg object,
|
||||
* dereferencing any string table references.
|
||||
* @param {!Object} options A JSON object with options (text, and class).
|
||||
* @returns {!Blockly.FieldLabelSerializable} The new field instance.
|
||||
* @package
|
||||
* @nocollapse
|
||||
*/
|
||||
Blockly.FieldLabelSerializable.fromJson = function(options) {
|
||||
var text = Blockly.utils.replaceMessageReferences(options['text']);
|
||||
return new Blockly.FieldLabelSerializable(text, options['class']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Editable fields usually show some sort of UI indicating they are
|
||||
* editable. This field should not.
|
||||
* @type {boolean}
|
||||
* @public
|
||||
*/
|
||||
Blockly.FieldLabelSerializable.prototype.EDITABLE = false;
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. This field should be serialized, but only edited programmatically.
|
||||
* @type {boolean}
|
||||
* @public
|
||||
*/
|
||||
Blockly.FieldLabelSerializable.prototype.SERIALIZABLE = true;
|
||||
|
||||
Blockly.Field.register(
|
||||
'field_label_serializable', Blockly.FieldLabelSerializable);
|
||||
+43
-22
@@ -31,24 +31,25 @@ goog.require('Blockly.FieldTextInput');
|
||||
|
||||
/**
|
||||
* Class for an editable number field.
|
||||
* @param {(string|number)=} opt_value The initial content of the field.
|
||||
* The value should cast to a number, and if it does not, '0' will be used.
|
||||
* @param {string|number=} opt_value The initial value of the field. Should cast
|
||||
* to a number. Defaults to 0.
|
||||
* @param {(string|number)=} opt_min Minimum value.
|
||||
* @param {(string|number)=} opt_max Maximum value.
|
||||
* @param {(string|number)=} opt_precision Precision for value.
|
||||
* @param {Function=} opt_validator An optional function that is called
|
||||
* to validate any constraints on what the user entered. Takes the new
|
||||
* text as an argument and returns either the accepted text, a replacement
|
||||
* text, or null to abort the change.
|
||||
* @extends {Blockly.FieldTextInput}
|
||||
* @param {Function=} opt_validator A function that is called to validate
|
||||
* changes to the field's value. Takes in a number & returns a validated
|
||||
* number, or null to abort the change.
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.FieldNumber = function(opt_value, opt_min, opt_max, opt_precision,
|
||||
opt_validator) {
|
||||
opt_value = (opt_value && !isNaN(opt_value)) ? String(opt_value) : '0';
|
||||
this.setConstraints(opt_min, opt_max, opt_precision);
|
||||
opt_value = this.doClassValidation_(opt_value);
|
||||
if (opt_value === null) {
|
||||
opt_value = 0;
|
||||
}
|
||||
Blockly.FieldNumber.superClass_.constructor.call(
|
||||
this, opt_value, opt_validator);
|
||||
this.setConstraints(opt_min, opt_max, opt_precision);
|
||||
};
|
||||
goog.inherits(Blockly.FieldNumber, Blockly.FieldTextInput);
|
||||
|
||||
@@ -65,6 +66,14 @@ Blockly.FieldNumber.fromJson = function(options) {
|
||||
options['min'], options['max'], options['precision']);
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldNumber.prototype.SERIALIZABLE = true;
|
||||
|
||||
/**
|
||||
* Set the maximum, minimum and precision constraints on this field.
|
||||
* Any of these properties may be undefiend or NaN to be disabled.
|
||||
@@ -79,40 +88,52 @@ Blockly.FieldNumber.fromJson = function(options) {
|
||||
Blockly.FieldNumber.prototype.setConstraints = function(min, max, precision) {
|
||||
precision = parseFloat(precision);
|
||||
this.precision_ = isNaN(precision) ? 0 : precision;
|
||||
var precisionString = this.precision_.toString();
|
||||
var decimalIndex = precisionString.indexOf('.');
|
||||
this.fractionalDigits_ = (decimalIndex == -1) ? -1 :
|
||||
precisionString.length - (decimalIndex + 1);
|
||||
min = parseFloat(min);
|
||||
this.min_ = isNaN(min) ? -Infinity : min;
|
||||
max = parseFloat(max);
|
||||
this.max_ = isNaN(max) ? Infinity : max;
|
||||
this.setValue(this.callValidator(this.getValue()));
|
||||
this.setValue(this.getValue());
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure that only a number in the correct range may be entered.
|
||||
* @param {string} text The user's text.
|
||||
* @return {?string} A string representing a valid number, or null if invalid.
|
||||
* Ensure that the input value is a valid number (must fulfill the
|
||||
* constraints placed on the field).
|
||||
* @param {string|number=} newValue The input value.
|
||||
* @return {?number} A valid number, or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldNumber.prototype.classValidator = function(text) {
|
||||
if (text === null) {
|
||||
Blockly.FieldNumber.prototype.doClassValidation_ = function(newValue) {
|
||||
if (newValue === null || newValue === undefined) {
|
||||
return null;
|
||||
}
|
||||
text = String(text);
|
||||
// Clean up text.
|
||||
newValue = String(newValue);
|
||||
// TODO: Handle cases like 'ten', '1.203,14', etc.
|
||||
// 'O' is sometimes mistaken for '0' by inexperienced users.
|
||||
text = text.replace(/O/ig, '0');
|
||||
newValue = newValue.replace(/O/ig, '0');
|
||||
// Strip out thousands separators.
|
||||
text = text.replace(/,/g, '');
|
||||
var n = parseFloat(text || 0);
|
||||
newValue = newValue.replace(/,/g, '');
|
||||
|
||||
// Clean up number.
|
||||
var n = parseFloat(newValue || 0);
|
||||
if (isNaN(n)) {
|
||||
// Invalid number.
|
||||
return null;
|
||||
}
|
||||
// Get the value in range.
|
||||
n = Math.min(Math.max(n, this.min_), this.max_);
|
||||
// Round to nearest multiple of precision.
|
||||
if (this.precision_ && isFinite(n)) {
|
||||
n = Math.round(n / this.precision_) * this.precision_;
|
||||
}
|
||||
// Get the value in range.
|
||||
n = Math.min(Math.max(n, this.min_), this.max_);
|
||||
return String(n);
|
||||
// Clean up floating point errors.
|
||||
n = (this.fractionalDigits_ == -1) ? n :
|
||||
Number(n.toFixed(this.fractionalDigits_));
|
||||
return n;
|
||||
};
|
||||
|
||||
Blockly.Field.register('field_number', Blockly.FieldNumber);
|
||||
|
||||
+174
-180
@@ -26,27 +26,32 @@
|
||||
|
||||
goog.provide('Blockly.FieldTextInput');
|
||||
|
||||
goog.require('Blockly.DropDownDiv');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.Field');
|
||||
goog.require('Blockly.Msg');
|
||||
goog.require('Blockly.utils');
|
||||
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('goog.userAgent');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* Class for an editable text field.
|
||||
* @param {string} text The initial content of the field.
|
||||
* @param {Function=} opt_validator An optional function that is called
|
||||
* to validate any constraints on what the user entered. Takes the new
|
||||
* text as an argument and returns either the accepted text, a replacement
|
||||
* text, or null to abort the change.
|
||||
* @param {string=} opt_value The initial value of the field. Should cast to a
|
||||
* string. Defaults to an empty string if null or undefined.
|
||||
* @param {Function=} opt_validator A function that is called to validate
|
||||
* changes to the field's value. Takes in a string & returns a validated
|
||||
* string, or null to abort the change.
|
||||
* @extends {Blockly.Field}
|
||||
* @constructor
|
||||
*/
|
||||
Blockly.FieldTextInput = function(text, opt_validator) {
|
||||
Blockly.FieldTextInput.superClass_.constructor.call(this, text,
|
||||
Blockly.FieldTextInput = function(opt_value, opt_validator) {
|
||||
opt_value = this.doClassValidation_(opt_value);
|
||||
if (opt_value === null) {
|
||||
opt_value = '';
|
||||
}
|
||||
Blockly.FieldTextInput.superClass_.constructor.call(this, opt_value,
|
||||
opt_validator);
|
||||
};
|
||||
goog.inherits(Blockly.FieldTextInput, Blockly.Field);
|
||||
@@ -62,26 +67,26 @@ goog.inherits(Blockly.FieldTextInput, Blockly.Field);
|
||||
*/
|
||||
Blockly.FieldTextInput.fromJson = function(options) {
|
||||
var text = Blockly.utils.replaceMessageReferences(options['text']);
|
||||
var field = new Blockly.FieldTextInput(text, options['class']);
|
||||
var field = new Blockly.FieldTextInput(text);
|
||||
if (typeof options['spellcheck'] === 'boolean') {
|
||||
field.setSpellcheck(options['spellcheck']);
|
||||
}
|
||||
return field;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.SERIALIZABLE = true;
|
||||
|
||||
/**
|
||||
* Point size of text. Should match blocklyText's font-size in CSS.
|
||||
*/
|
||||
Blockly.FieldTextInput.FONTSIZE = 11;
|
||||
|
||||
/**
|
||||
* The HTML input element for the user to type, or null if no FieldTextInput
|
||||
* editor is currently open.
|
||||
* @type {HTMLInputElement}
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldTextInput.htmlInput_ = null;
|
||||
|
||||
/**
|
||||
* Mouse cursor style when over the hotspot that initiates the editor.
|
||||
*/
|
||||
@@ -94,51 +99,74 @@ Blockly.FieldTextInput.prototype.CURSOR = 'text';
|
||||
Blockly.FieldTextInput.prototype.spellcheck_ = true;
|
||||
|
||||
/**
|
||||
* Close the input widget if this input is being deleted.
|
||||
* Ensure that the input value casts to a valid string.
|
||||
* @param {string=} newValue The input value.
|
||||
* @return {?string} A valid string, or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.dispose = function() {
|
||||
Blockly.WidgetDiv.hideIfOwner(this);
|
||||
Blockly.FieldTextInput.superClass_.dispose.call(this);
|
||||
Blockly.FieldTextInput.prototype.doClassValidation_ = function(newValue) {
|
||||
if (newValue === null || newValue === undefined) {
|
||||
return null;
|
||||
}
|
||||
return String(newValue);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the value of this field.
|
||||
* @param {?string} newValue New value.
|
||||
* @override
|
||||
* Called by setValue if the text input is not valid. If the field is
|
||||
* currently being edited it reverts value of the field to the previous
|
||||
* value while allowing the display text to be handled by the htmlInput_.
|
||||
* @param {*} _invalidValue The input value that was determined to be invalid.
|
||||
* This is not used by the text input because its display value is stored on
|
||||
* the htmlInput_.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.setValue = function(newValue) {
|
||||
if (newValue !== null) { // No change if null.
|
||||
if (this.sourceBlock_) {
|
||||
var validated = this.callValidator(newValue);
|
||||
// If the new value is invalid, validation returns null.
|
||||
// In this case we still want to display the illegal result.
|
||||
if (validated !== null) {
|
||||
newValue = validated;
|
||||
}
|
||||
Blockly.FieldTextInput.prototype.doValueInvalid_ = function(_invalidValue) {
|
||||
if (this.isBeingEdited_) {
|
||||
this.isTextValid_ = false;
|
||||
var oldValue = this.value_;
|
||||
// Revert value when the text becomes invalid.
|
||||
this.value_ = this.htmlInput_.untypedDefaultValue_;
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, oldValue, this.value_));
|
||||
}
|
||||
Blockly.Field.prototype.setValue.call(this, newValue);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the text in this field and fire a change event.
|
||||
* @param {*} newText New text.
|
||||
* Called by setValue if the text input is valid. Updates the value of the
|
||||
* field, and updates the text of the field if it is not currently being
|
||||
* edited (i.e. handled by the htmlInput_).
|
||||
* @param {string} newValue The new validated value of the field.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.setText = function(newText) {
|
||||
if (newText === null) {
|
||||
// No change if null.
|
||||
return;
|
||||
Blockly.FieldTextInput.prototype.doValueUpdate_ = function(newValue) {
|
||||
this.isTextValid_ = true;
|
||||
this.value_ = newValue;
|
||||
if (!this.isBeingEdited_) {
|
||||
// This should only occur if setValue is triggered programmatically.
|
||||
this.text_ = String(newValue);
|
||||
this.isDirty_ = true;
|
||||
}
|
||||
newText = String(newText);
|
||||
if (newText === this.text_) {
|
||||
// No change.
|
||||
return;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the colour of the htmlInput given the current validity of the
|
||||
* field's value.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.render_ = function() {
|
||||
Blockly.FieldTextInput.superClass_.render_.call(this);
|
||||
// This logic is done in render_ rather than doValueInvalid_ or
|
||||
// doValueUpdate_ so that the code is more centralized.
|
||||
if (this.isBeingEdited_) {
|
||||
this.resizeEditor_();
|
||||
if (!this.isTextValid_) {
|
||||
Blockly.utils.dom.addClass(this.htmlInput_, 'blocklyInvalidInput');
|
||||
} else {
|
||||
Blockly.utils.dom.removeClass(this.htmlInput_, 'blocklyInvalidInput');
|
||||
}
|
||||
}
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, this.text_, newText));
|
||||
}
|
||||
Blockly.Field.prototype.setText.call(this, newText);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -158,8 +186,9 @@ Blockly.FieldTextInput.prototype.setSpellcheck = function(check) {
|
||||
Blockly.FieldTextInput.prototype.showEditor_ = function(opt_quietInput) {
|
||||
this.workspace_ = this.sourceBlock_.workspace;
|
||||
var quietInput = opt_quietInput || false;
|
||||
if (!quietInput && (goog.userAgent.MOBILE || goog.userAgent.ANDROID ||
|
||||
goog.userAgent.IPAD)) {
|
||||
if (!quietInput && (Blockly.utils.userAgent.MOBILE ||
|
||||
Blockly.utils.userAgent.ANDROID ||
|
||||
Blockly.utils.userAgent.IPAD)) {
|
||||
this.showPromptEditor_();
|
||||
} else {
|
||||
this.showInlineEditor_(quietInput);
|
||||
@@ -175,9 +204,6 @@ Blockly.FieldTextInput.prototype.showPromptEditor_ = function() {
|
||||
var fieldText = this;
|
||||
Blockly.prompt(Blockly.Msg['CHANGE_VALUE_TITLE'], this.text_,
|
||||
function(newValue) {
|
||||
if (fieldText.sourceBlock_) {
|
||||
newValue = fieldText.callValidator(newValue);
|
||||
}
|
||||
fieldText.setValue(newValue);
|
||||
});
|
||||
};
|
||||
@@ -189,9 +215,25 @@ Blockly.FieldTextInput.prototype.showPromptEditor_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) {
|
||||
Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, this.widgetDispose_());
|
||||
this.isBeingEdited_ = true;
|
||||
Blockly.WidgetDiv.show(
|
||||
this, this.sourceBlock_.RTL, this.widgetDispose_.bind(this));
|
||||
this.htmlInput_ = this.widgetCreate_();
|
||||
|
||||
if (!quietInput) {
|
||||
this.htmlInput_.focus();
|
||||
this.htmlInput_.select();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create the text input editor widget.
|
||||
* @return {!HTMLInputElement} The newly created text input editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.widgetCreate_ = function() {
|
||||
var div = Blockly.WidgetDiv.DIV;
|
||||
// Create the input.
|
||||
|
||||
var htmlInput = document.createElement('input');
|
||||
htmlInput.className = 'blocklyHtmlInput';
|
||||
htmlInput.setAttribute('spellcheck', this.spellcheck_);
|
||||
@@ -199,56 +241,88 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) {
|
||||
(Blockly.FieldTextInput.FONTSIZE * this.workspace_.scale) + 'pt';
|
||||
div.style.fontSize = fontSize;
|
||||
htmlInput.style.fontSize = fontSize;
|
||||
|
||||
Blockly.FieldTextInput.htmlInput_ = htmlInput;
|
||||
div.appendChild(htmlInput);
|
||||
|
||||
htmlInput.value = htmlInput.defaultValue = this.text_;
|
||||
htmlInput.value = htmlInput.defaultValue = this.value_;
|
||||
htmlInput.untypedDefaultValue_ = this.value_;
|
||||
htmlInput.oldValue_ = null;
|
||||
this.validate_();
|
||||
this.resizeEditor_();
|
||||
if (!quietInput) {
|
||||
htmlInput.focus();
|
||||
htmlInput.select();
|
||||
}
|
||||
|
||||
this.bindEvents_(htmlInput);
|
||||
this.bindInputEvents_(htmlInput);
|
||||
|
||||
return htmlInput;
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind handlers for user input on this field and size changes on the workspace.
|
||||
* @param {!HTMLInputElement} htmlInput The htmlInput created in showEditor, to
|
||||
* which event handlers will be bound.
|
||||
* Close the editor, save the results, and dispose any events bound to the
|
||||
* text input's editor.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.bindEvents_ = function(htmlInput) {
|
||||
// Bind to keydown -- trap Enter without IME and Esc to hide.
|
||||
htmlInput.onKeyDownWrapper_ =
|
||||
Blockly.FieldTextInput.prototype.widgetDispose_ = function() {
|
||||
// Finalize value.
|
||||
this.isBeingEdited_ = false;
|
||||
// No need to call setValue because if the widget is being closed the
|
||||
// latest input text has already been validated.
|
||||
if (this.value_ !== this.text_) {
|
||||
// At the end of an edit the text should be the same as the value. It
|
||||
// may not be if the input text is different than the validated text.
|
||||
// We should fix that.
|
||||
this.text_ = String(this.value_);
|
||||
this.isTextValid_ = true;
|
||||
this.forceRerender();
|
||||
}
|
||||
// Otherwise don't rerender.
|
||||
|
||||
// Call onFinishEditing
|
||||
// TODO: Get rid of this or make it less of a hack.
|
||||
if (this.onFinishEditing_) {
|
||||
this.onFinishEditing_(this.value_);
|
||||
}
|
||||
|
||||
// Remove htmlInput events.
|
||||
this.unbindInputEvents_();
|
||||
|
||||
// Delete style properties.
|
||||
var style = Blockly.WidgetDiv.DIV.style;
|
||||
style.width = 'auto';
|
||||
style.height = 'auto';
|
||||
style.fontSize = '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Bind handlers for user input on the text input field's editor.
|
||||
* @param {!HTMLInputElement} htmlInput The htmlInput to which event
|
||||
* handlers will be bound.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.bindInputEvents_ = function(htmlInput) {
|
||||
// Trap Enter without IME and Esc to hide.
|
||||
this.onKeyDownWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
htmlInput, 'keydown', this, this.onHtmlInputKeyDown_);
|
||||
// Bind to keyup -- trap Enter; resize after every keystroke.
|
||||
htmlInput.onKeyUpWrapper_ =
|
||||
// Resize after every keystroke.
|
||||
this.onKeyUpWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
htmlInput, 'keyup', this, this.onHtmlInputChange_);
|
||||
// Bind to keyPress -- repeatedly resize when holding down a key.
|
||||
htmlInput.onKeyPressWrapper_ =
|
||||
// Repeatedly resize when holding down a key.
|
||||
this.onKeyPressWrapper_ =
|
||||
Blockly.bindEventWithChecks_(
|
||||
htmlInput, 'keypress', this, this.onHtmlInputChange_);
|
||||
htmlInput.onWorkspaceChangeWrapper_ = this.resizeEditor_.bind(this);
|
||||
this.workspace_.addChangeListener(htmlInput.onWorkspaceChangeWrapper_);
|
||||
|
||||
// TODO: Figure out if this is necessary.
|
||||
this.onWorkspaceChangeWrapper_ = this.resizeEditor_.bind(this);
|
||||
this.workspace_.addChangeListener(this.onWorkspaceChangeWrapper_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Unbind handlers for user input and workspace size changes.
|
||||
* @param {!HTMLInputElement} htmlInput The html for this text input.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.unbindEvents_ = function(htmlInput) {
|
||||
Blockly.unbindEvent_(htmlInput.onKeyDownWrapper_);
|
||||
Blockly.unbindEvent_(htmlInput.onKeyUpWrapper_);
|
||||
Blockly.unbindEvent_(htmlInput.onKeyPressWrapper_);
|
||||
this.workspace_.removeChangeListener(
|
||||
htmlInput.onWorkspaceChangeWrapper_);
|
||||
Blockly.FieldTextInput.prototype.unbindInputEvents_ = function() {
|
||||
Blockly.unbindEvent_(this.onKeyDownWrapper_);
|
||||
Blockly.unbindEvent_(this.onKeyUpWrapper_);
|
||||
Blockly.unbindEvent_(this.onKeyPressWrapper_);
|
||||
this.workspace_.removeChangeListener(this.onWorkspaceChangeWrapper_);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -257,18 +331,14 @@ Blockly.FieldTextInput.prototype.unbindEvents_ = function(htmlInput) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_ = function(e) {
|
||||
var htmlInput = Blockly.FieldTextInput.htmlInput_;
|
||||
var tabKey = 9, enterKey = 13, escKey = 27;
|
||||
if (e.keyCode == enterKey) {
|
||||
Blockly.WidgetDiv.hide();
|
||||
Blockly.DropDownDiv.hideIfOwner(this);
|
||||
} else if (e.keyCode == escKey) {
|
||||
htmlInput.value = htmlInput.defaultValue;
|
||||
this.htmlInput_.value = this.htmlInput_.defaultValue;
|
||||
Blockly.WidgetDiv.hide();
|
||||
Blockly.DropDownDiv.hideIfOwner(this);
|
||||
} else if (e.keyCode == tabKey) {
|
||||
Blockly.WidgetDiv.hide();
|
||||
Blockly.DropDownDiv.hideIfOwner(this);
|
||||
this.sourceBlock_.tab(this, !e.shiftKey);
|
||||
e.preventDefault();
|
||||
}
|
||||
@@ -280,51 +350,24 @@ Blockly.FieldTextInput.prototype.onHtmlInputKeyDown_ = function(e) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.onHtmlInputChange_ = function(_e) {
|
||||
var htmlInput = Blockly.FieldTextInput.htmlInput_;
|
||||
// Update source block.
|
||||
var text = htmlInput.value;
|
||||
if (text !== htmlInput.oldValue_) {
|
||||
htmlInput.oldValue_ = text;
|
||||
var text = this.htmlInput_.value;
|
||||
if (text !== this.htmlInput_.oldValue_) {
|
||||
this.htmlInput_.oldValue_ = text;
|
||||
|
||||
// TODO(#2169): Once issue is fixed the setGroup functionality could be
|
||||
// moved up to the Field setValue method. This would create a
|
||||
// broader fix for all field types.
|
||||
Blockly.Events.setGroup(true);
|
||||
this.setValue(text);
|
||||
// Always render the input text.
|
||||
this.text_ = this.htmlInput_.value;
|
||||
this.forceRerender();
|
||||
Blockly.Events.setGroup(false);
|
||||
this.validate_();
|
||||
} else if (goog.userAgent.WEBKIT) {
|
||||
// Cursor key. Render the source block to show the caret moving.
|
||||
// Chrome only (version 26, OS X).
|
||||
this.sourceBlock_.render();
|
||||
}
|
||||
this.resizeEditor_();
|
||||
Blockly.svgResize(this.sourceBlock_.workspace);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check to see if the contents of the editor validates.
|
||||
* Style the editor accordingly.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.validate_ = function() {
|
||||
var valid = true;
|
||||
if (!Blockly.FieldTextInput.htmlInput_) {
|
||||
throw Error('htmlInput not defined');
|
||||
}
|
||||
var htmlInput = Blockly.FieldTextInput.htmlInput_;
|
||||
if (this.sourceBlock_) {
|
||||
valid = this.callValidator(htmlInput.value);
|
||||
}
|
||||
if (valid === null) {
|
||||
Blockly.utils.addClass(htmlInput, 'blocklyInvalidInput');
|
||||
} else {
|
||||
Blockly.utils.removeClass(htmlInput, 'blocklyInvalidInput');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resize the editor and the underlying block to fit the text.
|
||||
* Resize the editor to fit the text.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.resizeEditor_ = function() {
|
||||
@@ -336,78 +379,28 @@ Blockly.FieldTextInput.prototype.resizeEditor_ = function() {
|
||||
// In RTL mode block fields and LTR input fields the left edge moves,
|
||||
// whereas the right edge is fixed. Reposition the editor.
|
||||
var x = this.sourceBlock_.RTL ? bBox.right - div.offsetWidth : bBox.left;
|
||||
var xy = new goog.math.Coordinate(x, bBox.top);
|
||||
var xy = new Blockly.utils.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) {
|
||||
if (Blockly.utils.userAgent.GECKO && Blockly.WidgetDiv.DIV.style.top) {
|
||||
// Firefox mis-reports the location of the border by a pixel
|
||||
// once the WidgetDiv is moved into position.
|
||||
xy.x -= 1;
|
||||
xy.y -= 1;
|
||||
}
|
||||
if (goog.userAgent.WEBKIT) {
|
||||
if (Blockly.utils.userAgent.WEBKIT) {
|
||||
xy.y -= 3;
|
||||
}
|
||||
div.style.left = xy.x + 'px';
|
||||
div.style.top = xy.y + 'px';
|
||||
};
|
||||
|
||||
/**
|
||||
* Close the editor, save the results, and dispose of the editable
|
||||
* text field's elements.
|
||||
* @return {!Function} Closure to call on destruction of the WidgetDiv.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.widgetDispose_ = function() {
|
||||
var thisField = this;
|
||||
return function() {
|
||||
var htmlInput = Blockly.FieldTextInput.htmlInput_;
|
||||
// Save the edit (if it validates).
|
||||
thisField.maybeSaveEdit_();
|
||||
|
||||
thisField.unbindEvents_(htmlInput);
|
||||
Blockly.FieldTextInput.htmlInput_ = null;
|
||||
Blockly.Events.setGroup(false);
|
||||
|
||||
// Delete style properties.
|
||||
var style = Blockly.WidgetDiv.DIV.style;
|
||||
style.width = 'auto';
|
||||
style.height = 'auto';
|
||||
style.fontSize = '';
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempt to save the text field changes when the user input loses focus.
|
||||
* If the value is not valid, revert to the default value.
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldTextInput.prototype.maybeSaveEdit_ = function() {
|
||||
var htmlInput = Blockly.FieldTextInput.htmlInput_;
|
||||
// Save the edit (if it validates).
|
||||
var text = htmlInput.value;
|
||||
if (this.sourceBlock_) {
|
||||
var text1 = this.callValidator(text);
|
||||
if (text1 === null) {
|
||||
// Invalid edit.
|
||||
text = htmlInput.defaultValue;
|
||||
} else {
|
||||
// Validation function has changed the text.
|
||||
text = text1;
|
||||
if (this.onFinishEditing_) {
|
||||
this.onFinishEditing_(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.setText(text);
|
||||
this.sourceBlock_.rendered && this.sourceBlock_.render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure that only a number may be entered.
|
||||
* @param {string} text The user's text.
|
||||
* @return {?string} A string representing a valid number, or null if invalid.
|
||||
* @deprecated
|
||||
*/
|
||||
Blockly.FieldTextInput.numberValidator = function(text) {
|
||||
console.warn('Blockly.FieldTextInput.numberValidator is deprecated. ' +
|
||||
@@ -429,6 +422,7 @@ Blockly.FieldTextInput.numberValidator = function(text) {
|
||||
* Ensure that only a nonnegative integer may be entered.
|
||||
* @param {string} text The user's text.
|
||||
* @return {?string} A string representing a valid int, or null if invalid.
|
||||
* @deprecated
|
||||
*/
|
||||
Blockly.FieldTextInput.nonnegativeIntegerValidator = function(text) {
|
||||
var n = Blockly.FieldTextInput.numberValidator(text);
|
||||
|
||||
+116
-60
@@ -26,11 +26,14 @@
|
||||
|
||||
goog.provide('Blockly.FieldVariable');
|
||||
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockChange');
|
||||
goog.require('Blockly.FieldDropdown');
|
||||
goog.require('Blockly.Msg');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.VariableModel');
|
||||
goog.require('Blockly.Variables');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.require('goog.math.Size');
|
||||
|
||||
@@ -39,8 +42,9 @@ goog.require('goog.math.Size');
|
||||
* Class for a variable's dropdown field.
|
||||
* @param {?string} varname The default name for the variable. If null,
|
||||
* 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 {Function=} opt_validator A function that is called to validate
|
||||
* changes to the field's value. Takes in a variable ID & returns a
|
||||
* validated variable ID, or null to abort the change.
|
||||
* @param {Array.<string>=} opt_variableTypes A list of the types of variables
|
||||
* to include in the dropdown.
|
||||
* @param {string=} opt_defaultType The type of variable to create if this
|
||||
@@ -79,20 +83,19 @@ Blockly.FieldVariable.fromJson = function(options) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize everything needed to render this field. This includes making sure
|
||||
* that the field's value is valid.
|
||||
* @public
|
||||
* The workspace that this variable field belongs to.
|
||||
* @type {?Blockly.Workspace}
|
||||
* @private
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.init = function() {
|
||||
if (this.fieldGroup_) {
|
||||
// Dropdown has already been initialized once.
|
||||
return;
|
||||
}
|
||||
Blockly.FieldVariable.superClass_.init.call(this);
|
||||
Blockly.FieldVariable.prototype.workspace_ = null;
|
||||
|
||||
// TODO (#1010): Change from init/initModel to initView/initModel
|
||||
this.initModel();
|
||||
};
|
||||
/**
|
||||
* Serializable fields are saved by the XML renderer, non-serializable fields
|
||||
* are not. Editable fields should also be serializable.
|
||||
* @type {boolean}
|
||||
* @const
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.SERIALIZABLE = true;
|
||||
|
||||
/**
|
||||
* Initialize the model for this field if it has not already been initialized.
|
||||
@@ -104,28 +107,59 @@ Blockly.FieldVariable.prototype.initModel = function() {
|
||||
if (this.variable_) {
|
||||
return; // Initialization already happened.
|
||||
}
|
||||
this.workspace_ = this.sourceBlock_.workspace;
|
||||
var variable = Blockly.Variables.getOrCreateVariablePackage(
|
||||
this.workspace_, null, this.defaultVariableName, this.defaultType_);
|
||||
|
||||
// Don't fire a change event for this setValue. It would have null as the
|
||||
// old value, which is not valid.
|
||||
Blockly.Events.disable();
|
||||
try {
|
||||
this.setValue(variable.getId());
|
||||
} finally {
|
||||
Blockly.Events.enable();
|
||||
}
|
||||
this.setValue(variable.getId());
|
||||
Blockly.Events.enable();
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of this field.
|
||||
* @public
|
||||
* Initialize this field based on the given XML.
|
||||
* @param {!Element} fieldElement The element containing information about the
|
||||
* variable field's state.
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.dispose = function() {
|
||||
Blockly.FieldVariable.superClass_.dispose.call(this);
|
||||
this.workspace_ = null;
|
||||
this.variableMap_ = null;
|
||||
Blockly.FieldVariable.prototype.fromXml = function(fieldElement) {
|
||||
var id = fieldElement.getAttribute('id');
|
||||
var variableName = fieldElement.textContent;
|
||||
// 'variabletype' should be lowercase, but until July 2019 it was sometimes
|
||||
// recorded as 'variableType'. Thus we need to check for both.
|
||||
var variableType = fieldElement.getAttribute('variabletype') ||
|
||||
fieldElement.getAttribute('variableType') || '';
|
||||
|
||||
var variable = Blockly.Variables.getOrCreateVariablePackage(
|
||||
this.workspace_, id, variableName, variableType);
|
||||
|
||||
// This should never happen :)
|
||||
if (variableType != null && variableType !== 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(fieldElement) + '.');
|
||||
}
|
||||
|
||||
this.setValue(variable.getId());
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize this field to XML.
|
||||
* @param {!Element} fieldElement The element to populate with info about the
|
||||
* field's state.
|
||||
* @return {!Element} The element containing info about the field's state.
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.toXml = function(fieldElement) {
|
||||
// Make sure the variable is initialized.
|
||||
this.initModel();
|
||||
|
||||
fieldElement.id = this.variable_.getId();
|
||||
fieldElement.textContent = this.variable_.name;
|
||||
if (this.variable_.type) {
|
||||
fieldElement.setAttribute('variabletype', this.variable_.type);
|
||||
}
|
||||
return fieldElement;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -137,6 +171,7 @@ Blockly.FieldVariable.prototype.setSourceBlock = function(block) {
|
||||
throw Error('Variable fields are not allowed to exist on shadow blocks.');
|
||||
}
|
||||
Blockly.FieldVariable.superClass_.setSourceBlock.call(this, block);
|
||||
this.workspace_ = block.workspace;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -169,30 +204,57 @@ Blockly.FieldVariable.prototype.getVariable = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the variable ID.
|
||||
* @param {string} id New variable ID, which must reference an existing
|
||||
* variable.
|
||||
* Gets the validation function for this field, or null if not set.
|
||||
* Returns null if the variable is not set, because validators should not
|
||||
* run on the initial setValue call, because the field won't be attached to
|
||||
* a block and workspace at that point.
|
||||
* @return {Function} Validation function, or null.
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.setValue = function(id) {
|
||||
var workspace = this.sourceBlock_.workspace;
|
||||
var variable = Blockly.Variables.getVariable(workspace, id);
|
||||
|
||||
if (!variable) {
|
||||
throw Error('Variable id doesn\'t point to a real variable! ID was ' + id);
|
||||
Blockly.FieldVariable.prototype.getValidator = function() {
|
||||
// Validators shouldn't operate on the initial setValue call.
|
||||
// Normally this is achieved by calling setValidator after setValue, but
|
||||
// this is not a possibility with variable fields.
|
||||
if (this.variable_) {
|
||||
return this.validator_;
|
||||
}
|
||||
// Type checks!
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ensure that the id belongs to a valid variable of an allowed type.
|
||||
* @param {string} newId The id of the new variable to set.
|
||||
* @return {?string} The validated id, or null if invalid.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.doClassValidation_ = function(newId) {
|
||||
var variable = Blockly.Variables.getVariable(this.workspace_, newId);
|
||||
if (!variable) {
|
||||
console.warn('Variable id doesn\'t point to a real variable! ' +
|
||||
'ID was ' + newId);
|
||||
return null;
|
||||
}
|
||||
// Type Checks.
|
||||
var type = variable.type;
|
||||
if (!this.typeIsAllowed_(type)) {
|
||||
throw Error('Variable type doesn\'t match this field! Type was ' + type);
|
||||
console.warn('Variable type doesn\'t match this field! Type was ' + type);
|
||||
return null;
|
||||
}
|
||||
if (this.sourceBlock_ && Blockly.Events.isEnabled()) {
|
||||
var oldValue = this.variable_ ? this.variable_.getId() : null;
|
||||
Blockly.Events.fire(new Blockly.Events.BlockChange(
|
||||
this.sourceBlock_, 'field', this.name, oldValue, id));
|
||||
}
|
||||
this.variable_ = variable;
|
||||
this.value_ = id;
|
||||
this.setText(variable.name);
|
||||
return newId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the value of this variable field, as well as its variable and text.
|
||||
*
|
||||
* The variable ID should be valid at this point, but if a variable field
|
||||
* validator returns a bad ID, this could break.
|
||||
* @param {string} newId The id of the new variable.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.doValueUpdate_ = function(newId) {
|
||||
this.variable_ = Blockly.Variables.getVariable(this.workspace_, newId);
|
||||
this.value_ = newId;
|
||||
this.text_ = (this.variable_.name);
|
||||
this.isDirty_ = true;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -225,9 +287,8 @@ Blockly.FieldVariable.prototype.getVariableTypes_ = function() {
|
||||
var variableTypes = this.variableTypes;
|
||||
if (variableTypes === null) {
|
||||
// If variableTypes is null, return all variable types.
|
||||
if (this.sourceBlock_) {
|
||||
var workspace = this.sourceBlock_.workspace;
|
||||
return workspace.getVariableTypes();
|
||||
if (this.workspace_) {
|
||||
return this.workspace_.getVariableTypes();
|
||||
}
|
||||
}
|
||||
variableTypes = variableTypes || [''];
|
||||
@@ -292,18 +353,14 @@ Blockly.FieldVariable.dropdownCreate = function() {
|
||||
' variable selected.');
|
||||
}
|
||||
var name = this.getText();
|
||||
var workspace = null;
|
||||
if (this.sourceBlock_) {
|
||||
workspace = this.sourceBlock_.workspace;
|
||||
}
|
||||
var variableModelList = [];
|
||||
if (workspace) {
|
||||
if (this.workspace_) {
|
||||
var variableTypes = this.getVariableTypes_();
|
||||
// Get a copy of the list, so that adding rename and new variable options
|
||||
// doesn't modify the workspace's list.
|
||||
for (var i = 0; i < variableTypes.length; i++) {
|
||||
var variableType = variableTypes[i];
|
||||
var variables = workspace.getVariablesOfType(variableType);
|
||||
var variables = this.workspace_.getVariablesOfType(variableType);
|
||||
variableModelList = variableModelList.concat(variables);
|
||||
}
|
||||
}
|
||||
@@ -336,20 +393,19 @@ Blockly.FieldVariable.dropdownCreate = function() {
|
||||
*/
|
||||
Blockly.FieldVariable.prototype.onItemSelected = function(menu, menuItem) {
|
||||
var id = menuItem.getValue();
|
||||
if (this.sourceBlock_ && this.sourceBlock_.workspace) {
|
||||
var workspace = this.sourceBlock_.workspace;
|
||||
// Handle special cases.
|
||||
if (this.workspace_) {
|
||||
if (id == Blockly.RENAME_VARIABLE_ID) {
|
||||
// Rename variable.
|
||||
Blockly.Variables.renameVariable(workspace, this.variable_);
|
||||
Blockly.Variables.renameVariable(this.workspace_, this.variable_);
|
||||
return;
|
||||
} else if (id == Blockly.DELETE_VARIABLE_ID) {
|
||||
// Delete variable.
|
||||
workspace.deleteVariableById(this.variable_.getId());
|
||||
this.workspace_.deleteVariableById(this.variable_.getId());
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO (#1529): Call any validation function, and allow it to override.
|
||||
}
|
||||
// Handle unspecial case.
|
||||
this.setValue(id);
|
||||
};
|
||||
|
||||
|
||||
+40
-37
@@ -32,13 +32,14 @@ goog.require('Blockly.Events.BlockCreate');
|
||||
goog.require('Blockly.Events.VarCreate');
|
||||
goog.require('Blockly.FlyoutButton');
|
||||
goog.require('Blockly.Gesture');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.WorkspaceSvg');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.require('goog.math.Rect');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a flyout.
|
||||
@@ -212,9 +213,9 @@ Blockly.Flyout.prototype.createDom = function(tagName) {
|
||||
*/
|
||||
// Setting style to display:none to start. The toolbox and flyout
|
||||
// hide/show code will set up proper visibility and size later.
|
||||
this.svgGroup_ = Blockly.utils.createSvgElement(tagName,
|
||||
this.svgGroup_ = Blockly.utils.dom.createSvgElement(tagName,
|
||||
{'class': 'blocklyFlyout', 'style': 'display: none'}, null);
|
||||
this.svgBackground_ = Blockly.utils.createSvgElement('path',
|
||||
this.svgBackground_ = Blockly.utils.dom.createSvgElement('path',
|
||||
{'class': 'blocklyFlyoutBackground'}, this.svgGroup_);
|
||||
this.svgGroup_.appendChild(this.workspace_.createDom());
|
||||
return this.svgGroup_;
|
||||
@@ -278,7 +279,7 @@ Blockly.Flyout.prototype.dispose = function() {
|
||||
this.workspace_ = null;
|
||||
}
|
||||
if (this.svgGroup_) {
|
||||
Blockly.utils.removeNode(this.svgGroup_);
|
||||
Blockly.utils.dom.removeNode(this.svgGroup_);
|
||||
this.svgGroup_ = null;
|
||||
}
|
||||
this.svgBackground_ = null;
|
||||
@@ -375,7 +376,7 @@ Blockly.Flyout.prototype.positionAt_ = function(width, height, x, y) {
|
||||
this.svgGroup_.setAttribute("height", height);
|
||||
if (this.svgGroup_.tagName == 'svg') {
|
||||
var transform = 'translate(' + x + 'px,' + y + 'px)';
|
||||
Blockly.utils.setCssTransform(this.svgGroup_, transform);
|
||||
Blockly.utils.dom.setCssTransform(this.svgGroup_, transform);
|
||||
} else {
|
||||
// IE and Edge don't support CSS transforms on SVG elements so
|
||||
// it's important to set the transform on the SVG element itself
|
||||
@@ -404,7 +405,7 @@ Blockly.Flyout.prototype.hide = function() {
|
||||
}
|
||||
this.setVisible(false);
|
||||
// Delete all the event listeners.
|
||||
for (var x = 0, listen; listen = this.listeners_[x]; x++) {
|
||||
for (var i = 0, listen; listen = this.listeners_[i]; i++) {
|
||||
Blockly.unbindEvent_(listen);
|
||||
}
|
||||
this.listeners_.length = 0;
|
||||
@@ -447,27 +448,30 @@ Blockly.Flyout.prototype.show = function(xmlList) {
|
||||
var contents = [];
|
||||
var gaps = [];
|
||||
this.permanentlyDisabled_.length = 0;
|
||||
var default_gap = this.horizontalLayout_ ? this.GAP_X : this.GAP_Y;
|
||||
for (var i = 0, xml; xml = xmlList[i]; i++) {
|
||||
if (xml.tagName) {
|
||||
var tagName = xml.tagName.toUpperCase();
|
||||
var default_gap = this.horizontalLayout_ ? this.GAP_X : this.GAP_Y;
|
||||
if (tagName == 'BLOCK') {
|
||||
if (!xml.tagName) {
|
||||
continue;
|
||||
}
|
||||
switch (xml.tagName.toUpperCase()) {
|
||||
case 'BLOCK':
|
||||
var curBlock = Blockly.Xml.domToBlock(xml, this.workspace_);
|
||||
if (curBlock.disabled) {
|
||||
if (!curBlock.isEnabled()) {
|
||||
// Record blocks that were initially disabled.
|
||||
// Do not enable these blocks as a result of capacity filtering.
|
||||
this.permanentlyDisabled_.push(curBlock);
|
||||
}
|
||||
contents.push({type: 'block', block: curBlock});
|
||||
// This is a deprecated method for adding gap to a block.
|
||||
// <block type="math_arithmetic" gap="8"></block>
|
||||
var gap = parseInt(xml.getAttribute('gap'), 10);
|
||||
gaps.push(isNaN(gap) ? default_gap : gap);
|
||||
} else if (xml.tagName.toUpperCase() == 'SEP') {
|
||||
// Change the gap between two blocks.
|
||||
break;
|
||||
case 'SEP':
|
||||
// Change the gap between two toolbox elements.
|
||||
// <sep gap="36"></sep>
|
||||
// The default gap is 24, can be set larger or smaller.
|
||||
// This overwrites the gap attribute on the previous block.
|
||||
// Note that a deprecated method is to add a gap to a block.
|
||||
// <block type="math_arithmetic" gap="8"></block>
|
||||
// This overwrites the gap attribute on the previous element.
|
||||
var newGap = parseInt(xml.getAttribute('gap'), 10);
|
||||
// Ignore gaps before the first block.
|
||||
if (!isNaN(newGap) && gaps.length > 0) {
|
||||
@@ -475,14 +479,15 @@ Blockly.Flyout.prototype.show = function(xmlList) {
|
||||
} else {
|
||||
gaps.push(default_gap);
|
||||
}
|
||||
} else if (tagName == 'BUTTON' || tagName == 'LABEL') {
|
||||
// Labels behave the same as buttons, but are styled differently.
|
||||
var isLabel = tagName == 'LABEL';
|
||||
break;
|
||||
case 'LABEL':
|
||||
case 'BUTTON':
|
||||
var isLabel = xml.tagName.toUpperCase() == 'LABEL';
|
||||
var curButton = new Blockly.FlyoutButton(this.workspace_,
|
||||
this.targetWorkspace_, xml, isLabel);
|
||||
contents.push({type: 'button', button: curButton});
|
||||
gaps.push(default_gap);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,7 +538,7 @@ Blockly.Flyout.prototype.clearOldBlocks_ = function() {
|
||||
for (var j = 0; j < this.mats_.length; j++) {
|
||||
var rect = this.mats_[j];
|
||||
if (rect) {
|
||||
Blockly.utils.removeNode(rect);
|
||||
Blockly.utils.dom.removeNode(rect);
|
||||
}
|
||||
}
|
||||
this.mats_.length = 0;
|
||||
@@ -603,12 +608,12 @@ Blockly.Flyout.prototype.onMouseDown_ = function(e) {
|
||||
* Does this flyout allow you to create a new instance of the given block?
|
||||
* Used for deciding if a block can be "dragged out of" the flyout.
|
||||
* @param {!Blockly.BlockSvg} block The block to copy from the flyout.
|
||||
* @return {!boolean} True if you can create a new instance of the block, false
|
||||
* @return {boolean} True if you can create a new instance of the block, false
|
||||
* otherwise.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Flyout.prototype.isBlockCreatable_ = function(block) {
|
||||
return !block.disabled;
|
||||
return block.isEnabled();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -688,7 +693,7 @@ Blockly.Flyout.prototype.initFlyoutButton_ = function(button, x, y) {
|
||||
Blockly.Flyout.prototype.createRect_ = function(block, x, y, blockHW, index) {
|
||||
// Create an invisible rectangle under the block to act as a button. Just
|
||||
// using the block as a button is poor, since blocks have holes in them.
|
||||
var rect = Blockly.utils.createSvgElement('rect',
|
||||
var rect = Blockly.utils.dom.createSvgElement('rect',
|
||||
{
|
||||
'fill-opacity': 0,
|
||||
'x': x,
|
||||
@@ -744,10 +749,10 @@ Blockly.Flyout.prototype.filterForCapacity_ = function() {
|
||||
var blocks = this.workspace_.getTopBlocks(false);
|
||||
for (var i = 0, block; block = blocks[i]; i++) {
|
||||
if (this.permanentlyDisabled_.indexOf(block) == -1) {
|
||||
var disable = !this.targetWorkspace_
|
||||
var enable = this.targetWorkspace_
|
||||
.isCapacityAvailable(Blockly.utils.getBlockTypeCounts(block));
|
||||
while (block) {
|
||||
block.setDisabled(disable);
|
||||
block.setEnabled(enable);
|
||||
block = block.getNextBlock();
|
||||
}
|
||||
}
|
||||
@@ -790,7 +795,7 @@ Blockly.Flyout.prototype.placeNewBlock_ = function(oldBlock) {
|
||||
}
|
||||
|
||||
// Create the new block by cloning the block in the flyout (via XML).
|
||||
var xml = Blockly.Xml.blockToDom(oldBlock);
|
||||
var xml = Blockly.Xml.blockToDom(oldBlock, true);
|
||||
// The target workspace would normally resize during domToBlock, which will
|
||||
// lead to weird jumps. Save it for terminateDrag.
|
||||
targetWorkspace.setResizesEnabled(false);
|
||||
@@ -812,25 +817,23 @@ Blockly.Flyout.prototype.placeNewBlock_ = function(oldBlock) {
|
||||
var flyoutOffsetPixels = this.workspace_.getOriginOffsetInPixels();
|
||||
|
||||
// The position of the old block in flyout workspace coordinates.
|
||||
var oldBlockPosWs = oldBlock.getRelativeToSurfaceXY();
|
||||
|
||||
var oldBlockPos = oldBlock.getRelativeToSurfaceXY();
|
||||
// The position of the old block in pixels relative to the flyout
|
||||
// workspace's origin.
|
||||
var oldBlockPosPixels = oldBlockPosWs.scale(this.workspace_.scale);
|
||||
oldBlockPos.scale(this.workspace_.scale);
|
||||
|
||||
// The position of the old block in pixels relative to the upper left corner
|
||||
// of the injection div.
|
||||
var oldBlockOffsetPixels = goog.math.Coordinate.sum(flyoutOffsetPixels,
|
||||
oldBlockPosPixels);
|
||||
var oldBlockOffsetPixels = Blockly.utils.Coordinate.sum(flyoutOffsetPixels,
|
||||
oldBlockPos);
|
||||
|
||||
// The position of the old block in pixels relative to the origin of the
|
||||
// main workspace.
|
||||
var finalOffsetPixels = goog.math.Coordinate.difference(oldBlockOffsetPixels,
|
||||
var finalOffset = Blockly.utils.Coordinate.difference(oldBlockOffsetPixels,
|
||||
mainOffsetPixels);
|
||||
|
||||
// The position of the old block in main workspace coordinates.
|
||||
var finalOffsetMainWs = finalOffsetPixels.scale(1 / targetWorkspace.scale);
|
||||
finalOffset.scale(1 / targetWorkspace.scale);
|
||||
|
||||
block.moveBy(finalOffsetMainWs.x, finalOffsetMainWs.y);
|
||||
block.moveBy(finalOffset.x, finalOffset.y);
|
||||
return block;
|
||||
};
|
||||
|
||||
+10
-10
@@ -27,8 +27,8 @@
|
||||
goog.provide('Blockly.FlyoutButton');
|
||||
|
||||
goog.require('Blockly.utils');
|
||||
|
||||
goog.require('goog.math.Coordinate');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.utils.dom');
|
||||
|
||||
|
||||
/**
|
||||
@@ -62,10 +62,10 @@ Blockly.FlyoutButton = function(workspace, targetWorkspace, xml, isLabel) {
|
||||
this.text_ = xml.getAttribute('text');
|
||||
|
||||
/**
|
||||
* @type {!goog.math.Coordinate}
|
||||
* @type {!Blockly.utils.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.position_ = new goog.math.Coordinate(0, 0);
|
||||
this.position_ = new Blockly.utils.Coordinate(0, 0);
|
||||
|
||||
/**
|
||||
* Whether this button should be styled as a label.
|
||||
@@ -123,12 +123,12 @@ Blockly.FlyoutButton.prototype.createDom = function() {
|
||||
cssClass += ' ' + this.cssClass_;
|
||||
}
|
||||
|
||||
this.svgGroup_ = Blockly.utils.createSvgElement('g', {'class': cssClass},
|
||||
this.svgGroup_ = Blockly.utils.dom.createSvgElement('g', {'class': cssClass},
|
||||
this.workspace_.getCanvas());
|
||||
|
||||
if (!this.isLabel_) {
|
||||
// Shadow rectangle (light source does not mirror in RTL).
|
||||
var shadow = Blockly.utils.createSvgElement('rect',
|
||||
var shadow = Blockly.utils.dom.createSvgElement('rect',
|
||||
{
|
||||
'class': 'blocklyFlyoutButtonShadow',
|
||||
'rx': 4, 'ry': 4, 'x': 1, 'y': 1
|
||||
@@ -136,7 +136,7 @@ Blockly.FlyoutButton.prototype.createDom = function() {
|
||||
this.svgGroup_);
|
||||
}
|
||||
// Background rectangle.
|
||||
var rect = Blockly.utils.createSvgElement('rect',
|
||||
var rect = Blockly.utils.dom.createSvgElement('rect',
|
||||
{
|
||||
'class': this.isLabel_ ?
|
||||
'blocklyFlyoutLabelBackground' : 'blocklyFlyoutButtonBackground',
|
||||
@@ -144,7 +144,7 @@ Blockly.FlyoutButton.prototype.createDom = function() {
|
||||
},
|
||||
this.svgGroup_);
|
||||
|
||||
var svgText = Blockly.utils.createSvgElement('text',
|
||||
var svgText = Blockly.utils.dom.createSvgElement('text',
|
||||
{
|
||||
'class': this.isLabel_ ? 'blocklyFlyoutLabelText' : 'blocklyText',
|
||||
'x': 0,
|
||||
@@ -205,7 +205,7 @@ Blockly.FlyoutButton.prototype.moveTo = function(x, y) {
|
||||
|
||||
/**
|
||||
* Location of the button.
|
||||
* @return {!goog.math.Coordinate} x, y coordinates.
|
||||
* @return {!Blockly.utils.Coordinate} x, y coordinates.
|
||||
* @package
|
||||
*/
|
||||
Blockly.FlyoutButton.prototype.getPosition = function() {
|
||||
@@ -229,7 +229,7 @@ Blockly.FlyoutButton.prototype.dispose = function() {
|
||||
Blockly.unbindEvent_(this.onMouseUpWrapper_);
|
||||
}
|
||||
if (this.svgGroup_) {
|
||||
Blockly.utils.removeNode(this.svgGroup_);
|
||||
Blockly.utils.dom.removeNode(this.svgGroup_);
|
||||
this.svgGroup_ = null;
|
||||
}
|
||||
this.workspace_ = null;
|
||||
|
||||
+10
-16
@@ -27,13 +27,10 @@
|
||||
goog.provide('Blockly.HorizontalFlyout');
|
||||
|
||||
goog.require('Blockly.Block');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.FlyoutButton');
|
||||
goog.require('Blockly.Flyout');
|
||||
goog.require('Blockly.WorkspaceSvg');
|
||||
|
||||
goog.require('goog.math.Rect');
|
||||
goog.require('goog.userAgent');
|
||||
goog.require('Blockly.FlyoutButton');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
|
||||
|
||||
/**
|
||||
@@ -315,7 +312,7 @@ Blockly.HorizontalFlyout.prototype.layout_ = function(contents, gaps) {
|
||||
* Determine if a drag delta is toward the workspace, based on the position
|
||||
* and orientation of the flyout. This is used in determineDragIntention_ to
|
||||
* determine if a new block should be created or if the flyout should scroll.
|
||||
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* moved from the position at mouse down, in pixel units.
|
||||
* @return {boolean} True if the drag is toward the workspace.
|
||||
* @package
|
||||
@@ -338,7 +335,7 @@ Blockly.HorizontalFlyout.prototype.isDragTowardWorkspace = function(
|
||||
|
||||
/**
|
||||
* Return the deletion rectangle for this flyout in viewport coordinates.
|
||||
* @return {goog.math.Rect} Rectangle in which to delete.
|
||||
* @return {Blockly.utils.Rect} Rectangle in which to delete.
|
||||
*/
|
||||
Blockly.HorizontalFlyout.prototype.getClientRect = function() {
|
||||
if (!this.svgGroup_) {
|
||||
@@ -350,17 +347,14 @@ Blockly.HorizontalFlyout.prototype.getClientRect = function() {
|
||||
// area are still deleted. Must be larger than the largest screen size,
|
||||
// but be smaller than half Number.MAX_SAFE_INTEGER (not available on IE).
|
||||
var BIG_NUM = 1000000000;
|
||||
var y = flyoutRect.top;
|
||||
var height = flyoutRect.height;
|
||||
var top = flyoutRect.top;
|
||||
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_TOP) {
|
||||
return new goog.math.Rect(-BIG_NUM, y - BIG_NUM, BIG_NUM * 2,
|
||||
BIG_NUM + height);
|
||||
} else if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_BOTTOM) {
|
||||
return new goog.math.Rect(-BIG_NUM, y, BIG_NUM * 2,
|
||||
BIG_NUM + height);
|
||||
var height = flyoutRect.height;
|
||||
return new Blockly.utils.Rect(-BIG_NUM, top + height, -BIG_NUM, BIG_NUM);
|
||||
} else { // Bottom.
|
||||
return new Blockly.utils.Rect(top, -BIG_NUM, -BIG_NUM, BIG_NUM);
|
||||
}
|
||||
// TODO: Else throw error (should never happen).
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+12
-15
@@ -27,13 +27,11 @@
|
||||
goog.provide('Blockly.VerticalFlyout');
|
||||
|
||||
goog.require('Blockly.Block');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Flyout');
|
||||
goog.require('Blockly.FlyoutButton');
|
||||
goog.require('Blockly.WorkspaceSvg');
|
||||
|
||||
goog.require('goog.math.Rect');
|
||||
goog.require('goog.userAgent');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
@@ -292,7 +290,7 @@ Blockly.VerticalFlyout.prototype.layout_ = function(contents, gaps) {
|
||||
* Determine if a drag delta is toward the workspace, based on the position
|
||||
* and orientation of the flyout. This is used in determineDragIntention_ to
|
||||
* determine if a new block should be created or if the flyout should scroll.
|
||||
* @param {!goog.math.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* @param {!Blockly.utils.Coordinate} currentDragDeltaXY How far the pointer has
|
||||
* moved from the position at mouse down, in pixel units.
|
||||
* @return {boolean} True if the drag is toward the workspace.
|
||||
* @package
|
||||
@@ -315,7 +313,7 @@ Blockly.VerticalFlyout.prototype.isDragTowardWorkspace = function(
|
||||
|
||||
/**
|
||||
* Return the deletion rectangle for this flyout in viewport coordinates.
|
||||
* @return {goog.math.Rect} Rectangle in which to delete.
|
||||
* @return {Blockly.utils.Rect} Rectangle in which to delete.
|
||||
*/
|
||||
Blockly.VerticalFlyout.prototype.getClientRect = function() {
|
||||
if (!this.svgGroup_) {
|
||||
@@ -327,17 +325,16 @@ Blockly.VerticalFlyout.prototype.getClientRect = function() {
|
||||
// area are still deleted. Must be larger than the largest screen size,
|
||||
// but be smaller than half Number.MAX_SAFE_INTEGER (not available on IE).
|
||||
var BIG_NUM = 1000000000;
|
||||
var x = flyoutRect.left;
|
||||
var width = flyoutRect.width;
|
||||
var left = flyoutRect.left;
|
||||
|
||||
if (this.toolboxPosition_ == Blockly.TOOLBOX_AT_LEFT) {
|
||||
return new goog.math.Rect(x - BIG_NUM, -BIG_NUM, BIG_NUM + width,
|
||||
BIG_NUM * 2);
|
||||
var width = flyoutRect.width;
|
||||
return new Blockly.utils.Rect(-BIG_NUM, BIG_NUM, -BIG_NUM, left + width);
|
||||
} else { // Right
|
||||
// Firefox sometimes reports the wrong value for the client rect.
|
||||
// See https://github.com/google/blockly/issues/1425 and
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1066435
|
||||
if (goog.userAgent.GECKO &&
|
||||
if (Blockly.utils.userAgent.GECKO &&
|
||||
this.targetWorkspace_ && this.targetWorkspace_.isMutator) {
|
||||
// The position of the left side of the mutator workspace in pixels
|
||||
// relative to the window origin.
|
||||
@@ -350,15 +347,15 @@ Blockly.VerticalFlyout.prototype.getClientRect = function() {
|
||||
// visible area of the workspace should be more than ten pixels wide. If
|
||||
// the browser reports that the flyout is within ten pixels of the left
|
||||
// side of the workspace, ignore it and manually calculate the value.
|
||||
if (Math.abs(targetWsLeftPixels - x) < 10) {
|
||||
if (Math.abs(targetWsLeftPixels - left) < 10) {
|
||||
// If we're in a mutator, its scale is always 1, purely because of some
|
||||
// oddities in our rendering optimizations. The actual scale is the
|
||||
// same as the scale on the parent workspace.
|
||||
var scale = this.targetWorkspace_.options.parentWorkspace.scale;
|
||||
x = x + this.leftEdge_ * scale;
|
||||
left += this.leftEdge_ * scale;
|
||||
}
|
||||
}
|
||||
return new goog.math.Rect(x, -BIG_NUM, BIG_NUM + width, BIG_NUM * 2);
|
||||
return new Blockly.utils.Rect(-BIG_NUM, BIG_NUM, left, BIG_NUM);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+54
-16
@@ -62,6 +62,14 @@ Blockly.Generator.prototype.INFINITE_LOOP_TRAP = null;
|
||||
*/
|
||||
Blockly.Generator.prototype.STATEMENT_PREFIX = null;
|
||||
|
||||
/**
|
||||
* Arbitrary code to inject after every statement.
|
||||
* Any instances of '%1' will be replaced by the block ID of the statement.
|
||||
* E.g. 'highlight(%1);\n'
|
||||
* @type {?string}
|
||||
*/
|
||||
Blockly.Generator.prototype.STATEMENT_SUFFIX = null;
|
||||
|
||||
/**
|
||||
* The method of indenting. Defaults to two spaces, but language generators
|
||||
* may override this to increase indent or change to tabs.
|
||||
@@ -96,7 +104,7 @@ Blockly.Generator.prototype.workspaceToCode = function(workspace) {
|
||||
var code = [];
|
||||
this.init(workspace);
|
||||
var blocks = workspace.getTopBlocks(true);
|
||||
for (var x = 0, block; block = blocks[x]; x++) {
|
||||
for (var i = 0, block; block = blocks[i]; i++) {
|
||||
var line = this.blockToCode(block);
|
||||
if (Array.isArray(line)) {
|
||||
// Value blocks return tuples of code and operator order.
|
||||
@@ -108,6 +116,12 @@ Blockly.Generator.prototype.workspaceToCode = function(workspace) {
|
||||
// This block is a naked value. Ask the language's code generator if
|
||||
// it wants to append a semicolon, or something.
|
||||
line = this.scrubNakedValue(line);
|
||||
if (this.STATEMENT_PREFIX && !block.suppressPrefixSuffix) {
|
||||
line = this.injectId(this.STATEMENT_PREFIX, block) + line;
|
||||
}
|
||||
if (this.STATEMENT_SUFFIX && !block.suppressPrefixSuffix) {
|
||||
line = line + this.injectId(this.STATEMENT_SUFFIX, block);
|
||||
}
|
||||
}
|
||||
code.push(line);
|
||||
}
|
||||
@@ -126,6 +140,7 @@ Blockly.Generator.prototype.workspaceToCode = function(workspace) {
|
||||
|
||||
/**
|
||||
* Prepend a common prefix onto each line of code.
|
||||
* Intended for indenting code or adding comment markers.
|
||||
* @param {string} text The lines of code.
|
||||
* @param {string} prefix The common prefix.
|
||||
* @return {string} The prefixed lines of code.
|
||||
@@ -167,7 +182,7 @@ Blockly.Generator.prototype.blockToCode = function(block, opt_thisOnly) {
|
||||
if (!block) {
|
||||
return '';
|
||||
}
|
||||
if (block.disabled) {
|
||||
if (!block.isEnabled()) {
|
||||
// Skip past this block if it is disabled.
|
||||
return opt_thisOnly ? '' : this.blockToCode(block.getNextBlock());
|
||||
}
|
||||
@@ -189,9 +204,11 @@ Blockly.Generator.prototype.blockToCode = function(block, opt_thisOnly) {
|
||||
}
|
||||
return [this.scrub_(block, code[0], opt_thisOnly), code[1]];
|
||||
} else if (typeof code == 'string') {
|
||||
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
|
||||
if (this.STATEMENT_PREFIX) {
|
||||
code = this.STATEMENT_PREFIX.replace(/%1/g, '\'' + id + '\'') + code;
|
||||
if (this.STATEMENT_PREFIX && !block.suppressPrefixSuffix) {
|
||||
code = this.injectId(this.STATEMENT_PREFIX, block) + code;
|
||||
}
|
||||
if (this.STATEMENT_SUFFIX && !block.suppressPrefixSuffix) {
|
||||
code = code + this.injectId(this.STATEMENT_SUFFIX, block);
|
||||
}
|
||||
return this.scrub_(block, code, opt_thisOnly);
|
||||
} else if (code === null) {
|
||||
@@ -274,7 +291,10 @@ Blockly.Generator.prototype.valueToCode = function(block, name, outerOrder) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate code representing the statement. Indent the code.
|
||||
* Generate a code string representing the blocks attached to the named
|
||||
* statement input. Indent the code.
|
||||
* This is mainly used in generators. When trying to generate code to evaluate
|
||||
* look at using workspaceToCode or blockToCode.
|
||||
* @param {!Blockly.Block} block The block containing the input.
|
||||
* @param {string} name The name of the input.
|
||||
* @return {string} Generated code or '' if no blocks are connected.
|
||||
@@ -296,23 +316,41 @@ Blockly.Generator.prototype.statementToCode = function(block, name) {
|
||||
|
||||
/**
|
||||
* Add an infinite loop trap to the contents of a loop.
|
||||
* If loop is empty, add a statment prefix for the loop block.
|
||||
* Add statement suffix at the start of the loop block (right after the loop
|
||||
* statement executes), and a statement prefix to the end of the loop block
|
||||
* (right before the loop statement executes).
|
||||
* @param {string} branch Code for loop contents.
|
||||
* @param {string} id ID of enclosing block.
|
||||
* @param {!Blockly.Block} block Enclosing block.
|
||||
* @return {string} Loop contents, with infinite loop trap added.
|
||||
*/
|
||||
Blockly.Generator.prototype.addLoopTrap = function(branch, id) {
|
||||
id = id.replace(/\$/g, '$$$$'); // Issue 251.
|
||||
Blockly.Generator.prototype.addLoopTrap = function(branch, block) {
|
||||
if (this.INFINITE_LOOP_TRAP) {
|
||||
branch = this.INFINITE_LOOP_TRAP.replace(/%1/g, '\'' + id + '\'') + branch;
|
||||
branch = this.prefixLines(this.injectId(this.INFINITE_LOOP_TRAP, block),
|
||||
this.INDENT) + branch;
|
||||
}
|
||||
if (this.STATEMENT_PREFIX) {
|
||||
branch += this.prefixLines(this.STATEMENT_PREFIX.replace(/%1/g,
|
||||
'\'' + id + '\''), this.INDENT);
|
||||
if (this.STATEMENT_SUFFIX && !block.suppressPrefixSuffix) {
|
||||
branch = this.prefixLines(this.injectId(this.STATEMENT_SUFFIX, block),
|
||||
this.INDENT) + branch;
|
||||
}
|
||||
if (this.STATEMENT_PREFIX && !block.suppressPrefixSuffix) {
|
||||
branch = branch + this.prefixLines(this.injectId(this.STATEMENT_PREFIX,
|
||||
block), this.INDENT);
|
||||
}
|
||||
return branch;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject a block ID into a message to replace '%1'.
|
||||
* Used for STATEMENT_PREFIX, STATEMENT_SUFFIX, and INFINITE_LOOP_TRAP.
|
||||
* @param {string} msg Code snippet with '%1'.
|
||||
* @param {!Blockly.Block} block Block which has an ID.
|
||||
* @return {string} Code snippet with ID.
|
||||
*/
|
||||
Blockly.Generator.prototype.injectId = function(msg, block) {
|
||||
var id = block.id.replace(/\$/g, '$$$$'); // Issue 251.
|
||||
return msg.replace(/%1/g, '\'' + id + '\'');
|
||||
};
|
||||
|
||||
/**
|
||||
* Comma-separated list of reserved words.
|
||||
* @type {string}
|
||||
@@ -395,8 +433,8 @@ Blockly.Generator.prototype.init = function(_workspace) {
|
||||
* the block, or to handle comments for the specified block and any connected
|
||||
* value blocks.
|
||||
* @param {!Blockly.Block} _block The current block.
|
||||
* @param {string} code The JavaScript code created for this block.
|
||||
* @return {string} JavaScript code with comments and subsequent blocks added.
|
||||
* @param {string} code The code created for this block.
|
||||
* @return {string} Code with comments and subsequent blocks added.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Generator.prototype.scrub_ = function(_block, code) {
|
||||
|
||||
+17
-17
@@ -27,19 +27,19 @@
|
||||
|
||||
goog.provide('Blockly.Gesture');
|
||||
|
||||
goog.require('Blockly.BlockAnimations');
|
||||
goog.require('Blockly.blockAnimations');
|
||||
goog.require('Blockly.BlockDragger');
|
||||
goog.require('Blockly.BubbleDragger');
|
||||
goog.require('Blockly.constants');
|
||||
goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.Ui');
|
||||
goog.require('Blockly.FlyoutDragger');
|
||||
goog.require('Blockly.Tooltip');
|
||||
goog.require('Blockly.Touch');
|
||||
goog.require('Blockly.utils');
|
||||
goog.require('Blockly.utils.Coordinate');
|
||||
goog.require('Blockly.WorkspaceDragger');
|
||||
|
||||
goog.require('goog.math.Coordinate');
|
||||
|
||||
|
||||
/*
|
||||
* Note: In this file "start" refers to touchstart, mousedown, and pointerstart
|
||||
@@ -57,16 +57,16 @@ goog.require('goog.math.Coordinate');
|
||||
Blockly.Gesture = function(e, creatorWorkspace) {
|
||||
|
||||
/**
|
||||
* The position of the mouse when the gesture started. Units are css pixels,
|
||||
* The position of the mouse when the gesture started. Units are CSS pixels,
|
||||
* with (0, 0) at the top left of the browser window (mouseEvent clientX/Y).
|
||||
* @type {goog.math.Coordinate}
|
||||
* @type {Blockly.utils.Coordinate}
|
||||
*/
|
||||
this.mouseDownXY_ = null;
|
||||
|
||||
/**
|
||||
* How far the mouse has moved during this drag, in pixel units.
|
||||
* (0, 0) is at this.mouseDownXY_.
|
||||
* @type {goog.math.Coordinate}
|
||||
* @type {Blockly.utils.Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.currentDragDeltaXY_ = null;
|
||||
@@ -280,7 +280,7 @@ Blockly.Gesture.prototype.dispose = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.Gesture.prototype.updateFromEvent_ = function(e) {
|
||||
var currentXY = new goog.math.Coordinate(e.clientX, e.clientY);
|
||||
var currentXY = new Blockly.utils.Coordinate(e.clientX, e.clientY);
|
||||
var changed = this.updateDragDelta_(currentXY);
|
||||
// Exceeded the drag radius for the first time.
|
||||
if (changed) {
|
||||
@@ -292,18 +292,18 @@ Blockly.Gesture.prototype.updateFromEvent_ = function(e) {
|
||||
|
||||
/**
|
||||
* DO MATH to set currentDragDeltaXY_ based on the most recent mouse position.
|
||||
* @param {!goog.math.Coordinate} currentXY The most recent mouse/pointer
|
||||
* @param {!Blockly.utils.Coordinate} currentXY The most recent mouse/pointer
|
||||
* position, in pixel units, with (0, 0) at the window's top left corner.
|
||||
* @return {boolean} True if the drag just exceeded the drag radius for the
|
||||
* first time.
|
||||
* @private
|
||||
*/
|
||||
Blockly.Gesture.prototype.updateDragDelta_ = function(currentXY) {
|
||||
this.currentDragDeltaXY_ = goog.math.Coordinate.difference(currentXY,
|
||||
this.currentDragDeltaXY_ = Blockly.utils.Coordinate.difference(currentXY,
|
||||
this.mouseDownXY_);
|
||||
|
||||
if (!this.hasExceededDragRadius_) {
|
||||
var currentDragDelta = goog.math.Coordinate.magnitude(
|
||||
var currentDragDelta = Blockly.utils.Coordinate.magnitude(
|
||||
this.currentDragDeltaXY_);
|
||||
|
||||
// The flyout has a different drag radius from the rest of Blockly.
|
||||
@@ -482,7 +482,7 @@ Blockly.Gesture.prototype.doStart = function(e) {
|
||||
}
|
||||
this.hasStarted_ = true;
|
||||
|
||||
Blockly.BlockAnimations.disconnectUiStop();
|
||||
Blockly.blockAnimations.disconnectUiStop();
|
||||
this.startWorkspace_.updateScreenCalculationsIfScrolled();
|
||||
if (this.startWorkspace_.isMutator) {
|
||||
// Mutator's coordinate system could be out of date because the bubble was
|
||||
@@ -512,7 +512,7 @@ Blockly.Gesture.prototype.doStart = function(e) {
|
||||
Blockly.longStart_(e, this);
|
||||
}
|
||||
|
||||
this.mouseDownXY_ = new goog.math.Coordinate(e.clientX, e.clientY);
|
||||
this.mouseDownXY_ = new Blockly.utils.Coordinate(e.clientX, e.clientY);
|
||||
this.healStack_ = e.altKey || e.ctrlKey || e.metaKey;
|
||||
|
||||
this.bindMouseEvents(e);
|
||||
@@ -734,7 +734,7 @@ Blockly.Gesture.prototype.doFieldClick_ = function() {
|
||||
Blockly.Gesture.prototype.doBlockClick_ = function() {
|
||||
// Block click in an autoclosing flyout.
|
||||
if (this.flyout_ && this.flyout_.autoClose) {
|
||||
if (!this.targetBlock_.disabled) {
|
||||
if (this.targetBlock_.isEnabled()) {
|
||||
if (!Blockly.Events.getGroup()) {
|
||||
Blockly.Events.setGroup(true);
|
||||
}
|
||||
@@ -898,10 +898,10 @@ Blockly.Gesture.prototype.isBlockClick_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.Gesture.prototype.isFieldClick_ = function() {
|
||||
var fieldEditable = this.startField_ ?
|
||||
this.startField_.isCurrentlyEditable() : false;
|
||||
return fieldEditable && !this.hasExceededDragRadius_ && (!this.flyout_ ||
|
||||
!this.flyout_.autoClose);
|
||||
var fieldClickable = this.startField_ ?
|
||||
this.startField_.isClickable() : false;
|
||||
return fieldClickable && !this.hasExceededDragRadius_ &&
|
||||
(!this.flyout_ || !this.flyout_.autoClose);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user