mirror of
https://github.com/google/blockly.git
synced 2026-01-13 20:07:08 +01:00
Fix: Revert focus prs (#8933)
* Revert "feat: Make toolbox and flyout focusable (#8920)" This reverts commit5bc83808bf. * Revert "feat: Make WorkspaceSvg and BlockSvg focusable (#8916)" This reverts commitd7680cf32e.
This commit is contained in:
@@ -44,8 +44,6 @@ import {IContextMenu} from './interfaces/i_contextmenu.js';
|
||||
import type {ICopyable} from './interfaces/i_copyable.js';
|
||||
import {IDeletable} from './interfaces/i_deletable.js';
|
||||
import type {IDragStrategy, IDraggable} from './interfaces/i_draggable.js';
|
||||
import type {IFocusableNode} from './interfaces/i_focusable_node.js';
|
||||
import type {IFocusableTree} from './interfaces/i_focusable_tree.js';
|
||||
import {IIcon} from './interfaces/i_icon.js';
|
||||
import * as internalConstants from './internal_constants.js';
|
||||
import {MarkerManager} from './marker_manager.js';
|
||||
@@ -78,8 +76,7 @@ export class BlockSvg
|
||||
IContextMenu,
|
||||
ICopyable<BlockCopyData>,
|
||||
IDraggable,
|
||||
IDeletable,
|
||||
IFocusableNode
|
||||
IDeletable
|
||||
{
|
||||
/**
|
||||
* Constant for identifying rows that are to be rendered inline.
|
||||
@@ -213,7 +210,6 @@ export class BlockSvg
|
||||
|
||||
// Expose this block's ID on its top-level SVG group.
|
||||
this.svgGroup.setAttribute('data-id', this.id);
|
||||
svgPath.id = this.id;
|
||||
|
||||
this.doInit_();
|
||||
}
|
||||
@@ -1823,26 +1819,4 @@ export class BlockSvg
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** See IFocusableNode.getFocusableElement. */
|
||||
getFocusableElement(): HTMLElement | SVGElement {
|
||||
return this.pathObject.svgPath;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.getFocusableTree. */
|
||||
getFocusableTree(): IFocusableTree {
|
||||
return this.workspace;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.onNodeFocus. */
|
||||
onNodeFocus(): void {
|
||||
common.setSelected(this);
|
||||
}
|
||||
|
||||
/** See IFocusableNode.onNodeBlur. */
|
||||
onNodeBlur(): void {
|
||||
if (common.getSelected() === this) {
|
||||
common.setSelected(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,12 +21,9 @@ import * as eventUtils from './events/utils.js';
|
||||
import {FlyoutItem} from './flyout_item.js';
|
||||
import {FlyoutMetricsManager} from './flyout_metrics_manager.js';
|
||||
import {FlyoutSeparator, SeparatorAxis} from './flyout_separator.js';
|
||||
import {getFocusManager} from './focus_manager.js';
|
||||
import {IAutoHideable} from './interfaces/i_autohideable.js';
|
||||
import type {IFlyout} from './interfaces/i_flyout.js';
|
||||
import type {IFlyoutInflater} from './interfaces/i_flyout_inflater.js';
|
||||
import {IFocusableNode} from './interfaces/i_focusable_node.js';
|
||||
import {IFocusableTree} from './interfaces/i_focusable_tree.js';
|
||||
import type {Options} from './options.js';
|
||||
import * as registry from './registry.js';
|
||||
import * as renderManagement from './render_management.js';
|
||||
@@ -46,7 +43,7 @@ import {WorkspaceSvg} from './workspace_svg.js';
|
||||
*/
|
||||
export abstract class Flyout
|
||||
extends DeleteArea
|
||||
implements IAutoHideable, IFlyout, IFocusableNode
|
||||
implements IAutoHideable, IFlyout
|
||||
{
|
||||
/**
|
||||
* Position the flyout.
|
||||
@@ -306,7 +303,6 @@ export abstract class Flyout
|
||||
// hide/show code will set up proper visibility and size later.
|
||||
this.svgGroup_ = dom.createSvgElement(tagName, {
|
||||
'class': 'blocklyFlyout',
|
||||
'tabindex': '0',
|
||||
});
|
||||
this.svgGroup_.style.display = 'none';
|
||||
this.svgBackground_ = dom.createSvgElement(
|
||||
@@ -321,9 +317,6 @@ export abstract class Flyout
|
||||
this.workspace_
|
||||
.getThemeManager()
|
||||
.subscribe(this.svgBackground_, 'flyoutOpacity', 'fill-opacity');
|
||||
|
||||
getFocusManager().registerTree(this);
|
||||
|
||||
return this.svgGroup_;
|
||||
}
|
||||
|
||||
@@ -405,7 +398,6 @@ export abstract class Flyout
|
||||
if (this.svgGroup_) {
|
||||
dom.removeNode(this.svgGroup_);
|
||||
}
|
||||
getFocusManager().unregisterTree(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -969,63 +961,4 @@ export abstract class Flyout
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.getFocusableElement. */
|
||||
getFocusableElement(): HTMLElement | SVGElement {
|
||||
if (!this.svgGroup_) throw new Error('Flyout DOM is not yet created.');
|
||||
return this.svgGroup_;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.getFocusableTree. */
|
||||
getFocusableTree(): IFocusableTree {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.onNodeFocus. */
|
||||
onNodeFocus(): void {}
|
||||
|
||||
/** See IFocusableNode.onNodeBlur. */
|
||||
onNodeBlur(): void {}
|
||||
|
||||
/** See IFocusableTree.getRootFocusableNode. */
|
||||
getRootFocusableNode(): IFocusableNode {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** See IFocusableTree.getRestoredFocusableNode. */
|
||||
getRestoredFocusableNode(
|
||||
_previousNode: IFocusableNode | null,
|
||||
): IFocusableNode | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** See IFocusableTree.getNestedTrees. */
|
||||
getNestedTrees(): Array<IFocusableTree> {
|
||||
return [this.workspace_];
|
||||
}
|
||||
|
||||
/** See IFocusableTree.lookUpFocusableNode. */
|
||||
lookUpFocusableNode(_id: string): IFocusableNode | null {
|
||||
// No focusable node needs to be returned since the flyout's subtree is a
|
||||
// workspace that will manage its own focusable state.
|
||||
return null;
|
||||
}
|
||||
|
||||
/** See IFocusableTree.onTreeFocus. */
|
||||
onTreeFocus(
|
||||
_node: IFocusableNode,
|
||||
_previousTree: IFocusableTree | null,
|
||||
): void {}
|
||||
|
||||
/** See IFocusableTree.onTreeBlur. */
|
||||
onTreeBlur(nextTree: IFocusableTree | null): void {
|
||||
const toolbox = this.targetWorkspace.getToolbox();
|
||||
// If focus is moving to either the toolbox or the flyout's workspace, do
|
||||
// not close the flyout. For anything else, do close it since the flyout is
|
||||
// no longer focused.
|
||||
if (toolbox && nextTree === toolbox) return;
|
||||
if (nextTree == this.workspace_) return;
|
||||
if (toolbox) toolbox.clearSelection();
|
||||
this.autoHide(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,11 +13,13 @@ import * as common from './common.js';
|
||||
import * as Css from './css.js';
|
||||
import * as dropDownDiv from './dropdowndiv.js';
|
||||
import {Grid} from './grid.js';
|
||||
import {Msg} from './msg.js';
|
||||
import {Options} from './options.js';
|
||||
import {ScrollbarPair} from './scrollbar_pair.js';
|
||||
import {ShortcutRegistry} from './shortcut_registry.js';
|
||||
import * as Tooltip from './tooltip.js';
|
||||
import * as Touch from './touch.js';
|
||||
import * as aria from './utils/aria.js';
|
||||
import * as dom from './utils/dom.js';
|
||||
import {Svg} from './utils/svg.js';
|
||||
import * as WidgetDiv from './widgetdiv.js';
|
||||
@@ -54,6 +56,8 @@ export function inject(
|
||||
if (opt_options?.rtl) {
|
||||
dom.addClass(subContainer, 'blocklyRTL');
|
||||
}
|
||||
subContainer.tabIndex = 0;
|
||||
aria.setState(subContainer, aria.State.LABEL, Msg['WORKSPACE_ARIA_LABEL']);
|
||||
|
||||
containerElement!.appendChild(subContainer);
|
||||
const svg = createDom(subContainer, options);
|
||||
@@ -122,6 +126,7 @@ function createDom(container: HTMLElement, options: Options): SVGElement {
|
||||
'xmlns:xlink': dom.XLINK_NS,
|
||||
'version': '1.1',
|
||||
'class': 'blocklySvg',
|
||||
'tabindex': '0',
|
||||
},
|
||||
container,
|
||||
);
|
||||
|
||||
@@ -12,13 +12,12 @@ import type {Coordinate} from '../utils/coordinate.js';
|
||||
import type {Svg} from '../utils/svg.js';
|
||||
import type {FlyoutDefinition} from '../utils/toolbox.js';
|
||||
import type {WorkspaceSvg} from '../workspace_svg.js';
|
||||
import {IFocusableTree} from './i_focusable_tree.js';
|
||||
import type {IRegistrable} from './i_registrable.js';
|
||||
|
||||
/**
|
||||
* Interface for a flyout.
|
||||
*/
|
||||
export interface IFlyout extends IRegistrable, IFocusableTree {
|
||||
export interface IFlyout extends IRegistrable {
|
||||
/** Whether the flyout is laid out horizontally or not. */
|
||||
horizontalLayout: boolean;
|
||||
|
||||
|
||||
@@ -9,14 +9,13 @@
|
||||
import type {ToolboxInfo} from '../utils/toolbox.js';
|
||||
import type {WorkspaceSvg} from '../workspace_svg.js';
|
||||
import type {IFlyout} from './i_flyout.js';
|
||||
import type {IFocusableTree} from './i_focusable_tree.js';
|
||||
import type {IRegistrable} from './i_registrable.js';
|
||||
import type {IToolboxItem} from './i_toolbox_item.js';
|
||||
|
||||
/**
|
||||
* Interface for a toolbox.
|
||||
*/
|
||||
export interface IToolbox extends IRegistrable, IFocusableTree {
|
||||
export interface IToolbox extends IRegistrable {
|
||||
/** Initializes the toolbox. */
|
||||
init(): void;
|
||||
|
||||
|
||||
@@ -6,12 +6,10 @@
|
||||
|
||||
// Former goog.module ID: Blockly.IToolboxItem
|
||||
|
||||
import type {IFocusableNode} from './i_focusable_node.js';
|
||||
|
||||
/**
|
||||
* Interface for an item in the toolbox.
|
||||
*/
|
||||
export interface IToolboxItem extends IFocusableNode {
|
||||
export interface IToolboxItem {
|
||||
/**
|
||||
* Initializes the toolbox item.
|
||||
* This includes creating the DOM and updating the state of any items based
|
||||
|
||||
@@ -62,7 +62,7 @@ export class PathObject implements IPathObject {
|
||||
/** The primary path of the block. */
|
||||
this.svgPath = dom.createSvgElement(
|
||||
Svg.PATH,
|
||||
{'class': 'blocklyPath', 'tabindex': '-1'},
|
||||
{'class': 'blocklyPath'},
|
||||
this.svgRoot,
|
||||
);
|
||||
|
||||
|
||||
@@ -225,8 +225,6 @@ export class ToolboxCategory
|
||||
*/
|
||||
protected createContainer_(): HTMLDivElement {
|
||||
const container = document.createElement('div');
|
||||
container.tabIndex = -1;
|
||||
container.id = this.getId();
|
||||
const className = this.cssConfig_['container'];
|
||||
if (className) {
|
||||
dom.addClass(container, className);
|
||||
|
||||
@@ -54,8 +54,6 @@ export class ToolboxSeparator extends ToolboxItem {
|
||||
*/
|
||||
protected createDom_(): HTMLDivElement {
|
||||
const container = document.createElement('div');
|
||||
container.tabIndex = -1;
|
||||
container.id = this.getId();
|
||||
const className = this.cssConfig_['container'];
|
||||
if (className) {
|
||||
dom.addClass(container, className);
|
||||
|
||||
@@ -22,14 +22,11 @@ import {DeleteArea} from '../delete_area.js';
|
||||
import '../events/events_toolbox_item_select.js';
|
||||
import {EventType} from '../events/type.js';
|
||||
import * as eventUtils from '../events/utils.js';
|
||||
import {getFocusManager} from '../focus_manager.js';
|
||||
import type {IAutoHideable} from '../interfaces/i_autohideable.js';
|
||||
import type {ICollapsibleToolboxItem} from '../interfaces/i_collapsible_toolbox_item.js';
|
||||
import {isDeletable} from '../interfaces/i_deletable.js';
|
||||
import type {IDraggable} from '../interfaces/i_draggable.js';
|
||||
import type {IFlyout} from '../interfaces/i_flyout.js';
|
||||
import type {IFocusableNode} from '../interfaces/i_focusable_node.js';
|
||||
import type {IFocusableTree} from '../interfaces/i_focusable_tree.js';
|
||||
import type {IKeyboardAccessible} from '../interfaces/i_keyboard_accessible.js';
|
||||
import type {ISelectableToolboxItem} from '../interfaces/i_selectable_toolbox_item.js';
|
||||
import {isSelectableToolboxItem} from '../interfaces/i_selectable_toolbox_item.js';
|
||||
@@ -54,12 +51,7 @@ import {CollapsibleToolboxCategory} from './collapsible_category.js';
|
||||
*/
|
||||
export class Toolbox
|
||||
extends DeleteArea
|
||||
implements
|
||||
IAutoHideable,
|
||||
IKeyboardAccessible,
|
||||
IStyleable,
|
||||
IToolbox,
|
||||
IFocusableNode
|
||||
implements IAutoHideable, IKeyboardAccessible, IStyleable, IToolbox
|
||||
{
|
||||
/**
|
||||
* The unique ID for this component that is used to register with the
|
||||
@@ -171,7 +163,6 @@ export class Toolbox
|
||||
ComponentManager.Capability.DRAG_TARGET,
|
||||
],
|
||||
});
|
||||
getFocusManager().registerTree(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,6 +177,7 @@ export class Toolbox
|
||||
const container = this.createContainer_();
|
||||
|
||||
this.contentsDiv_ = this.createContentsContainer_();
|
||||
this.contentsDiv_.tabIndex = 0;
|
||||
aria.setRole(this.contentsDiv_, aria.Role.TREE);
|
||||
container.appendChild(this.contentsDiv_);
|
||||
|
||||
@@ -202,7 +194,6 @@ export class Toolbox
|
||||
*/
|
||||
protected createContainer_(): HTMLDivElement {
|
||||
const toolboxContainer = document.createElement('div');
|
||||
toolboxContainer.tabIndex = 0;
|
||||
toolboxContainer.setAttribute('layout', this.isHorizontal() ? 'h' : 'v');
|
||||
dom.addClass(toolboxContainer, 'blocklyToolbox');
|
||||
toolboxContainer.setAttribute('dir', this.RTL ? 'RTL' : 'LTR');
|
||||
@@ -1086,71 +1077,7 @@ export class Toolbox
|
||||
this.workspace_.getThemeManager().unsubscribe(this.HtmlDiv);
|
||||
dom.removeNode(this.HtmlDiv);
|
||||
}
|
||||
|
||||
getFocusManager().unregisterTree(this);
|
||||
}
|
||||
|
||||
/** See IFocusableNode.getFocusableElement. */
|
||||
getFocusableElement(): HTMLElement | SVGElement {
|
||||
if (!this.HtmlDiv) throw Error('Toolbox DOM has not yet been created.');
|
||||
return this.HtmlDiv;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.getFocusableTree. */
|
||||
getFocusableTree(): IFocusableTree {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.onNodeFocus. */
|
||||
onNodeFocus(): void {}
|
||||
|
||||
/** See IFocusableNode.onNodeBlur. */
|
||||
onNodeBlur(): void {}
|
||||
|
||||
/** See IFocusableTree.getRootFocusableNode. */
|
||||
getRootFocusableNode(): IFocusableNode {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** See IFocusableTree.getRestoredFocusableNode. */
|
||||
getRestoredFocusableNode(
|
||||
previousNode: IFocusableNode | null,
|
||||
): IFocusableNode | null {
|
||||
// Always try to select the first selectable toolbox item rather than the
|
||||
// root of the toolbox.
|
||||
if (!previousNode || previousNode === this) {
|
||||
return this.getToolboxItems().find((item) => item.isSelectable()) ?? null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** See IFocusableTree.getNestedTrees. */
|
||||
getNestedTrees(): Array<IFocusableTree> {
|
||||
return [];
|
||||
}
|
||||
|
||||
/** See IFocusableTree.lookUpFocusableNode. */
|
||||
lookUpFocusableNode(id: string): IFocusableNode | null {
|
||||
return this.getToolboxItemById(id) as IFocusableNode;
|
||||
}
|
||||
|
||||
/** See IFocusableTree.onTreeFocus. */
|
||||
onTreeFocus(
|
||||
node: IFocusableNode,
|
||||
_previousTree: IFocusableTree | null,
|
||||
): void {
|
||||
if (node !== this) {
|
||||
// Only select the item if it isn't already selected so as to not toggle.
|
||||
if (this.getSelectedItem() !== node) {
|
||||
this.setSelectedItem(node as IToolboxItem);
|
||||
}
|
||||
} else {
|
||||
this.clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
/** See IFocusableTree.onTreeBlur. */
|
||||
onTreeBlur(_nextTree: IFocusableTree | null): void {}
|
||||
}
|
||||
|
||||
/** CSS for Toolbox. See css.js for use. */
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
// Former goog.module ID: Blockly.ToolboxItem
|
||||
|
||||
import type {ICollapsibleToolboxItem} from '../interfaces/i_collapsible_toolbox_item.js';
|
||||
import type {IFocusableTree} from '../interfaces/i_focusable_tree.js';
|
||||
import type {IToolbox} from '../interfaces/i_toolbox.js';
|
||||
import type {IToolboxItem} from '../interfaces/i_toolbox_item.js';
|
||||
import * as idGenerator from '../utils/idgenerator.js';
|
||||
@@ -149,28 +148,5 @@ export class ToolboxItem implements IToolboxItem {
|
||||
* @param _isVisible True if category should be visible.
|
||||
*/
|
||||
setVisible_(_isVisible: boolean) {}
|
||||
|
||||
/** See IFocusableNode.getFocusableElement. */
|
||||
getFocusableElement(): HTMLElement | SVGElement {
|
||||
const div = this.getDiv();
|
||||
if (!div) {
|
||||
throw Error('Trying to access toolbox item before DOM is initialized.');
|
||||
}
|
||||
if (!(div instanceof HTMLElement)) {
|
||||
throw Error('Toolbox item div is unexpectedly not an HTML element.');
|
||||
}
|
||||
return div as HTMLElement;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.getFocusableTree. */
|
||||
getFocusableTree(): IFocusableTree {
|
||||
return this.parentToolbox_;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.onNodeFocus. */
|
||||
onNodeFocus(): void {}
|
||||
|
||||
/** See IFocusableNode.onNodeBlur. */
|
||||
onNodeBlur(): void {}
|
||||
}
|
||||
// nop by default
|
||||
|
||||
@@ -37,7 +37,6 @@ import {EventType} from './events/type.js';
|
||||
import * as eventUtils from './events/utils.js';
|
||||
import {Flyout} from './flyout_base.js';
|
||||
import type {FlyoutButton} from './flyout_button.js';
|
||||
import {getFocusManager} from './focus_manager.js';
|
||||
import {Gesture} from './gesture.js';
|
||||
import {Grid} from './grid.js';
|
||||
import type {IASTNodeLocationSvg} from './interfaces/i_ast_node_location_svg.js';
|
||||
@@ -45,8 +44,6 @@ import type {IBoundedElement} from './interfaces/i_bounded_element.js';
|
||||
import {IContextMenu} from './interfaces/i_contextmenu.js';
|
||||
import type {IDragTarget} from './interfaces/i_drag_target.js';
|
||||
import type {IFlyout} from './interfaces/i_flyout.js';
|
||||
import type {IFocusableNode} from './interfaces/i_focusable_node.js';
|
||||
import type {IFocusableTree} from './interfaces/i_focusable_tree.js';
|
||||
import type {IMetricsManager} from './interfaces/i_metrics_manager.js';
|
||||
import type {IToolbox} from './interfaces/i_toolbox.js';
|
||||
import type {
|
||||
@@ -57,7 +54,6 @@ import type {LineCursor} from './keyboard_nav/line_cursor.js';
|
||||
import type {Marker} from './keyboard_nav/marker.js';
|
||||
import {LayerManager} from './layer_manager.js';
|
||||
import {MarkerManager} from './marker_manager.js';
|
||||
import {Msg} from './msg.js';
|
||||
import {Options} from './options.js';
|
||||
import * as Procedures from './procedures.js';
|
||||
import * as registry from './registry.js';
|
||||
@@ -70,7 +66,6 @@ import {Classic} from './theme/classic.js';
|
||||
import {ThemeManager} from './theme_manager.js';
|
||||
import * as Tooltip from './tooltip.js';
|
||||
import type {Trashcan} from './trashcan.js';
|
||||
import * as aria from './utils/aria.js';
|
||||
import * as arrayUtils from './utils/array.js';
|
||||
import {Coordinate} from './utils/coordinate.js';
|
||||
import * as dom from './utils/dom.js';
|
||||
@@ -98,7 +93,7 @@ const ZOOM_TO_FIT_MARGIN = 20;
|
||||
*/
|
||||
export class WorkspaceSvg
|
||||
extends Workspace
|
||||
implements IASTNodeLocationSvg, IContextMenu, IFocusableNode, IFocusableTree
|
||||
implements IASTNodeLocationSvg, IContextMenu
|
||||
{
|
||||
/**
|
||||
* A wrapper function called when a resize event occurs.
|
||||
@@ -769,19 +764,7 @@ export class WorkspaceSvg
|
||||
* <g class="blocklyBubbleCanvas"></g>
|
||||
* </g>
|
||||
*/
|
||||
this.svgGroup_ = dom.createSvgElement(Svg.G, {
|
||||
'class': 'blocklyWorkspace',
|
||||
// Only the top-level workspace should be tabbable.
|
||||
'tabindex': injectionDiv ? '0' : '-1',
|
||||
'id': this.id,
|
||||
});
|
||||
if (injectionDiv) {
|
||||
aria.setState(
|
||||
this.svgGroup_,
|
||||
aria.State.LABEL,
|
||||
Msg['WORKSPACE_ARIA_LABEL'],
|
||||
);
|
||||
}
|
||||
this.svgGroup_ = dom.createSvgElement(Svg.G, {'class': 'blocklyWorkspace'});
|
||||
|
||||
// Note that a <g> alone does not receive mouse events--it must have a
|
||||
// valid target inside it. If no background class is specified, as in the
|
||||
@@ -857,9 +840,6 @@ export class WorkspaceSvg
|
||||
this.getTheme(),
|
||||
isParentWorkspace ? this.getInjectionDiv() : undefined,
|
||||
);
|
||||
|
||||
getFocusManager().registerTree(this);
|
||||
|
||||
return this.svgGroup_;
|
||||
}
|
||||
|
||||
@@ -944,10 +924,6 @@ export class WorkspaceSvg
|
||||
document.body.removeEventListener('wheel', this.dummyWheelListener);
|
||||
this.dummyWheelListener = null;
|
||||
}
|
||||
|
||||
if (getFocusManager().isRegistered(this)) {
|
||||
getFocusManager().unregisterTree(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2642,67 +2618,6 @@ export class WorkspaceSvg
|
||||
deltaY *= scale;
|
||||
this.scroll(this.scrollX + deltaX, this.scrollY + deltaY);
|
||||
}
|
||||
|
||||
/** See IFocusableNode.getFocusableElement. */
|
||||
getFocusableElement(): HTMLElement | SVGElement {
|
||||
return this.svgGroup_;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.getFocusableTree. */
|
||||
getFocusableTree(): IFocusableTree {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** See IFocusableNode.onNodeFocus. */
|
||||
onNodeFocus(): void {}
|
||||
|
||||
/** See IFocusableNode.onNodeBlur. */
|
||||
onNodeBlur(): void {}
|
||||
|
||||
/** See IFocusableTree.getRootFocusableNode. */
|
||||
getRootFocusableNode(): IFocusableNode {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** See IFocusableTree.getRestoredFocusableNode. */
|
||||
getRestoredFocusableNode(
|
||||
previousNode: IFocusableNode | null,
|
||||
): IFocusableNode | null {
|
||||
if (!previousNode) {
|
||||
return this.getTopBlocks(true)[0] ?? null;
|
||||
} else return null;
|
||||
}
|
||||
|
||||
/** See IFocusableTree.getNestedTrees. */
|
||||
getNestedTrees(): Array<IFocusableTree> {
|
||||
return [];
|
||||
}
|
||||
|
||||
/** See IFocusableTree.lookUpFocusableNode. */
|
||||
lookUpFocusableNode(id: string): IFocusableNode | null {
|
||||
return this.getBlockById(id) as IFocusableNode;
|
||||
}
|
||||
|
||||
/** See IFocusableTree.onTreeFocus. */
|
||||
onTreeFocus(
|
||||
_node: IFocusableNode,
|
||||
_previousTree: IFocusableTree | null,
|
||||
): void {}
|
||||
|
||||
/** See IFocusableTree.onTreeBlur. */
|
||||
onTreeBlur(nextTree: IFocusableTree | null): void {
|
||||
// If the flyout loses focus, make sure to close it.
|
||||
if (this.isFlyout && this.targetWorkspace) {
|
||||
// Only hide the flyout if the flyout's workspace is losing focus and that
|
||||
// focus isn't returning to the flyout itself or the toolbox.
|
||||
const flyout = this.targetWorkspace.getFlyout();
|
||||
const toolbox = this.targetWorkspace.getToolbox();
|
||||
if (flyout && nextTree === flyout) return;
|
||||
if (toolbox && nextTree === toolbox) return;
|
||||
if (toolbox) toolbox.clearSelection();
|
||||
if (flyout && flyout instanceof Flyout) flyout.autoHide(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,6 @@ suite('Toolbox', function () {
|
||||
const themeManagerSpy = sinon.spy(themeManager, 'subscribe');
|
||||
const componentManager = this.toolbox.workspace_.getComponentManager();
|
||||
sinon.stub(componentManager, 'addComponent');
|
||||
this.toolbox.dispose(); // Dispose of the old toolbox so that it can be reinited.
|
||||
this.toolbox.init();
|
||||
sinon.assert.calledWith(
|
||||
themeManagerSpy,
|
||||
@@ -73,14 +72,12 @@ suite('Toolbox', function () {
|
||||
const renderSpy = sinon.spy(this.toolbox, 'render');
|
||||
const componentManager = this.toolbox.workspace_.getComponentManager();
|
||||
sinon.stub(componentManager, 'addComponent');
|
||||
this.toolbox.dispose(); // Dispose of the old toolbox so that it can be reinited.
|
||||
this.toolbox.init();
|
||||
sinon.assert.calledOnce(renderSpy);
|
||||
});
|
||||
test('Init called -> Flyout is initialized', function () {
|
||||
const componentManager = this.toolbox.workspace_.getComponentManager();
|
||||
sinon.stub(componentManager, 'addComponent');
|
||||
this.toolbox.dispose(); // Dispose of the old toolbox so that it can be reinited.
|
||||
this.toolbox.init();
|
||||
assert.isDefined(this.toolbox.getFlyout());
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user