mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
@@ -82,6 +82,7 @@ goog.addDependency("../../core/keyboard_nav/key_map.js", ['Blockly.user.keyMap']
|
||||
goog.addDependency("../../core/keyboard_nav/marker.js", ['Blockly.Marker'], ['Blockly.ASTNode', 'Blockly.navigation']);
|
||||
goog.addDependency("../../core/keyboard_nav/navigation.js", ['Blockly.navigation'], ['Blockly.Action', 'Blockly.ASTNode', 'Blockly.utils.Coordinate', 'Blockly.user.keyMap']);
|
||||
goog.addDependency("../../core/keyboard_nav/tab_navigate_cursor.js", ['Blockly.TabNavigateCursor'], ['Blockly.ASTNode', 'Blockly.BasicCursor', 'Blockly.utils.object']);
|
||||
goog.addDependency("../../core/marker_manager.js", ['Blockly.MarkerManager'], ['Blockly.Marker', 'Blockly.Cursor']);
|
||||
goog.addDependency("../../core/msg.js", ['Blockly.Msg'], ['Blockly.utils.global']);
|
||||
goog.addDependency("../../core/mutator.js", ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.Ui', 'Blockly.Icon', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.object', 'Blockly.utils.xml', 'Blockly.WorkspaceSvg', 'Blockly.Xml']);
|
||||
goog.addDependency("../../core/names.js", ['Blockly.Names'], ['Blockly.Msg']);
|
||||
@@ -167,7 +168,7 @@ goog.addDependency("../../core/variables.js", ['Blockly.Variables'], ['Blockly.B
|
||||
goog.addDependency("../../core/variables_dynamic.js", ['Blockly.VariablesDynamic'], ['Blockly.Variables', 'Blockly.Blocks', 'Blockly.Msg', 'Blockly.utils.xml', 'Blockly.VariableModel']);
|
||||
goog.addDependency("../../core/warning.js", ['Blockly.Warning'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Icon', 'Blockly.utils.dom', 'Blockly.utils.object']);
|
||||
goog.addDependency("../../core/widgetdiv.js", ['Blockly.WidgetDiv'], ['Blockly.utils.style']);
|
||||
goog.addDependency("../../core/workspace.js", ['Blockly.Workspace'], ['Blockly.Cursor', 'Blockly.Marker', 'Blockly.Events', 'Blockly.utils', 'Blockly.utils.math', 'Blockly.VariableMap']);
|
||||
goog.addDependency("../../core/workspace.js", ['Blockly.Workspace'], ['Blockly.Cursor', 'Blockly.Marker', 'Blockly.MarkerManager', 'Blockly.Events', 'Blockly.utils', 'Blockly.utils.math', 'Blockly.VariableMap']);
|
||||
goog.addDependency("../../core/workspace_audio.js", ['Blockly.WorkspaceAudio'], ['Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.userAgent']);
|
||||
goog.addDependency("../../core/workspace_comment.js", ['Blockly.WorkspaceComment'], ['Blockly.Events', 'Blockly.Events.CommentChange', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.xml']);
|
||||
goog.addDependency("../../core/workspace_comment_render_svg.js", ['Blockly.WorkspaceCommentSvg.render'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom']);
|
||||
|
||||
@@ -57,8 +57,6 @@ Blockly.Flyout = function(workspaceOptions) {
|
||||
*/
|
||||
this.workspace_ = new Blockly.WorkspaceSvg(workspaceOptions);
|
||||
this.workspace_.isFlyout = true;
|
||||
this.workspace_.setCursor(new Blockly.FlyoutCursor());
|
||||
this.workspace_.setMarker(new Blockly.Marker());
|
||||
|
||||
/**
|
||||
* Is RTL vs LTR.
|
||||
@@ -233,6 +231,7 @@ Blockly.Flyout.prototype.createDom = function(tagName) {
|
||||
this.svgBackground_, 'flyout', 'fill');
|
||||
this.workspace_.getThemeManager().subscribe(
|
||||
this.svgBackground_, 'flyoutOpacity', 'fill-opacity');
|
||||
this.workspace_.getMarkerManager().setCursor(new Blockly.FlyoutCursor());
|
||||
return this.svgGroup_;
|
||||
};
|
||||
|
||||
|
||||
@@ -122,3 +122,12 @@ Blockly.Marker.prototype.hide = function() {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of this marker.
|
||||
*/
|
||||
Blockly.Marker.prototype.dispose = function() {
|
||||
if (this.getDrawer()) {
|
||||
this.getDrawer().dispose();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -86,10 +86,25 @@ Blockly.navigation.actionNames = {
|
||||
TOGGLE_KEYBOARD_NAV: 'toggle_keyboard_nav'
|
||||
};
|
||||
|
||||
/**
|
||||
* The name of the marker reserved for internal use.
|
||||
* @type {string}
|
||||
* @const
|
||||
*/
|
||||
Blockly.navigation.MARKER_NAME = 'local_marker_1';
|
||||
|
||||
/** ****** */
|
||||
/** Focus */
|
||||
/** ****** */
|
||||
|
||||
/**
|
||||
* Get the local marker.
|
||||
* @return {!Blockly.Marker} The local marker for the main workspace.
|
||||
*/
|
||||
Blockly.navigation.getMarker = function() {
|
||||
return Blockly.getMainWorkspace().getMarker(Blockly.navigation.MARKER_NAME);
|
||||
};
|
||||
|
||||
/**
|
||||
* If a toolbox exists, set the navigation state to toolbox and select the first
|
||||
* category in the toolbox.
|
||||
@@ -103,7 +118,7 @@ Blockly.navigation.focusToolbox_ = function() {
|
||||
Blockly.navigation.currentState_ = Blockly.navigation.STATE_TOOLBOX;
|
||||
Blockly.navigation.resetFlyout_(false /* shouldHide */);
|
||||
|
||||
if (!workspace.getMarker().getCurNode()) {
|
||||
if (!Blockly.navigation.getMarker().getCurNode()) {
|
||||
Blockly.navigation.markAtCursor_();
|
||||
}
|
||||
toolbox.selectFirstCategory();
|
||||
@@ -121,7 +136,7 @@ Blockly.navigation.focusFlyout_ = function() {
|
||||
var toolbox = workspace.getToolbox();
|
||||
var flyout = toolbox ? toolbox.flyout_ : workspace.getFlyout();
|
||||
|
||||
if (!workspace.getMarker().getCurNode()) {
|
||||
if (!Blockly.navigation.getMarker().getCurNode()) {
|
||||
Blockly.navigation.markAtCursor_();
|
||||
}
|
||||
|
||||
@@ -242,7 +257,7 @@ Blockly.navigation.resetFlyout_ = function(shouldHide) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.modifyWarn_ = function() {
|
||||
var markerNode = Blockly.getMainWorkspace().getMarker().getCurNode();
|
||||
var markerNode = Blockly.navigation.getMarker().getCurNode();
|
||||
var cursorNode = Blockly.getMainWorkspace().getCursor().getCurNode();
|
||||
|
||||
if (!markerNode) {
|
||||
@@ -313,7 +328,7 @@ Blockly.navigation.moveBlockToWorkspace_ = function(block, wsNode) {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.modify_ = function() {
|
||||
var markerNode = Blockly.getMainWorkspace().getMarker().getCurNode();
|
||||
var markerNode = Blockly.navigation.getMarker().getCurNode();
|
||||
var cursorNode = Blockly.getMainWorkspace().getCursor().getCurNode();
|
||||
if (!Blockly.navigation.modifyWarn_()) {
|
||||
return false;
|
||||
@@ -566,8 +581,8 @@ Blockly.navigation.disconnectBlocks_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.markAtCursor_ = function() {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
workspace.getMarker().setCurNode(workspace.getCursor().getCurNode());
|
||||
Blockly.navigation.getMarker().setCurNode(
|
||||
Blockly.getMainWorkspace().getCursor().getCurNode());
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -575,9 +590,9 @@ Blockly.navigation.markAtCursor_ = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.navigation.removeMark_ = function() {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
workspace.getMarker().setCurNode(null);
|
||||
workspace.getMarker().hide();
|
||||
var marker = Blockly.navigation.getMarker();
|
||||
marker.setCurNode(null);
|
||||
marker.hide();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -680,7 +695,7 @@ Blockly.navigation.disableKeyboardAccessibility = function() {
|
||||
var workspace = Blockly.getMainWorkspace();
|
||||
Blockly.getMainWorkspace().keyboardAccessibilityMode = false;
|
||||
workspace.getCursor().hide();
|
||||
workspace.getMarker().hide();
|
||||
Blockly.navigation.getMarker().hide();
|
||||
if (Blockly.navigation.getFlyoutCursor_()) {
|
||||
Blockly.navigation.getFlyoutCursor_().hide();
|
||||
}
|
||||
|
||||
182
core/marker_manager.js
Normal file
182
core/marker_manager.js
Normal file
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2019 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Object in charge of managing markers and the cursor.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.MarkerManager');
|
||||
|
||||
goog.require('Blockly.Cursor');
|
||||
goog.require('Blockly.Marker');
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage the multiple markers and the cursor on a workspace.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace for the marker manager.
|
||||
* @constructor
|
||||
* @package
|
||||
*/
|
||||
Blockly.MarkerManager = function(workspace){
|
||||
/**
|
||||
* The cursor.
|
||||
* @type {Blockly.Cursor}
|
||||
* @private
|
||||
*/
|
||||
this.cursor_ = null;
|
||||
|
||||
/**
|
||||
* The cursor's svg element.
|
||||
* @type {SVGElement}
|
||||
* @private
|
||||
*/
|
||||
this.cursorSvg_ = null;
|
||||
|
||||
/**
|
||||
* The map of markers for the workspace.
|
||||
* @type {!Object<string, !Blockly.Marker>}
|
||||
* @private
|
||||
*/
|
||||
this.markers_ = {};
|
||||
|
||||
/**
|
||||
* The workspace this marker manager is associated with.
|
||||
* @type {!Blockly.WorkspaceSvg}
|
||||
* @private
|
||||
*/
|
||||
this.workspace_ = workspace;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register the marker by adding it to the map of markers.
|
||||
* @param {string} id A unique identifier for the marker.
|
||||
* @param {!Blockly.Marker} marker The marker to register.
|
||||
*/
|
||||
Blockly.MarkerManager.prototype.registerMarker = function(id, marker) {
|
||||
if (this.markers_[id]) {
|
||||
this.unregisterMarker(id);
|
||||
}
|
||||
marker.setDrawer(this.workspace_.getRenderer()
|
||||
.makeMarkerDrawer(this.workspace_, marker));
|
||||
this.setMarkerSvg(marker.getDrawer().createDom());
|
||||
this.markers_[id] = marker;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unregister the marker by removing it from the map of markers.
|
||||
* @param {string} id The id of the marker to unregister.
|
||||
*/
|
||||
Blockly.MarkerManager.prototype.unregisterMarker = function(id) {
|
||||
var marker = this.markers_[id];
|
||||
if (marker) {
|
||||
marker.dispose();
|
||||
delete this.markers_[id];
|
||||
} else {
|
||||
throw Error('Marker with id ' + id + ' does not exist. Can only unregister' +
|
||||
'markers that exist.');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the cursor for the workspace.
|
||||
* @return {Blockly.Cursor} The cursor for this workspace.
|
||||
*/
|
||||
Blockly.MarkerManager.prototype.getCursor = function() {
|
||||
return this.cursor_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a single marker that corresponds to the given id.
|
||||
* @param {string} id A unique identifier for the marker.
|
||||
* @return {Blockly.Marker} The marker that corresponds to the given id, or null
|
||||
* if none exists.
|
||||
*/
|
||||
Blockly.MarkerManager.prototype.getMarker = function(id) {
|
||||
return this.markers_[id];
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the cursor and initializes the drawer for use with keyboard navigation.
|
||||
* @param {Blockly.Cursor} cursor The cursor used to move around this workspace.
|
||||
*/
|
||||
Blockly.MarkerManager.prototype.setCursor = function(cursor) {
|
||||
if (this.cursor_ && this.cursor_.getDrawer()) {
|
||||
this.cursor_.getDrawer().dispose();
|
||||
}
|
||||
this.cursor_ = cursor;
|
||||
if (this.cursor_) {
|
||||
var drawer = this.workspace_.getRenderer()
|
||||
.makeMarkerDrawer(this.workspace_, this.cursor_);
|
||||
this.cursor_.setDrawer(drawer);
|
||||
this.setCursorSvg(this.cursor_.getDrawer().createDom());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the cursor svg to this workspace svg group.
|
||||
* @param {SVGElement} cursorSvg The svg root of the cursor to be added to the
|
||||
* workspace svg group.
|
||||
* @package
|
||||
*/
|
||||
Blockly.MarkerManager.prototype.setCursorSvg = function(cursorSvg) {
|
||||
if (!cursorSvg) {
|
||||
this.cursorSvg_ = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.workspace_.getBlockCanvas().appendChild(cursorSvg);
|
||||
this.cursorSvg_ = cursorSvg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the marker svg to this workspaces svg group.
|
||||
* @param {SVGElement} markerSvg The svg root of the marker to be added to the
|
||||
* workspace svg group.
|
||||
* @package
|
||||
*/
|
||||
Blockly.MarkerManager.prototype.setMarkerSvg = function(markerSvg) {
|
||||
if (!markerSvg) {
|
||||
this.markerSvg_ = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.workspace_.getBlockCanvas()) {
|
||||
if (this.cursorSvg_) {
|
||||
this.workspace_.getBlockCanvas().insertBefore(markerSvg, this.cursorSvg_);
|
||||
} else {
|
||||
this.workspace_.getBlockCanvas().appendChild(markerSvg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of the marker manager.
|
||||
* Go through and delete all markers associated with this marker manager.
|
||||
* @suppress {checkTypes}
|
||||
* @package
|
||||
*/
|
||||
Blockly.MarkerManager.prototype.dispose = function() {
|
||||
var markerIds = Object.keys(this.markers_);
|
||||
for (var i = 0, markerId; (markerId = markerIds[i]); i++) {
|
||||
this.unregisterMarker(markerId);
|
||||
}
|
||||
this.markers_ = null;
|
||||
this.cursor_.dispose();
|
||||
this.cursor_ = null;
|
||||
};
|
||||
@@ -112,20 +112,6 @@ Blockly.Workspace = function(opt_options) {
|
||||
*/
|
||||
this.potentialVariableMap_ = null;
|
||||
|
||||
/**
|
||||
* The cursor used to navigate around the AST for keyboard navigation.
|
||||
* @type {!Blockly.Cursor}
|
||||
* @protected
|
||||
*/
|
||||
this.cursor_ = new Blockly.Cursor();
|
||||
|
||||
/**
|
||||
* The marker used to mark a location for keyboard navigation.
|
||||
* @type {!Blockly.Marker}
|
||||
* @protected
|
||||
*/
|
||||
this.marker_ = new Blockly.Marker();
|
||||
|
||||
/**
|
||||
* True if keyboard accessibility mode is on, false otherwise.
|
||||
* @type {boolean}
|
||||
@@ -160,41 +146,6 @@ Blockly.Workspace.prototype.MAX_UNDO = 1024;
|
||||
*/
|
||||
Blockly.Workspace.prototype.connectionDBList = null;
|
||||
|
||||
/**
|
||||
* Sets the cursor for keyboard navigation.
|
||||
* @param {!Blockly.Cursor} cursor The cursor used to navigate around the Blockly
|
||||
* AST for keyboard navigation.
|
||||
*/
|
||||
Blockly.Workspace.prototype.setCursor = function(cursor) {
|
||||
this.cursor_ = cursor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the marker for keyboard navigation.
|
||||
* @param {!Blockly.Marker} marker The marker used to mark a location for
|
||||
* keyboard navigation.
|
||||
*/
|
||||
Blockly.Workspace.prototype.setMarker = function(marker) {
|
||||
this.marker_ = marker;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the cursor used to navigate around the AST for keyboard navigation.
|
||||
* @return {Blockly.Cursor} The cursor for this workspace.
|
||||
*/
|
||||
Blockly.Workspace.prototype.getCursor = function() {
|
||||
return this.cursor_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the marker used to mark a location for keyboard navigation.
|
||||
* @return {Blockly.Marker} The marker used to mark a location for keyboard
|
||||
* navigation.
|
||||
*/
|
||||
Blockly.Workspace.prototype.getMarker = function() {
|
||||
return this.marker_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dispose of this workspace.
|
||||
* Unlink from all DOM elements to prevent memory leaks.
|
||||
|
||||
@@ -31,6 +31,7 @@ goog.require('Blockly.Events');
|
||||
goog.require('Blockly.Events.BlockCreate');
|
||||
goog.require('Blockly.Gesture');
|
||||
goog.require('Blockly.Grid');
|
||||
goog.require('Blockly.MarkerManager');
|
||||
goog.require('Blockly.Msg');
|
||||
goog.require('Blockly.navigation');
|
||||
goog.require('Blockly.Options');
|
||||
@@ -109,20 +110,11 @@ Blockly.WorkspaceSvg = function(options,
|
||||
new Blockly.Grid(options.gridPattern, options.gridOptions) : null;
|
||||
|
||||
/**
|
||||
* Holds the cursors svg element when the cursor is attached to the workspace.
|
||||
* This is null if there is no cursor on the workspace.
|
||||
* @type {SVGElement}
|
||||
* Manager in charge of markers and cursors.
|
||||
* @type {!Blockly.MarkerManager}
|
||||
* @private
|
||||
*/
|
||||
this.cursorSvg_ = null;
|
||||
|
||||
/**
|
||||
* Holds the markers svg element when the marker is attached to the workspace.
|
||||
* This is null if there is no marker on the workspace.
|
||||
* @type {SVGElement}
|
||||
* @private
|
||||
*/
|
||||
this.markerSvg_ = null;
|
||||
this.markerManager_ = new Blockly.MarkerManager(this);
|
||||
|
||||
if (Blockly.Variables && Blockly.Variables.flyoutCategory) {
|
||||
this.registerToolboxCategoryCallback(Blockly.VARIABLE_CATEGORY_NAME,
|
||||
@@ -432,6 +424,59 @@ Blockly.WorkspaceSvg.prototype.inverseScreenCTM_ = null;
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.inverseScreenCTMDirty_ = true;
|
||||
|
||||
/**
|
||||
* Get the marker manager for this workspace.
|
||||
* @return {Blockly.MarkerManager} The marker manager.
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.getMarkerManager = function() {
|
||||
return this.markerManager_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the cursor svg to this workspaces svg group.
|
||||
* @param {SVGElement} cursorSvg The svg root of the cursor to be added to the
|
||||
* workspace svg group.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.setCursorSvg = function(cursorSvg) {
|
||||
this.markerManager_.setCursorSvg(cursorSvg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the marker svg to this workspaces svg group.
|
||||
* @param {SVGElement} markerSvg The svg root of the marker to be added to the
|
||||
* workspace svg group.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.setMarkerSvg = function(markerSvg) {
|
||||
this.markerManager_.setMarkerSvg(markerSvg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the marker with the given id.
|
||||
* @param {string} id The id of the marker.
|
||||
* @return {Blockly.Marker} The marker with the given id or null if no marker
|
||||
* with the given id exists.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.getMarker = function(id) {
|
||||
if (this.markerManager_) {
|
||||
return this.markerManager_.getMarker(id);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* The cursor for this workspace.
|
||||
* @return {Blockly.Cursor} The cursor for the workspace.
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.getCursor = function() {
|
||||
if (this.markerManager_) {
|
||||
return this.markerManager_.getCursor();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the block renderer attached to this workspace.
|
||||
* @return {!Blockly.blockRendering.Renderer} The renderer attached to this workspace.
|
||||
@@ -512,74 +557,6 @@ Blockly.WorkspaceSvg.prototype.updateBlockStyles_ = function(blocks) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the cursor for use with keyboard navigation.
|
||||
* @param {!Blockly.Cursor} cursor The cursor used to move around this workspace.
|
||||
* @override
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.setCursor = function(cursor) {
|
||||
if (this.cursor_.getDrawer()) {
|
||||
this.cursor_.getDrawer().dispose();
|
||||
}
|
||||
this.cursor_ = cursor;
|
||||
this.cursor_.setDrawer(this.getRenderer().makeMarkerDrawer(this, this.cursor_));
|
||||
this.setCursorSvg(this.cursor_.getDrawer().createDom());
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the marker for use with keyboard navigation.
|
||||
* @param {!Blockly.Marker} marker Used to save a location in the Blockly AST.
|
||||
* @override
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.setMarker = function(marker) {
|
||||
if (this.marker_.getDrawer()) {
|
||||
this.marker_.getDrawer().dispose();
|
||||
}
|
||||
this.marker_ = marker;
|
||||
this.marker_.setDrawer(this.getRenderer().makeMarkerDrawer(this, this.marker_));
|
||||
this.setMarkerSvg(this.marker_.getDrawer().createDom());
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the cursor svg to this workspaces svg group.
|
||||
* @param {SVGElement} cursorSvg The svg root of the cursor to be added to the
|
||||
* workspace svg group.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.setCursorSvg = function(cursorSvg) {
|
||||
if (!cursorSvg) {
|
||||
this.cursorSvg_ = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.svgBlockCanvas_) {
|
||||
this.svgBlockCanvas_.appendChild(cursorSvg);
|
||||
this.cursorSvg_ = cursorSvg;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add the marker svg to this workspaces svg group.
|
||||
* @param {SVGElement} markerSvg The svg root of the marker to be added to the
|
||||
* workspace svg group.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.setMarkerSvg = function(markerSvg) {
|
||||
if (!markerSvg) {
|
||||
this.markerSvg_ = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.svgBlockCanvas_) {
|
||||
if (this.cursorSvg_) {
|
||||
this.svgBlockCanvas_.insertBefore(markerSvg, this.cursorSvg_);
|
||||
} else {
|
||||
this.svgBlockCanvas_.appendChild(markerSvg);
|
||||
}
|
||||
this.markerSvg_ = markerSvg;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Getter for the inverted screen CTM.
|
||||
* @return {SVGMatrix} The matrix to use in mouseToSvg
|
||||
@@ -684,6 +661,15 @@ Blockly.WorkspaceSvg.prototype.getInjectionDiv = function() {
|
||||
return /** @type {!Element} */ (this.injectionDiv_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the svg block canvas for the workspace.
|
||||
* @return {SVGElement} The svg group for the workspace.
|
||||
* @package
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.getBlockCanvas = function() {
|
||||
return this.svgBlockCanvas_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Save resize handler data so we can delete it later in dispose.
|
||||
* @param {!Array.<!Array>} handler Data that can be passed to unbindEvent_.
|
||||
@@ -754,13 +740,9 @@ Blockly.WorkspaceSvg.prototype.createDom = function(opt_backgroundClass) {
|
||||
}
|
||||
this.recordDeleteAreas();
|
||||
|
||||
this.cursor_.setDrawer(this.getRenderer().makeMarkerDrawer(this, this.cursor_));
|
||||
var svgCursor = this.cursor_.getDrawer().createDom();
|
||||
this.svgGroup_.appendChild(svgCursor);
|
||||
|
||||
this.marker_.setDrawer(this.getRenderer().makeMarkerDrawer(this, this.marker_));
|
||||
var svgMarker = this.marker_.getDrawer().createDom();
|
||||
this.svgGroup_.appendChild(svgMarker);
|
||||
this.markerManager_.setCursor(new Blockly.Cursor());
|
||||
this.markerManager_.registerMarker(Blockly.navigation.MARKER_NAME,
|
||||
new Blockly.Marker());
|
||||
|
||||
this.getRenderer().getConstants().createDom(this.svgGroup_);
|
||||
return this.svgGroup_;
|
||||
@@ -804,14 +786,6 @@ Blockly.WorkspaceSvg.prototype.dispose = function() {
|
||||
this.zoomControls_ = null;
|
||||
}
|
||||
|
||||
if (this.marker_ && this.marker_.getDrawer()) {
|
||||
this.marker_.getDrawer().dispose();
|
||||
}
|
||||
|
||||
if (this.getCursor() && this.getCursor().getDrawer()) {
|
||||
this.getCursor().getDrawer().dispose();
|
||||
}
|
||||
|
||||
if (this.audioManager_) {
|
||||
this.audioManager_.dispose();
|
||||
this.audioManager_ = null;
|
||||
@@ -832,6 +806,12 @@ Blockly.WorkspaceSvg.prototype.dispose = function() {
|
||||
this.themeManager_ = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.markerManager_) {
|
||||
this.markerManager_.dispose();
|
||||
this.markerManager_ = null;
|
||||
}
|
||||
|
||||
Blockly.WorkspaceSvg.superClass_.dispose.call(this);
|
||||
|
||||
this.connectionDBList = null;
|
||||
@@ -1292,7 +1272,7 @@ Blockly.WorkspaceSvg.prototype.pasteBlock_ = function(xmlBlock) {
|
||||
var block = Blockly.Xml.domToBlock(xmlBlock, this);
|
||||
|
||||
// Handle paste for keyboard navigation
|
||||
var markedNode = this.getMarker().getCurNode();
|
||||
var markedNode = this.getMarker(Blockly.navigation.MARKER_NAME).getCurNode();
|
||||
if (this.keyboardAccessibilityMode && markedNode &&
|
||||
markedNode.isConnection()) {
|
||||
var markedLocation =
|
||||
|
||||
@@ -62,8 +62,7 @@ suite('Cursor', function() {
|
||||
"helpUrl": ""
|
||||
}
|
||||
]);
|
||||
this.workspace = new Blockly.Workspace();
|
||||
this.workspace.setCursor(new Blockly.Cursor());
|
||||
this.workspace = Blockly.inject('blocklyDiv', {});
|
||||
this.cursor = this.workspace.getCursor();
|
||||
var blockA = this.workspace.newBlock('input_statement');
|
||||
var blockB = this.workspace.newBlock('input_statement');
|
||||
@@ -74,7 +73,7 @@ suite('Cursor', function() {
|
||||
blockA.nextConnection.connect(blockB.previousConnection);
|
||||
blockA.inputList[0].connection.connect(blockE.outputConnection);
|
||||
blockB.inputList[1].connection.connect(blockC.previousConnection);
|
||||
|
||||
this.cursor.drawer_ = null;
|
||||
this.blocks = {
|
||||
A: blockA,
|
||||
B: blockB,
|
||||
|
||||
@@ -54,7 +54,7 @@ suite('Insert/Modify', function() {
|
||||
// TODO: Marked connection or cursor connection is already connected.
|
||||
suite('Marker on next', function() {
|
||||
setup(function() {
|
||||
this.workspace.getMarker().setCurNode(
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(
|
||||
Blockly.ASTNode.createConnectionNode(
|
||||
this.stack_block_1.nextConnection));
|
||||
});
|
||||
@@ -98,7 +98,7 @@ suite('Insert/Modify', function() {
|
||||
|
||||
suite('Marker on previous', function() {
|
||||
setup(function() {
|
||||
this.workspace.getMarker().setCurNode(
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(
|
||||
Blockly.ASTNode.createConnectionNode(
|
||||
this.stack_block_1.previousConnection));
|
||||
});
|
||||
@@ -141,7 +141,7 @@ suite('Insert/Modify', function() {
|
||||
|
||||
suite('Marker on value input', function() {
|
||||
setup(function() {
|
||||
this.workspace.getMarker().setCurNode(
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(
|
||||
Blockly.ASTNode.createConnectionNode(
|
||||
this.row_block_1.inputList[0].connection));
|
||||
});
|
||||
@@ -182,7 +182,7 @@ suite('Insert/Modify', function() {
|
||||
this.statement_block_1.inputList[0].connection.connect(
|
||||
this.stack_block_1.previousConnection);
|
||||
this.stack_block_1.nextConnection.connect(this.stack_block_2.previousConnection);
|
||||
this.workspace.getMarker().setCurNode(
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(
|
||||
Blockly.ASTNode.createInputNode(
|
||||
this.statement_block_1.inputList[0]));
|
||||
});
|
||||
@@ -213,7 +213,7 @@ suite('Insert/Modify', function() {
|
||||
|
||||
suite('Marker on output', function() {
|
||||
setup(function() {
|
||||
this.workspace.getMarker().setCurNode(
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(
|
||||
Blockly.ASTNode.createConnectionNode(
|
||||
this.row_block_1.outputConnection));
|
||||
});
|
||||
@@ -249,7 +249,8 @@ suite('Insert/Modify', function() {
|
||||
|
||||
suite('Marked Workspace', function() {
|
||||
setup(function() {
|
||||
this.workspace.getMarker().setCurNode(
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).drawer_ = null;
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(
|
||||
Blockly.ASTNode.createWorkspaceNode(
|
||||
this.workspace, new Blockly.utils.Coordinate(100, 200)));
|
||||
});
|
||||
@@ -344,7 +345,7 @@ suite('Insert/Modify', function() {
|
||||
// These tests are using a stack block, but do not depend on the type of
|
||||
// the block.
|
||||
setup(function() {
|
||||
this.workspace.getMarker().setCurNode(
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(
|
||||
Blockly.ASTNode.createBlockNode(
|
||||
this.stack_block_1));
|
||||
});
|
||||
@@ -358,7 +359,7 @@ suite('Insert/Modify', function() {
|
||||
});
|
||||
suite('Marked stack block', function() {
|
||||
setup(function() {
|
||||
this.workspace.getMarker().setCurNode(
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(
|
||||
Blockly.ASTNode.createBlockNode(
|
||||
this.stack_block_1));
|
||||
});
|
||||
@@ -389,7 +390,7 @@ suite('Insert/Modify', function() {
|
||||
});
|
||||
suite('Marked row block', function() {
|
||||
setup(function() {
|
||||
this.workspace.getMarker().setCurNode(
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(
|
||||
Blockly.ASTNode.createBlockNode(
|
||||
this.row_block_1));
|
||||
});
|
||||
|
||||
@@ -166,6 +166,7 @@ suite('Navigation', function() {
|
||||
]
|
||||
}]);
|
||||
this.workspace = createNavigationWorkspace(true);
|
||||
Blockly.mainWorkspace = this.workspace;
|
||||
Blockly.navigation.focusToolbox_();
|
||||
Blockly.navigation.focusFlyout_();
|
||||
this.mockEvent = {
|
||||
@@ -329,7 +330,7 @@ suite('Navigation', function() {
|
||||
Blockly.ASTNode.createConnectionNode(this.basicBlock.previousConnection));
|
||||
this.mockEvent.keyCode = Blockly.utils.KeyCodes.ENTER;
|
||||
chai.assert.isTrue(Blockly.navigation.onKeyPress(this.mockEvent));
|
||||
var markedNode = this.workspace.getMarker().getCurNode();
|
||||
var markedNode = this.workspace.getMarker(Blockly.navigation.MARKER_NAME).getCurNode();
|
||||
chai.assert.equal(markedNode.getLocation(), this.basicBlock.previousConnection);
|
||||
chai.assert.equal(Blockly.navigation.currentState_,
|
||||
Blockly.navigation.STATE_WS);
|
||||
@@ -346,7 +347,26 @@ suite('Navigation', function() {
|
||||
|
||||
suite('Test key press', function() {
|
||||
setup(function() {
|
||||
this.workspace = new Blockly.Workspace({readOnly: false});
|
||||
Blockly.defineBlocksWithJsonArray([{
|
||||
"type": "basic_block",
|
||||
"message0": "%1",
|
||||
"args0": [
|
||||
{
|
||||
"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"]
|
||||
]
|
||||
}
|
||||
]
|
||||
}]);
|
||||
this.workspace = createNavigationWorkspace(true);
|
||||
this.workspace.getCursor().drawer_ = null;
|
||||
this.basicBlock = this.workspace.newBlock('basic_block');
|
||||
Blockly.user.keyMap.setKeyMap(Blockly.user.keyMap.createDefaultKeyMap());
|
||||
Blockly.mainWorkspace = this.workspace;
|
||||
Blockly.getMainWorkspace().keyboardAccessibilityMode = true;
|
||||
@@ -359,12 +379,10 @@ suite('Navigation', function() {
|
||||
};
|
||||
});
|
||||
test('Action does not exist', function() {
|
||||
var block = new Blockly.Block(this.workspace);
|
||||
var field = new Blockly.FieldDropdown([['a','b'], ['c','d']]);
|
||||
field.setSourceBlock(block);
|
||||
var block = this.workspace.getTopBlocks()[0];
|
||||
var field = block.inputList[0].fieldRow[0];
|
||||
sinon.spy(field, 'onBlocklyAction');
|
||||
this.workspace.getCursor().setCurNode(Blockly.ASTNode.createFieldNode(field));
|
||||
|
||||
this.mockEvent.keyCode = Blockly.utils.KeyCodes.N;
|
||||
var isHandled = Blockly.navigation.onKeyPress(this.mockEvent);
|
||||
chai.assert.isFalse(isHandled);
|
||||
@@ -374,9 +392,9 @@ suite('Navigation', function() {
|
||||
});
|
||||
|
||||
test('Action exists - field handles action', function() {
|
||||
var block = new Blockly.Block(this.workspace);
|
||||
var field = new Blockly.FieldDropdown([['a','b'], ['c','d']]);
|
||||
field.setSourceBlock(block);
|
||||
var block = this.workspace.getTopBlocks()[0];
|
||||
var field = block.inputList[0].fieldRow[0];
|
||||
|
||||
sinon.stub(field, 'onBlocklyAction').callsFake(function(){
|
||||
return true;
|
||||
});
|
||||
@@ -390,9 +408,8 @@ suite('Navigation', function() {
|
||||
});
|
||||
|
||||
test('Action exists - field does not handle action', function() {
|
||||
var block = new Blockly.Block(this.workspace);
|
||||
var field = new Blockly.FieldDropdown([['a','b'], ['c','d']]);
|
||||
field.setSourceBlock(block);
|
||||
var block = this.workspace.getTopBlocks()[0];
|
||||
var field = block.inputList[0].fieldRow[0];
|
||||
sinon.spy(field, 'onBlocklyAction');
|
||||
this.workspace.getCursor().setCurNode(Blockly.ASTNode.createFieldNode(field));
|
||||
|
||||
@@ -456,9 +473,10 @@ suite('Navigation', function() {
|
||||
"tooltip": "",
|
||||
"helpUrl": ""
|
||||
}]);
|
||||
this.workspace = new Blockly.Workspace({readOnly: true});
|
||||
this.workspace.setCursor(new Blockly.Cursor());
|
||||
this.workspace = Blockly.inject('blocklyDiv', {readOnly: true});
|
||||
|
||||
Blockly.mainWorkspace = this.workspace;
|
||||
this.workspace.getCursor().drawer_ = null;
|
||||
Blockly.getMainWorkspace().keyboardAccessibilityMode = true;
|
||||
Blockly.navigation.currentState_ = Blockly.navigation.STATE_WS;
|
||||
|
||||
@@ -525,7 +543,7 @@ suite('Navigation', function() {
|
||||
test('Insert from flyout with a valid connection marked', function() {
|
||||
var previousConnection = this.basicBlock.previousConnection;
|
||||
var prevNode = Blockly.ASTNode.createConnectionNode(previousConnection);
|
||||
this.workspace.getMarker().setCurNode(prevNode);
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(prevNode);
|
||||
|
||||
Blockly.navigation.focusToolbox_();
|
||||
Blockly.navigation.focusFlyout_();
|
||||
@@ -557,7 +575,7 @@ suite('Navigation', function() {
|
||||
|
||||
test('Connect two blocks that are on the workspace', function() {
|
||||
var targetNode = Blockly.ASTNode.createConnectionNode(this.basicBlock.previousConnection);
|
||||
this.workspace.getMarker().setCurNode(targetNode);
|
||||
this.workspace.getMarker(Blockly.navigation.MARKER_NAME).setCurNode(targetNode);
|
||||
|
||||
var sourceNode = Blockly.ASTNode.createConnectionNode(this.basicBlock2.nextConnection);
|
||||
this.workspace.getCursor().setCurNode(sourceNode);
|
||||
|
||||
Reference in New Issue
Block a user