blockly 12.0.0-beta.2 → 12.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,18 +10,18 @@
10
10
  */
11
11
  import './events/events_selected.js';
12
12
  import { Block } from './block.js';
13
- import { IDeletable } from './blockly.js';
14
13
  import { BlockCopyData } from './clipboard/block_paster.js';
15
14
  import type { Connection } from './connection.js';
16
15
  import { ConnectionType } from './connection_type.js';
17
16
  import { ContextMenuOption, LegacyContextMenuOption } from './contextmenu_registry.js';
18
- import type { Field } from './field.js';
19
17
  import { IconType } from './icons/icon_types.js';
20
18
  import { MutatorIcon } from './icons/mutator_icon.js';
21
19
  import type { Input } from './inputs/input.js';
22
20
  import type { IASTNodeLocationSvg } from './interfaces/i_ast_node_location_svg.js';
23
21
  import type { IBoundedElement } from './interfaces/i_bounded_element.js';
22
+ import { IContextMenu } from './interfaces/i_contextmenu.js';
24
23
  import type { ICopyable } from './interfaces/i_copyable.js';
24
+ import { IDeletable } from './interfaces/i_deletable.js';
25
25
  import type { IDragStrategy, IDraggable } from './interfaces/i_draggable.js';
26
26
  import { IIcon } from './interfaces/i_icon.js';
27
27
  import { RenderedConnection } from './rendered_connection.js';
@@ -36,7 +36,7 @@ import type { WorkspaceSvg } from './workspace_svg.js';
36
36
  * Class for a block's SVG representation.
37
37
  * Not normally called directly, workspace.newBlock() is preferred.
38
38
  */
39
- export declare class BlockSvg extends Block implements IASTNodeLocationSvg, IBoundedElement, ICopyable<BlockCopyData>, IDraggable, IDeletable {
39
+ export declare class BlockSvg extends Block implements IASTNodeLocationSvg, IBoundedElement, IContextMenu, ICopyable<BlockCopyData>, IDraggable, IDeletable {
40
40
  /**
41
41
  * Constant for identifying rows that are to be rendered inline.
42
42
  * Don't collide with Blockly.inputTypes.
@@ -232,13 +232,6 @@ export declare class BlockSvg extends Block implements IASTNodeLocationSvg, IBou
232
232
  * for that state.
233
233
  */
234
234
  private updateCollapsed;
235
- /**
236
- * Open the next (or previous) FieldTextInput.
237
- *
238
- * @param start Current field.
239
- * @param forward If true go forward, otherwise backward.
240
- */
241
- tab(start: Field, forward: boolean): void;
242
235
  /**
243
236
  * Handle a pointerdown on an SVG block.
244
237
  *
@@ -256,14 +249,20 @@ export declare class BlockSvg extends Block implements IASTNodeLocationSvg, IBou
256
249
  *
257
250
  * @returns Context menu options or null if no menu.
258
251
  */
259
- protected generateContextMenu(): Array<ContextMenuOption | LegacyContextMenuOption> | null;
252
+ protected generateContextMenu(e: Event): Array<ContextMenuOption | LegacyContextMenuOption> | null;
253
+ /**
254
+ * Gets the location in which to show the context menu for this block.
255
+ * Use the location of a click if the block was clicked, or a location
256
+ * based on the block's fields otherwise.
257
+ */
258
+ protected calculateContextMenuLocation(e: Event): Coordinate;
260
259
  /**
261
260
  * Show the context menu for this block.
262
261
  *
263
262
  * @param e Mouse event.
264
263
  * @internal
265
264
  */
266
- showContextMenu(e: PointerEvent): void;
265
+ showContextMenu(e: Event): void;
267
266
  /**
268
267
  * Updates the locations of any parts of the block that need to know where
269
268
  * they are (e.g. connections, icons).
@@ -713,6 +712,13 @@ export declare class BlockSvg extends Block implements IASTNodeLocationSvg, IBou
713
712
  * @internal
714
713
  */
715
714
  highlightShapeForInput(conn: RenderedConnection, add: boolean): void;
715
+ /**
716
+ * Returns the drag strategy currently in use by this block.
717
+ *
718
+ * @internal
719
+ * @returns This block's drag strategy.
720
+ */
721
+ getDragStrategy(): IDragStrategy;
716
722
  /** Sets the drag strategy for this block. */
717
723
  setDragStrategy(dragStrategy: IDragStrategy): void;
718
724
  /** Returns whether this block is movable or not. */
package/core/blockly.d.ts CHANGED
@@ -55,6 +55,7 @@ import { FlyoutItem } from './flyout_item.js';
55
55
  import { FlyoutMetricsManager } from './flyout_metrics_manager.js';
56
56
  import { FlyoutSeparator } from './flyout_separator.js';
57
57
  import { VerticalFlyout } from './flyout_vertical.js';
58
+ import { FocusManager, ReturnEphemeralFocus, getFocusManager } from './focus_manager.js';
58
59
  import { CodeGenerator } from './generator.js';
59
60
  import { Gesture } from './gesture.js';
60
61
  import { Grid } from './grid.js';
@@ -106,10 +107,8 @@ import { IVariableBackedParameterModel, isVariableBackedParameterModel } from '.
106
107
  import { IVariableMap } from './interfaces/i_variable_map.js';
107
108
  import { IVariableModel, IVariableState } from './interfaces/i_variable_model.js';
108
109
  import { ASTNode } from './keyboard_nav/ast_node.js';
109
- import { BasicCursor } from './keyboard_nav/basic_cursor.js';
110
- import { Cursor } from './keyboard_nav/cursor.js';
110
+ import { CursorOptions, LineCursor } from './keyboard_nav/line_cursor.js';
111
111
  import { Marker } from './keyboard_nav/marker.js';
112
- import { TabNavigateCursor } from './keyboard_nav/tab_navigate_cursor.js';
113
112
  import type { LayerManager } from './layer_manager.js';
114
113
  import * as layers from './layers.js';
115
114
  import { MarkerManager } from './marker_manager.js';
@@ -272,7 +271,7 @@ export declare const VARIABLE_DYNAMIC_CATEGORY_NAME: string;
272
271
  * procedure blocks.
273
272
  */
274
273
  export declare const PROCEDURE_CATEGORY_NAME: string;
275
- export { ASTNode, BasicCursor, Block, BlockSvg, BlocklyOptions, Blocks, CollapsibleToolboxCategory, ComponentManager, Connection, ConnectionChecker, ConnectionDB, ConnectionType, ContextMenu, ContextMenuItems, ContextMenuRegistry, Css, Cursor, DeleteArea, DragTarget, Events, Extensions, Procedures, ShortcutItems, Themes, Tooltip, Touch, Variables, VariablesDynamic, WidgetDiv, Xml, blockAnimations, blockRendering, browserEvents, bubbles, bumpObjects, clipboard, comments, common, constants, dialog, dragging, fieldRegistry, geras, Procedures as procedures, registry, thrasos, uiPosition, utils, zelos, };
274
+ export { ASTNode, Block, BlockSvg, BlocklyOptions, Blocks, CollapsibleToolboxCategory, ComponentManager, Connection, ConnectionChecker, ConnectionDB, ConnectionType, ContextMenu, ContextMenuItems, ContextMenuRegistry, Css, CursorOptions, DeleteArea, DragTarget, Events, Extensions, LineCursor, Procedures, ShortcutItems, Themes, Tooltip, Touch, Variables, VariablesDynamic, WidgetDiv, Xml, blockAnimations, blockRendering, browserEvents, bubbles, bumpObjects, clipboard, comments, common, constants, dialog, dragging, fieldRegistry, geras, Procedures as procedures, registry, thrasos, uiPosition, utils, zelos, };
276
275
  export declare const DropDownDiv: typeof dropDownDiv;
277
- export { BlockFlyoutInflater, ButtonFlyoutInflater, CodeGenerator, Field, FieldCheckbox, FieldCheckboxConfig, FieldCheckboxFromJsonConfig, FieldCheckboxValidator, FieldConfig, FieldDropdown, FieldDropdownConfig, FieldDropdownFromJsonConfig, FieldDropdownValidator, FieldImage, FieldImageConfig, FieldImageFromJsonConfig, FieldLabel, FieldLabelConfig, FieldLabelFromJsonConfig, FieldLabelSerializable, FieldNumber, FieldNumberConfig, FieldNumberFromJsonConfig, FieldNumberValidator, FieldTextInput, FieldTextInputConfig, FieldTextInputFromJsonConfig, FieldTextInputValidator, FieldValidator, FieldVariable, FieldVariableConfig, FieldVariableFromJsonConfig, FieldVariableValidator, Flyout, FlyoutButton, FlyoutItem, FlyoutMetricsManager, FlyoutSeparator, CodeGenerator as Generator, Gesture, Grid, HorizontalFlyout, IASTNodeLocation, IASTNodeLocationSvg, IASTNodeLocationWithBlock, IAutoHideable, IBoundedElement, IBubble, ICollapsibleToolboxItem, IComponent, IConnectionChecker, IConnectionPreviewer, IContextMenu, ICopyData, ICopyable, IDeletable, IDeleteArea, IDragStrategy, IDragTarget, IDraggable, IDragger, IFlyout, IFlyoutInflater, IFocusableNode, IFocusableTree, IHasBubble, IIcon, IKeyboardAccessible, IMetricsManager, IMovable, IObservable, IPaster, IPositionable, IRegistrable, IRenderedElement, ISelectable, ISelectableToolboxItem, ISerializable, IStyleable, IToolbox, IToolboxItem, IVariableBackedParameterModel, IVariableMap, IVariableModel, IVariableState, ImageProperties, Input, InsertionMarkerPreviewer, LabelFlyoutInflater, LayerManager, Marker, MarkerManager, Menu, MenuGenerator, MenuGeneratorFunction, MenuItem, MenuOption, MetricsManager, Msg, Names, Options, RenderedConnection, Scrollbar, ScrollbarPair, SeparatorFlyoutInflater, ShortcutRegistry, TabNavigateCursor, Theme, ThemeManager, Toolbox, ToolboxCategory, ToolboxItem, ToolboxSeparator, Trashcan, UnattachedFieldError, VariableMap, VariableModel, VerticalFlyout, Workspace, WorkspaceAudio, WorkspaceDragger, WorkspaceSvg, ZoomControls, config, hasBubble, icons, inject, inputs, isCopyable, isDeletable, isDraggable, isIcon, isObservable, isPaster, isRenderedElement, isSelectable, isSerializable, isVariableBackedParameterModel, layers, renderManagement, serialization, setLocale, };
276
+ export { BlockFlyoutInflater, ButtonFlyoutInflater, CodeGenerator, Field, FieldCheckbox, FieldCheckboxConfig, FieldCheckboxFromJsonConfig, FieldCheckboxValidator, FieldConfig, FieldDropdown, FieldDropdownConfig, FieldDropdownFromJsonConfig, FieldDropdownValidator, FieldImage, FieldImageConfig, FieldImageFromJsonConfig, FieldLabel, FieldLabelConfig, FieldLabelFromJsonConfig, FieldLabelSerializable, FieldNumber, FieldNumberConfig, FieldNumberFromJsonConfig, FieldNumberValidator, FieldTextInput, FieldTextInputConfig, FieldTextInputFromJsonConfig, FieldTextInputValidator, FieldValidator, FieldVariable, FieldVariableConfig, FieldVariableFromJsonConfig, FieldVariableValidator, Flyout, FlyoutButton, FlyoutItem, FlyoutMetricsManager, FlyoutSeparator, FocusManager, CodeGenerator as Generator, Gesture, Grid, HorizontalFlyout, IASTNodeLocation, IASTNodeLocationSvg, IASTNodeLocationWithBlock, IAutoHideable, IBoundedElement, IBubble, ICollapsibleToolboxItem, IComponent, IConnectionChecker, IConnectionPreviewer, IContextMenu, ICopyData, ICopyable, IDeletable, IDeleteArea, IDragStrategy, IDragTarget, IDraggable, IDragger, IFlyout, IFlyoutInflater, IFocusableNode, IFocusableTree, IHasBubble, IIcon, IKeyboardAccessible, IMetricsManager, IMovable, IObservable, IPaster, IPositionable, IRegistrable, IRenderedElement, ISelectable, ISelectableToolboxItem, ISerializable, IStyleable, IToolbox, IToolboxItem, IVariableBackedParameterModel, IVariableMap, IVariableModel, IVariableState, ImageProperties, Input, InsertionMarkerPreviewer, LabelFlyoutInflater, LayerManager, Marker, MarkerManager, Menu, MenuGenerator, MenuGeneratorFunction, MenuItem, MenuOption, MetricsManager, Msg, Names, Options, RenderedConnection, ReturnEphemeralFocus, Scrollbar, ScrollbarPair, SeparatorFlyoutInflater, ShortcutRegistry, Theme, ThemeManager, Toolbox, ToolboxCategory, ToolboxItem, ToolboxSeparator, Trashcan, UnattachedFieldError, VariableMap, VariableModel, VerticalFlyout, Workspace, WorkspaceAudio, WorkspaceDragger, WorkspaceSvg, ZoomControls, config, getFocusManager, hasBubble, icons, inject, inputs, isCopyable, isDeletable, isDraggable, isIcon, isObservable, isPaster, isRenderedElement, isSelectable, isSerializable, isVariableBackedParameterModel, layers, renderManagement, serialization, setLocale, };
278
277
  //# sourceMappingURL=blockly.d.ts.map
@@ -95,7 +95,7 @@ export declare class RenderedWorkspaceComment extends WorkspaceComment implement
95
95
  */
96
96
  toCopyData(): WorkspaceCommentCopyData | null;
97
97
  /** Show a context menu for this comment. */
98
- showContextMenu(e: PointerEvent): void;
98
+ showContextMenu(e: Event): void;
99
99
  /** Snap this comment to the nearest grid point. */
100
100
  snapToGrid(): void;
101
101
  }
@@ -7,9 +7,12 @@ import type { Block } from './block.js';
7
7
  import type { BlockSvg } from './block_svg.js';
8
8
  import type { ContextMenuOption, LegacyContextMenuOption } from './contextmenu_registry.js';
9
9
  import * as serializationBlocks from './serialization/blocks.js';
10
+ import { Coordinate } from './utils/coordinate.js';
10
11
  import type { WorkspaceSvg } from './workspace_svg.js';
11
12
  /**
12
13
  * Gets the block the context menu is currently attached to.
14
+ * It is not recommended that you use this function; instead,
15
+ * use the scope object passed to the context menu callback.
13
16
  *
14
17
  * @returns The block the context menu is attached to.
15
18
  */
@@ -23,12 +26,13 @@ export declare function setCurrentBlock(block: Block | null): void;
23
26
  /**
24
27
  * Construct the menu based on the list of options and show the menu.
25
28
  *
26
- * @param e Mouse event.
29
+ * @param menuOpenEvent Event that caused the menu to open.
27
30
  * @param options Array of menu options.
28
31
  * @param rtl True if RTL, false if LTR.
29
32
  * @param workspace The workspace associated with the context menu, if any.
33
+ * @param location The screen coordinates at which to show the menu.
30
34
  */
31
- export declare function show(e: PointerEvent, options: (ContextMenuOption | LegacyContextMenuOption)[], rtl: boolean, workspace?: WorkspaceSvg): void;
35
+ export declare function show(menuOpenEvent: Event, options: (ContextMenuOption | LegacyContextMenuOption)[], rtl: boolean, workspace?: WorkspaceSvg, location?: Coordinate): void;
32
36
  /**
33
37
  * Hide the context menu.
34
38
  */
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import type { BlockSvg } from './block_svg.js';
12
12
  import { RenderedWorkspaceComment } from './comments/rendered_workspace_comment.js';
13
+ import { Coordinate } from './utils/coordinate.js';
13
14
  import type { WorkspaceSvg } from './workspace_svg.js';
14
15
  /**
15
16
  * Class for the registry of context menu items. This is intended to be a
@@ -54,7 +55,7 @@ export declare class ContextMenuRegistry {
54
55
  * block being clicked on)
55
56
  * @returns the list of ContextMenuOptions
56
57
  */
57
- getContextMenuOptions(scopeType: ScopeType, scope: Scope): ContextMenuOption[];
58
+ getContextMenuOptions(scopeType: ScopeType, scope: Scope, menuOpenEvent: Event): ContextMenuOption[];
58
59
  }
59
60
  export declare namespace ContextMenuRegistry {
60
61
  /**
@@ -91,12 +92,13 @@ export declare namespace ContextMenuRegistry {
91
92
  /**
92
93
  * @param scope Object that provides a reference to the thing that had its
93
94
  * context menu opened.
94
- * @param e The original event that triggered the context menu to open. Not
95
- * the event that triggered the click on the option.
95
+ * @param menuOpenEvent The original event that triggered the context menu to open.
96
+ * @param menuSelectEvent The event that triggered the option being selected.
97
+ * @param location The location in screen coordinates where the menu was opened.
96
98
  */
97
- callback: (scope: Scope, e: PointerEvent) => void;
99
+ callback: (scope: Scope, menuOpenEvent: Event, menuSelectEvent: Event, location: Coordinate) => void;
98
100
  displayText: ((p1: Scope) => string | HTMLElement) | string | HTMLElement;
99
- preconditionFn: (p1: Scope) => string;
101
+ preconditionFn: (p1: Scope, menuOpenEvent: Event) => string;
100
102
  separator?: never;
101
103
  }
102
104
  /**
@@ -128,10 +130,11 @@ export declare namespace ContextMenuRegistry {
128
130
  /**
129
131
  * @param scope Object that provides a reference to the thing that had its
130
132
  * context menu opened.
131
- * @param e The original event that triggered the context menu to open. Not
132
- * the event that triggered the click on the option.
133
+ * @param menuOpenEvent The original event that triggered the context menu to open.
134
+ * @param menuSelectEvent The event that triggered the option being selected.
135
+ * @param location The location in screen coordinates where the menu was opened.
133
136
  */
134
- callback: (scope: Scope, e: PointerEvent) => void;
137
+ callback: (scope: Scope, menuOpenEvent: Event, menuSelectEvent: Event, location: Coordinate) => void;
135
138
  separator?: never;
136
139
  }
137
140
  /**
@@ -35,6 +35,14 @@ export declare class BlockDragStrategy implements IDragStrategy {
35
35
  * from any parent blocks.
36
36
  */
37
37
  startDrag(e?: PointerEvent): void;
38
+ /**
39
+ * Get whether the drag should act on a single block or a block stack.
40
+ *
41
+ * @param e The instigating pointer event, if any.
42
+ * @returns True if just the initial block should be dragged out, false
43
+ * if all following blocks should also be dragged.
44
+ */
45
+ protected shouldHealStack(e: PointerEvent | undefined): boolean;
38
46
  /** Starts a drag on a shadow, recording the drag offset. */
39
47
  private startDraggingShadow;
40
48
  /**
@@ -84,6 +92,10 @@ export declare class BlockDragStrategy implements IDragStrategy {
84
92
  * compatible type (input, output, etc) and connection check.
85
93
  */
86
94
  private getConnectionCandidate;
95
+ /**
96
+ * Get the radius to use when searching for a nearby valid connection.
97
+ */
98
+ protected getSearchRadius(): number;
87
99
  /**
88
100
  * Returns all of the connections we might connect to blocks on the workspace.
89
101
  *
package/core/field.d.ts CHANGED
@@ -203,8 +203,10 @@ export declare abstract class Field<T = any> implements IASTNodeLocationSvg, IAS
203
203
  * intend because the behavior was kind of hacked in. If you are thinking
204
204
  * about overriding this function, post on the forum with your intended
205
205
  * behavior to see if there's another approach.
206
+ *
207
+ * @internal
206
208
  */
207
- protected isFullBlockField(): boolean;
209
+ isFullBlockField(): boolean;
208
210
  /**
209
211
  * Create a field border rect element. Not to be overridden by subclasses.
210
212
  * Instead modify the result of the function inside initView, or create a
@@ -660,12 +662,6 @@ export declare abstract class Field<T = any> implements IASTNodeLocationSvg, IAS
660
662
  * @returns True if we should flip in RTL.
661
663
  */
662
664
  getFlipRtl(): boolean;
663
- /**
664
- * Returns whether or not the field is tab navigable.
665
- *
666
- * @returns True if the field is tab navigable.
667
- */
668
- isTabNavigable(): boolean;
669
665
  /**
670
666
  * Handles the given keyboard shortcut.
671
667
  *
@@ -79,7 +79,7 @@ export declare abstract class FieldInput<T extends InputTypes> extends Field<str
79
79
  constructor(value?: string | typeof Field.SKIP_SETUP, validator?: FieldInputValidator<T> | null, config?: FieldInputConfig);
80
80
  protected configure_(config: FieldInputConfig): void;
81
81
  initView(): void;
82
- protected isFullBlockField(): boolean;
82
+ isFullBlockField(): boolean;
83
83
  /**
84
84
  * Called by setValue if the text input is not valid. If the field is
85
85
  * currently being edited it reverts value of the field to the previous
@@ -214,12 +214,6 @@ export declare abstract class FieldInput<T extends InputTypes> extends Field<str
214
214
  * div.
215
215
  */
216
216
  repositionForWindowResize(): boolean;
217
- /**
218
- * Returns whether or not the field is tab navigable.
219
- *
220
- * @returns True if the field is tab navigable.
221
- */
222
- isTabNavigable(): boolean;
223
217
  /**
224
218
  * Use the `getText_` developer hook to override the field's text
225
219
  * representation. When we're currently editing, return the current HTML value
@@ -47,7 +47,8 @@ export declare class FieldVariable extends FieldDropdown {
47
47
  * field's value. Takes in a variable ID & returns a validated variable
48
48
  * ID, or null to abort the change.
49
49
  * @param variableTypes A list of the types of variables to include in the
50
- * dropdown. Will only be used if config is not provided.
50
+ * dropdown. Pass `null` to include all types that exist on the
51
+ * workspace. Will only be used if config is not provided.
51
52
  * @param defaultType The type of variable to create if this field's value
52
53
  * is not explicitly set. Defaults to ''. Will only be used if config
53
54
  * is not provided.
@@ -56,7 +57,7 @@ export declare class FieldVariable extends FieldDropdown {
56
57
  * https://developers.google.com/blockly/guides/create-custom-blocks/fields/built-in-fields/variable#creation}
57
58
  * for a list of properties this parameter supports.
58
59
  */
59
- constructor(varName: string | null | typeof Field.SKIP_SETUP, validator?: FieldVariableValidator, variableTypes?: string[], defaultType?: string, config?: FieldVariableConfig);
60
+ constructor(varName: string | null | typeof Field.SKIP_SETUP, validator?: FieldVariableValidator, variableTypes?: string[] | null, defaultType?: string, config?: FieldVariableConfig);
60
61
  /**
61
62
  * Configure the field based on the given map of options.
62
63
  *
@@ -173,7 +174,6 @@ export declare class FieldVariable extends FieldDropdown {
173
174
  * Return a list of variable types to include in the dropdown.
174
175
  *
175
176
  * @returns Array of variable types.
176
- * @throws {Error} if variableTypes is an empty array.
177
177
  */
178
178
  private getVariableTypes;
179
179
  /**
@@ -0,0 +1,163 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { IFocusableNode } from './interfaces/i_focusable_node.js';
7
+ import type { IFocusableTree } from './interfaces/i_focusable_tree.js';
8
+ /**
9
+ * Type declaration for returning focus to FocusManager upon completing an
10
+ * ephemeral UI flow (such as a dialog).
11
+ *
12
+ * See FocusManager.takeEphemeralFocus for more details.
13
+ */
14
+ export type ReturnEphemeralFocus = () => void;
15
+ /**
16
+ * A per-page singleton that manages Blockly focus across one or more
17
+ * IFocusableTrees, and bidirectionally synchronizes this focus with the DOM.
18
+ *
19
+ * Callers that wish to explicitly change input focus for select Blockly
20
+ * components on the page should use the focus functions in this manager.
21
+ *
22
+ * The manager is responsible for handling focus events from the DOM (which may
23
+ * may arise from users clicking on page elements) and ensuring that
24
+ * corresponding IFocusableNodes are clearly marked as actively/passively
25
+ * highlighted in the same way that this would be represented with calls to
26
+ * focusNode().
27
+ */
28
+ export declare class FocusManager {
29
+ /**
30
+ * The CSS class assigned to IFocusableNode elements that presently have
31
+ * active DOM and Blockly focus.
32
+ *
33
+ * This should never be used directly. Instead, rely on FocusManager to ensure
34
+ * nodes have active focus (either automatically through DOM focus or manually
35
+ * through the various focus* methods provided by this class).
36
+ *
37
+ * It's recommended to not query using this class name, either. Instead, use
38
+ * FocusableTreeTraverser or IFocusableTree's methods to find a specific node.
39
+ */
40
+ static readonly ACTIVE_FOCUS_NODE_CSS_CLASS_NAME = "blocklyActiveFocus";
41
+ /**
42
+ * The CSS class assigned to IFocusableNode elements that presently have
43
+ * passive focus (that is, they were the most recent node in their relative
44
+ * tree to have active focus--see ACTIVE_FOCUS_NODE_CSS_CLASS_NAME--and will
45
+ * receive active focus again if their surrounding tree is requested to become
46
+ * focused, i.e. using focusTree below).
47
+ *
48
+ * See ACTIVE_FOCUS_NODE_CSS_CLASS_NAME for caveats and limitations around
49
+ * using this constant directly (generally it never should need to be used).
50
+ */
51
+ static readonly PASSIVE_FOCUS_NODE_CSS_CLASS_NAME = "blocklyPassiveFocus";
52
+ focusedNode: IFocusableNode | null;
53
+ registeredTrees: Array<IFocusableTree>;
54
+ private currentlyHoldsEphemeralFocus;
55
+ constructor(addGlobalEventListener: (type: string, listener: EventListener) => void);
56
+ /**
57
+ * Registers a new IFocusableTree for automatic focus management.
58
+ *
59
+ * If the tree currently has an element with DOM focus, it will not affect the
60
+ * internal state in this manager until the focus changes to a new,
61
+ * now-monitored element/node.
62
+ *
63
+ * This function throws if the provided tree is already currently registered
64
+ * in this manager. Use isRegistered to check in cases when it can't be
65
+ * certain whether the tree has been registered.
66
+ */
67
+ registerTree(tree: IFocusableTree): void;
68
+ /**
69
+ * Returns whether the specified tree has already been registered in this
70
+ * manager using registerTree and hasn't yet been unregistered using
71
+ * unregisterTree.
72
+ */
73
+ isRegistered(tree: IFocusableTree): boolean;
74
+ /**
75
+ * Unregisters a IFocusableTree from automatic focus management.
76
+ *
77
+ * If the tree had a previous focused node, it will have its highlight
78
+ * removed. This function does NOT change DOM focus.
79
+ *
80
+ * This function throws if the provided tree is not currently registered in
81
+ * this manager.
82
+ */
83
+ unregisterTree(tree: IFocusableTree): void;
84
+ /**
85
+ * Returns the current IFocusableTree that has focus, or null if none
86
+ * currently do.
87
+ *
88
+ * Note also that if ephemeral focus is currently captured (e.g. using
89
+ * takeEphemeralFocus) then the returned tree here may not currently have DOM
90
+ * focus.
91
+ */
92
+ getFocusedTree(): IFocusableTree | null;
93
+ /**
94
+ * Returns the current IFocusableNode with focus (which is always tied to a
95
+ * focused IFocusableTree), or null if there isn't one.
96
+ *
97
+ * Note that this function will maintain parity with
98
+ * IFocusableTree.getFocusedNode(). That is, if a tree itself has focus but
99
+ * none of its non-root children do, this will return null but
100
+ * getFocusedTree() will not.
101
+ *
102
+ * Note also that if ephemeral focus is currently captured (e.g. using
103
+ * takeEphemeralFocus) then the returned node here may not currently have DOM
104
+ * focus.
105
+ */
106
+ getFocusedNode(): IFocusableNode | null;
107
+ /**
108
+ * Focuses the specific IFocusableTree. This either means restoring active
109
+ * focus to the tree's passively focused node, or focusing the tree's root
110
+ * node.
111
+ *
112
+ * Note that if the specified tree already has a focused node then this will
113
+ * not change any existing focus (unless that node has passive focus, then it
114
+ * will be restored to active focus).
115
+ *
116
+ * See getFocusedNode for details on how other nodes are affected.
117
+ *
118
+ * @param focusableTree The tree that should receive active
119
+ * focus.
120
+ */
121
+ focusTree(focusableTree: IFocusableTree): void;
122
+ /**
123
+ * Focuses DOM input on the selected node, and marks it as actively focused.
124
+ *
125
+ * Any previously focused node will be updated to be passively highlighted (if
126
+ * it's in a different focusable tree) or blurred (if it's in the same one).
127
+ *
128
+ * @param focusableNode The node that should receive active
129
+ * focus.
130
+ */
131
+ focusNode(focusableNode: IFocusableNode): void;
132
+ /**
133
+ * Ephemerally captures focus for a selected element until the returned lambda
134
+ * is called. This is expected to be especially useful for ephemeral UI flows
135
+ * like dialogs.
136
+ *
137
+ * IMPORTANT: the returned lambda *must* be called, otherwise automatic focus
138
+ * will no longer work anywhere on the page. It is highly recommended to tie
139
+ * the lambda call to the closure of the corresponding UI so that if input is
140
+ * manually changed to an element outside of the ephemeral UI, the UI should
141
+ * close and automatic input restored. Note that this lambda must be called
142
+ * exactly once and that subsequent calls will throw an error.
143
+ *
144
+ * Note that the manager will continue to track DOM input signals even when
145
+ * ephemeral focus is active, but it won't actually change node state until
146
+ * the returned lambda is called. Additionally, only 1 ephemeral focus context
147
+ * can be active at any given time (attempting to activate more than one
148
+ * simultaneously will result in an error being thrown).
149
+ */
150
+ takeEphemeralFocus(focusableElement: HTMLElement | SVGElement): ReturnEphemeralFocus;
151
+ private defocusCurrentFocusedNode;
152
+ private setNodeToActive;
153
+ private setNodeToPassive;
154
+ private removeHighlight;
155
+ }
156
+ /**
157
+ * Returns the page-global FocusManager.
158
+ *
159
+ * The returned instance is guaranteed to not change across function calls, but
160
+ * may change across page loads.
161
+ */
162
+ export declare function getFocusManager(): FocusManager;
163
+ //# sourceMappingURL=focus_manager.d.ts.map
@@ -18,7 +18,10 @@ export interface IFocusableNode {
18
18
  * - blocklyPassiveFocus
19
19
  *
20
20
  * The returned element must also have a valid ID specified, and unique to the
21
- * element relative to its nearest IFocusableTree parent.
21
+ * element relative to its nearest IFocusableTree parent. It must also have a
22
+ * negative tabindex (since the focus manager itself will manage its tab index
23
+ * and a tab index must be present in order for the element to be focusable in
24
+ * the DOM).
22
25
  *
23
26
  * It's expected the return element will not change for the lifetime of the
24
27
  * node.
@@ -18,16 +18,14 @@ import type { IFocusableNode } from './i_focusable_node.js';
18
18
  * page at any given time). The idea of passive focus is to provide context to
19
19
  * users on where their focus will be restored upon navigating back to a
20
20
  * previously focused tree.
21
+ *
22
+ * Note that if the tree's current focused node (passive or active) is needed,
23
+ * FocusableTreeTraverser.findFocusedNode can be used.
24
+ *
25
+ * Note that if specific nodes are needed to be retrieved for this tree, either
26
+ * use lookUpFocusableNode or FocusableTreeTraverser.findFocusableNodeFor.
21
27
  */
22
28
  export interface IFocusableTree {
23
- /**
24
- * Returns the current node with focus in this tree, or null if none (or if
25
- * the root has focus).
26
- *
27
- * Note that this will never return a node from a nested sub-tree as that tree
28
- * should specifically be called in order to retrieve its focused node.
29
- */
30
- getFocusedNode(): IFocusableNode | null;
31
29
  /**
32
30
  * Returns the top-level focusable node of the tree.
33
31
  *
@@ -37,12 +35,24 @@ export interface IFocusableTree {
37
35
  */
38
36
  getRootFocusableNode(): IFocusableNode;
39
37
  /**
40
- * Returns the IFocusableNode corresponding to the select element, or null if
41
- * the element does not have such a node.
38
+ * Returns all directly nested trees under this tree.
39
+ *
40
+ * Note that the returned list of trees doesn't need to be stable, however all
41
+ * returned trees *do* need to be registered with FocusManager. Additionally,
42
+ * this must return actual nested trees as omitting a nested tree will affect
43
+ * how focus changes map to a specific node and its tree, potentially leading
44
+ * to user confusion.
45
+ */
46
+ getNestedTrees(): Array<IFocusableTree>;
47
+ /**
48
+ * Returns the IFocusableNode corresponding to the specified element ID, or
49
+ * null if there's no exact node within this tree with that ID or if the ID
50
+ * corresponds to the root of the tree.
51
+ *
52
+ * This will never match against nested trees.
42
53
  *
43
- * The provided element must have a non-null ID that conforms to the contract
44
- * mentioned in IFocusableNode.
54
+ * @param id The ID of the node's focusable HTMLElement or SVGElement.
45
55
  */
46
- findFocusableNodeFor(element: HTMLElement | SVGElement): IFocusableNode | null;
56
+ lookUpFocusableNode(id: string): IFocusableNode | null;
47
57
  }
48
58
  //# sourceMappingURL=i_focusable_tree.d.ts.map
@@ -72,7 +72,7 @@ export declare class ASTNode {
72
72
  * @returns The workspace coordinate or null if the location is not a
73
73
  * workspace.
74
74
  */
75
- getWsCoordinate(): Coordinate;
75
+ getWsCoordinate(): Coordinate | null;
76
76
  /**
77
77
  * Whether the node points to a connection.
78
78
  *
@@ -213,7 +213,7 @@ export declare class ASTNode {
213
213
  * @param field The location of the AST node.
214
214
  * @returns An AST node pointing to a field.
215
215
  */
216
- static createFieldNode(field: Field): ASTNode | null;
216
+ static createFieldNode(field: Field): ASTNode;
217
217
  /**
218
218
  * Creates an AST node pointing to a connection. If the connection has a
219
219
  * parent input then create an AST node of type input that will hold the
@@ -237,7 +237,7 @@ export declare class ASTNode {
237
237
  * @param block The block used to create an AST node.
238
238
  * @returns An AST node pointing to a block.
239
239
  */
240
- static createBlockNode(block: Block): ASTNode | null;
240
+ static createBlockNode(block: Block): ASTNode;
241
241
  /**
242
242
  * Create an AST node of type stack. A stack, represented by its top block, is
243
243
  * the set of all blocks connected to a top block, including the top
@@ -248,7 +248,7 @@ export declare class ASTNode {
248
248
  * @returns An AST node of type stack that points to the top block on the
249
249
  * stack.
250
250
  */
251
- static createStackNode(topBlock: Block): ASTNode | null;
251
+ static createStackNode(topBlock: Block): ASTNode;
252
252
  /**
253
253
  * Create an AST node of type button. A button in this case refers
254
254
  * specifically to a button in a flyout.
@@ -258,7 +258,7 @@ export declare class ASTNode {
258
258
  * @returns An AST node of type stack that points to the top block on the
259
259
  * stack.
260
260
  */
261
- static createButtonNode(button: FlyoutButton): ASTNode | null;
261
+ static createButtonNode(button: FlyoutButton): ASTNode;
262
262
  /**
263
263
  * Creates an AST node pointing to a workspace.
264
264
  *
@@ -267,7 +267,7 @@ export declare class ASTNode {
267
267
  * @returns An AST node pointing to a workspace and a position on the
268
268
  * workspace.
269
269
  */
270
- static createWorkspaceNode(workspace: Workspace | null, wsCoordinate: Coordinate | null): ASTNode | null;
270
+ static createWorkspaceNode(workspace: Workspace, wsCoordinate: Coordinate): ASTNode;
271
271
  /**
272
272
  * Creates an AST node for the top position on a block.
273
273
  * This is either an output connection, previous connection, or block.