blockly 12.0.0-beta.4 → 12.0.0-beta.5

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 (316) hide show
  1. package/blockly.min.js +552 -494
  2. package/blockly.mjs +10 -0
  3. package/blockly_compressed.js +517 -492
  4. package/blockly_compressed.js.map +1 -1
  5. package/blocks_compressed.js +2 -2
  6. package/blocks_compressed.js.map +1 -1
  7. package/core/block_svg.d.ts +36 -20
  8. package/core/blockly.d.ts +13 -1
  9. package/core/connection.d.ts +2 -0
  10. package/core/contextmenu_registry.d.ts +11 -9
  11. package/core/dialog.d.ts +36 -16
  12. package/core/field.d.ts +29 -31
  13. package/core/field_checkbox.d.ts +9 -0
  14. package/core/field_dropdown.d.ts +19 -2
  15. package/core/field_image.d.ts +9 -0
  16. package/core/field_label.d.ts +9 -0
  17. package/core/field_number.d.ts +9 -0
  18. package/core/field_textinput.d.ts +9 -0
  19. package/core/flyout_base.d.ts +23 -1
  20. package/core/flyout_button.d.ts +30 -7
  21. package/core/flyout_item.d.ts +3 -9
  22. package/core/flyout_separator.d.ts +18 -1
  23. package/core/focus_manager.d.ts +82 -14
  24. package/core/interfaces/i_ast_node_location_svg.d.ts +0 -12
  25. package/core/interfaces/i_autohideable.d.ts +2 -0
  26. package/core/interfaces/i_flyout.d.ts +2 -1
  27. package/core/interfaces/i_focusable_node.d.ts +31 -2
  28. package/core/interfaces/i_focusable_tree.d.ts +67 -0
  29. package/core/interfaces/i_navigable.d.ts +30 -0
  30. package/core/interfaces/i_navigation_policy.d.ts +42 -0
  31. package/core/interfaces/i_toolbox.d.ts +2 -1
  32. package/core/interfaces/i_toolbox_item.d.ts +2 -1
  33. package/core/keyboard_nav/ast_node.d.ts +1 -113
  34. package/core/keyboard_nav/block_navigation_policy.d.ts +56 -0
  35. package/core/keyboard_nav/connection_navigation_policy.d.ts +53 -0
  36. package/core/keyboard_nav/field_navigation_policy.d.ts +42 -0
  37. package/core/keyboard_nav/flyout_button_navigation_policy.d.ts +42 -0
  38. package/core/keyboard_nav/flyout_navigation_policy.d.ts +51 -0
  39. package/core/keyboard_nav/flyout_separator_navigation_policy.d.ts +19 -0
  40. package/core/keyboard_nav/line_cursor.d.ts +32 -103
  41. package/core/keyboard_nav/marker.d.ts +20 -29
  42. package/core/keyboard_nav/workspace_navigation_policy.d.ts +42 -0
  43. package/core/marker_manager.d.ts +0 -26
  44. package/core/navigator.d.ts +65 -0
  45. package/core/rendered_connection.d.ts +35 -1
  46. package/core/renderers/common/block_rendering.d.ts +1 -2
  47. package/core/renderers/common/drawer.d.ts +1 -1
  48. package/core/renderers/common/i_path_object.d.ts +1 -25
  49. package/core/renderers/common/path_object.d.ts +1 -26
  50. package/core/renderers/common/renderer.d.ts +0 -11
  51. package/core/renderers/zelos/drawer.d.ts +1 -1
  52. package/core/renderers/zelos/renderer.d.ts +0 -11
  53. package/core/renderers/zelos/zelos.d.ts +1 -2
  54. package/core/shortcut_registry.d.ts +7 -2
  55. package/core/toast.d.ts +74 -0
  56. package/core/toolbox/toolbox.d.ts +23 -1
  57. package/core/toolbox/toolbox_item.d.ts +9 -0
  58. package/core/utils/aria.d.ts +5 -2
  59. package/core/variable_map.d.ts +4 -4
  60. package/core/variables.d.ts +3 -1
  61. package/core/workspace.d.ts +10 -9
  62. package/core/workspace_svg.d.ts +103 -47
  63. package/index.mjs +10 -0
  64. package/msg/ab.js +33 -0
  65. package/msg/ab.mjs +33 -0
  66. package/msg/ace.js +33 -0
  67. package/msg/ace.mjs +33 -0
  68. package/msg/af.js +33 -0
  69. package/msg/af.mjs +33 -0
  70. package/msg/am.js +33 -0
  71. package/msg/am.mjs +33 -0
  72. package/msg/ar.js +33 -0
  73. package/msg/ar.mjs +33 -0
  74. package/msg/ast.js +33 -0
  75. package/msg/ast.mjs +33 -0
  76. package/msg/az.js +33 -0
  77. package/msg/az.mjs +33 -0
  78. package/msg/ba.js +33 -0
  79. package/msg/ba.mjs +33 -0
  80. package/msg/bcc.js +33 -0
  81. package/msg/bcc.mjs +33 -0
  82. package/msg/be-tarask.js +33 -0
  83. package/msg/be-tarask.mjs +33 -0
  84. package/msg/be.js +33 -0
  85. package/msg/be.mjs +33 -0
  86. package/msg/bg.js +33 -0
  87. package/msg/bg.mjs +33 -0
  88. package/msg/bn.js +33 -0
  89. package/msg/bn.mjs +33 -0
  90. package/msg/br.js +33 -0
  91. package/msg/br.mjs +33 -0
  92. package/msg/bs.js +33 -0
  93. package/msg/bs.mjs +33 -0
  94. package/msg/ca.js +33 -0
  95. package/msg/ca.mjs +33 -0
  96. package/msg/cdo.js +33 -0
  97. package/msg/cdo.mjs +33 -0
  98. package/msg/ce.js +33 -0
  99. package/msg/ce.mjs +33 -0
  100. package/msg/cs.js +33 -0
  101. package/msg/cs.mjs +33 -0
  102. package/msg/da.js +33 -0
  103. package/msg/da.mjs +33 -0
  104. package/msg/de.js +33 -0
  105. package/msg/de.mjs +33 -0
  106. package/msg/diq.js +33 -0
  107. package/msg/diq.mjs +33 -0
  108. package/msg/dtp.js +33 -0
  109. package/msg/dtp.mjs +33 -0
  110. package/msg/dty.js +33 -0
  111. package/msg/dty.mjs +33 -0
  112. package/msg/ee.js +33 -0
  113. package/msg/ee.mjs +33 -0
  114. package/msg/el.js +33 -0
  115. package/msg/el.mjs +33 -0
  116. package/msg/en-gb.js +33 -0
  117. package/msg/en-gb.mjs +33 -0
  118. package/msg/en.js +33 -0
  119. package/msg/en.mjs +33 -0
  120. package/msg/eo.js +33 -0
  121. package/msg/eo.mjs +33 -0
  122. package/msg/es.js +33 -0
  123. package/msg/es.mjs +33 -0
  124. package/msg/et.js +33 -0
  125. package/msg/et.mjs +33 -0
  126. package/msg/eu.js +33 -0
  127. package/msg/eu.mjs +33 -0
  128. package/msg/fa.js +33 -0
  129. package/msg/fa.mjs +33 -0
  130. package/msg/fi.js +33 -0
  131. package/msg/fi.mjs +33 -0
  132. package/msg/fo.js +33 -0
  133. package/msg/fo.mjs +33 -0
  134. package/msg/fr.js +33 -0
  135. package/msg/fr.mjs +33 -0
  136. package/msg/frr.js +33 -0
  137. package/msg/frr.mjs +33 -0
  138. package/msg/gl.js +33 -0
  139. package/msg/gl.mjs +33 -0
  140. package/msg/gn.js +33 -0
  141. package/msg/gn.mjs +33 -0
  142. package/msg/gor.js +33 -0
  143. package/msg/gor.mjs +33 -0
  144. package/msg/ha.js +33 -0
  145. package/msg/ha.mjs +33 -0
  146. package/msg/hak.js +33 -0
  147. package/msg/hak.mjs +33 -0
  148. package/msg/he.js +33 -0
  149. package/msg/he.mjs +33 -0
  150. package/msg/hi.js +33 -0
  151. package/msg/hi.mjs +33 -0
  152. package/msg/hr.js +33 -0
  153. package/msg/hr.mjs +33 -0
  154. package/msg/hrx.js +33 -0
  155. package/msg/hrx.mjs +33 -0
  156. package/msg/hsb.js +33 -0
  157. package/msg/hsb.mjs +33 -0
  158. package/msg/hu.js +33 -0
  159. package/msg/hu.mjs +33 -0
  160. package/msg/hy.js +33 -0
  161. package/msg/hy.mjs +33 -0
  162. package/msg/ia.js +33 -0
  163. package/msg/ia.mjs +33 -0
  164. package/msg/id.js +33 -0
  165. package/msg/id.mjs +33 -0
  166. package/msg/ig.js +33 -0
  167. package/msg/ig.mjs +33 -0
  168. package/msg/inh.js +33 -0
  169. package/msg/inh.mjs +33 -0
  170. package/msg/is.js +33 -0
  171. package/msg/is.mjs +33 -0
  172. package/msg/it.js +33 -0
  173. package/msg/it.mjs +33 -0
  174. package/msg/ja.js +33 -0
  175. package/msg/ja.mjs +33 -0
  176. package/msg/ka.js +33 -0
  177. package/msg/ka.mjs +33 -0
  178. package/msg/kab.js +33 -0
  179. package/msg/kab.mjs +33 -0
  180. package/msg/kbd-cyrl.js +33 -0
  181. package/msg/kbd-cyrl.mjs +33 -0
  182. package/msg/km.js +33 -0
  183. package/msg/km.mjs +33 -0
  184. package/msg/kn.js +33 -0
  185. package/msg/kn.mjs +33 -0
  186. package/msg/ko.js +33 -0
  187. package/msg/ko.mjs +33 -0
  188. package/msg/ksh.js +33 -0
  189. package/msg/ksh.mjs +33 -0
  190. package/msg/ku-latn.js +33 -0
  191. package/msg/ku-latn.mjs +33 -0
  192. package/msg/ky.js +33 -0
  193. package/msg/ky.mjs +33 -0
  194. package/msg/la.js +33 -0
  195. package/msg/la.mjs +33 -0
  196. package/msg/lb.js +33 -0
  197. package/msg/lb.mjs +33 -0
  198. package/msg/lki.js +33 -0
  199. package/msg/lki.mjs +33 -0
  200. package/msg/lo.js +33 -0
  201. package/msg/lo.mjs +33 -0
  202. package/msg/lrc.js +33 -0
  203. package/msg/lrc.mjs +33 -0
  204. package/msg/lt.js +33 -0
  205. package/msg/lt.mjs +33 -0
  206. package/msg/lv.js +33 -0
  207. package/msg/lv.mjs +33 -0
  208. package/msg/mg.js +33 -0
  209. package/msg/mg.mjs +33 -0
  210. package/msg/mk.js +33 -0
  211. package/msg/mk.mjs +33 -0
  212. package/msg/ml.js +33 -0
  213. package/msg/ml.mjs +33 -0
  214. package/msg/mnw.js +33 -0
  215. package/msg/mnw.mjs +33 -0
  216. package/msg/ms.js +33 -0
  217. package/msg/ms.mjs +33 -0
  218. package/msg/my.js +33 -0
  219. package/msg/my.mjs +33 -0
  220. package/msg/mzn.js +33 -0
  221. package/msg/mzn.mjs +33 -0
  222. package/msg/nb.js +33 -0
  223. package/msg/nb.mjs +33 -0
  224. package/msg/ne.js +33 -0
  225. package/msg/ne.mjs +33 -0
  226. package/msg/nl.js +33 -0
  227. package/msg/nl.mjs +33 -0
  228. package/msg/oc.js +33 -0
  229. package/msg/oc.mjs +33 -0
  230. package/msg/olo.js +33 -0
  231. package/msg/olo.mjs +33 -0
  232. package/msg/pa.js +33 -0
  233. package/msg/pa.mjs +33 -0
  234. package/msg/pl.js +33 -0
  235. package/msg/pl.mjs +33 -0
  236. package/msg/pms.js +33 -0
  237. package/msg/pms.mjs +33 -0
  238. package/msg/ps.js +33 -0
  239. package/msg/ps.mjs +33 -0
  240. package/msg/pt-br.js +33 -0
  241. package/msg/pt-br.mjs +33 -0
  242. package/msg/pt.js +33 -0
  243. package/msg/pt.mjs +33 -0
  244. package/msg/ro.js +33 -0
  245. package/msg/ro.mjs +33 -0
  246. package/msg/ru.js +33 -0
  247. package/msg/ru.mjs +33 -0
  248. package/msg/sc.js +33 -0
  249. package/msg/sc.mjs +33 -0
  250. package/msg/sco.js +33 -0
  251. package/msg/sco.mjs +33 -0
  252. package/msg/sd.js +33 -0
  253. package/msg/sd.mjs +33 -0
  254. package/msg/shn.js +33 -0
  255. package/msg/shn.mjs +33 -0
  256. package/msg/si.js +33 -0
  257. package/msg/si.mjs +33 -0
  258. package/msg/sk.js +33 -0
  259. package/msg/sk.mjs +33 -0
  260. package/msg/skr-arab.js +33 -0
  261. package/msg/skr-arab.mjs +33 -0
  262. package/msg/sl.js +33 -0
  263. package/msg/sl.mjs +33 -0
  264. package/msg/smn.js +33 -0
  265. package/msg/smn.mjs +33 -0
  266. package/msg/sq.js +33 -0
  267. package/msg/sq.mjs +33 -0
  268. package/msg/sr-latn.js +33 -0
  269. package/msg/sr-latn.mjs +33 -0
  270. package/msg/sr.js +33 -0
  271. package/msg/sr.mjs +33 -0
  272. package/msg/sv.js +33 -0
  273. package/msg/sv.mjs +33 -0
  274. package/msg/sw.js +33 -0
  275. package/msg/sw.mjs +33 -0
  276. package/msg/ta.js +33 -0
  277. package/msg/ta.mjs +33 -0
  278. package/msg/tcy.js +33 -0
  279. package/msg/tcy.mjs +33 -0
  280. package/msg/tdd.js +33 -0
  281. package/msg/tdd.mjs +33 -0
  282. package/msg/te.js +33 -0
  283. package/msg/te.mjs +33 -0
  284. package/msg/th.js +33 -0
  285. package/msg/th.mjs +33 -0
  286. package/msg/ti.js +33 -0
  287. package/msg/ti.mjs +33 -0
  288. package/msg/tl.js +33 -0
  289. package/msg/tl.mjs +33 -0
  290. package/msg/tlh.js +33 -0
  291. package/msg/tlh.mjs +33 -0
  292. package/msg/tr.js +33 -0
  293. package/msg/tr.mjs +33 -0
  294. package/msg/ug-arab.js +33 -0
  295. package/msg/ug-arab.mjs +33 -0
  296. package/msg/uk.js +33 -0
  297. package/msg/uk.mjs +33 -0
  298. package/msg/ur.js +33 -0
  299. package/msg/ur.mjs +33 -0
  300. package/msg/uz.js +33 -0
  301. package/msg/uz.mjs +33 -0
  302. package/msg/vi.js +33 -0
  303. package/msg/vi.mjs +33 -0
  304. package/msg/xmf.js +33 -0
  305. package/msg/xmf.mjs +33 -0
  306. package/msg/yo.js +33 -0
  307. package/msg/yo.mjs +33 -0
  308. package/msg/zgh.js +33 -0
  309. package/msg/zgh.mjs +33 -0
  310. package/msg/zh-hans.js +33 -0
  311. package/msg/zh-hans.mjs +33 -0
  312. package/msg/zh-hant.js +33 -0
  313. package/msg/zh-hant.mjs +33 -0
  314. package/package.json +4 -4
  315. package/core/renderers/common/marker_svg.d.ts +0 -256
  316. package/core/renderers/zelos/marker_svg.d.ts +0 -49
@@ -1,32 +1,26 @@
1
1
  import type { IBoundedElement } from './interfaces/i_bounded_element.js';
2
+ import type { INavigable } from './interfaces/i_navigable.js';
2
3
  /**
3
4
  * Representation of an item displayed in a flyout.
4
5
  */
5
6
  export declare class FlyoutItem {
6
7
  private element;
7
8
  private type;
8
- private focusable;
9
9
  /**
10
10
  * Creates a new FlyoutItem.
11
11
  *
12
12
  * @param element The element that will be displayed in the flyout.
13
13
  * @param type The type of element. Should correspond to the type of the
14
14
  * flyout inflater that created this object.
15
- * @param focusable True if the element should be allowed to be focused by
16
- * e.g. keyboard navigation in the flyout.
17
15
  */
18
- constructor(element: IBoundedElement, type: string, focusable: boolean);
16
+ constructor(element: IBoundedElement & INavigable<any>, type: string);
19
17
  /**
20
18
  * Returns the element displayed in the flyout.
21
19
  */
22
- getElement(): IBoundedElement;
20
+ getElement(): IBoundedElement & INavigable<any>;
23
21
  /**
24
22
  * Returns the type of flyout element this item represents.
25
23
  */
26
24
  getType(): string;
27
- /**
28
- * Returns whether or not the flyout element can receive focus.
29
- */
30
- isFocusable(): boolean;
31
25
  }
32
26
  //# sourceMappingURL=flyout_item.d.ts.map
@@ -4,11 +4,12 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import type { IBoundedElement } from './interfaces/i_bounded_element.js';
7
+ import type { INavigable } from './interfaces/i_navigable.js';
7
8
  import { Rect } from './utils/rect.js';
8
9
  /**
9
10
  * Representation of a gap between elements in a flyout.
10
11
  */
11
- export declare class FlyoutSeparator implements IBoundedElement {
12
+ export declare class FlyoutSeparator implements IBoundedElement, INavigable<FlyoutSeparator> {
12
13
  private gap;
13
14
  private axis;
14
15
  private x;
@@ -34,6 +35,22 @@ export declare class FlyoutSeparator implements IBoundedElement {
34
35
  * @param _reason The reason this move was initiated.
35
36
  */
36
37
  moveBy(dx: number, dy: number, _reason?: string[]): void;
38
+ /**
39
+ * Returns false to prevent this separator from being navigated to by the
40
+ * keyboard.
41
+ *
42
+ * @returns False.
43
+ */
44
+ isNavigable(): boolean;
45
+ /**
46
+ * Returns this separator's class.
47
+ *
48
+ * Used by keyboard navigation to look up the rules for navigating from this
49
+ * separator.
50
+ *
51
+ * @returns This separator's class.
52
+ */
53
+ getClass(): typeof FlyoutSeparator;
37
54
  }
38
55
  /**
39
56
  * Representation of an axis along which a separator occupies space.
@@ -49,9 +49,12 @@ export declare class FocusManager {
49
49
  * using this constant directly (generally it never should need to be used).
50
50
  */
51
51
  static readonly PASSIVE_FOCUS_NODE_CSS_CLASS_NAME = "blocklyPassiveFocus";
52
- focusedNode: IFocusableNode | null;
53
- registeredTrees: Array<IFocusableTree>;
52
+ private focusedNode;
53
+ private previouslyFocusedNode;
54
+ private registeredTrees;
54
55
  private currentlyHoldsEphemeralFocus;
56
+ private lockFocusStateChanges;
57
+ private recentlyLostAllFocus;
55
58
  constructor(addGlobalEventListener: (type: string, listener: EventListener) => void);
56
59
  /**
57
60
  * Registers a new IFocusableTree for automatic focus management.
@@ -120,17 +123,16 @@ export declare class FocusManager {
120
123
  */
121
124
  focusTree(focusableTree: IFocusableTree): void;
122
125
  /**
123
- * Focuses DOM input on the selected node, and marks it as actively focused.
126
+ * Focuses DOM input on the specified node, and marks it as actively focused.
124
127
  *
125
128
  * Any previously focused node will be updated to be passively highlighted (if
126
129
  * it's in a different focusable tree) or blurred (if it's in the same one).
127
130
  *
128
- * @param focusableNode The node that should receive active
129
- * focus.
131
+ * @param focusableNode The node that should receive active focus.
130
132
  */
131
133
  focusNode(focusableNode: IFocusableNode): void;
132
134
  /**
133
- * Ephemerally captures focus for a selected element until the returned lambda
135
+ * Ephemerally captures focus for a specific element until the returned lambda
134
136
  * is called. This is expected to be especially useful for ephemeral UI flows
135
137
  * like dialogs.
136
138
  *
@@ -148,16 +150,82 @@ export declare class FocusManager {
148
150
  * simultaneously will result in an error being thrown).
149
151
  */
150
152
  takeEphemeralFocus(focusableElement: HTMLElement | SVGElement): ReturnEphemeralFocus;
153
+ /**
154
+ * Ensures that the manager is currently allowing operations that change its
155
+ * internal focus state (such as via focusNode()).
156
+ *
157
+ * If the manager is currently not allowing state changes, an exception is
158
+ * thrown.
159
+ */
160
+ private ensureManagerIsUnlocked;
161
+ /**
162
+ * Updates the internally tracked focused node to the specified node, or null
163
+ * if focus is being lost. This also updates previous focus tracking.
164
+ *
165
+ * @param newFocusedNode The new node to set as focused.
166
+ */
167
+ private updateFocusedNode;
168
+ /**
169
+ * Defocuses the current actively focused node tracked by the manager, iff
170
+ * there's a node being tracked and the manager doesn't have ephemeral focus.
171
+ */
151
172
  private defocusCurrentFocusedNode;
152
- private setNodeToActive;
153
- private setNodeToPassive;
173
+ /**
174
+ * Marks the specified node as actively focused, also calling related lifecycle
175
+ * callback methods for both the node and its parent tree. This ensures that
176
+ * the node is properly styled to indicate its active focus.
177
+ *
178
+ * This does not change the manager's currently tracked node, nor does it
179
+ * change any other nodes.
180
+ *
181
+ * @param node The node to be actively focused.
182
+ * @param prevTree The tree of the previously actively focused node, or null
183
+ * if there wasn't a previously actively focused node.
184
+ */
185
+ private activelyFocusNode;
186
+ /**
187
+ * Marks the specified node as passively focused, also calling related
188
+ * lifecycle callback methods for both the node and its parent tree. This
189
+ * ensures that the node is properly styled to indicate its passive focus.
190
+ *
191
+ * This does not change the manager's currently tracked node, nor does it
192
+ * change any other nodes.
193
+ *
194
+ * @param node The node to be passively focused.
195
+ * @param nextTree The tree of the node receiving active focus, or null if no
196
+ * node will be actively focused.
197
+ */
198
+ private passivelyFocusNode;
199
+ /**
200
+ * Updates the node's styling to indicate that it should have an active focus
201
+ * indicator.
202
+ *
203
+ * @param node The node to be styled for active focus.
204
+ */
205
+ private setNodeToVisualActiveFocus;
206
+ /**
207
+ * Updates the node's styling to indicate that it should have a passive focus
208
+ * indicator.
209
+ *
210
+ * @param node The node to be styled for passive focus.
211
+ */
212
+ private setNodeToVisualPassiveFocus;
213
+ /**
214
+ * Removes any active/passive indicators for the specified node.
215
+ *
216
+ * @param node The node which should have neither passive nor active focus
217
+ * indication.
218
+ */
154
219
  private removeHighlight;
220
+ private static focusManager;
221
+ /**
222
+ * Returns the page-global FocusManager.
223
+ *
224
+ * The returned instance is guaranteed to not change across function calls, but
225
+ * may change across page loads.
226
+ */
227
+ static getFocusManager(): FocusManager;
155
228
  }
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
- */
229
+ /** Convenience function for FocusManager.getFocusManager. */
162
230
  export declare function getFocusManager(): FocusManager;
163
231
  //# sourceMappingURL=focus_manager.d.ts.map
@@ -8,17 +8,5 @@ import type { IASTNodeLocation } from './i_ast_node_location.js';
8
8
  * An AST node location SVG interface.
9
9
  */
10
10
  export interface IASTNodeLocationSvg extends IASTNodeLocation {
11
- /**
12
- * Add the marker SVG to this node's SVG group.
13
- *
14
- * @param markerSvg The SVG root of the marker to be added to the SVG group.
15
- */
16
- setMarkerSvg(markerSvg: SVGElement | null): void;
17
- /**
18
- * Add the cursor SVG to this node's SVG group.
19
- *
20
- * @param cursorSvg The SVG root of the cursor to be added to the SVG group.
21
- */
22
- setCursorSvg(cursorSvg: SVGElement | null): void;
23
11
  }
24
12
  //# sourceMappingURL=i_ast_node_location_svg.d.ts.map
@@ -16,4 +16,6 @@ export interface IAutoHideable extends IComponent {
16
16
  */
17
17
  autoHide(onlyClosePopups: boolean): void;
18
18
  }
19
+ /** Returns true if the given object is autohideable. */
20
+ export declare function isAutoHideable(obj: any): obj is IAutoHideable;
19
21
  //# sourceMappingURL=i_autohideable.d.ts.map
@@ -9,11 +9,12 @@ import type { Coordinate } from '../utils/coordinate.js';
9
9
  import type { Svg } from '../utils/svg.js';
10
10
  import type { FlyoutDefinition } from '../utils/toolbox.js';
11
11
  import type { WorkspaceSvg } from '../workspace_svg.js';
12
+ import { IFocusableTree } from './i_focusable_tree.js';
12
13
  import type { IRegistrable } from './i_registrable.js';
13
14
  /**
14
15
  * Interface for a flyout.
15
16
  */
16
- export interface IFlyout extends IRegistrable {
17
+ export interface IFlyout extends IRegistrable, IFocusableTree {
17
18
  /** Whether the flyout is laid out horizontally or not. */
18
19
  horizontalLayout: boolean;
19
20
  /** Is RTL vs LTR. */
@@ -23,8 +23,14 @@ export interface IFocusableNode {
23
23
  * and a tab index must be present in order for the element to be focusable in
24
24
  * the DOM).
25
25
  *
26
- * It's expected the return element will not change for the lifetime of the
27
- * node.
26
+ * The returned element must be visible if the node is ever focused via
27
+ * FocusManager.focusNode() or FocusManager.focusTree(). It's allowed for an
28
+ * element to be hidden until onNodeFocus() is called, or become hidden with a
29
+ * call to onNodeBlur().
30
+ *
31
+ * It's expected the actual returned element will not change for the lifetime
32
+ * of the node (that is, its properties can change but a new element should
33
+ * never be returned).
28
34
  */
29
35
  getFocusableElement(): HTMLElement | SVGElement;
30
36
  /**
@@ -33,5 +39,28 @@ export interface IFocusableNode {
33
39
  * belongs.
34
40
  */
35
41
  getFocusableTree(): IFocusableTree;
42
+ /**
43
+ * Called when this node receives active focus.
44
+ *
45
+ * Note that it's fine for implementations to change visibility modifiers, but
46
+ * they should avoid the following:
47
+ * - Creating or removing DOM elements (including via the renderer or drawer).
48
+ * - Affecting focus via DOM focus() calls or the FocusManager.
49
+ */
50
+ onNodeFocus(): void;
51
+ /**
52
+ * Called when this node loses active focus. It may still have passive focus.
53
+ *
54
+ * This has the same implementation restrictions as onNodeFocus().
55
+ */
56
+ onNodeBlur(): void;
36
57
  }
58
+ /**
59
+ * Determines whether the provided object fulfills the contract of
60
+ * IFocusableNode.
61
+ *
62
+ * @param object The object to test.
63
+ * @returns Whether the provided object can be used as an IFocusableNode.
64
+ */
65
+ export declare function isFocusableNode(object: any | null): object is IFocusableNode;
37
66
  //# sourceMappingURL=i_focusable_node.d.ts.map
@@ -34,6 +34,35 @@ export interface IFocusableTree {
34
34
  * currently have a focused node.
35
35
  */
36
36
  getRootFocusableNode(): IFocusableNode;
37
+ /**
38
+ * Returns the IFocusableNode of this tree that should receive active focus
39
+ * when the tree itself has focus returned to it.
40
+ *
41
+ * There are some very important notes to consider about a tree's focus
42
+ * lifecycle when implementing a version of this method that doesn't return
43
+ * null:
44
+ * 1. A null previousNode does not guarantee first-time focus state as nodes
45
+ * can be deleted.
46
+ * 2. This method is only used when the tree itself is focused, either through
47
+ * tab navigation or via FocusManager.focusTree(). In many cases, the
48
+ * previously focused node will be directly focused instead which will
49
+ * bypass this method.
50
+ * 3. The default behavior (i.e. returning null here) involves either
51
+ * restoring the previous node (previousNode) or focusing the tree's root.
52
+ * 4. The provided node may sometimes no longer be valid, such as in the case
53
+ * an attempt is made to focus a node that has been recently removed from
54
+ * its parent tree. Implementations can check for the validity of the node
55
+ * in order to specialize the node to which focus should fall back.
56
+ *
57
+ * This method is largely intended to provide tree implementations with the
58
+ * means of specifying a better default node than their root.
59
+ *
60
+ * @param previousNode The node that previously held passive focus for this
61
+ * tree, or null if the tree hasn't yet been focused.
62
+ * @returns The IFocusableNode that should now receive focus, or null if
63
+ * default behavior should be used, instead.
64
+ */
65
+ getRestoredFocusableNode(previousNode: IFocusableNode | null): IFocusableNode | null;
37
66
  /**
38
67
  * Returns all directly nested trees under this tree.
39
68
  *
@@ -54,5 +83,43 @@ export interface IFocusableTree {
54
83
  * @param id The ID of the node's focusable HTMLElement or SVGElement.
55
84
  */
56
85
  lookUpFocusableNode(id: string): IFocusableNode | null;
86
+ /**
87
+ * Called when a node of this tree has received active focus.
88
+ *
89
+ * Note that a null previousTree does not necessarily indicate that this is
90
+ * the first time Blockly is receiving focus. In fact, few assumptions can be
91
+ * made about previous focus state as a previous null tree simply indicates
92
+ * that Blockly did not hold active focus prior to this tree becoming focused
93
+ * (which can happen due to focus exiting the Blockly injection div, or for
94
+ * other cases like ephemeral focus).
95
+ *
96
+ * See IFocusableNode.onNodeFocus() as implementations have the same
97
+ * restrictions as with that method.
98
+ *
99
+ * @param node The node receiving active focus.
100
+ * @param previousTree The previous tree that held active focus, or null if
101
+ * none.
102
+ */
103
+ onTreeFocus(node: IFocusableNode, previousTree: IFocusableTree | null): void;
104
+ /**
105
+ * Called when the previously actively focused node of this tree is now
106
+ * passively focused and there is no other active node of this tree taking its
107
+ * place.
108
+ *
109
+ * This has the same implementation restrictions and considerations as
110
+ * onTreeFocus().
111
+ *
112
+ * @param nextTree The next tree receiving active focus, or null if none (such
113
+ * as in the case that Blockly is entirely losing DOM focus).
114
+ */
115
+ onTreeBlur(nextTree: IFocusableTree | null): void;
57
116
  }
117
+ /**
118
+ * Determines whether the provided object fulfills the contract of
119
+ * IFocusableTree.
120
+ *
121
+ * @param object The object to test.
122
+ * @returns Whether the provided object can be used as an IFocusableTree.
123
+ */
124
+ export declare function isFocusableTree(object: any | null): object is IFocusableTree;
58
125
  //# sourceMappingURL=i_focusable_tree.d.ts.map
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Represents a UI element which can be navigated to using the keyboard.
8
+ */
9
+ export interface INavigable<T> {
10
+ /**
11
+ * Returns whether or not this specific instance should be reachable via
12
+ * keyboard navigation.
13
+ *
14
+ * Implementors should generally return true, unless there are circumstances
15
+ * under which this item should be skipped while using keyboard navigation.
16
+ * Common examples might include being disabled, invalid, readonly, or purely
17
+ * a visual decoration. For example, while Fields are navigable, non-editable
18
+ * fields return false, since they cannot be interacted with when focused.
19
+ *
20
+ * @returns True if this element should be included in keyboard navigation.
21
+ */
22
+ isNavigable(): boolean;
23
+ /**
24
+ * Returns the class of this instance.
25
+ *
26
+ * @returns This object's class.
27
+ */
28
+ getClass(): new (...args: any) => T;
29
+ }
30
+ //# sourceMappingURL=i_navigable.d.ts.map
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { INavigable } from './i_navigable.js';
7
+ /**
8
+ * A set of rules that specify where keyboard navigation should proceed.
9
+ */
10
+ export interface INavigationPolicy<T> {
11
+ /**
12
+ * Returns the first child element of the given element, if any.
13
+ *
14
+ * @param current The element which the user is navigating into.
15
+ * @returns The current element's first child, or null if it has none.
16
+ */
17
+ getFirstChild(current: T): INavigable<any> | null;
18
+ /**
19
+ * Returns the parent element of the given element, if any.
20
+ *
21
+ * @param current The element which the user is navigating out of.
22
+ * @returns The parent element of the current element, or null if it has none.
23
+ */
24
+ getParent(current: T): INavigable<any> | null;
25
+ /**
26
+ * Returns the peer element following the given element, if any.
27
+ *
28
+ * @param current The element which the user is navigating past.
29
+ * @returns The next peer element of the current element, or null if there is
30
+ * none.
31
+ */
32
+ getNextSibling(current: T): INavigable<any> | null;
33
+ /**
34
+ * Returns the peer element preceding the given element, if any.
35
+ *
36
+ * @param current The element which the user is navigating past.
37
+ * @returns The previous peer element of the current element, or null if
38
+ * there is none.
39
+ */
40
+ getPreviousSibling(current: T): INavigable<any> | null;
41
+ }
42
+ //# sourceMappingURL=i_navigation_policy.d.ts.map
@@ -6,12 +6,13 @@
6
6
  import type { ToolboxInfo } from '../utils/toolbox.js';
7
7
  import type { WorkspaceSvg } from '../workspace_svg.js';
8
8
  import type { IFlyout } from './i_flyout.js';
9
+ import type { IFocusableTree } from './i_focusable_tree.js';
9
10
  import type { IRegistrable } from './i_registrable.js';
10
11
  import type { IToolboxItem } from './i_toolbox_item.js';
11
12
  /**
12
13
  * Interface for a toolbox.
13
14
  */
14
- export interface IToolbox extends IRegistrable {
15
+ export interface IToolbox extends IRegistrable, IFocusableTree {
15
16
  /** Initializes the toolbox. */
16
17
  init(): void;
17
18
  /**
@@ -3,10 +3,11 @@
3
3
  * Copyright 2020 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
+ import type { IFocusableNode } from './i_focusable_node.js';
6
7
  /**
7
8
  * Interface for an item in the toolbox.
8
9
  */
9
- export interface IToolboxItem {
10
+ export interface IToolboxItem extends IFocusableNode {
10
11
  /**
11
12
  * Initializes the toolbox item.
12
13
  * This includes creating the DOM and updating the state of any items based
@@ -80,89 +80,7 @@ export declare class ASTNode {
80
80
  * @internal
81
81
  */
82
82
  isConnection(): boolean;
83
- /**
84
- * Given an input find the next editable field or an input with a non null
85
- * connection in the same block. The current location must be an input
86
- * connection.
87
- *
88
- * @returns The AST node holding the next field or connection or null if there
89
- * is no editable field or input connection after the given input.
90
- */
91
- private findNextForInput;
92
- /**
93
- * Given a field find the next editable field or an input with a non null
94
- * connection in the same block. The current location must be a field.
95
- *
96
- * @returns The AST node pointing to the next field or connection or null if
97
- * there is no editable field or input connection after the given input.
98
- */
99
- private findNextForField;
100
- /**
101
- * Given an input find the previous editable field or an input with a non null
102
- * connection in the same block. The current location must be an input
103
- * connection.
104
- *
105
- * @returns The AST node holding the previous field or connection.
106
- */
107
- private findPrevForInput;
108
- /**
109
- * Given a field find the previous editable field or an input with a non null
110
- * connection in the same block. The current location must be a field.
111
- *
112
- * @returns The AST node holding the previous input or field.
113
- */
114
- private findPrevForField;
115
- /**
116
- * Navigate between stacks of blocks on the workspace.
117
- *
118
- * @param forward True to go forward. False to go backwards.
119
- * @returns The first block of the next stack or null if there are no blocks
120
- * on the workspace.
121
- */
122
- private navigateBetweenStacks;
123
- /**
124
- * Navigate between buttons and stacks of blocks on the flyout workspace.
125
- *
126
- * @param forward True to go forward. False to go backwards.
127
- * @returns The next button, or next stack's first block, or null
128
- */
129
- private navigateFlyoutContents;
130
- /**
131
- * Finds the next (or previous if navigating backward) item in the flyout that should be navigated to.
132
- *
133
- * @param flyoutContents Contents of the current flyout.
134
- * @param currentLocation Current ASTNode location.
135
- * @param forward True if we're navigating forward, else false.
136
- * @returns The next (or previous) FlyoutItem, or null if there is none.
137
- */
138
- private findNextLocationInFlyout;
139
- /**
140
- * Finds the top most AST node for a given block.
141
- * This is either the previous connection, output connection or block
142
- * depending on what kind of connections the block has.
143
- *
144
- * @param block The block that we want to find the top connection on.
145
- * @returns The AST node containing the top connection.
146
- */
147
- private findTopASTNodeForBlock;
148
- /**
149
- * Get the AST node pointing to the input that the block is nested under or if
150
- * the block is not nested then get the stack AST node.
151
- *
152
- * @param block The source block of the current location.
153
- * @returns The AST node pointing to the input connection or the top block of
154
- * the stack this block is in.
155
- */
156
- private getOutAstNodeForBlock;
157
- /**
158
- * Find the first editable field or input with a connection on a given block.
159
- *
160
- * @param block The source block of the current location.
161
- * @returns An AST node pointing to the first field or input.
162
- * Null if there are no editable fields or inputs with connections on the
163
- * block.
164
- */
165
- private findFirstFieldOrInput;
83
+ private getVisibleInputs;
166
84
  /**
167
85
  * Finds the source block of the location of this node.
168
86
  *
@@ -170,36 +88,6 @@ export declare class ASTNode {
170
88
  * workspace or button.
171
89
  */
172
90
  getSourceBlock(): Block | null;
173
- /**
174
- * Find the element to the right of the current element in the AST.
175
- *
176
- * @returns An AST node that wraps the next field, connection, block, or
177
- * workspace. Or null if there is no node to the right.
178
- */
179
- next(): ASTNode | null;
180
- /**
181
- * Find the element one level below and all the way to the left of the current
182
- * location.
183
- *
184
- * @returns An AST node that wraps the next field, connection, workspace, or
185
- * block. Or null if there is nothing below this node.
186
- */
187
- in(): ASTNode | null;
188
- /**
189
- * Find the element to the left of the current element in the AST.
190
- *
191
- * @returns An AST node that wraps the previous field, connection, workspace
192
- * or block. Or null if no node exists to the left. null.
193
- */
194
- prev(): ASTNode | null;
195
- /**
196
- * Find the next element that is one position above and all the way to the
197
- * left of the current location.
198
- *
199
- * @returns An AST node that wraps the next field, connection, workspace or
200
- * block. Or null if we are at the workspace level.
201
- */
202
- out(): ASTNode | null;
203
91
  /**
204
92
  * Whether an AST node of the given type points to a connection.
205
93
  *
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { BlockSvg } from '../block_svg.js';
7
+ import type { INavigable } from '../interfaces/i_navigable.js';
8
+ import type { INavigationPolicy } from '../interfaces/i_navigation_policy.js';
9
+ import type { RenderedConnection } from '../rendered_connection.js';
10
+ /**
11
+ * Set of rules controlling keyboard navigation from a block.
12
+ */
13
+ export declare class BlockNavigationPolicy implements INavigationPolicy<BlockSvg> {
14
+ /**
15
+ * Returns the first child of the given block.
16
+ *
17
+ * @param current The block to return the first child of.
18
+ * @returns The first field or input of the given block, if any.
19
+ */
20
+ getFirstChild(current: BlockSvg): INavigable<unknown> | null;
21
+ /**
22
+ * Returns the parent of the given block.
23
+ *
24
+ * @param current The block to return the parent of.
25
+ * @returns The top block of the given block's stack, or the connection to
26
+ * which it is attached.
27
+ */
28
+ getParent(current: BlockSvg): INavigable<unknown> | null;
29
+ /**
30
+ * Returns the next peer node of the given block.
31
+ *
32
+ * @param current The block to find the following element of.
33
+ * @returns The first block of the next stack if the given block is a terminal
34
+ * block, or its next connection.
35
+ */
36
+ getNextSibling(current: BlockSvg): INavigable<unknown> | null;
37
+ /**
38
+ * Returns the previous peer node of the given block.
39
+ *
40
+ * @param current The block to find the preceding element of.
41
+ * @returns The block's previous/output connection, or the last
42
+ * connection/block of the previous block stack if it is a root block.
43
+ */
44
+ getPreviousSibling(current: BlockSvg): INavigable<unknown> | null;
45
+ /**
46
+ * Gets the parent connection on a block.
47
+ * This is either an output connection, previous connection or undefined.
48
+ * If both connections exist return the one that is actually connected
49
+ * to another block.
50
+ *
51
+ * @param block The block to find the parent connection on.
52
+ * @returns The connection connecting to the parent of the block.
53
+ */
54
+ protected getParentConnection(block: BlockSvg): RenderedConnection;
55
+ }
56
+ //# sourceMappingURL=block_navigation_policy.d.ts.map