mirror of
https://github.com/google/blockly.git
synced 2026-01-10 02:17:09 +01:00
Some type annotations were missing curly brackets, which makes closure-make-deps emit uninteresting warnings. Now any output from the command will be informative and related to whatever one is presently working on.
544 lines
18 KiB
JavaScript
544 lines
18 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2020 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @fileoverview Registers default context menu items.
|
|
* @author maribethb@google.com (Maribeth Bottorff)
|
|
*/
|
|
'use strict';
|
|
|
|
/**
|
|
* @name Blockly.ContextMenuItems
|
|
* @namespace
|
|
*/
|
|
goog.provide('Blockly.ContextMenuItems');
|
|
|
|
/** @suppress {extraRequire} */
|
|
goog.require('Blockly.constants');
|
|
goog.require('Blockly.ContextMenuRegistry');
|
|
goog.require('Blockly.Events');
|
|
goog.require('Blockly.inputTypes');
|
|
|
|
goog.requireType('Blockly.BlockSvg');
|
|
|
|
|
|
/** Option to undo previous action. */
|
|
Blockly.ContextMenuItems.registerUndo = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var undoOption = {
|
|
displayText: function() {
|
|
return Blockly.Msg['UNDO'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (scope.workspace.getUndoStack().length > 0) {
|
|
return 'enabled';
|
|
}
|
|
return 'disabled';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
scope.workspace.undo(false);
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
|
|
id: 'undoWorkspace',
|
|
weight: 1,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(undoOption);
|
|
};
|
|
|
|
/** Option to redo previous action. */
|
|
Blockly.ContextMenuItems.registerRedo = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var redoOption = {
|
|
displayText: function() { return Blockly.Msg['REDO']; },
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (scope.workspace.getRedoStack().length > 0) {
|
|
return 'enabled';
|
|
}
|
|
return 'disabled';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
scope.workspace.undo(true);
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
|
|
id: 'redoWorkspace',
|
|
weight: 2,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(redoOption);
|
|
};
|
|
|
|
/** Option to clean up blocks. */
|
|
Blockly.ContextMenuItems.registerCleanup = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var cleanOption = {
|
|
displayText: function() {
|
|
return Blockly.Msg['CLEAN_UP'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (scope.workspace.isMovable()) {
|
|
if (scope.workspace.getTopBlocks(false).length > 1) {
|
|
return 'enabled';
|
|
}
|
|
return 'disabled';
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
scope.workspace.cleanUp();
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
|
|
id: 'cleanWorkspace',
|
|
weight: 3,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(cleanOption);
|
|
};
|
|
|
|
/**
|
|
* Creates a callback to collapse or expand top blocks.
|
|
* @param {boolean} shouldCollapse Whether a block should collapse.
|
|
* @param {!Array<Blockly.BlockSvg>} topBlocks Top blocks in the workspace.
|
|
* @private
|
|
*/
|
|
Blockly.ContextMenuItems.toggleOption_ = function(shouldCollapse, topBlocks) {
|
|
var DELAY = 10;
|
|
var ms = 0;
|
|
for (var i = 0; i < topBlocks.length; i++) {
|
|
var block = topBlocks[i];
|
|
while (block) {
|
|
setTimeout(block.setCollapsed.bind(block, shouldCollapse), ms);
|
|
block = block.getNextBlock();
|
|
ms += DELAY;
|
|
}
|
|
}
|
|
};
|
|
|
|
/** Option to collapse all blocks. */
|
|
Blockly.ContextMenuItems.registerCollapse = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var collapseOption = {
|
|
displayText: function() {
|
|
return Blockly.Msg['COLLAPSE_ALL'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (scope.workspace.options.collapse) {
|
|
var topBlocks = scope.workspace.getTopBlocks(false);
|
|
for (var i = 0; i < topBlocks.length; i++) {
|
|
var block = topBlocks[i];
|
|
while (block) {
|
|
if (!block.isCollapsed()) {
|
|
return 'enabled';
|
|
}
|
|
block = block.getNextBlock();
|
|
}
|
|
}
|
|
return 'disabled';
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
Blockly.ContextMenuItems.toggleOption_(true, scope.workspace.getTopBlocks(true));
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
|
|
id: 'collapseWorkspace',
|
|
weight: 4,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(collapseOption);
|
|
};
|
|
|
|
/** Option to expand all blocks. */
|
|
Blockly.ContextMenuItems.registerExpand = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var expandOption = {
|
|
displayText: function() {
|
|
return Blockly.Msg['EXPAND_ALL'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (scope.workspace.options.collapse) {
|
|
var topBlocks = scope.workspace.getTopBlocks(false);
|
|
for (var i = 0; i < topBlocks.length; i++) {
|
|
var block = topBlocks[i];
|
|
while (block) {
|
|
if (block.isCollapsed()) {
|
|
return 'enabled';
|
|
}
|
|
block = block.getNextBlock();
|
|
}
|
|
}
|
|
return 'disabled';
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
Blockly.ContextMenuItems.toggleOption_(false, scope.workspace.getTopBlocks(true));
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
|
|
id: 'expandWorkspace',
|
|
weight: 5,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(expandOption);
|
|
};
|
|
|
|
/**
|
|
* Adds a block and its children to a list of deletable blocks.
|
|
* @param {!Blockly.BlockSvg} block to delete.
|
|
* @param {!Array<!Blockly.BlockSvg>} deleteList list of blocks that can be deleted. This will be
|
|
* modifed in place with the given block and its descendants.
|
|
* @private
|
|
*/
|
|
Blockly.ContextMenuItems.addDeletableBlocks_ = function(block, deleteList) {
|
|
if (block.isDeletable()) {
|
|
Array.prototype.push.apply(deleteList, block.getDescendants(false));
|
|
} else {
|
|
var children =
|
|
/** @type {!Array<!Blockly.BlockSvg>} */ (block.getChildren(false));
|
|
for (var i = 0; i < children.length; i++) {
|
|
Blockly.ContextMenuItems.addDeletableBlocks_(children[i], deleteList);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Constructs a list of blocks that can be deleted in the given workspace.
|
|
* @param {!Blockly.WorkspaceSvg} workspace to delete all blocks from.
|
|
* @return {!Array<!Blockly.BlockSvg>} list of blocks to delete.
|
|
* @private
|
|
*/
|
|
Blockly.ContextMenuItems.getDeletableBlocks_ = function(workspace) {
|
|
var deleteList = [];
|
|
var topBlocks = workspace.getTopBlocks(true);
|
|
for (var i = 0; i < topBlocks.length; i++) {
|
|
Blockly.ContextMenuItems.addDeletableBlocks_(topBlocks[i], deleteList);
|
|
}
|
|
return deleteList;
|
|
};
|
|
|
|
/** Deletes the given blocks. Used to delete all blocks in the workspace.
|
|
* @param {!Array<!Blockly.BlockSvg>} deleteList list of blocks to delete.
|
|
* @param {string} eventGroup event group ID with which all delete events should be associated.
|
|
* @private
|
|
*/
|
|
Blockly.ContextMenuItems.deleteNext_ = function(deleteList, eventGroup) {
|
|
var DELAY = 10;
|
|
Blockly.Events.setGroup(eventGroup);
|
|
var block = deleteList.shift();
|
|
if (block) {
|
|
if (block.workspace) {
|
|
block.dispose(false, true);
|
|
setTimeout(Blockly.ContextMenuItems.deleteNext_, DELAY, deleteList, eventGroup);
|
|
} else {
|
|
Blockly.ContextMenuItems.deleteNext_(deleteList, eventGroup);
|
|
}
|
|
}
|
|
Blockly.Events.setGroup(false);
|
|
};
|
|
|
|
/** Option to delete all blocks. */
|
|
Blockly.ContextMenuItems.registerDeleteAll = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var deleteOption = {
|
|
displayText: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (!scope.workspace) {
|
|
return;
|
|
}
|
|
var deletableBlocksLength =
|
|
Blockly.ContextMenuItems.getDeletableBlocks_(scope.workspace).length;
|
|
if (deletableBlocksLength == 1) {
|
|
return Blockly.Msg['DELETE_BLOCK'];
|
|
} else {
|
|
return Blockly.Msg['DELETE_X_BLOCKS'].replace('%1', String(deletableBlocksLength));
|
|
}
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (!scope.workspace) {
|
|
return;
|
|
}
|
|
var deletableBlocksLength =
|
|
Blockly.ContextMenuItems.getDeletableBlocks_(scope.workspace).length;
|
|
return deletableBlocksLength > 0 ? 'enabled' : 'disabled';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (!scope.workspace) {
|
|
return;
|
|
}
|
|
scope.workspace.cancelCurrentGesture();
|
|
var deletableBlocks = Blockly.ContextMenuItems.getDeletableBlocks_(scope.workspace);
|
|
var eventGroup = Blockly.utils.genUid();
|
|
if (deletableBlocks.length < 2) {
|
|
Blockly.ContextMenuItems.deleteNext_(deletableBlocks, eventGroup);
|
|
} else {
|
|
Blockly.confirm(
|
|
Blockly.Msg['DELETE_ALL_BLOCKS'].replace('%1', deletableBlocks.length),
|
|
function(ok) {
|
|
if (ok) {
|
|
Blockly.ContextMenuItems.deleteNext_(deletableBlocks, eventGroup);
|
|
}
|
|
});
|
|
}
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.WORKSPACE,
|
|
id: 'workspaceDelete',
|
|
weight: 6,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(deleteOption);
|
|
};
|
|
|
|
/**
|
|
* Registers all workspace-scoped context menu items.
|
|
* @private
|
|
*/
|
|
Blockly.ContextMenuItems.registerWorkspaceOptions_ = function() {
|
|
Blockly.ContextMenuItems.registerUndo();
|
|
Blockly.ContextMenuItems.registerRedo();
|
|
Blockly.ContextMenuItems.registerCleanup();
|
|
Blockly.ContextMenuItems.registerCollapse();
|
|
Blockly.ContextMenuItems.registerExpand();
|
|
Blockly.ContextMenuItems.registerDeleteAll();
|
|
};
|
|
|
|
/** Option to duplicate a block. */
|
|
Blockly.ContextMenuItems.registerDuplicate = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var duplicateOption = {
|
|
displayText: function() {
|
|
return Blockly.Msg['DUPLICATE_BLOCK'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
var block = scope.block;
|
|
if (!block.isInFlyout && block.isDeletable() && block.isMovable()) {
|
|
if (block.isDuplicatable()) {
|
|
return 'enabled';
|
|
}
|
|
return 'disabled';
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (scope.block) {
|
|
Blockly.duplicate(scope.block);
|
|
}
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
|
|
id: 'blockDuplicate',
|
|
weight: 1,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(duplicateOption);
|
|
};
|
|
|
|
/** Option to add or remove block-level comment. */
|
|
Blockly.ContextMenuItems.registerComment = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var commentOption = {
|
|
displayText: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (scope.block.getCommentIcon()) {
|
|
// If there's already a comment, option is to remove.
|
|
return Blockly.Msg['REMOVE_COMMENT'];
|
|
}
|
|
// If there's no comment yet, option is to add.
|
|
return Blockly.Msg['ADD_COMMENT'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
var block = scope.block;
|
|
// IE doesn't support necessary features for comment editing.
|
|
if (!Blockly.utils.userAgent.IE && !block.isInFlyout && block.workspace.options.comments &&
|
|
!block.isCollapsed() && block.isEditable()) {
|
|
return 'enabled';
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
var block = scope.block;
|
|
if (block.getCommentIcon()) {
|
|
block.setCommentText(null);
|
|
} else {
|
|
block.setCommentText('');
|
|
}
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
|
|
id: 'blockComment',
|
|
weight: 2,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(commentOption);
|
|
};
|
|
|
|
/** Option to inline variables. */
|
|
Blockly.ContextMenuItems.registerInline = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var inlineOption = {
|
|
displayText: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
return (scope.block.getInputsInline()) ?
|
|
Blockly.Msg['EXTERNAL_INPUTS'] : Blockly.Msg['INLINE_INPUTS'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
var block = scope.block;
|
|
if (!block.isInFlyout && block.isMovable() && !block.isCollapsed()) {
|
|
for (var i = 1; i < block.inputList.length; i++) {
|
|
// Only display this option if there are two value or dummy inputs next to each other.
|
|
if (block.inputList[i - 1].type != Blockly.inputTypes.STATEMENT &&
|
|
block.inputList[i].type != Blockly.inputTypes.STATEMENT) {
|
|
return 'enabled';
|
|
}
|
|
}
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
scope.block.setInputsInline(!scope.block.getInputsInline());
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
|
|
id: 'blockInline',
|
|
weight: 3,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(inlineOption);
|
|
};
|
|
|
|
/** Option to collapse or expand a block. */
|
|
Blockly.ContextMenuItems.registerCollapseExpandBlock = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var collapseExpandOption = {
|
|
displayText: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
return scope.block.isCollapsed() ?
|
|
Blockly.Msg['EXPAND_BLOCK'] : Blockly.Msg['COLLAPSE_BLOCK'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
var block = scope.block;
|
|
if (!block.isInFlyout && block.isMovable() && block.workspace.options.collapse) {
|
|
return 'enabled';
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
scope.block.setCollapsed(!scope.block.isCollapsed());
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
|
|
id: 'blockCollapseExpand',
|
|
weight: 4,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(collapseExpandOption);
|
|
};
|
|
|
|
/** Option to disable or enable a block. */
|
|
Blockly.ContextMenuItems.registerDisable = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var disableOption = {
|
|
displayText: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
return (scope.block.isEnabled()) ?
|
|
Blockly.Msg['DISABLE_BLOCK'] : Blockly.Msg['ENABLE_BLOCK'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
var block = scope.block;
|
|
if (!block.isInFlyout && block.workspace.options.disable && block.isEditable()) {
|
|
if (block.getInheritedDisabled()) {
|
|
return 'disabled';
|
|
}
|
|
return 'enabled';
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
var block = scope.block;
|
|
var group = Blockly.Events.getGroup();
|
|
if (!group) {
|
|
Blockly.Events.setGroup(true);
|
|
}
|
|
block.setEnabled(!block.isEnabled());
|
|
if (!group) {
|
|
Blockly.Events.setGroup(false);
|
|
}
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
|
|
id: 'blockDisable',
|
|
weight: 5,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(disableOption);
|
|
};
|
|
|
|
/** Option to delete a block. */
|
|
Blockly.ContextMenuItems.registerDelete = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var deleteOption = {
|
|
displayText: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
var block = scope.block;
|
|
// Count the number of blocks that are nested in this block.
|
|
var descendantCount = block.getDescendants(false).length;
|
|
var nextBlock = block.getNextBlock();
|
|
if (nextBlock) {
|
|
// Blocks in the current stack would survive this block's deletion.
|
|
descendantCount -= nextBlock.getDescendants(false).length;
|
|
}
|
|
return (descendantCount == 1) ? Blockly.Msg['DELETE_BLOCK'] :
|
|
Blockly.Msg['DELETE_X_BLOCKS'].replace('%1', String(descendantCount));
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
if (!scope.block.isInFlyout && scope.block.isDeletable()) {
|
|
return 'enabled';
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
Blockly.Events.setGroup(true);
|
|
if (scope.block) {
|
|
Blockly.deleteBlock(scope.block);
|
|
}
|
|
Blockly.Events.setGroup(false);
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
|
|
id: 'blockDelete',
|
|
weight: 6,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(deleteOption);
|
|
};
|
|
|
|
/** Option to open help for a block. */
|
|
Blockly.ContextMenuItems.registerHelp = function() {
|
|
/** @type {!Blockly.ContextMenuRegistry.RegistryItem} */
|
|
var helpOption = {
|
|
displayText: function() {
|
|
return Blockly.Msg['HELP'];
|
|
},
|
|
preconditionFn: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
var block = scope.block;
|
|
var url = (typeof block.helpUrl == 'function') ?
|
|
block.helpUrl() : block.helpUrl;
|
|
if (url) {
|
|
return 'enabled';
|
|
}
|
|
return 'hidden';
|
|
},
|
|
callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) {
|
|
scope.block.showHelp();
|
|
},
|
|
scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK,
|
|
id: 'blockHelp',
|
|
weight: 7,
|
|
};
|
|
Blockly.ContextMenuRegistry.registry.register(helpOption);
|
|
};
|
|
|
|
/**
|
|
* Registers all block-scoped context menu items.
|
|
* @private
|
|
*/
|
|
Blockly.ContextMenuItems.registerBlockOptions_ = function() {
|
|
Blockly.ContextMenuItems.registerDuplicate();
|
|
Blockly.ContextMenuItems.registerComment();
|
|
Blockly.ContextMenuItems.registerInline();
|
|
Blockly.ContextMenuItems.registerCollapseExpandBlock();
|
|
Blockly.ContextMenuItems.registerDisable();
|
|
Blockly.ContextMenuItems.registerDelete();
|
|
Blockly.ContextMenuItems.registerHelp();
|
|
};
|
|
|
|
/**
|
|
* Registers all default context menu items. This should be called once per instance of
|
|
* ContextMenuRegistry.
|
|
* @package
|
|
*/
|
|
Blockly.ContextMenuItems.registerDefaultOptions = function() {
|
|
Blockly.ContextMenuItems.registerWorkspaceOptions_();
|
|
Blockly.ContextMenuItems.registerBlockOptions_();
|
|
};
|
|
|
|
Blockly.ContextMenuItems.registerDefaultOptions();
|