mirror of
https://github.com/google/blockly.git
synced 2026-01-08 01:20:12 +01:00
Strip out more bloat from toolbox (#3068)
Also removes three private accesses from workspaceSvg into toolbox tree. The strategy for workspace.updateToolbox is no longer to clear and repopulate the toolbox, but rather to throw away the old toolbox and rebuild a new one. This is simpler and more reliable. This commit trims off another KB from the compiled code.
This commit is contained in:
@@ -47,7 +47,7 @@ Blockly.Component = function() {
|
||||
* been set by calling {@link #setRightToLeft} explicitly.
|
||||
* @private {?boolean}
|
||||
*/
|
||||
this.rightToLeft_ = Blockly.Component.defaultRightToLeft_;
|
||||
this.rightToLeft_ = Blockly.Component.defaultRightToLeft;
|
||||
|
||||
/**
|
||||
* Unique ID of the component, lazily initialized in {@link
|
||||
@@ -77,42 +77,37 @@ Blockly.Component = function() {
|
||||
this.parent_ = null;
|
||||
|
||||
/**
|
||||
* Array of child components. Lazily initialized on first use. Must be kept
|
||||
* in sync with `childIndex_`. This property is strictly private and
|
||||
* must not be accessed directly outside of this class!
|
||||
* Array of child components.
|
||||
* Must be kept in sync with `childIndex_`. This property is strictly
|
||||
* private and must not be accessed directly outside of this class!
|
||||
* @private {?Array.<?Blockly.Component>}
|
||||
*/
|
||||
this.children_ = null;
|
||||
this.children_ = [];
|
||||
|
||||
/**
|
||||
* Map of child component IDs to child components. Used for constant-time
|
||||
* random access to child components by ID. Lazily initialized on first use.
|
||||
* random access to child components by ID.
|
||||
* Must be kept in sync with `children_`. This property is strictly
|
||||
* private and must not be accessed directly outside of this class!
|
||||
*
|
||||
* @private {?Object}
|
||||
*/
|
||||
this.childIndex_ = null;
|
||||
this.childIndex_ = {};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The default right to left value.
|
||||
* @type {?boolean}
|
||||
* @private
|
||||
* @type {boolean}
|
||||
* @package
|
||||
*/
|
||||
Blockly.Component.defaultRightToLeft_ = false;
|
||||
Blockly.Component.defaultRightToLeft = false;
|
||||
|
||||
/**
|
||||
* Errors thrown by the component.
|
||||
* @enum {string}
|
||||
*/
|
||||
Blockly.Component.Error = {
|
||||
/**
|
||||
* Error when a method is not supported.
|
||||
*/
|
||||
NOT_SUPPORTED: 'Method not supported',
|
||||
|
||||
/**
|
||||
* Error when the component is already rendered and another render attempt is
|
||||
* made.
|
||||
@@ -129,32 +124,7 @@ Blockly.Component.Error = {
|
||||
* Error when an attempt is made to add a child component at an out-of-bounds
|
||||
* index. We don't support sparse child arrays.
|
||||
*/
|
||||
CHILD_INDEX_OUT_OF_BOUNDS: 'Child component index out of bounds',
|
||||
|
||||
/**
|
||||
* Error when an attempt is made to remove a child component from a component
|
||||
* other than its parent.
|
||||
*/
|
||||
NOT_OUR_CHILD: 'Child is not in parent component',
|
||||
|
||||
/**
|
||||
* Error when an operation requiring DOM interaction is made when the
|
||||
* component is not in the document
|
||||
*/
|
||||
NOT_IN_DOCUMENT: 'Operation not supported while component is not in document'
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the default right-to-left value. This causes all component's created from
|
||||
* this point forward to have the given value. This is useful for cases where
|
||||
* a given page is always in one directionality, avoiding unnecessary
|
||||
* right to left determinations.
|
||||
* @param {?boolean} rightToLeft Whether the components should be rendered
|
||||
* right-to-left. Null iff components should determine their directionality.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Component.setDefaultRightToLeft = function(rightToLeft) {
|
||||
Blockly.Component.defaultRightToLeft_ = rightToLeft;
|
||||
CHILD_INDEX_OUT_OF_BOUNDS: 'Child component index out of bounds'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -196,11 +166,7 @@ Blockly.Component.prototype.setElementInternal = function(element) {
|
||||
/**
|
||||
* Sets the parent of this component to use for event bubbling. Throws an error
|
||||
* if the component already has a parent or if an attempt is made to add a
|
||||
* component to itself as a child. Callers must use `removeChild`
|
||||
* or `removeChildAt` to remove components from their containers before
|
||||
* calling this method.
|
||||
* @see Blockly.Component#removeChild
|
||||
* @see Blockly.Component#removeChildAt
|
||||
* component to itself as a child.
|
||||
* @param {Blockly.Component} parent The parent component.
|
||||
* @protected
|
||||
*/
|
||||
@@ -212,8 +178,7 @@ Blockly.Component.prototype.setParent = function(parent) {
|
||||
|
||||
if (parent && this.parent_ && this.id_ && this.parent_.getChild(this.id_) &&
|
||||
this.parent_ != parent) {
|
||||
// This component is already the child of some parent, so it should be
|
||||
// removed using removeChild/removeChildAt first.
|
||||
// This component is already the child of some parent.
|
||||
throw Error(Blockly.Component.Error.PARENT_UNABLE_TO_BE_SET);
|
||||
}
|
||||
|
||||
@@ -479,12 +444,6 @@ Blockly.Component.prototype.addChildAt = function(child, index, opt_render) {
|
||||
throw Error(Blockly.Component.Error.CHILD_INDEX_OUT_OF_BOUNDS);
|
||||
}
|
||||
|
||||
// Create the index and the child array on first use.
|
||||
if (!this.childIndex_ || !this.children_) {
|
||||
this.childIndex_ = {};
|
||||
this.children_ = [];
|
||||
}
|
||||
|
||||
// Moving child within component, remove old reference.
|
||||
this.childIndex_[child.getId()] = child;
|
||||
if (child.getParent() == this) {
|
||||
@@ -554,16 +513,12 @@ Blockly.Component.prototype.getContentElement = function() {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Component.prototype.isRightToLeft = function() {
|
||||
if (this.rightToLeft_ == null) {
|
||||
this.rightToLeft_ = Blockly.utils.style.isRightToLeft(
|
||||
this.inDocument_ ? this.element_ : document.body);
|
||||
}
|
||||
return this.rightToLeft_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set is right-to-left. This function should be used if the component needs
|
||||
* to know the rendering direction during dom creation (i.e. before
|
||||
* to know the rendering direction during DOM creation (i.e. before
|
||||
* {@link #enterDocument} is called and is right-to-left is set).
|
||||
* @param {boolean} rightToLeft Whether the component is rendered
|
||||
* right-to-left.
|
||||
@@ -582,7 +537,7 @@ Blockly.Component.prototype.setRightToLeft = function(rightToLeft) {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Component.prototype.hasChildren = function() {
|
||||
return !!this.children_ && this.children_.length != 0;
|
||||
return this.children_.length != 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -591,7 +546,7 @@ Blockly.Component.prototype.hasChildren = function() {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Component.prototype.getChildCount = function() {
|
||||
return this.children_ ? this.children_.length : 0;
|
||||
return this.children_.length;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -602,10 +557,8 @@ Blockly.Component.prototype.getChildCount = function() {
|
||||
*/
|
||||
Blockly.Component.prototype.getChild = function(id) {
|
||||
// Use childIndex_ for O(1) access by ID.
|
||||
return (this.childIndex_ && id) ?
|
||||
/** @type {Blockly.Component} */ (
|
||||
this.childIndex_[id]) ||
|
||||
null : null;
|
||||
return id ?
|
||||
/** @type {Blockly.Component} */ (this.childIndex_[id]) || null : null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -616,7 +569,7 @@ Blockly.Component.prototype.getChild = function(id) {
|
||||
*/
|
||||
Blockly.Component.prototype.getChildAt = function(index) {
|
||||
// Use children_ for access by index.
|
||||
return this.children_ ? this.children_[index] || null : null;
|
||||
return this.children_[index] || null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -631,10 +584,8 @@ Blockly.Component.prototype.getChildAt = function(index) {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Component.prototype.forEachChild = function(f, opt_obj) {
|
||||
if (this.children_) {
|
||||
for (var i = 0; i < this.children_.length; i++) {
|
||||
f.call(/** @type {?} */ (opt_obj), this.children_[i], i);
|
||||
}
|
||||
for (var i = 0; i < this.children_.length; i++) {
|
||||
f.call(/** @type {?} */ (opt_obj), this.children_[i], i);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -646,96 +597,5 @@ Blockly.Component.prototype.forEachChild = function(f, opt_obj) {
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Component.prototype.indexOfChild = function(child) {
|
||||
return (this.children_ && child) ? this.children_.indexOf(child) : -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the given child from this component, and returns it. Throws an error
|
||||
* if the argument is invalid or if the specified child isn't found in the
|
||||
* parent component. The argument can either be a string (interpreted as the
|
||||
* ID of the child component to remove) or the child component itself.
|
||||
*
|
||||
* If `opt_unrender` is true, calls {@link Blockly.Component#exitDocument}
|
||||
* on the removed child, and subsequently detaches the child's DOM from the
|
||||
* document. Otherwise it is the caller's responsibility to clean up the child
|
||||
* component's DOM.
|
||||
*
|
||||
* @see Blockly.Component#removeChildAt
|
||||
* @param {string|Blockly.Component|null} child The ID of the child to remove,
|
||||
* or the child component itself.
|
||||
* @param {boolean=} opt_unrender If true, calls `exitDocument` on the
|
||||
* removed child component, and detaches its DOM from the document.
|
||||
* @return {Blockly.Component} The removed component, if any.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Component.prototype.removeChild = function(child, opt_unrender) {
|
||||
if (child) {
|
||||
// Normalize child to be the object and id to be the ID string. This also
|
||||
// ensures that the child is really ours.
|
||||
var id = (typeof child === 'string' || child instanceof String) ?
|
||||
String(child) : child.getId();
|
||||
child = this.getChild(id);
|
||||
|
||||
if (id && child) {
|
||||
delete this.childIndex_[id];
|
||||
var index = this.children_.indexOf(child);
|
||||
if (index > -1) {
|
||||
this.children_.splice(index, 1);
|
||||
}
|
||||
|
||||
if (opt_unrender) {
|
||||
// Remove the child component's DOM from the document. We have to call
|
||||
// exitDocument first (see documentation).
|
||||
child.exitDocument();
|
||||
if (child.element_) {
|
||||
Blockly.utils.dom.removeNode(child.element_);
|
||||
}
|
||||
}
|
||||
|
||||
// Child's parent must be set to null after exitDocument is called
|
||||
// so that the child can unlisten to its parent if required.
|
||||
child.setParent(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (!child) {
|
||||
throw Error(Blockly.Component.Error.NOT_OUR_CHILD);
|
||||
}
|
||||
|
||||
return /** @type {!Blockly.Component} */ (child);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the child at the given index from this component, and returns it.
|
||||
* Throws an error if the argument is out of bounds, or if the specified child
|
||||
* isn't found in the parent. See {@link Blockly.Component#removeChild} for
|
||||
* detailed semantics.
|
||||
*
|
||||
* @see Blockly.Component#removeChild
|
||||
* @param {number} index 0-based index of the child to remove.
|
||||
* @param {boolean=} opt_unrender If true, calls `exitDocument` on the
|
||||
* removed child component, and detaches its DOM from the document.
|
||||
* @return {Blockly.Component} The removed component, if any.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Component.prototype.removeChildAt = function(index, opt_unrender) {
|
||||
// removeChild(null) will throw error.
|
||||
return this.removeChild(this.getChildAt(index), opt_unrender);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes every child component attached to this one and returns them.
|
||||
*
|
||||
* @see Blockly.Component#removeChild
|
||||
* @param {boolean=} opt_unrender If true, calls {@link #exitDocument} on the
|
||||
* removed child components, and detaches their DOM from the document.
|
||||
* @return {!Array.<Blockly.Component>} The removed components if any.
|
||||
* @protected
|
||||
*/
|
||||
Blockly.Component.prototype.removeChildren = function(opt_unrender) {
|
||||
var removedChildren = [];
|
||||
while (this.hasChildren()) {
|
||||
removedChildren.push(this.removeChildAt(0, opt_unrender));
|
||||
}
|
||||
return removedChildren;
|
||||
return this.children_.indexOf(child);
|
||||
};
|
||||
|
||||
@@ -82,12 +82,11 @@ Blockly.MenuItem.prototype.createDom = function() {
|
||||
(!this.enabled_ ? 'goog-menuitem-disabled ' : '') +
|
||||
(this.checked_ ? 'goog-option-selected ' : '') +
|
||||
(this.isRightToLeft() ? 'goog-menuitem-rtl ' : ''));
|
||||
element.setAttribute('style', 'user-select: none');
|
||||
|
||||
var content = this.getContentWrapperDom();
|
||||
element.appendChild(content);
|
||||
|
||||
// Add a cheeckbox for checkable menu items.
|
||||
// Add a checkbox for checkable menu items.
|
||||
var checkboxDom = this.getCheckboxDom();
|
||||
if (checkboxDom) {
|
||||
content.appendChild(checkboxDom);
|
||||
@@ -113,7 +112,6 @@ Blockly.MenuItem.prototype.getCheckboxDom = function() {
|
||||
}
|
||||
var menuItemCheckbox = document.createElement('div');
|
||||
menuItemCheckbox.setAttribute('class', 'goog-menuitem-checkbox');
|
||||
menuItemCheckbox.setAttribute('style', 'user-select: none;');
|
||||
return menuItemCheckbox;
|
||||
};
|
||||
|
||||
@@ -136,7 +134,6 @@ Blockly.MenuItem.prototype.getContentDom = function() {
|
||||
Blockly.MenuItem.prototype.getContentWrapperDom = function() {
|
||||
var contentWrapper = document.createElement('div');
|
||||
contentWrapper.setAttribute('class', 'goog-menuitem-content');
|
||||
contentWrapper.setAttribute('style', 'user-select: none;');
|
||||
return contentWrapper;
|
||||
};
|
||||
|
||||
@@ -212,15 +209,6 @@ Blockly.MenuItem.prototype.setChecked = function(checked) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if the component is currently highlighted, false otherwise.
|
||||
* @return {boolean} Whether the component is highlighted.
|
||||
* @package
|
||||
*/
|
||||
Blockly.MenuItem.prototype.isHighlighted = function() {
|
||||
return this.highlight_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Highlights or unhighlights the component.
|
||||
* @param {boolean} highlight Whether to highlight or unhighlight the component.
|
||||
|
||||
@@ -233,8 +233,7 @@ Blockly.tree.BaseNode.prototype.exitDocument = function() {
|
||||
* The method assumes that the child doesn't have parent node yet.
|
||||
* @override
|
||||
*/
|
||||
Blockly.tree.BaseNode.prototype.addChildAt = function(
|
||||
child, index) {
|
||||
Blockly.tree.BaseNode.prototype.addChildAt = function(child, index) {
|
||||
child = /** @type {Blockly.tree.BaseNode} */ (child);
|
||||
var prevNode = this.getChildAt(index - 1);
|
||||
var nextNode = this.getChildAt(index);
|
||||
@@ -293,21 +292,15 @@ Blockly.tree.BaseNode.prototype.addChildAt = function(
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a node as a child to the current node.
|
||||
* Appends a node as a child to the current node.
|
||||
* @param {Blockly.tree.BaseNode} child The child to add.
|
||||
* @param {Blockly.tree.BaseNode=} opt_before If specified, the new child is
|
||||
* added as a child before this one. If not specified, it's appended to the
|
||||
* end.
|
||||
* @return {!Blockly.tree.BaseNode} The added child.
|
||||
* @package
|
||||
*/
|
||||
Blockly.tree.BaseNode.prototype.add = function(child, opt_before) {
|
||||
Blockly.tree.BaseNode.prototype.add = function(child) {
|
||||
if (child.getParent()) {
|
||||
child.getParent().removeChild(child);
|
||||
throw Error(Blockly.Component.Error.PARENT_UNABLE_TO_BE_SET);
|
||||
}
|
||||
this.addChildAt(
|
||||
child, opt_before ? this.indexOfChild(opt_before) : this.getChildCount());
|
||||
return child;
|
||||
this.addChildAt(child, this.getChildCount());
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -136,7 +136,6 @@ Blockly.Css.CONTENT = [
|
||||
|
||||
'.blocklyNonSelectable {',
|
||||
'user-select: none;',
|
||||
'-moz-user-select: none;',
|
||||
'-ms-user-select: none;',
|
||||
'-webkit-user-select: none;',
|
||||
'}',
|
||||
@@ -431,7 +430,6 @@ Blockly.Css.CONTENT = [
|
||||
*/
|
||||
'.blocklySvg text, .blocklyBlockDragSurface text {',
|
||||
'user-select: none;',
|
||||
'-moz-user-select: none;',
|
||||
'-ms-user-select: none;',
|
||||
'-webkit-user-select: none;',
|
||||
'cursor: inherit;',
|
||||
@@ -699,7 +697,6 @@ Blockly.Css.CONTENT = [
|
||||
'overflow-y: auto;',
|
||||
'position: absolute;',
|
||||
'user-select: none;',
|
||||
'-moz-user-select: none;',
|
||||
'-ms-user-select: none;',
|
||||
'-webkit-user-select: none;',
|
||||
'z-index: 70;', /* so blocks go under toolbox when dragging */
|
||||
|
||||
@@ -504,7 +504,7 @@ Blockly.FieldColour.prototype.setHighlightedCell_ = function(cell, index) {
|
||||
if (highlighted) {
|
||||
Blockly.utils.dom.removeClass(highlighted, 'blocklyColourHighlighted');
|
||||
}
|
||||
// Highight new item.
|
||||
// Highlight new item.
|
||||
Blockly.utils.dom.addClass(cell, 'blocklyColourHighlighted');
|
||||
// Set new highlighted index.
|
||||
this.highlightedIndex_ = index;
|
||||
|
||||
@@ -371,7 +371,7 @@ Blockly.Flyout.prototype.updateDisplay_ = function() {
|
||||
show = this.isVisible();
|
||||
}
|
||||
this.svgGroup_.style.display = show ? 'block' : 'none';
|
||||
// Update the scrollbar's visiblity too since it should mimic the
|
||||
// Update the scrollbar's visibility too since it should mimic the
|
||||
// flyout's visibility.
|
||||
this.scrollbar_.setContainerVisible(show);
|
||||
};
|
||||
|
||||
@@ -96,7 +96,7 @@ Blockly.createDom_ = function(container, options) {
|
||||
// then manually positions content in RTL as needed.
|
||||
container.setAttribute('dir', 'LTR');
|
||||
// Set the default direction for Components to use.
|
||||
Blockly.Component.setDefaultRightToLeft(options.RTL);
|
||||
Blockly.Component.defaultRightToLeft = options.RTL;
|
||||
|
||||
// Load CSS.
|
||||
Blockly.Css.inject(options.hasCss, options.pathToMedia);
|
||||
|
||||
@@ -198,6 +198,19 @@ Blockly.Toolbox.prototype.init = function() {
|
||||
this.config_['cleardotPath'] = workspace.options.pathToMedia + '1x1.gif';
|
||||
this.config_['cssCollapsedFolderIcon'] =
|
||||
'blocklyTreeIconClosed' + (workspace.RTL ? 'Rtl' : 'Ltr');
|
||||
this.renderTree(workspace.options.languageTree);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill the toolbox with categories and blocks.
|
||||
* @param {!Node} languageTree DOM tree of blocks.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Toolbox.prototype.renderTree = function(languageTree) {
|
||||
if (this.tree_) {
|
||||
this.tree_.dispose(); // Delete any existing content.
|
||||
this.lastCategory_ = null;
|
||||
}
|
||||
var tree = new Blockly.tree.TreeControl(this,
|
||||
/** @type {!Blockly.tree.BaseNode.Config} */ (this.config_));
|
||||
this.tree_ = tree;
|
||||
@@ -205,8 +218,18 @@ Blockly.Toolbox.prototype.init = function() {
|
||||
tree.onBeforeSelected(this.handleBeforeTreeSelected_);
|
||||
tree.onAfterSelected(this.handleAfterTreeSelected_);
|
||||
var openNode = null;
|
||||
if (workspace.options.languageTree) {
|
||||
openNode = this.populate_(workspace.options.languageTree);
|
||||
if (languageTree) {
|
||||
this.tree_.blocks = [];
|
||||
this.hasColours_ = false;
|
||||
var openNode =
|
||||
this.syncTrees_(languageTree, this.tree_, this.workspace_.options.pathToMedia);
|
||||
|
||||
if (this.tree_.blocks.length) {
|
||||
throw Error('Toolbox cannot have both blocks and categories ' +
|
||||
'in the root level.');
|
||||
}
|
||||
// Fire a resize event since the toolbox may have changed width and height.
|
||||
this.workspace_.resizeContents();
|
||||
}
|
||||
tree.render(this.HtmlDiv);
|
||||
if (openNode) {
|
||||
@@ -377,29 +400,6 @@ Blockly.Toolbox.prototype.position = function() {
|
||||
this.flyout_.position();
|
||||
};
|
||||
|
||||
/**
|
||||
* Fill the toolbox with categories and blocks.
|
||||
* @param {!Node} newTree DOM tree of blocks.
|
||||
* @return {Blockly.tree.BaseNode} Tree node to open at startup (or null).
|
||||
* @private
|
||||
*/
|
||||
Blockly.Toolbox.prototype.populate_ = function(newTree) {
|
||||
this.tree_.removeChildren(); // Delete any existing content.
|
||||
this.tree_.blocks = [];
|
||||
this.hasColours_ = false;
|
||||
var openNode =
|
||||
this.syncTrees_(newTree, this.tree_, this.workspace_.options.pathToMedia);
|
||||
|
||||
if (this.tree_.blocks.length) {
|
||||
throw Error('Toolbox cannot have both blocks and categories ' +
|
||||
'in the root level.');
|
||||
}
|
||||
|
||||
// Fire a resize event since the toolbox may have changed width and height.
|
||||
this.workspace_.resizeContents();
|
||||
return openNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sync trees of the toolbox.
|
||||
* @param {!Node} treeIn DOM tree of blocks.
|
||||
|
||||
@@ -1727,10 +1727,7 @@ Blockly.WorkspaceSvg.prototype.updateToolbox = function(tree) {
|
||||
throw Error('Existing toolbox has no categories. Can\'t change mode.');
|
||||
}
|
||||
this.options.languageTree = tree;
|
||||
var openNode = this.toolbox_.populate_(tree);
|
||||
this.toolbox_.addColour_();
|
||||
this.toolbox_.position();
|
||||
this.toolbox_.tree_.setSelectedItem(openNode);
|
||||
this.toolbox_.renderTree(tree);
|
||||
} else {
|
||||
if (!this.flyout_) {
|
||||
throw Error('Existing toolbox has categories. Can\'t change mode.');
|
||||
@@ -1750,7 +1747,7 @@ Blockly.WorkspaceSvg.prototype.markFocused = function() {
|
||||
Blockly.mainWorkspace = this;
|
||||
// We call e.preventDefault in many event handlers which means we
|
||||
// need to explicitly grab focus (e.g from a textarea) because
|
||||
// the browser will not do it for us. How to do this is browser dependant.
|
||||
// the browser will not do it for us. How to do this is browser dependent.
|
||||
this.setBrowserFocus();
|
||||
}
|
||||
};
|
||||
@@ -1760,7 +1757,7 @@ Blockly.WorkspaceSvg.prototype.markFocused = function() {
|
||||
* @private
|
||||
*/
|
||||
Blockly.WorkspaceSvg.prototype.setBrowserFocus = function() {
|
||||
// Blur whatever was focused since explcitly grabbing focus below does not
|
||||
// Blur whatever was focused since explicitly grabbing focus below does not
|
||||
// work in Edge.
|
||||
if (document.activeElement) {
|
||||
document.activeElement.blur();
|
||||
|
||||
Reference in New Issue
Block a user