mirror of
https://github.com/google/blockly.git
synced 2026-01-21 15:57:10 +01:00
@@ -27,6 +27,7 @@ goog.requireType('Blockly.blockRendering.ConstantProvider');
|
||||
goog.requireType('Blockly.IASTNodeLocationSvg');
|
||||
goog.requireType('Blockly.IASTNodeLocationWithBlock');
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
goog.requireType('Blockly.IRegistrable');
|
||||
|
||||
|
||||
/**
|
||||
@@ -42,6 +43,7 @@ goog.requireType('Blockly.IBlocklyActionable');
|
||||
* @implements {Blockly.IASTNodeLocationSvg}
|
||||
* @implements {Blockly.IASTNodeLocationWithBlock}
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
* @implements {Blockly.IRegistrable}
|
||||
*/
|
||||
Blockly.Field = function(value, opt_validator, opt_config) {
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@ goog.require('Blockly.WorkspaceSvg');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
goog.requireType('Blockly.IDeleteArea');
|
||||
goog.requireType('Blockly.utils.Metrics');
|
||||
|
||||
|
||||
@@ -40,6 +41,7 @@ goog.requireType('Blockly.utils.Metrics');
|
||||
* @constructor
|
||||
* @abstract
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
* @implements {Blockly.IDeleteArea}
|
||||
*/
|
||||
Blockly.Flyout = function(workspaceOptions) {
|
||||
workspaceOptions.getMetrics =
|
||||
|
||||
28
core/interfaces/i_deletearea.js
Normal file
28
core/interfaces/i_deletearea.js
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview The interface for a component that can delete a block that is
|
||||
* dropped on top of it.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.IDeleteArea');
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a component that can delete a block that is dropped on top of it.
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IDeleteArea = function() {};
|
||||
|
||||
/**
|
||||
* Return the deletion rectangle.
|
||||
* @return {Blockly.utils.Rect} Rectangle in which to delete.
|
||||
*/
|
||||
Blockly.IDeleteArea.prototype.getClientRect;
|
||||
19
core/interfaces/i_registrable.js
Normal file
19
core/interfaces/i_registrable.js
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview The interface for a Blockly component that can be registered.
|
||||
* (Ex. Toolbox, Fields, Renderers)
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.IRegistrable');
|
||||
|
||||
|
||||
/** @interface */
|
||||
Blockly.IRegistrable = function() {};
|
||||
111
core/interfaces/i_toolbox.js
Normal file
111
core/interfaces/i_toolbox.js
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2020 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview The interface for a toolbox.
|
||||
* @author aschmiedt@google.com (Abby Schmiedt)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
goog.provide('Blockly.IToolbox');
|
||||
|
||||
goog.requireType('Blockly.IRegistrable');
|
||||
|
||||
|
||||
/**
|
||||
* Interface for a toolbox.
|
||||
* @extends {Blockly.IRegistrable}
|
||||
* @interface
|
||||
*/
|
||||
Blockly.IToolbox = function() {};
|
||||
|
||||
/**
|
||||
* Initializes the toolbox.
|
||||
* @return {void}
|
||||
*/
|
||||
Blockly.IToolbox.prototype.init;
|
||||
|
||||
/**
|
||||
* Fill the toolbox with categories and blocks.
|
||||
* @param {Array.<Blockly.utils.toolbox.Toolbox>} toolboxDef Array holding objects
|
||||
* containing information on the contents of the toolbox.
|
||||
*/
|
||||
Blockly.IToolbox.prototype.render;
|
||||
|
||||
/**
|
||||
* Dispose of this toolbox.
|
||||
* @return {void}
|
||||
*/
|
||||
Blockly.IToolbox.prototype.dispose;
|
||||
|
||||
/**
|
||||
* Get the width of the toolbox.
|
||||
* @return {number} The width of the toolbox.
|
||||
*/
|
||||
Blockly.IToolbox.prototype.getWidth;
|
||||
|
||||
/**
|
||||
* Get the height of the toolbox.
|
||||
* @return {number} The width of the toolbox.
|
||||
*/
|
||||
Blockly.IToolbox.prototype.getHeight;
|
||||
|
||||
/**
|
||||
* Get the toolbox flyout.
|
||||
* @return {Blockly.Flyout} The toolbox flyout.
|
||||
*/
|
||||
Blockly.IToolbox.prototype.getFlyout;
|
||||
|
||||
/**
|
||||
* Move the toolbox to the edge.
|
||||
* @return {void}
|
||||
*/
|
||||
Blockly.IToolbox.prototype.position;
|
||||
|
||||
/**
|
||||
* Unhighlight any previously specified option.
|
||||
* @return {void}
|
||||
*/
|
||||
Blockly.IToolbox.prototype.clearSelection;
|
||||
|
||||
/**
|
||||
* Updates the category colours and background colour of selected categories.
|
||||
* @return {void}
|
||||
*/
|
||||
Blockly.IToolbox.prototype.updateColourFromTheme;
|
||||
|
||||
/**
|
||||
* Adds a style on the toolbox. Usually used to change the cursor.
|
||||
* @param {string} style The name of the class to add.
|
||||
*/
|
||||
Blockly.IToolbox.prototype.addStyle;
|
||||
|
||||
/**
|
||||
* Removes a style from the toolbox. Usually used to change the cursor.
|
||||
* @param {string} style The name of the class to remove.
|
||||
*/
|
||||
Blockly.IToolbox.prototype.removeStyle;
|
||||
|
||||
/**
|
||||
* Update the flyout's contents without closing it. Should be used in response
|
||||
* to a change in one of the dynamic categories, such as variables or
|
||||
* procedures.
|
||||
* @return {void}
|
||||
*/
|
||||
Blockly.IToolbox.prototype.refreshSelection;
|
||||
|
||||
/**
|
||||
* Toggles the visibility of the toolbox.
|
||||
* @param {boolean} isVisible True if the toolbox should be visible.
|
||||
*/
|
||||
Blockly.IToolbox.prototype.setVisible;
|
||||
|
||||
/**
|
||||
* Select the first toolbox category if no category is selected.
|
||||
* @return {void}
|
||||
*/
|
||||
Blockly.IToolbox.prototype.selectFirstCategory;
|
||||
@@ -855,7 +855,8 @@ Blockly.navigation.flyoutOnAction_ = function(action) {
|
||||
Blockly.navigation.toolboxOnAction_ = function(action) {
|
||||
var workspace = Blockly.navigation.getNavigationWorkspace();
|
||||
var toolbox = workspace.getToolbox();
|
||||
var handled = toolbox ? toolbox.onBlocklyAction(action) : false;
|
||||
var handled = toolbox && typeof toolbox.onBlocklyAction == 'function' ?
|
||||
toolbox.onBlocklyAction(action) : false;
|
||||
|
||||
if (handled) {
|
||||
return true;
|
||||
|
||||
@@ -21,6 +21,7 @@ goog.require('Blockly.blockRendering.RenderInfo');
|
||||
goog.require('Blockly.InsertionMarkerManager');
|
||||
|
||||
goog.requireType('Blockly.blockRendering.Debug');
|
||||
goog.requireType('Blockly.IRegistrable');
|
||||
|
||||
|
||||
/**
|
||||
@@ -28,6 +29,7 @@ goog.requireType('Blockly.blockRendering.Debug');
|
||||
* @param {string} name The renderer name.
|
||||
* @package
|
||||
* @constructor
|
||||
* @implements {Blockly.IRegistrable}
|
||||
*/
|
||||
Blockly.blockRendering.Renderer = function(name) {
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.utils.toolbox');
|
||||
|
||||
goog.requireType('Blockly.IBlocklyActionable');
|
||||
goog.requireType('Blockly.IDeleteArea');
|
||||
goog.requireType('Blockly.IToolbox');
|
||||
|
||||
|
||||
/**
|
||||
@@ -37,6 +39,8 @@ goog.requireType('Blockly.IBlocklyActionable');
|
||||
* blocks.
|
||||
* @constructor
|
||||
* @implements {Blockly.IBlocklyActionable}
|
||||
* @implements {Blockly.IDeleteArea}
|
||||
* @implements {Blockly.IToolbox}
|
||||
*/
|
||||
Blockly.Toolbox = function(workspace) {
|
||||
/**
|
||||
@@ -206,7 +210,7 @@ Blockly.Toolbox.prototype.init = function() {
|
||||
|
||||
this.config_['cssCollapsedFolderIcon'] =
|
||||
'blocklyTreeIconClosed' + (workspace.RTL ? 'Rtl' : 'Ltr');
|
||||
this.renderTree(workspace.options.languageTree);
|
||||
this.render(workspace.options.languageTree);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -215,7 +219,7 @@ Blockly.Toolbox.prototype.init = function() {
|
||||
* containing information on the contents of the toolbox.
|
||||
* @package
|
||||
*/
|
||||
Blockly.Toolbox.prototype.renderTree = function(toolboxDef) {
|
||||
Blockly.Toolbox.prototype.render = function(toolboxDef) {
|
||||
if (this.tree_) {
|
||||
this.tree_.dispose(); // Delete any existing content.
|
||||
this.lastCategory_ = null;
|
||||
@@ -506,6 +510,14 @@ Blockly.Toolbox.prototype.dispose = function() {
|
||||
this.lastCategory_ = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggles the visibility of the toolbox.
|
||||
* @param {boolean} isVisible True if toolbox should be visible.
|
||||
*/
|
||||
Blockly.Toolbox.prototype.setVisible = function(isVisible) {
|
||||
this.HtmlDiv.style.display = isVisible ? 'block' : 'none';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the width of the toolbox.
|
||||
* @return {number} The width of the toolbox.
|
||||
|
||||
@@ -17,11 +17,14 @@ goog.require('Blockly.utils.dom');
|
||||
goog.require('Blockly.utils.Rect');
|
||||
goog.require('Blockly.Xml');
|
||||
|
||||
goog.requireType('Blockly.IDeleteArea');
|
||||
|
||||
|
||||
/**
|
||||
* Class for a trash can.
|
||||
* @param {!Blockly.WorkspaceSvg} workspace The workspace to sit in.
|
||||
* @constructor
|
||||
* @implements {Blockly.IDeleteArea}
|
||||
*/
|
||||
Blockly.Trashcan = function(workspace) {
|
||||
/**
|
||||
|
||||
@@ -1187,7 +1187,7 @@ Blockly.WorkspaceSvg.prototype.setVisible = function(isVisible) {
|
||||
this.getParentSvg().style.display = isVisible ? 'block' : 'none';
|
||||
if (this.toolbox_) {
|
||||
// Currently does not support toolboxes in mutators.
|
||||
this.toolbox_.HtmlDiv.style.display = isVisible ? 'block' : 'none';
|
||||
this.toolbox_.setVisible(isVisible);
|
||||
}
|
||||
if (isVisible) {
|
||||
var blocks = this.getAllBlocks(false);
|
||||
@@ -1455,7 +1455,7 @@ Blockly.WorkspaceSvg.prototype.recordDeleteAreas = function() {
|
||||
}
|
||||
if (this.flyout_) {
|
||||
this.deleteAreaToolbox_ = this.flyout_.getClientRect();
|
||||
} else if (this.toolbox_) {
|
||||
} else if (this.toolbox_ && typeof this.toolbox_.getClientRect == 'function') {
|
||||
this.deleteAreaToolbox_ = this.toolbox_.getClientRect();
|
||||
} else {
|
||||
this.deleteAreaToolbox_ = null;
|
||||
@@ -1849,7 +1849,7 @@ Blockly.WorkspaceSvg.prototype.updateToolbox = function(toolboxDef) {
|
||||
throw Error('Existing toolbox has no categories. Can\'t change mode.');
|
||||
}
|
||||
this.options.languageTree = toolboxDef;
|
||||
this.toolbox_.renderTree(toolboxDef);
|
||||
this.toolbox_.render(toolboxDef);
|
||||
} else {
|
||||
if (!this.flyout_) {
|
||||
throw Error('Existing toolbox has categories. Can\'t change mode.');
|
||||
|
||||
@@ -53,7 +53,7 @@ suite('Toolbox', function() {
|
||||
});
|
||||
});
|
||||
|
||||
suite('renderTree', function() {
|
||||
suite('render', function() {
|
||||
setup(function() {
|
||||
this.toolboxXml = Blockly.utils.toolbox.convertToolboxToJSON(this.toolboxXml);
|
||||
this.toolbox.selectFirstCategory();
|
||||
@@ -62,7 +62,7 @@ suite('Toolbox', function() {
|
||||
this.toolbox.handleBeforeTreeSelected_(this.secondChild);
|
||||
});
|
||||
test('Tree is created and set', function() {
|
||||
this.toolbox.renderTree(this.toolboxXml);
|
||||
this.toolbox.render(this.toolboxXml);
|
||||
chai.assert.isDefined(this.toolbox.tree_);
|
||||
});
|
||||
test('Throws error if a toolbox has both blocks and categories at root level', function() {
|
||||
@@ -94,17 +94,17 @@ suite('Toolbox', function() {
|
||||
}
|
||||
];
|
||||
chai.assert.throws(function() {
|
||||
toolbox.renderTree(badToolboxDef);
|
||||
toolbox.render(badToolboxDef);
|
||||
}, 'Toolbox cannot have both blocks and categories in the root level.');
|
||||
});
|
||||
test('Select any open nodes', function() {
|
||||
this.toolbox.renderTree(this.toolboxXml);
|
||||
this.toolbox.render(this.toolboxXml);
|
||||
var selectedNode = this.toolbox.tree_.children_[0];
|
||||
chai.assert.isTrue(selectedNode.selected_);
|
||||
});
|
||||
test('Set the state for horizontal layout ', function() {
|
||||
this.toolbox.horizontalLayout_ = true;
|
||||
this.toolbox.renderTree(this.toolboxXml);
|
||||
this.toolbox.render(this.toolboxXml);
|
||||
var orientationAttribute = this.toolbox.tree_.getElement()
|
||||
.getAttribute('aria-orientation');
|
||||
chai.assert.equal(orientationAttribute, 'horizontal');
|
||||
@@ -136,7 +136,7 @@ suite('Toolbox', function() {
|
||||
]
|
||||
}
|
||||
];
|
||||
this.toolbox.renderTree(jsonDef);
|
||||
this.toolbox.render(jsonDef);
|
||||
chai.assert.lengthOf(this.toolbox.tree_.children_, 1);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user