blockly 12.2.0 → 12.3.0-beta.0

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.
package/core/block.d.ts CHANGED
@@ -544,7 +544,7 @@ export declare class Block {
544
544
  *
545
545
  * @yields A generator that can be used to iterate the fields on the block.
546
546
  */
547
- getFields(): Generator<Field>;
547
+ getFields(): Generator<Field, undefined, void>;
548
548
  /**
549
549
  * Return all variables referenced by this block.
550
550
  *
@@ -361,9 +361,12 @@ export declare class BlockSvg extends Block implements IBoundedElement, IContext
361
361
  /**
362
362
  * Encode a block for copying.
363
363
  *
364
+ * @param addNextBlocks If true, copy subsequent blocks attached to this one
365
+ * as well.
366
+ *
364
367
  * @returns Copy metadata, or null if the block is an insertion marker.
365
368
  */
366
- toCopyData(): BlockCopyData | null;
369
+ toCopyData(addNextBlocks?: boolean): BlockCopyData | null;
367
370
  /**
368
371
  * Updates the colour of the block to match the block's state.
369
372
  *
@@ -4,7 +4,9 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { IBubble } from '../interfaces/i_bubble.js';
7
+ import type { IFocusableNode } from '../interfaces/i_focusable_node.js';
7
8
  import type { IFocusableTree } from '../interfaces/i_focusable_tree.js';
9
+ import type { IHasBubble } from '../interfaces/i_has_bubble.js';
8
10
  import { ISelectable } from '../interfaces/i_selectable.js';
9
11
  import { Coordinate } from '../utils/coordinate.js';
10
12
  import { Rect } from '../utils/rect.js';
@@ -15,10 +17,11 @@ import { WorkspaceSvg } from '../workspace_svg.js';
15
17
  * bubble, where it has a "tail" that points to the block, and a "head" that
16
18
  * displays arbitrary svg elements.
17
19
  */
18
- export declare abstract class Bubble implements IBubble, ISelectable {
20
+ export declare abstract class Bubble implements IBubble, ISelectable, IFocusableNode {
19
21
  readonly workspace: WorkspaceSvg;
20
22
  protected anchor: Coordinate;
21
23
  protected ownerRect?: Rect | undefined;
24
+ protected owner?: (IHasBubble & IFocusableNode) | undefined;
22
25
  /** The width of the border around the bubble. */
23
26
  static readonly BORDER_WIDTH = 6;
24
27
  /** Double the width of the border around the bubble. */
@@ -72,8 +75,9 @@ export declare abstract class Bubble implements IBubble, ISelectable {
72
75
  * element that's represented by this bubble (as a focusable node). This
73
76
  * element will have its ID overwritten. If not provided, the focusable
74
77
  * element of this node will default to the bubble's SVG root.
78
+ * @param owner The object responsible for hosting/spawning this bubble.
75
79
  */
76
- constructor(workspace: WorkspaceSvg, anchor: Coordinate, ownerRect?: Rect | undefined, overriddenFocusableElement?: SVGElement | HTMLElement);
80
+ constructor(workspace: WorkspaceSvg, anchor: Coordinate, ownerRect?: Rect | undefined, overriddenFocusableElement?: SVGElement | HTMLElement, owner?: (IHasBubble & IFocusableNode) | undefined);
77
81
  /** Dispose of this bubble. */
78
82
  dispose(): void;
79
83
  /**
@@ -107,6 +111,13 @@ export declare abstract class Bubble implements IBubble, ISelectable {
107
111
  * is focused.
108
112
  */
109
113
  private onMouseDown;
114
+ /**
115
+ * Handles key events when this bubble is focused. By default, closes the
116
+ * bubble on Escape.
117
+ *
118
+ * @param e The keyboard event to handle.
119
+ */
120
+ protected onKeyDown(e: KeyboardEvent): void;
110
121
  /** Positions the bubble relative to its anchor. Does not render its tail. */
111
122
  protected positionRelativeToAnchor(): void;
112
123
  /**
@@ -209,5 +220,9 @@ export declare abstract class Bubble implements IBubble, ISelectable {
209
220
  onNodeBlur(): void;
210
221
  /** See IFocusableNode.canBeFocused. */
211
222
  canBeFocused(): boolean;
223
+ /**
224
+ * Returns the object that owns/hosts this bubble, if any.
225
+ */
226
+ getOwner(): (IHasBubble & IFocusableNode) | undefined;
212
227
  }
213
228
  //# sourceMappingURL=bubble.d.ts.map
@@ -3,6 +3,9 @@
3
3
  * Copyright 2023 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ import { CommentEditor } from '../comments/comment_editor.js';
7
+ import type { IFocusableNode } from '../interfaces/i_focusable_node.js';
8
+ import type { IHasBubble } from '../interfaces/i_has_bubble.js';
6
9
  import { Coordinate } from '../utils/coordinate.js';
7
10
  import { Rect } from '../utils/rect.js';
8
11
  import { Size } from '../utils/size.js';
@@ -16,10 +19,7 @@ export declare class TextInputBubble extends Bubble {
16
19
  readonly workspace: WorkspaceSvg;
17
20
  protected anchor: Coordinate;
18
21
  protected ownerRect?: Rect | undefined;
19
- /** The root of the elements specific to the text element. */
20
- private inputRoot;
21
- /** The text input area element. */
22
- private textArea;
22
+ protected owner?: (IHasBubble & IFocusableNode) | undefined;
23
23
  /** The group containing the lines indicating the bubble is resizable. */
24
24
  private resizeGroup;
25
25
  /**
@@ -32,27 +32,26 @@ export declare class TextInputBubble extends Bubble {
32
32
  * resize group.
33
33
  */
34
34
  private resizePointerMoveListener;
35
- /** Functions listening for changes to the text of this bubble. */
36
- private textChangeListeners;
37
35
  /** Functions listening for changes to the size of this bubble. */
38
36
  private sizeChangeListeners;
39
37
  /** Functions listening for changes to the location of this bubble. */
40
38
  private locationChangeListeners;
41
- /** The text of this bubble. */
42
- private text;
43
39
  /** The default size of this bubble, including borders. */
44
40
  private readonly DEFAULT_SIZE;
45
41
  /** The minimum size of this bubble, including borders. */
46
42
  private readonly MIN_SIZE;
47
43
  private editable;
44
+ /** View responsible for supporting text editing. */
45
+ private editor;
48
46
  /**
49
47
  * @param workspace The workspace this bubble belongs to.
50
48
  * @param anchor The anchor location of the thing this bubble is attached to.
51
49
  * The tail of the bubble will point to this location.
52
50
  * @param ownerRect An optional rect we don't want the bubble to overlap with
53
51
  * when automatically positioning.
52
+ * @param owner The object that owns/hosts this bubble.
54
53
  */
55
- constructor(workspace: WorkspaceSvg, anchor: Coordinate, ownerRect?: Rect | undefined);
54
+ constructor(workspace: WorkspaceSvg, anchor: Coordinate, ownerRect?: Rect | undefined, owner?: (IHasBubble & IFocusableNode) | undefined);
56
55
  /** @returns the text of this bubble. */
57
56
  getText(): string;
58
57
  /** Sets the text of this bubble. Calls change listeners. */
@@ -67,12 +66,6 @@ export declare class TextInputBubble extends Bubble {
67
66
  addSizeChangeListener(listener: () => void): void;
68
67
  /** Adds a change listener to be notified when this bubble's location changes. */
69
68
  addLocationChangeListener(listener: () => void): void;
70
- /** Creates and returns the editable text area for this bubble's editor. */
71
- private static createTextArea;
72
- /** Creates and returns the UI container element for this bubble's editor. */
73
- private createEditor;
74
- /** Binds events to the text area element. */
75
- private bindTextAreaEvents;
76
69
  /** Creates the resize handler elements and binds events to them. */
77
70
  private createResizeHandle;
78
71
  /**
@@ -95,11 +88,15 @@ export declare class TextInputBubble extends Bubble {
95
88
  private onResizePointerUp;
96
89
  /** Handles pointer move events on the resize target. */
97
90
  private onResizePointerMove;
98
- /** Handles a text change event for the text area. Calls event listeners. */
99
- private onTextChange;
100
91
  /** Handles a size change event for the text area. Calls event listeners. */
101
92
  private onSizeChange;
102
93
  /** Handles a location change event for the text area. Calls event listeners. */
103
94
  private onLocationChange;
95
+ /**
96
+ * Returns the text editor component of this bubble.
97
+ *
98
+ * @internal
99
+ */
100
+ getEditor(): CommentEditor;
104
101
  }
105
102
  //# sourceMappingURL=textinput_bubble.d.ts.map
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import type { WorkspaceSvg } from '../workspace_svg.js';
7
7
  import { CommentBarButton } from './comment_bar_button.js';
8
+ import type { CommentView } from './comment_view.js';
8
9
  /**
9
10
  * Magic string appended to the comment ID to create a unique ID for this button.
10
11
  */
@@ -16,6 +17,7 @@ export declare class CollapseCommentBarButton extends CommentBarButton {
16
17
  protected readonly id: string;
17
18
  protected readonly workspace: WorkspaceSvg;
18
19
  protected readonly container: SVGGElement;
20
+ protected readonly commentView: CommentView;
19
21
  /**
20
22
  * Opaque ID used to unbind event handlers during disposal.
21
23
  */
@@ -31,7 +33,7 @@ export declare class CollapseCommentBarButton extends CommentBarButton {
31
33
  * @param workspace The workspace this button's parent comment is displayed on.
32
34
  * @param container An SVG group that this button should be a child of.
33
35
  */
34
- constructor(id: string, workspace: WorkspaceSvg, container: SVGGElement);
36
+ constructor(id: string, workspace: WorkspaceSvg, container: SVGGElement, commentView: CommentView);
35
37
  /**
36
38
  * Disposes of this button.
37
39
  */
@@ -6,7 +6,7 @@
6
6
  import type { IFocusableNode } from '../interfaces/i_focusable_node.js';
7
7
  import { Rect } from '../utils/rect.js';
8
8
  import type { WorkspaceSvg } from '../workspace_svg.js';
9
- import type { RenderedWorkspaceComment } from './rendered_workspace_comment.js';
9
+ import type { CommentView } from './comment_view.js';
10
10
  /**
11
11
  * Button displayed on a comment's top bar.
12
12
  */
@@ -14,6 +14,7 @@ export declare abstract class CommentBarButton implements IFocusableNode {
14
14
  protected readonly id: string;
15
15
  protected readonly workspace: WorkspaceSvg;
16
16
  protected readonly container: SVGGElement;
17
+ protected readonly commentView: CommentView;
17
18
  /**
18
19
  * SVG image displayed on this button.
19
20
  */
@@ -25,15 +26,15 @@ export declare abstract class CommentBarButton implements IFocusableNode {
25
26
  * @param workspace The workspace this button's parent comment is on.
26
27
  * @param container An SVG group that this button should be a child of.
27
28
  */
28
- constructor(id: string, workspace: WorkspaceSvg, container: SVGGElement);
29
+ constructor(id: string, workspace: WorkspaceSvg, container: SVGGElement, commentView: CommentView);
29
30
  /**
30
31
  * Returns whether or not this button is currently visible.
31
32
  */
32
33
  isVisible(): boolean;
33
34
  /**
34
- * Returns the parent comment of this comment bar button.
35
+ * Returns the parent comment view of this comment bar button.
35
36
  */
36
- getParentComment(): RenderedWorkspaceComment;
37
+ getCommentView(): CommentView;
37
38
  /** Adjusts the position of this button within its parent container. */
38
39
  abstract reposition(): void;
39
40
  /** Perform the action this button should take when it is acted on. */
@@ -11,7 +11,7 @@ import { WorkspaceSvg } from '../workspace_svg.js';
11
11
  import { CommentBarButton } from './comment_bar_button.js';
12
12
  export declare class CommentView implements IRenderedElement {
13
13
  readonly workspace: WorkspaceSvg;
14
- private commentId;
14
+ readonly commentId: string;
15
15
  /** The root group element of the comment view. */
16
16
  private svgRoot;
17
17
  /**
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import type { WorkspaceSvg } from '../workspace_svg.js';
7
7
  import { CommentBarButton } from './comment_bar_button.js';
8
+ import type { CommentView } from './comment_view.js';
8
9
  /**
9
10
  * Magic string appended to the comment ID to create a unique ID for this button.
10
11
  */
@@ -16,6 +17,7 @@ export declare class DeleteCommentBarButton extends CommentBarButton {
16
17
  protected readonly id: string;
17
18
  protected readonly workspace: WorkspaceSvg;
18
19
  protected readonly container: SVGGElement;
20
+ protected readonly commentView: CommentView;
19
21
  /**
20
22
  * Opaque ID used to unbind event handlers during disposal.
21
23
  */
@@ -31,7 +33,7 @@ export declare class DeleteCommentBarButton extends CommentBarButton {
31
33
  * @param workspace The workspace this button's parent comment is shown on.
32
34
  * @param container An SVG group that this button should be a child of.
33
35
  */
34
- constructor(id: string, workspace: WorkspaceSvg, container: SVGGElement);
36
+ constructor(id: string, workspace: WorkspaceSvg, container: SVGGElement, commentView: CommentView);
35
37
  /**
36
38
  * Disposes of this button.
37
39
  */
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import type { Block } from '../block.js';
7
- import type { IBubble } from '../interfaces/i_bubble.js';
7
+ import { TextInputBubble } from '../bubbles/textinput_bubble.js';
8
8
  import type { IHasBubble } from '../interfaces/i_has_bubble.js';
9
9
  import type { ISerializable } from '../interfaces/i_serializable.js';
10
10
  import { Coordinate } from '../utils.js';
@@ -34,7 +34,7 @@ export declare class CommentIcon extends Icon implements IHasBubble, ISerializab
34
34
  /**
35
35
  * The visibility of the bubble for this comment.
36
36
  *
37
- * This is used to track what the visibile state /should/ be, not necessarily
37
+ * This is used to track what the visible state /should/ be, not necessarily
38
38
  * what it currently /is/. E.g. sometimes this will be true, but the block
39
39
  * hasn't been rendered yet, so the bubble will not currently be visible.
40
40
  */
@@ -94,7 +94,7 @@ export declare class CommentIcon extends Icon implements IHasBubble, ISerializab
94
94
  bubbleIsVisible(): boolean;
95
95
  setBubbleVisible(visible: boolean): Promise<void>;
96
96
  /** See IHasBubble.getBubble. */
97
- getBubble(): IBubble | null;
97
+ getBubble(): TextInputBubble | null;
98
98
  /**
99
99
  * Shows the editable text bubble for this comment, and adds change listeners
100
100
  * to update the state of this icon in response to changes in the bubble.
@@ -6,6 +6,7 @@
6
6
  import { BlockSvg } from './block_svg.js';
7
7
  import { IConnectionPreviewer } from './interfaces/i_connection_previewer.js';
8
8
  import { RenderedConnection } from './rendered_connection.js';
9
+ import * as blocks from './serialization/blocks.js';
9
10
  export declare class InsertionMarkerPreviewer implements IConnectionPreviewer {
10
11
  private readonly workspace;
11
12
  private fadedBlock;
@@ -36,6 +37,16 @@ export declare class InsertionMarkerPreviewer implements IConnectionPreviewer {
36
37
  previewConnection(draggedConn: RenderedConnection, staticConn: RenderedConnection): void;
37
38
  private shouldUseMarkerPreview;
38
39
  private previewMarker;
40
+ /**
41
+ * Transforms the given block into a JSON representation used to construct an
42
+ * insertion marker.
43
+ *
44
+ * @param block The block to serialize and use as an insertion marker.
45
+ * @returns A JSON-formatted string corresponding to a serialized
46
+ * representation of the given block suitable for use as an insertion
47
+ * marker.
48
+ */
49
+ protected serializeBlockToInsertionMarker(block: BlockSvg): blocks.State;
39
50
  private createInsertionMarker;
40
51
  /**
41
52
  * Gets the connection on the marker block that matches the original
@@ -34,7 +34,7 @@ export interface IVariableMap<T extends IVariableModel<IVariableState>> {
34
34
  * Creates a new variable with the given name. If ID is not specified, the
35
35
  * variable map should create one. Returns the new variable.
36
36
  */
37
- createVariable(name: string, id?: string, type?: string | null): T;
37
+ createVariable(name: string, type?: string, id?: string | null): T;
38
38
  addVariable(variable: T): void;
39
39
  /**
40
40
  * Changes the name of the given variable to the name provided and returns the
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { TextInputBubble } from '../bubbles/textinput_bubble.js';
7
+ import type { IFocusableNode } from '../interfaces/i_focusable_node.js';
8
+ import type { INavigationPolicy } from '../interfaces/i_navigation_policy.js';
9
+ /**
10
+ * Set of rules controlling keyboard navigation from an TextInputBubble.
11
+ */
12
+ export declare class BlockCommentNavigationPolicy implements INavigationPolicy<TextInputBubble> {
13
+ /**
14
+ * Returns the first child of the given block comment.
15
+ *
16
+ * @param current The block comment to return the first child of.
17
+ * @returns The text editor of the given block comment bubble.
18
+ */
19
+ getFirstChild(current: TextInputBubble): IFocusableNode | null;
20
+ /**
21
+ * Returns the parent of the given block comment.
22
+ *
23
+ * @param current The block comment to return the parent of.
24
+ * @returns The parent block of the given block comment.
25
+ */
26
+ getParent(current: TextInputBubble): IFocusableNode | null;
27
+ /**
28
+ * Returns the next peer node of the given block comment.
29
+ *
30
+ * @param _current The block comment to find the following element of.
31
+ * @returns Null.
32
+ */
33
+ getNextSibling(_current: TextInputBubble): IFocusableNode | null;
34
+ /**
35
+ * Returns the previous peer node of the given block comment.
36
+ *
37
+ * @param _current The block comment to find the preceding element of.
38
+ * @returns Null.
39
+ */
40
+ getPreviousSibling(_current: TextInputBubble): IFocusableNode | null;
41
+ /**
42
+ * Returns whether or not the given block comment can be navigated to.
43
+ *
44
+ * @param current The instance to check for navigability.
45
+ * @returns True if the given block comment can be focused.
46
+ */
47
+ isNavigable(current: TextInputBubble): boolean;
48
+ /**
49
+ * Returns whether the given object can be navigated from by this policy.
50
+ *
51
+ * @param current The object to check if this policy applies to.
52
+ * @returns True if the object is an TextInputBubble.
53
+ */
54
+ isApplicable(current: any): current is TextInputBubble;
55
+ }
56
+ //# sourceMappingURL=block_comment_navigation_policy.d.ts.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { CommentEditor } from '../comments/comment_editor.js';
7
+ import type { IFocusableNode } from '../interfaces/i_focusable_node.js';
8
+ import type { INavigationPolicy } from '../interfaces/i_navigation_policy.js';
9
+ /**
10
+ * Set of rules controlling keyboard navigation from a comment editor.
11
+ * This is a no-op placeholder (other than isNavigable/isApplicable) since
12
+ * comment editors handle their own navigation when editing ends.
13
+ */
14
+ export declare class CommentEditorNavigationPolicy implements INavigationPolicy<CommentEditor> {
15
+ getFirstChild(_current: CommentEditor): IFocusableNode | null;
16
+ getParent(_current: CommentEditor): IFocusableNode | null;
17
+ getNextSibling(_current: CommentEditor): IFocusableNode | null;
18
+ getPreviousSibling(_current: CommentEditor): IFocusableNode | null;
19
+ /**
20
+ * Returns whether or not the given comment editor can be navigated to.
21
+ *
22
+ * @param current The instance to check for navigability.
23
+ * @returns False.
24
+ */
25
+ isNavigable(current: CommentEditor): boolean;
26
+ /**
27
+ * Returns whether the given object can be navigated from by this policy.
28
+ *
29
+ * @param current The object to check if this policy applies to.
30
+ * @returns True if the object is a CommentEditor.
31
+ */
32
+ isApplicable(current: any): current is CommentEditor;
33
+ }
34
+ //# sourceMappingURL=comment_editor_navigation_policy.d.ts.map
@@ -73,7 +73,7 @@ export declare class Type<_T> {
73
73
  static ICON: Type<IIcon>;
74
74
  /** @internal */
75
75
  static PASTER: Type<IPaster<ICopyable.ICopyData, ICopyable<ICopyable.ICopyData>>>;
76
- static VARIABLE_MODEL: Type<IVariableModelStatic<IVariableState>>;
76
+ static VARIABLE_MODEL: Type<IVariableModelStatic<IVariableState> & IVariableModel<IVariableState>>;
77
77
  static VARIABLE_MAP: Type<IVariableMap<IVariableModel<IVariableState>>>;
78
78
  }
79
79
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blockly",
3
- "version": "12.2.0",
3
+ "version": "12.3.0-beta.0",
4
4
  "description": "Blockly is a library for building visual programming editors.",
5
5
  "keywords": [
6
6
  "blockly"
@@ -67,24 +67,25 @@
67
67
  },
68
68
  "license": "Apache-2.0",
69
69
  "devDependencies": {
70
- "@blockly/block-test": "^7.0.1",
71
- "@blockly/dev-tools": "^9.0.0",
72
- "@blockly/theme-modern": "^6.0.3",
70
+ "@blockly/block-test": "^7.0.2",
71
+ "@blockly/dev-tools": "^9.0.2",
72
+ "@blockly/theme-modern": "^7.0.1",
73
73
  "@hyperjump/browser": "^1.1.4",
74
74
  "@hyperjump/json-schema": "^1.5.0",
75
- "@microsoft/api-documenter": "^7.22.4",
75
+ "@microsoft/api-documenter": "7.22.4",
76
76
  "@microsoft/api-extractor": "^7.29.5",
77
+ "ajv": "^8.17.1",
77
78
  "async-done": "^2.0.0",
78
79
  "chai": "^5.1.1",
79
80
  "concurrently": "^9.0.1",
80
81
  "eslint": "^9.15.0",
81
82
  "eslint-config-google": "^0.14.0",
82
83
  "eslint-config-prettier": "^10.1.1",
83
- "eslint-plugin-jsdoc": "^51.3.1",
84
+ "eslint-plugin-jsdoc": "^52.0.2",
84
85
  "eslint-plugin-prettier": "^5.2.1",
85
86
  "glob": "^11.0.1",
86
87
  "globals": "^16.0.0",
87
- "google-closure-compiler": "^20250625.0.0",
88
+ "google-closure-compiler": "^20250709.0.0",
88
89
  "gulp": "^5.0.0",
89
90
  "gulp-concat": "^2.6.1",
90
91
  "gulp-gzip": "^1.4.2",