@gtkx/testing 1.0.0-rc.4 → 1.1.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.
Files changed (212) hide show
  1. package/README.md +5 -5
  2. package/dist/accessible-native.d.ts +16 -0
  3. package/dist/accessible-native.d.ts.map +1 -0
  4. package/dist/accessible-native.js +206 -0
  5. package/dist/accessible-native.js.map +1 -0
  6. package/dist/act.d.ts +1 -3
  7. package/dist/act.d.ts.map +1 -1
  8. package/dist/act.js +1 -1
  9. package/dist/act.js.map +1 -1
  10. package/dist/build-queries.d.ts +27 -10
  11. package/dist/build-queries.d.ts.map +1 -1
  12. package/dist/build-queries.js +22 -24
  13. package/dist/build-queries.js.map +1 -1
  14. package/dist/cleanup-registry.d.ts +1 -1
  15. package/dist/cleanup-registry.d.ts.map +1 -1
  16. package/dist/cleanup-registry.js.map +1 -1
  17. package/dist/config.d.ts +8 -1
  18. package/dist/config.d.ts.map +1 -1
  19. package/dist/config.js +1 -0
  20. package/dist/config.js.map +1 -1
  21. package/dist/errors.d.ts +10 -1
  22. package/dist/errors.d.ts.map +1 -1
  23. package/dist/errors.js +10 -1
  24. package/dist/errors.js.map +1 -1
  25. package/dist/fire-event.d.ts +35 -6
  26. package/dist/fire-event.d.ts.map +1 -1
  27. package/dist/fire-event.js +23 -7
  28. package/dist/fire-event.js.map +1 -1
  29. package/dist/frame-sync.d.ts +3 -2
  30. package/dist/frame-sync.d.ts.map +1 -1
  31. package/dist/frame-sync.js +19 -9
  32. package/dist/frame-sync.js.map +1 -1
  33. package/dist/harness-window.d.ts +5 -0
  34. package/dist/harness-window.d.ts.map +1 -0
  35. package/dist/harness-window.js +17 -0
  36. package/dist/harness-window.js.map +1 -0
  37. package/dist/index.d.ts +14 -7
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +9 -5
  40. package/dist/index.js.map +1 -1
  41. package/dist/internal.d.ts +5 -0
  42. package/dist/internal.d.ts.map +1 -0
  43. package/dist/internal.js +5 -0
  44. package/dist/internal.js.map +1 -0
  45. package/dist/matchers.d.ts +88 -46
  46. package/dist/matchers.d.ts.map +1 -1
  47. package/dist/matchers.js +178 -20
  48. package/dist/matchers.js.map +1 -1
  49. package/dist/pretty-format.d.ts +2 -0
  50. package/dist/pretty-format.d.ts.map +1 -0
  51. package/dist/pretty-format.js +2 -0
  52. package/dist/pretty-format.js.map +1 -0
  53. package/dist/pretty-widget.d.ts +5 -2
  54. package/dist/pretty-widget.d.ts.map +1 -1
  55. package/dist/pretty-widget.js +75 -57
  56. package/dist/pretty-widget.js.map +1 -1
  57. package/dist/production.d.ts +8 -0
  58. package/dist/production.d.ts.map +1 -0
  59. package/dist/production.js +34 -0
  60. package/dist/production.js.map +1 -0
  61. package/dist/queries.d.ts +98 -56
  62. package/dist/queries.d.ts.map +1 -1
  63. package/dist/queries.js +123 -83
  64. package/dist/queries.js.map +1 -1
  65. package/dist/query-helpers.d.ts +44 -0
  66. package/dist/query-helpers.d.ts.map +1 -0
  67. package/dist/query-helpers.js +57 -0
  68. package/dist/query-helpers.js.map +1 -0
  69. package/dist/render-children.d.ts +9 -0
  70. package/dist/render-children.d.ts.map +1 -0
  71. package/dist/render-children.js +11 -0
  72. package/dist/render-children.js.map +1 -0
  73. package/dist/render.d.ts +12 -1
  74. package/dist/render.d.ts.map +1 -1
  75. package/dist/render.js +52 -16
  76. package/dist/render.js.map +1 -1
  77. package/dist/role-helpers.d.ts +12 -3
  78. package/dist/role-helpers.d.ts.map +1 -1
  79. package/dist/role-helpers.js +15 -5
  80. package/dist/role-helpers.js.map +1 -1
  81. package/dist/role-naming.d.ts +5 -0
  82. package/dist/role-naming.d.ts.map +1 -0
  83. package/dist/role-naming.js +96 -0
  84. package/dist/role-naming.js.map +1 -0
  85. package/dist/screenshot.d.ts +12 -20
  86. package/dist/screenshot.d.ts.map +1 -1
  87. package/dist/screenshot.js +179 -93
  88. package/dist/screenshot.js.map +1 -1
  89. package/dist/timers.d.ts +9 -0
  90. package/dist/timers.d.ts.map +1 -0
  91. package/dist/timers.js +21 -0
  92. package/dist/timers.js.map +1 -0
  93. package/dist/traversal.d.ts +7 -1
  94. package/dist/traversal.d.ts.map +1 -1
  95. package/dist/traversal.js +40 -6
  96. package/dist/traversal.js.map +1 -1
  97. package/dist/types.d.ts +32 -15
  98. package/dist/types.d.ts.map +1 -1
  99. package/dist/types.js.map +1 -1
  100. package/dist/user-event/adjustment.d.ts +3 -0
  101. package/dist/user-event/adjustment.d.ts.map +1 -1
  102. package/dist/user-event/adjustment.js +25 -3
  103. package/dist/user-event/adjustment.js.map +1 -1
  104. package/dist/user-event/click.d.ts +44 -8
  105. package/dist/user-event/click.d.ts.map +1 -1
  106. package/dist/user-event/click.js +176 -44
  107. package/dist/user-event/click.js.map +1 -1
  108. package/dist/user-event/column-header-click.d.ts +4 -0
  109. package/dist/user-event/column-header-click.d.ts.map +1 -0
  110. package/dist/user-event/column-header-click.js +55 -0
  111. package/dist/user-event/column-header-click.js.map +1 -0
  112. package/dist/user-event/event-wrapper.d.ts.map +1 -1
  113. package/dist/user-event/event-wrapper.js +34 -20
  114. package/dist/user-event/event-wrapper.js.map +1 -1
  115. package/dist/user-event/index.d.ts +80 -13
  116. package/dist/user-event/index.d.ts.map +1 -1
  117. package/dist/user-event/index.js +44 -26
  118. package/dist/user-event/index.js.map +1 -1
  119. package/dist/user-event/indexed-children.d.ts +10 -0
  120. package/dist/user-event/indexed-children.d.ts.map +1 -0
  121. package/dist/user-event/indexed-children.js +50 -0
  122. package/dist/user-event/indexed-children.js.map +1 -0
  123. package/dist/user-event/keyboard.d.ts.map +1 -1
  124. package/dist/user-event/keyboard.js +115 -31
  125. package/dist/user-event/keyboard.js.map +1 -1
  126. package/dist/user-event/list-row-click.d.ts +4 -0
  127. package/dist/user-event/list-row-click.d.ts.map +1 -0
  128. package/dist/user-event/list-row-click.js +38 -0
  129. package/dist/user-event/list-row-click.js.map +1 -0
  130. package/dist/user-event/native-click.d.ts +6 -0
  131. package/dist/user-event/native-click.d.ts.map +1 -0
  132. package/dist/user-event/native-click.js +36 -0
  133. package/dist/user-event/native-click.js.map +1 -0
  134. package/dist/user-event/notebook-tab-click.d.ts +5 -0
  135. package/dist/user-event/notebook-tab-click.d.ts.map +1 -0
  136. package/dist/user-event/notebook-tab-click.js +39 -0
  137. package/dist/user-event/notebook-tab-click.js.map +1 -0
  138. package/dist/user-event/pointer.d.ts +1 -1
  139. package/dist/user-event/pointer.d.ts.map +1 -1
  140. package/dist/user-event/pointer.js +33 -9
  141. package/dist/user-event/pointer.js.map +1 -1
  142. package/dist/user-event/selection.d.ts +11 -8
  143. package/dist/user-event/selection.d.ts.map +1 -1
  144. package/dist/user-event/selection.js +49 -38
  145. package/dist/user-event/selection.js.map +1 -1
  146. package/dist/user-event/text.d.ts +12 -5
  147. package/dist/user-event/text.d.ts.map +1 -1
  148. package/dist/user-event/text.js +151 -46
  149. package/dist/user-event/text.js.map +1 -1
  150. package/dist/wait-for.d.ts.map +1 -1
  151. package/dist/wait-for.js +4 -3
  152. package/dist/wait-for.js.map +1 -1
  153. package/dist/widget-accessible-properties.d.ts +14 -26
  154. package/dist/widget-accessible-properties.d.ts.map +1 -1
  155. package/dist/widget-accessible-properties.js +135 -190
  156. package/dist/widget-accessible-properties.js.map +1 -1
  157. package/dist/widget-getters.d.ts +11 -0
  158. package/dist/widget-getters.d.ts.map +1 -0
  159. package/dist/widget-getters.js +46 -0
  160. package/dist/widget-getters.js.map +1 -0
  161. package/dist/window-state.d.ts +10 -0
  162. package/dist/window-state.d.ts.map +1 -0
  163. package/dist/window-state.js +41 -0
  164. package/dist/window-state.js.map +1 -0
  165. package/dist/within.d.ts +3 -2
  166. package/dist/within.d.ts.map +1 -1
  167. package/dist/within.js +3 -2
  168. package/dist/within.js.map +1 -1
  169. package/package.json +21 -8
  170. package/src/accessible-native.ts +333 -0
  171. package/src/act.ts +1 -1
  172. package/src/build-queries.ts +47 -41
  173. package/src/cleanup-registry.ts +1 -1
  174. package/src/config.ts +10 -1
  175. package/src/errors.ts +12 -1
  176. package/src/fire-event.ts +61 -8
  177. package/src/frame-sync.ts +30 -9
  178. package/src/harness-window.ts +23 -0
  179. package/src/index.ts +18 -11
  180. package/src/internal.ts +12 -0
  181. package/src/matchers.ts +457 -72
  182. package/src/pretty-format.ts +1 -0
  183. package/src/pretty-widget.ts +98 -70
  184. package/src/production.ts +51 -0
  185. package/src/queries.ts +127 -89
  186. package/src/query-helpers.ts +97 -0
  187. package/src/render-children.ts +25 -0
  188. package/src/render.tsx +77 -17
  189. package/src/role-helpers.ts +16 -5
  190. package/src/role-naming.ts +99 -0
  191. package/src/screenshot.ts +266 -104
  192. package/src/timers.ts +31 -0
  193. package/src/traversal.ts +66 -6
  194. package/src/types.ts +34 -17
  195. package/src/user-event/adjustment.ts +31 -3
  196. package/src/user-event/click.ts +248 -52
  197. package/src/user-event/column-header-click.ts +76 -0
  198. package/src/user-event/event-wrapper.ts +41 -23
  199. package/src/user-event/index.ts +130 -40
  200. package/src/user-event/indexed-children.ts +75 -0
  201. package/src/user-event/keyboard.ts +161 -43
  202. package/src/user-event/list-row-click.ts +54 -0
  203. package/src/user-event/native-click.ts +51 -0
  204. package/src/user-event/notebook-tab-click.ts +57 -0
  205. package/src/user-event/pointer.ts +48 -9
  206. package/src/user-event/selection.ts +67 -41
  207. package/src/user-event/text.ts +192 -46
  208. package/src/wait-for.ts +4 -4
  209. package/src/widget-accessible-properties.ts +183 -230
  210. package/src/widget-getters.ts +85 -0
  211. package/src/window-state.ts +70 -0
  212. package/src/within.ts +3 -2
package/src/render.tsx CHANGED
@@ -5,23 +5,30 @@ import {
5
5
  isRootElement,
6
6
  type ReconcilerRoot,
7
7
  setReconcilerErrorHandler,
8
+ settleAccessible,
8
9
  } from "@gtkx/react/internal";
9
10
  import { type ErrorInfo, type ReactNode, StrictMode } from "react";
10
11
  import type { RenderResult } from "./bound-queries.js";
11
- import type { QueryMap, RenderOptions, ScreenshotOptions, WindowSelector } from "./types.js";
12
+ import type { QueryMap, RenderOptions, ScreenshotOptions } from "./types.js";
12
13
  import { runInAct } from "./act.js";
13
14
  import { addToCleanupQueue, runCleanup } from "./cleanup-registry.js";
14
- import { scheduleAfterLayout } from "./frame-sync.js";
15
+ import { getConfig } from "./config.js";
16
+ import { scheduleWhenWindowReady } from "./frame-sync.js";
17
+ import { createHarnessWindow, presentHarnessWindow } from "./harness-window.js";
15
18
  import { logWidget, type PrettyWidgetOptions } from "./pretty-widget.js";
16
19
  import { logRoles } from "./role-helpers.js";
17
20
  import { clearScreen, setScreen } from "./screen.js";
18
- import { captureAndSaveScreenshot } from "./screenshot.js";
19
- import { type Container, TOPLEVELS, traverse } from "./traversal.js";
21
+ import { captureScreen } from "./screenshot.js";
22
+ import { type Container, roots, TOPLEVELS } from "./traversal.js";
20
23
  import { resetClipboard } from "./user-event/index.js";
24
+ import { findPresentedWindowFailure, findRenderedWindowFailure, mappedToplevels } from "./window-state.js";
21
25
  import { within } from "./within.js";
22
26
 
27
+ /** A mounted render tracked so cleanup can unmount it. */
23
28
  type ActiveRender = {
29
+ /** Root that rerenders drive and that cleanup tears the tree down through. */
24
30
  root: ReconcilerRoot;
31
+ /** Harness window created for the render, null when it renders into a container the caller supplied. */
25
32
  window: Gtk.Window | null;
26
33
  };
27
34
 
@@ -35,16 +42,34 @@ type ReconcilerErrorState = {
35
42
  isHandlerInstalled: boolean;
36
43
  };
37
44
 
45
+ type WindowFailureReporter = (window: Gtk.Window) => string | null;
46
+ type SettleAction = "render" | "rerender";
47
+
38
48
  const reconcilerErrors: ReconcilerErrorState = { lastError: null, isHandlerInstalled: false };
39
49
  const activeRenders: Set<ActiveRender> = new Set();
40
- const HARNESS_WINDOW_WIDTH = 800;
41
- const HARNESS_WINDOW_HEIGHT = 600;
42
50
 
43
- const flushLayout = (window: Gtk.Window | null): Promise<void> =>
44
- new Promise((resolve) => {
45
- scheduleAfterLayout(window, resolve);
51
+ const settleWindow = async (
52
+ window: Gtk.Window | null,
53
+ findFailure: WindowFailureReporter,
54
+ action: SettleAction,
55
+ ): Promise<void> => {
56
+ const timeout = getConfig().windowActivationTimeout;
57
+
58
+ await new Promise<void>((resolve) => {
59
+ scheduleWhenWindowReady(window, (target) => findFailure(target) === null, timeout, resolve);
46
60
  });
47
61
 
62
+ settleAccessible();
63
+ const failure = window === null ? null : findFailure(window);
64
+
65
+ if (failure !== null) {
66
+ throw new Error(
67
+ `${action} timed out after ${String(timeout)}ms waiting for the window it rendered into: ${failure}. ` +
68
+ "Platform state such as focus is only readable once that window is allocated and active.",
69
+ );
70
+ }
71
+ };
72
+
48
73
  const update = async (element: ReactNode, root: ReconcilerRoot): Promise<void> => {
49
74
  await runInAct(() => {
50
75
  root.update(element);
@@ -96,7 +121,7 @@ const resolveContainer = (container: RenderOptions["container"]): ResolvedContai
96
121
  return { containerInfo: container, window: null };
97
122
  }
98
123
 
99
- const window = new Gtk.Window({ defaultWidth: HARNESS_WINDOW_WIDTH, defaultHeight: HARNESS_WINDOW_HEIGHT });
124
+ const window = createHarnessWindow();
100
125
  window.setDecorated(false);
101
126
 
102
127
  return { containerInfo: window, window };
@@ -107,7 +132,7 @@ const firstToplevelWidget = (baseElement: Container): Gtk.Widget => {
107
132
  return baseElement;
108
133
  }
109
134
 
110
- const [first] = traverse(baseElement);
135
+ const [first] = roots(baseElement);
111
136
 
112
137
  if (first) {
113
138
  return first;
@@ -132,6 +157,31 @@ const resolveResultContainer = (
132
157
  return firstToplevelWidget(baseElement);
133
158
  };
134
159
 
160
+ const realizedWindow = (root: Gtk.Root | null): Gtk.Window | null =>
161
+ root instanceof Gtk.Window && root.getFrameClock() !== null ? root : null;
162
+
163
+ const settleTarget = (resolved: ResolvedContainer, container: RenderOptions["container"]): Gtk.Window | null => {
164
+ if (resolved.window) {
165
+ return realizedWindow(resolved.window);
166
+ }
167
+
168
+ if (container instanceof Gtk.Widget) {
169
+ return realizedWindow(container.getRoot());
170
+ }
171
+
172
+ return realizedWindow(mappedToplevels()[0] ?? null);
173
+ };
174
+
175
+ const settleRender = async (
176
+ resolved: ResolvedContainer,
177
+ container: RenderOptions["container"],
178
+ action: SettleAction,
179
+ ): Promise<void> => {
180
+ const isPresentedNow = action === "render" && resolved.window !== null;
181
+ const findFailure = isPresentedNow ? findPresentedWindowFailure : findRenderedWindowFailure;
182
+ await settleWindow(settleTarget(resolved, container), findFailure, action);
183
+ };
184
+
135
185
  const renderErrorHandlers = <Q extends QueryMap>(options: RenderOptions<Q> | undefined) => ({
136
186
  onUncaughtError: handleError,
137
187
  onCaughtError: (error: unknown, errorInfo: ErrorInfo): void => {
@@ -154,11 +204,22 @@ const applyEnableAnimations = (areAnimationsEnabled: boolean): void => {
154
204
  /**
155
205
  * Renders a React element into a GTK4 widget tree and returns queries
156
206
  * scoped to it along with controls for rerendering and unmounting. When no
157
- * container is supplied, a harness window is created and presented.
207
+ * container is supplied, a harness window is created and presented, and the editable it hands the
208
+ * focus to keeps its text unselected, with its caret at the end. The returned promise settles once
209
+ * the window the tree is shown in has been laid out and activation has arrived, so platform state
210
+ * such as focus is already readable when it resolves. A presented harness window is waited on until
211
+ * it is itself active; a window the caller or the tree owns is waited on until the application holds
212
+ * activation, since only a present can claim it. Rendering into a container that is not shown waits
213
+ * for nothing, and a window that never becomes readable within `windowActivationTimeout` throws an
214
+ * error naming the condition that failed rather than resolving with unreadable platform state. A
215
+ * tree mounted into a container that sits outside every toplevel, or inside a window that is not
216
+ * visible, is out of reach of a pointer and a keyboard, so every `userEvent` helper aimed at it
217
+ * rejects after `actionabilityTimeout` naming that condition, and `fireEvent` drives it instead.
158
218
  *
159
219
  * @param element The React element to render.
160
220
  * @param options Optional container, wrapper, custom queries, and other render settings.
161
221
  * @returns A render result with bound queries, debug helpers, and lifecycle controls.
222
+ * @throws When the window the tree is shown in is not laid out and activated in time.
162
223
  */
163
224
  const render = async <Q extends QueryMap = Record<never, never>>(
164
225
  element: ReactNode,
@@ -188,8 +249,8 @@ const render = async <Q extends QueryMap = Record<never, never>>(
188
249
  };
189
250
 
190
251
  await update(wrap(element), root);
191
- resolved.window?.present();
192
- await flushLayout(resolved.window);
252
+ presentHarnessWindow(resolved.window);
253
+ await settleRender(resolved, options?.container, "render");
193
254
  const container = resolveResultContainer(resolved, options?.container, baseElement);
194
255
 
195
256
  const result: RenderResult<Q> = {
@@ -201,7 +262,7 @@ const render = async <Q extends QueryMap = Record<never, never>>(
201
262
  },
202
263
  rerender: async (newElement: ReactNode) => {
203
264
  await update(wrap(newElement), root);
204
- await flushLayout(resolved.window);
265
+ await settleRender(resolved, options?.container, "rerender");
205
266
  },
206
267
  debug: (element: Container | Container[] = baseElement, debugOptions?: PrettyWidgetOptions) => {
207
268
  logWidget(element, debugOptions);
@@ -209,8 +270,7 @@ const render = async <Q extends QueryMap = Record<never, never>>(
209
270
  logRoles: () => {
210
271
  logRoles(baseElement);
211
272
  },
212
- screenshot: (selector?: WindowSelector, screenshotOptions?: ScreenshotOptions) =>
213
- captureAndSaveScreenshot(selector, screenshotOptions),
273
+ screenshot: (screenshotOptions?: ScreenshotOptions) => captureScreen(screenshotOptions),
214
274
  };
215
275
 
216
276
  setScreen(result);
@@ -1,7 +1,8 @@
1
1
  import * as Gtk from "@gtkx/gi/gtk";
2
2
  import { sortStringsBy } from "@gtkx/utils";
3
3
  import { type Container, traverse } from "./traversal.js";
4
- import { getWidgetAccessibleName } from "./widget-accessible-properties.js";
4
+ import { getWidgetAccessibleName, getWidgetLevel } from "./widget-accessible-properties.js";
5
+ import { getTypeTag } from "./widget-getters.js";
5
6
 
6
7
  const ROLE_NAMES_BY_VALUE = enumNamesByValue(Gtk.AccessibleRole);
7
8
 
@@ -47,10 +48,11 @@ const formatRoleList = (roles: Iterable<Gtk.AccessibleRole>): string => {
47
48
  };
48
49
 
49
50
  /**
50
- * Groups every widget in a container's tree by its accessible role name.
51
+ * Groups every mapped widget in a container's tree by its accessible role name. Widgets that are not
52
+ * mapped are left out.
51
53
  *
52
54
  * @param container The scope to traverse.
53
- * @returns A map from role name to the widgets that have that role.
55
+ * @returns A map from role name to the mapped widgets that have that role.
54
56
  */
55
57
  const getRoles = (container: Container): Map<string, Gtk.Widget[]> => {
56
58
  const roles: Map<string, Gtk.Widget[]> = new Map();
@@ -70,7 +72,7 @@ const getRoles = (container: Container): Map<string, Gtk.Widget[]> => {
70
72
  };
71
73
 
72
74
  const formatWidgetPreview = (widget: Gtk.Widget, name: string | null): string => {
73
- const tagName = widget.constructor.name;
75
+ const tagName = getTypeTag(widget);
74
76
  const roleAttr = formatRole(widget.getAccessibleRole());
75
77
  const nameDisplay = name ? `Name "${name}"` : 'Name ""';
76
78
 
@@ -80,6 +82,7 @@ const formatWidgetPreview = (widget: Gtk.Widget, name: string | null): string =>
80
82
  /**
81
83
  * Formats the accessible roles in a container's tree as a readable string,
82
84
  * listing each role together with its widgets and their accessible names.
85
+ * Widgets that are not mapped are left out.
83
86
  *
84
87
  * @param container The scope to inspect.
85
88
  */
@@ -116,4 +119,12 @@ const logRoles = (container: Container): void => {
116
119
  console.log(prettyRoles(container));
117
120
  };
118
121
 
119
- export { formatRole, formatRoleList, getRoles, prettyRoles, logRoles };
122
+ /**
123
+ * Returns the heading or hierarchy level GTK reports for a widget, or undefined when it declares
124
+ * none.
125
+ *
126
+ * @param widget The widget to read the level from.
127
+ */
128
+ const computeHeadingLevel = (widget: Gtk.Widget): number | undefined => getWidgetLevel(widget) ?? undefined;
129
+
130
+ export { computeHeadingLevel, formatRole, formatRoleList, getRoles, prettyRoles, logRoles };
@@ -0,0 +1,99 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+
3
+ const FROM_AUTHOR = 1;
4
+ const FROM_CONTENT = 2;
5
+ const PROHIBITED = 4;
6
+
7
+ const NAMING: Partial<Record<Gtk.AccessibleRole, number>> = {
8
+ [Gtk.AccessibleRole.ALERT]: FROM_AUTHOR,
9
+ [Gtk.AccessibleRole.ALERT_DIALOG]: FROM_AUTHOR,
10
+ [Gtk.AccessibleRole.APPLICATION]: FROM_AUTHOR,
11
+ [Gtk.AccessibleRole.ARTICLE]: FROM_AUTHOR,
12
+ [Gtk.AccessibleRole.BANNER]: FROM_AUTHOR,
13
+ [Gtk.AccessibleRole.BLOCK_QUOTE]: FROM_AUTHOR,
14
+ [Gtk.AccessibleRole.BUTTON]: FROM_AUTHOR | FROM_CONTENT,
15
+ [Gtk.AccessibleRole.CAPTION]: PROHIBITED,
16
+ [Gtk.AccessibleRole.CELL]: FROM_AUTHOR | FROM_CONTENT,
17
+ [Gtk.AccessibleRole.CHECKBOX]: FROM_AUTHOR | FROM_CONTENT,
18
+ [Gtk.AccessibleRole.COLUMN_HEADER]: FROM_AUTHOR | FROM_CONTENT,
19
+ [Gtk.AccessibleRole.COMBO_BOX]: FROM_AUTHOR,
20
+ [Gtk.AccessibleRole.COMMAND]: PROHIBITED,
21
+ [Gtk.AccessibleRole.COMMENT]: FROM_AUTHOR | FROM_CONTENT,
22
+ [Gtk.AccessibleRole.COMPOSITE]: PROHIBITED,
23
+ [Gtk.AccessibleRole.DIALOG]: FROM_AUTHOR,
24
+ [Gtk.AccessibleRole.DOCUMENT]: FROM_AUTHOR,
25
+ [Gtk.AccessibleRole.FEED]: FROM_AUTHOR,
26
+ [Gtk.AccessibleRole.FORM]: FROM_AUTHOR,
27
+ [Gtk.AccessibleRole.GENERIC]: PROHIBITED,
28
+ [Gtk.AccessibleRole.GRID]: FROM_AUTHOR,
29
+ [Gtk.AccessibleRole.GRID_CELL]: FROM_AUTHOR | FROM_CONTENT,
30
+ [Gtk.AccessibleRole.GROUP]: FROM_AUTHOR,
31
+ [Gtk.AccessibleRole.HEADING]: FROM_AUTHOR | FROM_CONTENT,
32
+ [Gtk.AccessibleRole.IMG]: FROM_AUTHOR,
33
+ [Gtk.AccessibleRole.INPUT]: PROHIBITED,
34
+ [Gtk.AccessibleRole.LABEL]: FROM_AUTHOR | FROM_CONTENT,
35
+ [Gtk.AccessibleRole.LANDMARK]: PROHIBITED,
36
+ [Gtk.AccessibleRole.LEGEND]: PROHIBITED,
37
+ [Gtk.AccessibleRole.LINK]: FROM_AUTHOR | FROM_CONTENT,
38
+ [Gtk.AccessibleRole.LIST]: FROM_AUTHOR,
39
+ [Gtk.AccessibleRole.LIST_BOX]: FROM_AUTHOR,
40
+ [Gtk.AccessibleRole.LIST_ITEM]: FROM_AUTHOR,
41
+ [Gtk.AccessibleRole.LOG]: FROM_AUTHOR,
42
+ [Gtk.AccessibleRole.MAIN]: FROM_AUTHOR,
43
+ [Gtk.AccessibleRole.MARQUEE]: FROM_AUTHOR,
44
+ [Gtk.AccessibleRole.MATH]: FROM_AUTHOR,
45
+ [Gtk.AccessibleRole.METER]: FROM_AUTHOR,
46
+ [Gtk.AccessibleRole.MENU]: FROM_AUTHOR,
47
+ [Gtk.AccessibleRole.MENU_BAR]: FROM_AUTHOR,
48
+ [Gtk.AccessibleRole.MENU_ITEM]: FROM_AUTHOR | FROM_CONTENT,
49
+ [Gtk.AccessibleRole.MENU_ITEM_CHECKBOX]: FROM_AUTHOR | FROM_CONTENT,
50
+ [Gtk.AccessibleRole.MENU_ITEM_RADIO]: FROM_AUTHOR | FROM_CONTENT,
51
+ [Gtk.AccessibleRole.NAVIGATION]: FROM_AUTHOR,
52
+ [Gtk.AccessibleRole.NONE]: PROHIBITED,
53
+ [Gtk.AccessibleRole.NOTE]: FROM_AUTHOR,
54
+ [Gtk.AccessibleRole.OPTION]: FROM_AUTHOR | FROM_CONTENT,
55
+ [Gtk.AccessibleRole.PARAGRAPH]: PROHIBITED,
56
+ [Gtk.AccessibleRole.PRESENTATION]: PROHIBITED,
57
+ [Gtk.AccessibleRole.PROGRESS_BAR]: FROM_AUTHOR,
58
+ [Gtk.AccessibleRole.RADIO]: FROM_AUTHOR | FROM_CONTENT,
59
+ [Gtk.AccessibleRole.RADIO_GROUP]: FROM_AUTHOR,
60
+ [Gtk.AccessibleRole.RANGE]: PROHIBITED,
61
+ [Gtk.AccessibleRole.REGION]: FROM_AUTHOR,
62
+ [Gtk.AccessibleRole.ROW]: FROM_AUTHOR | FROM_CONTENT,
63
+ [Gtk.AccessibleRole.ROW_GROUP]: FROM_AUTHOR,
64
+ [Gtk.AccessibleRole.ROW_HEADER]: FROM_AUTHOR | FROM_CONTENT,
65
+ [Gtk.AccessibleRole.SCROLLBAR]: FROM_AUTHOR,
66
+ [Gtk.AccessibleRole.SEARCH]: FROM_AUTHOR,
67
+ [Gtk.AccessibleRole.SEARCH_BOX]: FROM_AUTHOR,
68
+ [Gtk.AccessibleRole.SECTION]: PROHIBITED,
69
+ [Gtk.AccessibleRole.SECTION_HEAD]: PROHIBITED,
70
+ [Gtk.AccessibleRole.SELECT]: PROHIBITED,
71
+ [Gtk.AccessibleRole.SEPARATOR]: FROM_AUTHOR,
72
+ [Gtk.AccessibleRole.SLIDER]: FROM_AUTHOR,
73
+ [Gtk.AccessibleRole.SPIN_BUTTON]: FROM_AUTHOR,
74
+ [Gtk.AccessibleRole.STATUS]: FROM_AUTHOR,
75
+ [Gtk.AccessibleRole.STRUCTURE]: PROHIBITED,
76
+ [Gtk.AccessibleRole.SWITCH]: FROM_AUTHOR | FROM_CONTENT,
77
+ [Gtk.AccessibleRole.TAB]: FROM_AUTHOR | FROM_CONTENT,
78
+ [Gtk.AccessibleRole.TABLE]: FROM_AUTHOR,
79
+ [Gtk.AccessibleRole.TAB_LIST]: FROM_AUTHOR,
80
+ [Gtk.AccessibleRole.TAB_PANEL]: FROM_AUTHOR,
81
+ [Gtk.AccessibleRole.TERMINAL]: FROM_AUTHOR,
82
+ [Gtk.AccessibleRole.TEXT_BOX]: FROM_AUTHOR,
83
+ [Gtk.AccessibleRole.TIME]: FROM_AUTHOR,
84
+ [Gtk.AccessibleRole.TIMER]: FROM_AUTHOR,
85
+ [Gtk.AccessibleRole.TOGGLE_BUTTON]: FROM_AUTHOR,
86
+ [Gtk.AccessibleRole.TOOLBAR]: FROM_AUTHOR,
87
+ [Gtk.AccessibleRole.TOOLTIP]: FROM_AUTHOR | FROM_CONTENT,
88
+ [Gtk.AccessibleRole.TREE]: FROM_AUTHOR,
89
+ [Gtk.AccessibleRole.TREE_GRID]: FROM_AUTHOR,
90
+ [Gtk.AccessibleRole.TREE_ITEM]: FROM_AUTHOR | FROM_CONTENT,
91
+ [Gtk.AccessibleRole.WIDGET]: FROM_AUTHOR | FROM_CONTENT,
92
+ [Gtk.AccessibleRole.WINDOW]: FROM_AUTHOR,
93
+ };
94
+
95
+ const namingFor = (role: Gtk.AccessibleRole): number => NAMING[role] ?? 0;
96
+ const isNameProhibited = (role: Gtk.AccessibleRole): boolean => (namingFor(role) & PROHIBITED) !== 0;
97
+ const isNameFromAuthor = (role: Gtk.AccessibleRole): boolean => (namingFor(role) & FROM_AUTHOR) !== 0;
98
+
99
+ export { isNameFromAuthor, isNameProhibited };