@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.
- package/README.md +5 -5
- package/dist/accessible-native.d.ts +16 -0
- package/dist/accessible-native.d.ts.map +1 -0
- package/dist/accessible-native.js +206 -0
- package/dist/accessible-native.js.map +1 -0
- package/dist/act.d.ts +1 -3
- package/dist/act.d.ts.map +1 -1
- package/dist/act.js +1 -1
- package/dist/act.js.map +1 -1
- package/dist/build-queries.d.ts +27 -10
- package/dist/build-queries.d.ts.map +1 -1
- package/dist/build-queries.js +22 -24
- package/dist/build-queries.js.map +1 -1
- package/dist/cleanup-registry.d.ts +1 -1
- package/dist/cleanup-registry.d.ts.map +1 -1
- package/dist/cleanup-registry.js.map +1 -1
- package/dist/config.d.ts +8 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +10 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -1
- package/dist/errors.js.map +1 -1
- package/dist/fire-event.d.ts +35 -6
- package/dist/fire-event.d.ts.map +1 -1
- package/dist/fire-event.js +23 -7
- package/dist/fire-event.js.map +1 -1
- package/dist/frame-sync.d.ts +3 -2
- package/dist/frame-sync.d.ts.map +1 -1
- package/dist/frame-sync.js +19 -9
- package/dist/frame-sync.js.map +1 -1
- package/dist/harness-window.d.ts +5 -0
- package/dist/harness-window.d.ts.map +1 -0
- package/dist/harness-window.js +17 -0
- package/dist/harness-window.js.map +1 -0
- package/dist/index.d.ts +14 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +5 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +5 -0
- package/dist/internal.js.map +1 -0
- package/dist/matchers.d.ts +88 -46
- package/dist/matchers.d.ts.map +1 -1
- package/dist/matchers.js +178 -20
- package/dist/matchers.js.map +1 -1
- package/dist/pretty-format.d.ts +2 -0
- package/dist/pretty-format.d.ts.map +1 -0
- package/dist/pretty-format.js +2 -0
- package/dist/pretty-format.js.map +1 -0
- package/dist/pretty-widget.d.ts +5 -2
- package/dist/pretty-widget.d.ts.map +1 -1
- package/dist/pretty-widget.js +75 -57
- package/dist/pretty-widget.js.map +1 -1
- package/dist/production.d.ts +8 -0
- package/dist/production.d.ts.map +1 -0
- package/dist/production.js +34 -0
- package/dist/production.js.map +1 -0
- package/dist/queries.d.ts +98 -56
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +123 -83
- package/dist/queries.js.map +1 -1
- package/dist/query-helpers.d.ts +44 -0
- package/dist/query-helpers.d.ts.map +1 -0
- package/dist/query-helpers.js +57 -0
- package/dist/query-helpers.js.map +1 -0
- package/dist/render-children.d.ts +9 -0
- package/dist/render-children.d.ts.map +1 -0
- package/dist/render-children.js +11 -0
- package/dist/render-children.js.map +1 -0
- package/dist/render.d.ts +12 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +52 -16
- package/dist/render.js.map +1 -1
- package/dist/role-helpers.d.ts +12 -3
- package/dist/role-helpers.d.ts.map +1 -1
- package/dist/role-helpers.js +15 -5
- package/dist/role-helpers.js.map +1 -1
- package/dist/role-naming.d.ts +5 -0
- package/dist/role-naming.d.ts.map +1 -0
- package/dist/role-naming.js +96 -0
- package/dist/role-naming.js.map +1 -0
- package/dist/screenshot.d.ts +12 -20
- package/dist/screenshot.d.ts.map +1 -1
- package/dist/screenshot.js +179 -93
- package/dist/screenshot.js.map +1 -1
- package/dist/timers.d.ts +9 -0
- package/dist/timers.d.ts.map +1 -0
- package/dist/timers.js +21 -0
- package/dist/timers.js.map +1 -0
- package/dist/traversal.d.ts +7 -1
- package/dist/traversal.d.ts.map +1 -1
- package/dist/traversal.js +40 -6
- package/dist/traversal.js.map +1 -1
- package/dist/types.d.ts +32 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/user-event/adjustment.d.ts +3 -0
- package/dist/user-event/adjustment.d.ts.map +1 -1
- package/dist/user-event/adjustment.js +25 -3
- package/dist/user-event/adjustment.js.map +1 -1
- package/dist/user-event/click.d.ts +44 -8
- package/dist/user-event/click.d.ts.map +1 -1
- package/dist/user-event/click.js +176 -44
- package/dist/user-event/click.js.map +1 -1
- package/dist/user-event/column-header-click.d.ts +4 -0
- package/dist/user-event/column-header-click.d.ts.map +1 -0
- package/dist/user-event/column-header-click.js +55 -0
- package/dist/user-event/column-header-click.js.map +1 -0
- package/dist/user-event/event-wrapper.d.ts.map +1 -1
- package/dist/user-event/event-wrapper.js +34 -20
- package/dist/user-event/event-wrapper.js.map +1 -1
- package/dist/user-event/index.d.ts +80 -13
- package/dist/user-event/index.d.ts.map +1 -1
- package/dist/user-event/index.js +44 -26
- package/dist/user-event/index.js.map +1 -1
- package/dist/user-event/indexed-children.d.ts +10 -0
- package/dist/user-event/indexed-children.d.ts.map +1 -0
- package/dist/user-event/indexed-children.js +50 -0
- package/dist/user-event/indexed-children.js.map +1 -0
- package/dist/user-event/keyboard.d.ts.map +1 -1
- package/dist/user-event/keyboard.js +115 -31
- package/dist/user-event/keyboard.js.map +1 -1
- package/dist/user-event/list-row-click.d.ts +4 -0
- package/dist/user-event/list-row-click.d.ts.map +1 -0
- package/dist/user-event/list-row-click.js +38 -0
- package/dist/user-event/list-row-click.js.map +1 -0
- package/dist/user-event/native-click.d.ts +6 -0
- package/dist/user-event/native-click.d.ts.map +1 -0
- package/dist/user-event/native-click.js +36 -0
- package/dist/user-event/native-click.js.map +1 -0
- package/dist/user-event/notebook-tab-click.d.ts +5 -0
- package/dist/user-event/notebook-tab-click.d.ts.map +1 -0
- package/dist/user-event/notebook-tab-click.js +39 -0
- package/dist/user-event/notebook-tab-click.js.map +1 -0
- package/dist/user-event/pointer.d.ts +1 -1
- package/dist/user-event/pointer.d.ts.map +1 -1
- package/dist/user-event/pointer.js +33 -9
- package/dist/user-event/pointer.js.map +1 -1
- package/dist/user-event/selection.d.ts +11 -8
- package/dist/user-event/selection.d.ts.map +1 -1
- package/dist/user-event/selection.js +49 -38
- package/dist/user-event/selection.js.map +1 -1
- package/dist/user-event/text.d.ts +12 -5
- package/dist/user-event/text.d.ts.map +1 -1
- package/dist/user-event/text.js +151 -46
- package/dist/user-event/text.js.map +1 -1
- package/dist/wait-for.d.ts.map +1 -1
- package/dist/wait-for.js +4 -3
- package/dist/wait-for.js.map +1 -1
- package/dist/widget-accessible-properties.d.ts +14 -26
- package/dist/widget-accessible-properties.d.ts.map +1 -1
- package/dist/widget-accessible-properties.js +135 -190
- package/dist/widget-accessible-properties.js.map +1 -1
- package/dist/widget-getters.d.ts +11 -0
- package/dist/widget-getters.d.ts.map +1 -0
- package/dist/widget-getters.js +46 -0
- package/dist/widget-getters.js.map +1 -0
- package/dist/window-state.d.ts +10 -0
- package/dist/window-state.d.ts.map +1 -0
- package/dist/window-state.js +41 -0
- package/dist/window-state.js.map +1 -0
- package/dist/within.d.ts +3 -2
- package/dist/within.d.ts.map +1 -1
- package/dist/within.js +3 -2
- package/dist/within.js.map +1 -1
- package/package.json +21 -8
- package/src/accessible-native.ts +333 -0
- package/src/act.ts +1 -1
- package/src/build-queries.ts +47 -41
- package/src/cleanup-registry.ts +1 -1
- package/src/config.ts +10 -1
- package/src/errors.ts +12 -1
- package/src/fire-event.ts +61 -8
- package/src/frame-sync.ts +30 -9
- package/src/harness-window.ts +23 -0
- package/src/index.ts +18 -11
- package/src/internal.ts +12 -0
- package/src/matchers.ts +457 -72
- package/src/pretty-format.ts +1 -0
- package/src/pretty-widget.ts +98 -70
- package/src/production.ts +51 -0
- package/src/queries.ts +127 -89
- package/src/query-helpers.ts +97 -0
- package/src/render-children.ts +25 -0
- package/src/render.tsx +77 -17
- package/src/role-helpers.ts +16 -5
- package/src/role-naming.ts +99 -0
- package/src/screenshot.ts +266 -104
- package/src/timers.ts +31 -0
- package/src/traversal.ts +66 -6
- package/src/types.ts +34 -17
- package/src/user-event/adjustment.ts +31 -3
- package/src/user-event/click.ts +248 -52
- package/src/user-event/column-header-click.ts +76 -0
- package/src/user-event/event-wrapper.ts +41 -23
- package/src/user-event/index.ts +130 -40
- package/src/user-event/indexed-children.ts +75 -0
- package/src/user-event/keyboard.ts +161 -43
- package/src/user-event/list-row-click.ts +54 -0
- package/src/user-event/native-click.ts +51 -0
- package/src/user-event/notebook-tab-click.ts +57 -0
- package/src/user-event/pointer.ts +48 -9
- package/src/user-event/selection.ts +67 -41
- package/src/user-event/text.ts +192 -46
- package/src/wait-for.ts +4 -4
- package/src/widget-accessible-properties.ts +183 -230
- package/src/widget-getters.ts +85 -0
- package/src/window-state.ts +70 -0
- 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
|
|
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 {
|
|
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 {
|
|
19
|
-
import { type Container,
|
|
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
|
|
44
|
-
|
|
45
|
-
|
|
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 =
|
|
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] =
|
|
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
|
|
192
|
-
await
|
|
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
|
|
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: (
|
|
213
|
-
captureAndSaveScreenshot(selector, screenshotOptions),
|
|
273
|
+
screenshot: (screenshotOptions?: ScreenshotOptions) => captureScreen(screenshotOptions),
|
|
214
274
|
};
|
|
215
275
|
|
|
216
276
|
setScreen(result);
|
package/src/role-helpers.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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 };
|