blockly 13.0.0-beta.0 → 13.0.0-beta.2

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.
Files changed (313) hide show
  1. package/blockly.min.js +2092 -1318
  2. package/blockly.mjs +1 -1
  3. package/blockly_compressed.js +1887 -1190
  4. package/blockly_compressed.js.map +1 -1
  5. package/blocks_compressed.js +71 -71
  6. package/blocks_compressed.js.map +1 -1
  7. package/core/block.d.ts +18 -0
  8. package/core/block_aria_composer.d.ts +119 -0
  9. package/core/block_svg.d.ts +21 -1
  10. package/core/blockly.d.ts +1 -1
  11. package/core/bubbles/bubble.d.ts +39 -0
  12. package/core/bubbles/mini_workspace_bubble.d.ts +4 -1
  13. package/core/bubbles/text_bubble.d.ts +4 -1
  14. package/core/dragging/block_drag_strategy.d.ts +45 -3
  15. package/core/field.d.ts +15 -17
  16. package/core/field_checkbox.d.ts +27 -0
  17. package/core/field_dropdown.d.ts +51 -1
  18. package/core/field_image.d.ts +24 -0
  19. package/core/field_input.d.ts +23 -0
  20. package/core/field_number.d.ts +10 -0
  21. package/core/field_textinput.d.ts +10 -0
  22. package/core/field_variable.d.ts +9 -0
  23. package/core/flyout_base.d.ts +10 -0
  24. package/core/focus_manager.d.ts +47 -2
  25. package/core/inputs/input.d.ts +15 -0
  26. package/core/interfaces/i_flyout_inflater.d.ts +9 -0
  27. package/core/interfaces/i_focusable_node.d.ts +3 -1
  28. package/core/interfaces/i_json_block_definition.d.ts +1 -0
  29. package/core/keyboard_nav/keyboard_mover.d.ts +16 -5
  30. package/core/keyboard_nav/navigation_policies/bubble_navigation_policy.d.ts +63 -0
  31. package/core/keyboard_nav/navigation_policies/icon_navigation_policy.d.ts +2 -2
  32. package/core/keyboard_nav/navigators/flyout_navigator.d.ts +1 -1
  33. package/core/menu.d.ts +3 -0
  34. package/core/menuitem.d.ts +8 -1
  35. package/core/shortcut_items.d.ts +16 -1
  36. package/core/shortcut_registry.d.ts +6 -0
  37. package/core/toolbox/toolbox.d.ts +5 -11
  38. package/core/tooltip.d.ts +10 -0
  39. package/core/trashcan.d.ts +23 -38
  40. package/core/utils/aria.d.ts +16 -62
  41. package/core/utils/dom.d.ts +1 -1
  42. package/core/utils/shortcut_formatting.d.ts +5 -7
  43. package/core/variables.d.ts +1 -1
  44. package/core/workspace.d.ts +5 -1
  45. package/core/workspace_svg.d.ts +8 -0
  46. package/core/zoom_controls.d.ts +43 -50
  47. package/dart_compressed.js +62 -62
  48. package/dart_compressed.js.map +1 -1
  49. package/index.mjs +1 -1
  50. package/javascript_compressed.js +55 -55
  51. package/javascript_compressed.js.map +1 -1
  52. package/lua_compressed.js +50 -50
  53. package/lua_compressed.js.map +1 -1
  54. package/media/drop.mp3 +0 -0
  55. package/msg/ab.js +78 -1
  56. package/msg/ab.mjs +78 -1
  57. package/msg/ace.js +79 -2
  58. package/msg/ace.mjs +78 -1
  59. package/msg/af.js +78 -1
  60. package/msg/af.mjs +78 -1
  61. package/msg/am.js +79 -2
  62. package/msg/am.mjs +78 -1
  63. package/msg/ar.js +101 -24
  64. package/msg/ar.mjs +78 -1
  65. package/msg/ast.js +79 -2
  66. package/msg/ast.mjs +78 -1
  67. package/msg/az.js +79 -2
  68. package/msg/az.mjs +78 -1
  69. package/msg/ba.js +78 -1
  70. package/msg/ba.mjs +78 -1
  71. package/msg/bcc.js +78 -1
  72. package/msg/bcc.mjs +78 -1
  73. package/msg/be-tarask.js +112 -35
  74. package/msg/be-tarask.mjs +78 -1
  75. package/msg/be.js +79 -2
  76. package/msg/be.mjs +78 -1
  77. package/msg/bg.js +78 -1
  78. package/msg/bg.mjs +78 -1
  79. package/msg/bn.js +79 -2
  80. package/msg/bn.mjs +78 -1
  81. package/msg/br.js +79 -2
  82. package/msg/br.mjs +78 -1
  83. package/msg/bs.js +78 -1
  84. package/msg/bs.mjs +78 -1
  85. package/msg/ca.js +78 -1
  86. package/msg/ca.mjs +78 -1
  87. package/msg/ce.js +78 -1
  88. package/msg/ce.mjs +78 -1
  89. package/msg/cs.js +86 -9
  90. package/msg/cs.mjs +78 -1
  91. package/msg/da.js +102 -25
  92. package/msg/da.mjs +78 -1
  93. package/msg/de.js +78 -1
  94. package/msg/de.mjs +78 -1
  95. package/msg/diq.js +80 -3
  96. package/msg/diq.mjs +78 -1
  97. package/msg/dtp.js +78 -1
  98. package/msg/dtp.mjs +78 -1
  99. package/msg/dty.js +78 -1
  100. package/msg/dty.mjs +78 -1
  101. package/msg/ee.js +78 -1
  102. package/msg/ee.mjs +78 -1
  103. package/msg/el.js +109 -32
  104. package/msg/el.mjs +78 -1
  105. package/msg/en-gb.js +78 -1
  106. package/msg/en-gb.mjs +78 -1
  107. package/msg/en.js +79 -2
  108. package/msg/en.mjs +78 -1
  109. package/msg/eo.js +78 -1
  110. package/msg/eo.mjs +78 -1
  111. package/msg/es.js +88 -11
  112. package/msg/es.mjs +78 -1
  113. package/msg/et.js +78 -1
  114. package/msg/et.mjs +78 -1
  115. package/msg/eu.js +78 -1
  116. package/msg/eu.mjs +78 -1
  117. package/msg/fa.js +79 -2
  118. package/msg/fa.mjs +78 -1
  119. package/msg/fi.js +97 -20
  120. package/msg/fi.mjs +78 -1
  121. package/msg/fo.js +78 -1
  122. package/msg/fo.mjs +78 -1
  123. package/msg/fr.js +101 -24
  124. package/msg/fr.mjs +78 -1
  125. package/msg/frr.js +79 -2
  126. package/msg/frr.mjs +78 -1
  127. package/msg/ga.js +550 -0
  128. package/msg/{cdo.mjs → ga.mjs} +80 -3
  129. package/msg/gl.js +101 -24
  130. package/msg/gl.mjs +78 -1
  131. package/msg/gn.js +79 -2
  132. package/msg/gn.mjs +78 -1
  133. package/msg/gor.js +78 -1
  134. package/msg/gor.mjs +78 -1
  135. package/msg/ha.js +78 -1
  136. package/msg/ha.mjs +78 -1
  137. package/msg/hak.js +79 -2
  138. package/msg/hak.mjs +78 -1
  139. package/msg/he.js +128 -51
  140. package/msg/he.mjs +78 -1
  141. package/msg/hi.js +78 -1
  142. package/msg/hi.mjs +78 -1
  143. package/msg/hr.js +78 -1
  144. package/msg/hr.mjs +78 -1
  145. package/msg/hrx.js +78 -1
  146. package/msg/hrx.mjs +78 -1
  147. package/msg/hsb.js +78 -1
  148. package/msg/hsb.mjs +78 -1
  149. package/msg/hu.js +80 -3
  150. package/msg/hu.mjs +78 -1
  151. package/msg/hy.js +78 -1
  152. package/msg/hy.mjs +78 -1
  153. package/msg/ia.js +101 -24
  154. package/msg/ia.mjs +78 -1
  155. package/msg/id.js +308 -231
  156. package/msg/id.mjs +78 -1
  157. package/msg/ig.js +86 -9
  158. package/msg/ig.mjs +78 -1
  159. package/msg/inh.js +78 -1
  160. package/msg/inh.mjs +78 -1
  161. package/msg/is.js +78 -1
  162. package/msg/is.mjs +78 -1
  163. package/msg/it.js +104 -27
  164. package/msg/it.mjs +78 -1
  165. package/msg/ja.js +101 -24
  166. package/msg/ja.mjs +78 -1
  167. package/msg/ka.js +80 -3
  168. package/msg/ka.mjs +78 -1
  169. package/msg/kab.js +87 -10
  170. package/msg/kab.mjs +78 -1
  171. package/msg/kbd-cyrl.js +79 -2
  172. package/msg/kbd-cyrl.mjs +78 -1
  173. package/msg/km.js +78 -1
  174. package/msg/km.mjs +78 -1
  175. package/msg/kn.js +78 -1
  176. package/msg/kn.mjs +78 -1
  177. package/msg/ko.js +103 -26
  178. package/msg/ko.mjs +78 -1
  179. package/msg/krc.js +550 -0
  180. package/msg/krc.mjs +531 -0
  181. package/msg/ksh.js +79 -2
  182. package/msg/ksh.mjs +78 -1
  183. package/msg/ku-latn.js +79 -2
  184. package/msg/ku-latn.mjs +78 -1
  185. package/msg/ky.js +80 -3
  186. package/msg/ky.mjs +78 -1
  187. package/msg/la.js +79 -2
  188. package/msg/la.mjs +78 -1
  189. package/msg/lb.js +89 -12
  190. package/msg/lb.mjs +78 -1
  191. package/msg/lki.js +78 -1
  192. package/msg/lki.mjs +78 -1
  193. package/msg/lo.js +78 -1
  194. package/msg/lo.mjs +78 -1
  195. package/msg/lrc.js +78 -1
  196. package/msg/lrc.mjs +78 -1
  197. package/msg/lt.js +79 -2
  198. package/msg/lt.mjs +78 -1
  199. package/msg/lv.js +89 -12
  200. package/msg/lv.mjs +78 -1
  201. package/msg/mg.js +78 -1
  202. package/msg/mg.mjs +78 -1
  203. package/msg/mk.js +78 -1
  204. package/msg/mk.mjs +78 -1
  205. package/msg/ml.js +78 -1
  206. package/msg/ml.mjs +78 -1
  207. package/msg/mnw.js +78 -1
  208. package/msg/mnw.mjs +78 -1
  209. package/msg/ms.js +87 -10
  210. package/msg/ms.mjs +78 -1
  211. package/msg/my.js +78 -1
  212. package/msg/my.mjs +78 -1
  213. package/msg/mzn.js +79 -2
  214. package/msg/mzn.mjs +78 -1
  215. package/msg/nb.js +78 -1
  216. package/msg/nb.mjs +78 -1
  217. package/msg/ne.js +87 -10
  218. package/msg/ne.mjs +78 -1
  219. package/msg/nl.js +101 -24
  220. package/msg/nl.mjs +78 -1
  221. package/msg/oc.js +78 -1
  222. package/msg/oc.mjs +78 -1
  223. package/msg/olo.js +79 -2
  224. package/msg/olo.mjs +78 -1
  225. package/msg/pa.js +87 -10
  226. package/msg/pa.mjs +78 -1
  227. package/msg/pl.js +101 -24
  228. package/msg/pl.mjs +78 -1
  229. package/msg/pms.js +101 -24
  230. package/msg/pms.mjs +78 -1
  231. package/msg/ps.js +96 -19
  232. package/msg/ps.mjs +78 -1
  233. package/msg/pt-br.js +101 -24
  234. package/msg/pt-br.mjs +78 -1
  235. package/msg/pt.js +101 -24
  236. package/msg/pt.mjs +78 -1
  237. package/msg/ro.js +110 -33
  238. package/msg/ro.mjs +78 -1
  239. package/msg/ru.js +101 -24
  240. package/msg/ru.mjs +78 -1
  241. package/msg/sc.js +78 -1
  242. package/msg/sc.mjs +78 -1
  243. package/msg/sco.js +79 -2
  244. package/msg/sco.mjs +78 -1
  245. package/msg/sd.js +78 -1
  246. package/msg/sd.mjs +78 -1
  247. package/msg/shn.js +78 -1
  248. package/msg/shn.mjs +78 -1
  249. package/msg/si.js +79 -2
  250. package/msg/si.mjs +78 -1
  251. package/msg/sk.js +79 -2
  252. package/msg/sk.mjs +78 -1
  253. package/msg/skr-arab.js +81 -4
  254. package/msg/skr-arab.mjs +78 -1
  255. package/msg/sl.js +102 -25
  256. package/msg/sl.mjs +78 -1
  257. package/msg/smn.js +80 -3
  258. package/msg/smn.mjs +78 -1
  259. package/msg/sq.js +87 -10
  260. package/msg/sq.mjs +78 -1
  261. package/msg/sr-latn.js +78 -1
  262. package/msg/sr-latn.mjs +78 -1
  263. package/msg/sr.js +78 -1
  264. package/msg/sr.mjs +78 -1
  265. package/msg/sv.js +101 -24
  266. package/msg/sv.mjs +78 -1
  267. package/msg/sw.js +79 -2
  268. package/msg/sw.mjs +78 -1
  269. package/msg/ta.js +97 -20
  270. package/msg/ta.mjs +78 -1
  271. package/msg/tcy.js +148 -71
  272. package/msg/tcy.mjs +78 -1
  273. package/msg/tdd.js +78 -1
  274. package/msg/tdd.mjs +78 -1
  275. package/msg/te.js +78 -1
  276. package/msg/te.mjs +78 -1
  277. package/msg/th.js +79 -2
  278. package/msg/th.mjs +78 -1
  279. package/msg/ti.js +78 -1
  280. package/msg/ti.mjs +78 -1
  281. package/msg/tl.js +78 -1
  282. package/msg/tl.mjs +78 -1
  283. package/msg/tlh.js +78 -1
  284. package/msg/tlh.mjs +78 -1
  285. package/msg/tr.js +101 -24
  286. package/msg/tr.mjs +78 -1
  287. package/msg/ug-arab.js +78 -1
  288. package/msg/ug-arab.mjs +78 -1
  289. package/msg/uk.js +78 -1
  290. package/msg/uk.mjs +78 -1
  291. package/msg/ur.js +78 -1
  292. package/msg/ur.mjs +78 -1
  293. package/msg/uz.js +93 -16
  294. package/msg/uz.mjs +78 -1
  295. package/msg/vi.js +102 -25
  296. package/msg/vi.mjs +78 -1
  297. package/msg/xmf.js +78 -1
  298. package/msg/xmf.mjs +78 -1
  299. package/msg/yo.js +78 -1
  300. package/msg/yo.mjs +78 -1
  301. package/msg/zgh.js +78 -1
  302. package/msg/zgh.mjs +78 -1
  303. package/msg/zh-hans.js +101 -24
  304. package/msg/zh-hans.mjs +78 -1
  305. package/msg/zh-hant.js +101 -24
  306. package/msg/zh-hant.mjs +78 -1
  307. package/package.json +4 -4
  308. package/php_compressed.js +54 -55
  309. package/php_compressed.js.map +1 -1
  310. package/python_compressed.js +57 -57
  311. package/python_compressed.js.map +1 -1
  312. package/core/keyboard_nav/navigation_policies/block_comment_navigation_policy.d.ts +0 -63
  313. package/msg/cdo.js +0 -473
@@ -48,6 +48,16 @@ export declare class FieldTextInput extends FieldInput<string> {
48
48
  * @internal
49
49
  */
50
50
  static fromJson(options: FieldTextInputFromJsonConfig): FieldTextInput;
51
+ /**
52
+ * Gets an ARIA-friendly label representation of this field's type.
53
+ *
54
+ * Implementations are responsible for, and encouraged to, return a localized
55
+ * version of the ARIA representation of the field's type.
56
+ *
57
+ * @returns An ARIA representation of the field's type or a default if it is
58
+ * unspecified.
59
+ */
60
+ getAriaTypeName(): string | null;
51
61
  }
52
62
  /**
53
63
  * Config options for the text input field.
@@ -228,6 +228,15 @@ export declare class FieldVariable extends FieldDropdown {
228
228
  * @returns Array of variable names/id tuples.
229
229
  */
230
230
  static dropdownCreate(this: FieldVariable): MenuOption[];
231
+ /**
232
+ * Gets an ARIA-friendly label representation of this field's value.
233
+ *
234
+ * Implementations are responsible for, and encouraged to, return a localized
235
+ * version of the ARIA representation of the field's value.
236
+ *
237
+ * @returns An ARIA representation of the field's text.
238
+ */
239
+ getAriaValue(): string;
231
240
  }
232
241
  /**
233
242
  * Config options for the variable field.
@@ -268,6 +268,16 @@ export declare abstract class Flyout extends DeleteArea implements IAutoHideable
268
268
  * toolbox definition, or a string with the name of the dynamic category.
269
269
  */
270
270
  show(flyoutDef: toolbox.FlyoutDefinition | string): void;
271
+ /**
272
+ * Updates the aria attributes for the entire flyout dom.
273
+ * This needs to do two things:
274
+ * 1. Set aria-owns on the flyout's workspace canvas to include the ids of all
275
+ * focusable elements in the flyout.
276
+ * 2. Update the aria attributes on the flyout's workspace. This can't be done at workspace
277
+ * creation because the workspace may not have all required information until the flyout
278
+ * is fully shown.
279
+ */
280
+ protected updateAriaContext(): void;
271
281
  /**
272
282
  * Create the contents array and gaps array necessary to create the layout for
273
283
  * the flyout.
@@ -7,11 +7,15 @@ import type { IFocusableNode } from './interfaces/i_focusable_node.js';
7
7
  import type { IFocusableTree } from './interfaces/i_focusable_tree.js';
8
8
  /**
9
9
  * Type declaration for returning focus to FocusManager upon completing an
10
- * ephemeral UI flow (such as a dialog).
10
+ * ephemeral UI flow (such as a dialog). Normally, the FocusManager will refocus
11
+ * the previously-focused element. If callers do not wish for the FocusManager
12
+ * to do so, they may call this method with `restoreFocus` set to false to
13
+ * prevent automatic refocusing and leave focus where it is.
14
+ *
11
15
  *
12
16
  * See FocusManager.takeEphemeralFocus for more details.
13
17
  */
14
- export type ReturnEphemeralFocus = () => void;
18
+ export type ReturnEphemeralFocus = (restoreFocus?: boolean) => void;
15
19
  /**
16
20
  * A per-page singleton that manages Blockly focus across one or more
17
21
  * IFocusableTrees, and bidirectionally synchronizes this focus with the DOM.
@@ -56,6 +60,20 @@ export declare class FocusManager {
56
60
  private lockFocusStateChanges;
57
61
  private recentlyLostAllFocus;
58
62
  private isUpdatingFocusedNode;
63
+ /**
64
+ * Root element in which popovers (WidgetDiv, DropDownDiv) currently live.
65
+ */
66
+ private popoverFocusRoot?;
67
+ /**
68
+ * Set of callbacks to invoke if the popover focus root loses focus.
69
+ */
70
+ private popoverFocusLossHandlers;
71
+ /**
72
+ * Handler for focusout in the popover focus root that selectively
73
+ * invokes the popover focus loss handlers if focus has truly transitioned
74
+ * outside of the focus root, and not e.g. to a different popover.
75
+ */
76
+ private popoverFocusOutHandler;
59
77
  constructor(addGlobalEventListener: (type: string, listener: EventListener) => void);
60
78
  /**
61
79
  * Registers a new IFocusableTree for automatic focus management.
@@ -260,6 +278,33 @@ export declare class FocusManager {
260
278
  * but may change across page loads.
261
279
  */
262
280
  static getFocusManager(): FocusManager;
281
+ /**
282
+ * Sets the current popover focus root. Generally this is active
283
+ * workspace's injection div or the explicitly specified parent container for
284
+ * the WidgetDiv, DropDownDiv, etc.
285
+ *
286
+ * @internal
287
+ * @param newRoot The new element that contains all popovers.
288
+ */
289
+ setPopoverFocusRoot(newRoot: HTMLElement): void;
290
+ /**
291
+ * Registers a callback to be invoked if the popover focus root loses
292
+ * focus. This should only be called by popovers that need to react to
293
+ * focus changes by e.g. hiding themselves and resigning ephemeral focus.
294
+ *
295
+ * @internal
296
+ * @param handler A callback function.
297
+ */
298
+ registerPopoverFocusLossHandler(handler: () => void): void;
299
+ /**
300
+ * Unregisters a previously-registered popover focus loss handler. This
301
+ * should only be invoked by popovers when they no longer need to be
302
+ * notified of focus loss, typically when they are hidden.
303
+ *
304
+ * @internal
305
+ * @param handler A previously-registered callback function.
306
+ */
307
+ unregisterPopoverFocusLossHandler(handler: () => void): void;
263
308
  }
264
309
  /** Convenience function for FocusManager.getFocusManager. */
265
310
  export declare function getFocusManager(): FocusManager;
@@ -14,6 +14,7 @@ import type { BlockSvg } from '../block_svg.js';
14
14
  import type { Connection } from '../connection.js';
15
15
  import { ConnectionType } from '../connection_type.js';
16
16
  import type { Field } from '../field.js';
17
+ import { Verbosity } from '../utils/aria.js';
17
18
  import { Align } from './align.js';
18
19
  import { inputTypes } from './input_types.js';
19
20
  /** Class for an input with optional fields. */
@@ -149,5 +150,19 @@ export declare class Input {
149
150
  * @internal
150
151
  */
151
152
  getRowId(): string;
153
+ /**
154
+ * Returns an accessibility label describing this input, including the labels
155
+ * of any fields on the input and the labels of any connected blocks, to help
156
+ * disambiguate this input from others on the same block.
157
+ *
158
+ * @internal
159
+ */
160
+ getLabel(verbosity?: Verbosity): string;
161
+ /**
162
+ * Returns the index of this input on its source block.
163
+ *
164
+ * @internal
165
+ */
166
+ getIndex(): number;
152
167
  }
153
168
  //# sourceMappingURL=input.d.ts.map
@@ -7,6 +7,15 @@ export interface IFlyoutInflater {
7
7
  * Note that this method's interface is identical to that in ISerializer, to
8
8
  * allow for code reuse.
9
9
  *
10
+ * You must ensure that any item created by this method has the appropriate
11
+ * ARIA markup:
12
+ * - The role of the element's focusable element should be set to `listitem`.
13
+ * - The focusable element must have an `id` attribute.
14
+ * - Any DOM parents of the focusable element should set their role to
15
+ * `presentation` to avoid interfering with flyout list navigation.
16
+ * - If the element is not focusable, it must be hidden from the ARIA tree.
17
+ * Only do this if the content should be inaccessible to screenreaders.
18
+ *
10
19
  * @param state A JSON representation of an element to inflate on the flyout.
11
20
  * @param flyout The flyout on whose workspace the inflated element
12
21
  * should be created. If the inflated element is an `IRenderedElement` it
@@ -97,8 +97,10 @@ export interface IFocusableNode {
97
97
  * Optional method invoked when this node has focus and the user acts on it by
98
98
  * pressing Enter or Space. Behavior should generally be similar to the node
99
99
  * being clicked on.
100
+ *
101
+ * @param e The event that triggered this action, if any.
100
102
  */
101
- performAction?(): void;
103
+ performAction?(e?: Event): void;
102
104
  }
103
105
  /**
104
106
  * Determines whether the provided object fulfills the contract of
@@ -40,6 +40,7 @@ export interface JsonBlockDefinition {
40
40
  inputsInline?: boolean;
41
41
  tooltip?: string;
42
42
  helpUrl?: string;
43
+ ariaRoleDescription?: string;
43
44
  extensions?: string[];
44
45
  mutator?: string;
45
46
  enableContextMenu?: boolean;
@@ -1,8 +1,3 @@
1
- /**
2
- * @license
3
- * Copyright 2026 Raspberry Pi Foundation
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
1
  import type { IDraggable } from '../interfaces/i_draggable.js';
7
2
  /**
8
3
  * Cardinal directions in which a move can proceed.
@@ -113,6 +108,22 @@ export declare class KeyboardMover {
113
108
  * Repositions the move indicator to the corner of the item being moved.
114
109
  */
115
110
  private repositionMoveIndicator;
111
+ /**
112
+ * Returns a bounding box used for positioning the move indicator on a block.
113
+ * Blocks require special treatment because `BlockSvg.getBoundingRectangle()`
114
+ * includes the bounds of nested and subsequent blocks. Since the move
115
+ * indicator is positioned at the top right corner of the bounds, this can
116
+ * result in it appearing to float in empty space when e.g. a small block has
117
+ * a much wider block nested inside a statement input. BlockSvg also provides
118
+ * `getBoundingRectangleWithoutChildren()`, which addresses that case, but is
119
+ * insufficient because in the case of nested *value* blocks in a row, the
120
+ * child blocks' bounds should contribute to the bounding box.
121
+ *
122
+ * @param block The block to retrieve an adjusted bounding box for.
123
+ * @returns A bounding box for the given block whose top-right corner
124
+ * corresponds to the maximum visual extent of the given block's row.
125
+ */
126
+ private positionForBlockMoveIndicator;
116
127
  /**
117
128
  * Common clean-up for finish/abort run before terminating the move.
118
129
  */
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { Bubble } from '../../bubbles/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 a Bubble.
11
+ */
12
+ export declare class BubbleNavigationPolicy implements INavigationPolicy<Bubble> {
13
+ /**
14
+ * Returns the first child of the given bubble.
15
+ *
16
+ * @param _current The bubble to return the first child of.
17
+ * @returns Null.
18
+ */
19
+ getFirstChild(_current: Bubble): IFocusableNode | null;
20
+ /**
21
+ * Returns the parent of the given bubble.
22
+ *
23
+ * @param current The bubble to return the parent of.
24
+ * @returns The parent block of the given bubble.
25
+ */
26
+ getParent(current: Bubble): IFocusableNode | null;
27
+ /**
28
+ * Returns the next peer node of the given bubble.
29
+ *
30
+ * @param current The bubble to find the following element of.
31
+ * @returns The next navigable item on the bubble's icon's parent block.
32
+ */
33
+ getNextSibling(current: Bubble): IFocusableNode | null;
34
+ /**
35
+ * Returns the previous peer node of the given bubble.
36
+ *
37
+ * @param current The bubble to find the preceding element of.
38
+ * @returns The previous navigable item on the bubble's icon's parent block.
39
+ */
40
+ getPreviousSibling(current: Bubble): IFocusableNode | null;
41
+ /**
42
+ * Returns the row ID of the given bubble.
43
+ *
44
+ * @param current The bubble to retrieve the row ID of.
45
+ * @returns The row ID of the given bubble.
46
+ */
47
+ getRowId(current: Bubble): string;
48
+ /**
49
+ * Returns whether or not the given bubble can be navigated to.
50
+ *
51
+ * @param current The instance to check for navigability.
52
+ * @returns True if the given bubble can be focused.
53
+ */
54
+ isNavigable(current: Bubble): boolean;
55
+ /**
56
+ * Returns whether the given object can be navigated from by this policy.
57
+ *
58
+ * @param current The object to check if this policy applies to.
59
+ * @returns True if the object is an Bubble.
60
+ */
61
+ isApplicable(current: any): current is Bubble;
62
+ }
63
+ //# sourceMappingURL=bubble_navigation_policy.d.ts.map
@@ -13,10 +13,10 @@ export declare class IconNavigationPolicy implements INavigationPolicy<Icon> {
13
13
  /**
14
14
  * Returns the first child of the given icon.
15
15
  *
16
- * @param current The icon to return the first child of.
16
+ * @param _current The icon to return the first child of.
17
17
  * @returns Null.
18
18
  */
19
- getFirstChild(current: Icon): IFocusableNode | null;
19
+ getFirstChild(_current: Icon): IFocusableNode | null;
20
20
  /**
21
21
  * Returns the parent of the given icon.
22
22
  *
@@ -3,8 +3,8 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { IFocusableNode } from '../../blockly.js';
7
6
  import type { IFlyout } from '../../interfaces/i_flyout.js';
7
+ import type { IFocusableNode } from '../../interfaces/i_focusable_node.js';
8
8
  import { Navigator } from './navigator.js';
9
9
  /**
10
10
  * Navigator that handles keyboard navigation within a flyout.
package/core/menu.d.ts CHANGED
@@ -41,6 +41,8 @@ export declare class Menu {
41
41
  private element;
42
42
  /** ARIA name for this menu. */
43
43
  private roleName;
44
+ /** The menu's ID. */
45
+ private id;
44
46
  /** Constructs a new Menu instance. */
45
47
  constructor();
46
48
  /**
@@ -166,5 +168,6 @@ export declare class Menu {
166
168
  * @returns The MenuItem objects displayed in this menu.
167
169
  */
168
170
  private getMenuItems;
171
+ getId(): string;
169
172
  }
170
173
  //# sourceMappingURL=menu.d.ts.map
@@ -15,6 +15,7 @@ import * as aria from './utils/aria.js';
15
15
  export declare class MenuItem {
16
16
  private readonly content;
17
17
  private readonly opt_value?;
18
+ private readonly ariaLabel?;
18
19
  /** Is the menu item clickable, as opposed to greyed-out. */
19
20
  private enabled;
20
21
  /** The DOM element for the menu item. */
@@ -31,18 +32,24 @@ export declare class MenuItem {
31
32
  private highlight;
32
33
  /** Bound function to call when this menu item is clicked. */
33
34
  private actionHandler;
35
+ /** The unique ID for this menu item. */
36
+ private id;
34
37
  /**
35
38
  * @param content Text caption to display as the content of the item, or a
36
39
  * HTML element to display.
37
40
  * @param opt_value Data/model associated with the menu item.
38
41
  */
39
- constructor(content: string | HTMLElement, opt_value?: string | undefined);
42
+ constructor(content: string | HTMLElement, opt_value?: string | undefined, ariaLabel?: string | undefined);
40
43
  /**
41
44
  * Creates the menuitem's DOM.
42
45
  *
43
46
  * @returns Completed DOM.
44
47
  */
45
48
  createDom(): Element;
49
+ /**
50
+ * Gets the ARIA label for this menu item.
51
+ */
52
+ getAriaLabel(): string;
46
53
  /** Dispose of this menu item. */
47
54
  dispose(): void;
48
55
  /**
@@ -33,7 +33,10 @@ export declare enum names {
33
33
  NEXT_STACK = "next_stack",
34
34
  PREVIOUS_STACK = "previous_stack",
35
35
  INFORMATION = "information",
36
- PERFORM_ACTION = "perform_action"
36
+ PERFORM_ACTION = "perform_action",
37
+ DUPLICATE = "duplicate",
38
+ CLEANUP = "cleanup",
39
+ SHOW_TOOLTIP = "show_tooltip"
37
40
  }
38
41
  /**
39
42
  * Keyboard shortcut to hide chaff on escape.
@@ -102,6 +105,18 @@ export declare function registerStackNavigation(): void;
102
105
  * Registers keyboard shortcut to perform an action on the focused element.
103
106
  */
104
107
  export declare function registerPerformAction(): void;
108
+ /**
109
+ * Registers keyboard shortcut to duplicate a block or workspace comment.
110
+ */
111
+ export declare function registerDuplicate(): void;
112
+ /**
113
+ * Registers keyboard shortcut to clean up the workspace.
114
+ */
115
+ export declare function registerCleanup(): void;
116
+ /**
117
+ * Registers keyboard shortcut to display the tooltip for the focused element.
118
+ */
119
+ export declare function registerShowTooltip(): void;
105
120
  /**
106
121
  * Registers all default keyboard shortcut item. This should be called once per
107
122
  * instance of KeyboardShortcutRegistry.
@@ -223,6 +223,12 @@ export declare namespace ShortcutRegistry {
223
223
  * name.
224
224
  */
225
225
  allowCollision?: boolean;
226
+ /**
227
+ * Display text for the shortcut. This is not used in core but may
228
+ * be used by plugins or applications to provide a user-facing
229
+ * label for the shortcut.
230
+ */
231
+ displayText?: string | (() => string);
226
232
  }
227
233
  /** Supported modifiers. */
228
234
  enum modifierKeys {
@@ -3,6 +3,11 @@
3
3
  * Copyright 2020 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ /**
7
+ * Toolbox from whence to create blocks.
8
+ *
9
+ * @class
10
+ */
6
11
  import * as browserEvents from '../browser_events.js';
7
12
  import { DeleteArea } from '../delete_area.js';
8
13
  import '../events/events_toolbox_item_select.js';
@@ -179,17 +184,6 @@ export declare class Toolbox extends DeleteArea implements IAutoHideable, IKeybo
179
184
  * ignored.
180
185
  */
181
186
  getClientRect(): Rect | null;
182
- /**
183
- * Returns whether the provided block or bubble would be deleted if dropped on
184
- * this area.
185
- * This method should check if the element is deletable and is always called
186
- * before onDragEnter/onDragOver/onDragExit.
187
- *
188
- * @param element The block or bubble currently being dragged.
189
- * @returns Whether the element provided would be deleted if dropped on this
190
- * area.
191
- */
192
- wouldDelete(element: IDraggable): boolean;
193
187
  /**
194
188
  * Handles when a cursor with a block or bubble enters this drag target.
195
189
  *
package/core/tooltip.d.ts CHANGED
@@ -3,6 +3,8 @@
3
3
  * Copyright 2011 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ import type { IFocusableNode } from './interfaces/i_focusable_node.js';
7
+ import type { WorkspaceSvg } from './workspace_svg.js';
6
8
  /**
7
9
  * A type which can define a tooltip.
8
10
  * Either a string, an object containing a tooltip property, or a function which
@@ -101,6 +103,14 @@ export declare function dispose(): void;
101
103
  * Hide the tooltip.
102
104
  */
103
105
  export declare function hide(): void;
106
+ /**
107
+ * Display the tooltip for a given target.
108
+ *
109
+ * @internal
110
+ * @param target The node upon which the tooltip should be displayed.
111
+ * @param workspace The target node's workspace.
112
+ */
113
+ export declare function display(target: IFocusableNode, workspace?: WorkspaceSvg): void;
104
114
  /**
105
115
  * Hide any in-progress tooltips and block showing new tooltips until the next
106
116
  * call to unblock().
@@ -8,6 +8,7 @@ import './events/events_trashcan_open.js';
8
8
  import type { IAutoHideable } from './interfaces/i_autohideable.js';
9
9
  import type { IDraggable } from './interfaces/i_draggable.js';
10
10
  import type { IFlyout } from './interfaces/i_flyout.js';
11
+ import type { IFocusableNode } from './interfaces/i_focusable_node.js';
11
12
  import type { IPositionable } from './interfaces/i_positionable.js';
12
13
  import type { UiMetrics } from './metrics_manager.js';
13
14
  import { Rect } from './utils/rect.js';
@@ -15,13 +16,20 @@ import type { WorkspaceSvg } from './workspace_svg.js';
15
16
  /**
16
17
  * Class for a trash can.
17
18
  */
18
- export declare class Trashcan extends DeleteArea implements IAutoHideable, IPositionable {
19
+ export declare class Trashcan extends DeleteArea implements IAutoHideable, IPositionable, IFocusableNode {
19
20
  private workspace;
20
21
  /**
21
- * The unique id for this component that is used to register with the
22
+ * The id for this component that is used to register with the
22
23
  * ComponentManager.
23
24
  */
24
25
  id: string;
26
+ /**
27
+ * A globally unique ID for this particular trashcan. Component Manager IDs
28
+ * (the ID above) are 1:1 with classes, but if there are multiple workspaces
29
+ * with trashcans on a page, each actual trashcan DOM element needs a unique
30
+ * ID to support focusable node resolution. This ID is for that purpose.
31
+ */
32
+ private uniqueId;
25
33
  /**
26
34
  * A list of JSON (stored as strings) representing blocks in the trashcan.
27
35
  */
@@ -34,19 +42,8 @@ export declare class Trashcan extends DeleteArea implements IAutoHideable, IPosi
34
42
  flyout: IFlyout | null;
35
43
  /** Current open/close state of the lid. */
36
44
  isLidOpen: boolean;
37
- /**
38
- * The minimum openness of the lid. Used to indicate if the trashcan
39
- * contains blocks.
40
- */
41
- private minOpenness;
42
45
  /** The SVG group containing the trash can. */
43
46
  private svgGroup;
44
- /** The SVG image element of the trash can lid. */
45
- private svgLid;
46
- /** Task ID of opening/closing animation. */
47
- private lidTask;
48
- /** Current state of lid opening (0.0 = closed, 1.0 = open). */
49
- private lidOpen;
50
47
  /** Left coordinate of the trash can. */
51
48
  private left;
52
49
  /** Top coordinate of the trash can. */
@@ -148,22 +145,6 @@ export declare class Trashcan extends DeleteArea implements IAutoHideable, IPosi
148
145
  * @internal
149
146
  */
150
147
  setLidOpen(state: boolean): void;
151
- /** Rotate the lid open or closed by one step. Then wait and recurse. */
152
- private animateLid;
153
- /**
154
- * Set the angle of the trashcan's lid.
155
- *
156
- * @param lidAngle The angle at which to set the lid.
157
- */
158
- private setLidAngle;
159
- /**
160
- * Sets the minimum openness of the trashcan lid. If the lid is currently
161
- * closed, this will update lid's position.
162
- *
163
- * @param newMin The new minimum openness of the lid. Should be between 0
164
- * and 1.
165
- */
166
- private setMinOpenness;
167
148
  /**
168
149
  * Flip the lid shut.
169
150
  * Called externally after a drag.
@@ -183,15 +164,6 @@ export declare class Trashcan extends DeleteArea implements IAutoHideable, IPosi
183
164
  * @param e A mouse down event.
184
165
  */
185
166
  private blockMouseDownWhenOpenable;
186
- /**
187
- * Indicate that the trashcan can be clicked (by opening it) if it has blocks.
188
- */
189
- private mouseOver;
190
- /**
191
- * Close the lid of the trashcan if it was open (Vis. it was indicating it had
192
- * blocks).
193
- */
194
- private mouseOut;
195
167
  /**
196
168
  * Handle a BLOCK_DELETE event. Adds deleted blocks oldXml to the content
197
169
  * array.
@@ -208,5 +180,18 @@ export declare class Trashcan extends DeleteArea implements IAutoHideable, IPosi
208
180
  * unnecessary attributes.
209
181
  */
210
182
  private cleanBlockJson;
183
+ getFocusableElement(): SVGElement;
184
+ getFocusableTree(): WorkspaceSvg;
185
+ onNodeFocus(): void;
186
+ onNodeBlur(): void;
187
+ canBeFocused(): boolean;
188
+ performAction(): void;
189
+ /**
190
+ * Retrieves the globally unique ID of this Trashcan instance. Used for focus
191
+ * management.
192
+ *
193
+ * @internal
194
+ */
195
+ getGloballyUniqueId(): string;
211
196
  }
212
197
  //# sourceMappingURL=trashcan.d.ts.map