Add support for IAutoHideable (#4855)

This commit is contained in:
Monica Kozbial
2021-05-27 17:01:11 -07:00
committed by GitHub
parent 1cadbb94bd
commit 5344ad6c21
8 changed files with 106 additions and 33 deletions

View File

@@ -86,6 +86,7 @@ goog.addDependency('../../core/input.js', ['Blockly.Input'], ['Blockly.Connectio
goog.addDependency('../../core/input_types.js', ['Blockly.inputTypes'], ['Blockly.connectionTypes']);
goog.addDependency('../../core/insertion_marker_manager.js', ['Blockly.InsertionMarkerManager'], ['Blockly.Events', 'Blockly.blockAnimations', 'Blockly.connectionTypes', 'Blockly.constants'], {'lang': 'es5'});
goog.addDependency('../../core/interfaces/i_accessibility.js', ['Blockly.IASTNodeLocation', 'Blockly.IASTNodeLocationSvg', 'Blockly.IASTNodeLocationWithBlock', 'Blockly.IKeyboardAccessible'], []);
goog.addDependency('../../core/interfaces/i_autohideable.js', ['Blockly.IAutoHideable'], ['Blockly.IComponent']);
goog.addDependency('../../core/interfaces/i_bounded_element.js', ['Blockly.IBoundedElement'], []);
goog.addDependency('../../core/interfaces/i_bubble.js', ['Blockly.IBubble'], ['Blockly.IContextMenu', 'Blockly.IDeletable']);
goog.addDependency('../../core/interfaces/i_component.js', ['Blockly.IComponent'], []);
@@ -173,12 +174,12 @@ goog.addDependency('../../core/theme_manager.js', ['Blockly.ThemeManager'], ['Bl
goog.addDependency('../../core/toolbox/category.js', ['Blockly.ToolboxCategory'], ['Blockly.ISelectableToolboxItem', 'Blockly.ToolboxItem', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {'lang': 'es5'});
goog.addDependency('../../core/toolbox/collapsible_category.js', ['Blockly.CollapsibleToolboxCategory'], ['Blockly.ICollapsibleToolboxItem', 'Blockly.ToolboxCategory', 'Blockly.ToolboxItem', 'Blockly.ToolboxSeparator', 'Blockly.registry', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox']);
goog.addDependency('../../core/toolbox/separator.js', ['Blockly.ToolboxSeparator'], ['Blockly.IToolboxItem', 'Blockly.ToolboxItem', 'Blockly.registry', 'Blockly.utils.dom'], {'lang': 'es5'});
goog.addDependency('../../core/toolbox/toolbox.js', ['Blockly.Toolbox'], ['Blockly.CollapsibleToolboxCategory', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.ToolboxItemSelect', 'Blockly.IDeleteArea', 'Blockly.IKeyboardAccessible', 'Blockly.IStyleable', 'Blockly.IToolbox', 'Blockly.Options', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'});
goog.addDependency('../../core/toolbox/toolbox.js', ['Blockly.Toolbox'], ['Blockly.CollapsibleToolboxCategory', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.ToolboxItemSelect', 'Blockly.IAutoHideable', 'Blockly.IDeleteArea', 'Blockly.IKeyboardAccessible', 'Blockly.IStyleable', 'Blockly.IToolbox', 'Blockly.Options', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'});
goog.addDependency('../../core/toolbox/toolbox_item.js', ['Blockly.ToolboxItem'], ['Blockly.IToolboxItem']);
goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.browserEvents', 'Blockly.utils.string']);
goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.constants', 'Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.string']);
goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object']);
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.IDeleteArea', 'Blockly.IPositionable', 'Blockly.Options', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.registry', 'Blockly.uiPosition', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'});
goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.Events', 'Blockly.Events.TrashcanOpen', 'Blockly.IAutoHideable', 'Blockly.IDeleteArea', 'Blockly.IPositionable', 'Blockly.Options', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.constants', 'Blockly.registry', 'Blockly.uiPosition', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.toolbox'], {'lang': 'es5'});
goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Msg', 'Blockly.constants', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.colour', 'Blockly.utils.global', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.userAgent']);
goog.addDependency('../../core/utils/aria.js', ['Blockly.utils.aria'], []);
goog.addDependency('../../core/utils/colour.js', ['Blockly.utils.colour'], []);

View File

@@ -294,27 +294,20 @@ Blockly.onContextMenu_ = function(e) {
/**
* Close tooltips, context menus, dropdown selections, etc.
* @param {boolean=} opt_allowToolbox If true, don't close the toolbox.
* @param {boolean=} opt_onlyClosePopups Whether only popups should be closed.
*/
Blockly.hideChaff = function(opt_allowToolbox) {
Blockly.hideChaff = function(opt_onlyClosePopups) {
Blockly.Tooltip.hide();
Blockly.WidgetDiv.hide();
Blockly.DropDownDiv.hideWithoutAnimation();
if (!opt_allowToolbox) {
var workspace = Blockly.getMainWorkspace();
// For now the trashcan flyout always autocloses because it overlays the
// trashcan UI (no trashcan to click to close it).
if (workspace.trashcan &&
workspace.trashcan.flyout) {
workspace.trashcan.closeFlyout();
}
var toolbox = workspace.getToolbox();
if (toolbox &&
toolbox.getFlyout() &&
toolbox.getFlyout().autoClose) {
toolbox.clearSelection();
}
}
var onlyClosePopups = !!opt_onlyClosePopups;
var workspace = Blockly.getMainWorkspace();
var autoHideables = workspace.getComponentManager().getComponents(
Blockly.ComponentManager.Capability.AUTOHIDEABLE, true);
autoHideables.forEach(function(autoHideable) {
autoHideable.autoHide(onlyClosePopups);
});
};
/**

View File

@@ -13,6 +13,10 @@
goog.provide('Blockly.ComponentManager');
goog.requireType('Blockly.IAutoHideable');
goog.requireType('Blockly.IComponent');
goog.requireType('Blockly.IPositionable');
/**
* Manager for all items registered with the workspace.
@@ -136,3 +140,6 @@ Blockly.ComponentManager.Capability.prototype.toString = function() {
/** @type {!Blockly.ComponentManager.Capability<!Blockly.IPositionable>} */
Blockly.ComponentManager.Capability.POSITIONABLE =
new Blockly.ComponentManager.Capability('positionable');
/** @type {!Blockly.ComponentManager.Capability<!Blockly.IAutoHideable>} */
Blockly.ComponentManager.Capability.AUTOHIDEABLE =
new Blockly.ComponentManager.Capability('autohideable');

View File

@@ -0,0 +1,33 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @fileoverview The interface for a component that is automatically hidden
* when Blockly.hideChaff is called.
* @author kozbial@google.com (Monica Kozbial)
*/
'use strict';
goog.provide('Blockly.IAutoHideable');
goog.require('Blockly.IComponent');
/**
* Interface for a component that can be automatically hidden.
* @extends {Blockly.IComponent}
* @interface
*/
Blockly.IAutoHideable = function() {};
/**
* Hides the component. Called in Blockly.hideChaff.
* @param {boolean} onlyClosePopups Whether only popups should be closed.
* Flyouts should not be closed if this is true.
*/
Blockly.IAutoHideable.prototype.autoHide;

View File

@@ -20,6 +20,7 @@ goog.require('Blockly.Css');
goog.require('Blockly.Events');
/** @suppress {extraRequire} */
goog.require('Blockly.Events.ToolboxItemSelect');
goog.require('Blockly.IAutoHideable');
goog.require('Blockly.IDeleteArea');
goog.require('Blockly.IKeyboardAccessible');
goog.require('Blockly.IStyleable');
@@ -47,6 +48,7 @@ goog.requireType('Blockly.WorkspaceSvg');
* @param {!Blockly.WorkspaceSvg} workspace The workspace in which to create new
* blocks.
* @constructor
* @implements {Blockly.IAutoHideable}
* @implements {Blockly.IKeyboardAccessible}
* @implements {Blockly.IDeleteArea}
* @implements {Blockly.IStyleable}
@@ -187,6 +189,15 @@ Blockly.Toolbox.prototype.init = function() {
themeManager.subscribe(this.HtmlDiv, 'toolboxBackgroundColour',
'background-color');
themeManager.subscribe(this.HtmlDiv, 'toolboxForegroundColour', 'color');
this.workspace_.getComponentManager().addComponent({
id: 'toolbox',
component: this,
weight: 1,
capabilities: [
Blockly.ComponentManager.Capability.AUTOHIDEABLE
]
});
};
/**
@@ -696,6 +707,17 @@ Blockly.Toolbox.prototype.setVisible = function(isVisible) {
this.HtmlDiv.style.display = isVisible ? 'block' : 'none';
};
/**
* Hides the component. Called in Blockly.hideChaff.
* @param {boolean} onlyClosePopups Whether only popups should be closed.
* Flyouts should not be closed if this is true.
*/
Blockly.Toolbox.prototype.autoHide = function(onlyClosePopups) {
if (!onlyClosePopups && this.flyout_ && this.flyout_.autoClose) {
this.clearSelection();
}
};
/**
* Sets the given item as selected.
* No-op if the item is not selectable.

View File

@@ -18,6 +18,7 @@ goog.require('Blockly.constants');
goog.require('Blockly.Events');
/** @suppress {extraRequire} */
goog.require('Blockly.Events.TrashcanOpen');
goog.require('Blockly.IAutoHideable');
goog.require('Blockly.IDeleteArea');
goog.require('Blockly.IPositionable');
goog.require('Blockly.Options');
@@ -38,6 +39,7 @@ goog.requireType('Blockly.WorkspaceSvg');
* Class for a trash can.
* @param {!Blockly.WorkspaceSvg} workspace The workspace to sit in.
* @constructor
* @implements {Blockly.IAutoHideable}
* @implements {Blockly.IDeleteArea}
* @implements {Blockly.IPositionable}
*/
@@ -357,7 +359,15 @@ Blockly.Trashcan.prototype.init = function() {
this.workspace_.getParentSvg());
this.flyout.init(this.workspace_);
}
this.workspace_.getComponentManager().addComponent({
id: 'trashcan',
component: this,
weight: 1,
capabilities: [
Blockly.ComponentManager.Capability.POSITIONABLE,
Blockly.ComponentManager.Capability.AUTOHIDEABLE
]
});
this.initialized_ = true;
this.setLidOpen(false);
};
@@ -422,6 +432,19 @@ Blockly.Trashcan.prototype.closeFlyout = function() {
this.fireUiEvent_(false);
};
/**
* Hides the component. Called in Blockly.hideChaff.
* @param {boolean} onlyClosePopups Whether only popups should be closed.
* Flyouts should not be closed if this is true.
*/
Blockly.Trashcan.prototype.autoHide = function(onlyClosePopups) {
// For now the trashcan flyout always autocloses because it overlays the
// trashcan UI (no trashcan to click to close it).
if (!onlyClosePopups && this.flyout) {
this.closeFlyout();
}
};
/**
* Empties the trashcan's contents. If the contents-flyout is currently open
* it will be closed.

View File

@@ -1003,12 +1003,6 @@ Blockly.WorkspaceSvg.prototype.addTrashcan = function() {
this.trashcan = new Blockly.Trashcan(this);
var svgTrashcan = this.trashcan.createDom();
this.svgGroup_.insertBefore(svgTrashcan, this.svgBlockCanvas_);
this.componentManager_.addComponent({
id: 'trashcan',
component: this.trashcan,
weight: 1,
capabilities: [Blockly.ComponentManager.Capability.POSITIONABLE]
});
};
/**
@@ -1023,12 +1017,6 @@ Blockly.WorkspaceSvg.prototype.addZoomControls = function() {
this.zoomControls_ = new Blockly.ZoomControls(this);
var svgZoomControls = this.zoomControls_.createDom();
this.svgGroup_.appendChild(svgZoomControls);
this.componentManager_.addComponent({
id: 'zoomControls',
component: this.zoomControls_,
weight: 2,
capabilities: [Blockly.ComponentManager.Capability.POSITIONABLE]
});
};
/**
@@ -2261,7 +2249,7 @@ Blockly.WorkspaceSvg.prototype.getScale = function() {
* @package
*/
Blockly.WorkspaceSvg.prototype.scroll = function(x, y) {
Blockly.hideChaff(/* opt_allowToolbox */ true);
Blockly.hideChaff(/* opt_onlyClosePopups */ true);
// Keep scrolling within the bounds of the content.
var metrics = this.getMetrics();

View File

@@ -189,6 +189,12 @@ Blockly.ZoomControls.prototype.createDom = function() {
* Initializes the zoom controls.
*/
Blockly.ZoomControls.prototype.init = function() {
this.workspace_.getComponentManager().addComponent({
id: 'zoomControls',
component: this,
weight: 2,
capabilities: [Blockly.ComponentManager.Capability.POSITIONABLE]
});
this.initialized_ = true;
};