@gtkx/testing 0.21.0 → 1.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/README.md +137 -34
  2. package/dist/act.d.ts +19 -0
  3. package/dist/act.d.ts.map +1 -0
  4. package/dist/act.js +56 -0
  5. package/dist/act.js.map +1 -0
  6. package/dist/bound-queries.d.ts +33 -0
  7. package/dist/bound-queries.d.ts.map +1 -0
  8. package/dist/bound-queries.js +2 -0
  9. package/dist/bound-queries.js.map +1 -0
  10. package/dist/build-queries.d.ts +16 -0
  11. package/dist/build-queries.d.ts.map +1 -0
  12. package/dist/build-queries.js +115 -0
  13. package/dist/build-queries.js.map +1 -0
  14. package/dist/cleanup-registry.d.ts +5 -0
  15. package/dist/cleanup-registry.d.ts.map +1 -0
  16. package/dist/cleanup-registry.js +21 -0
  17. package/dist/cleanup-registry.js.map +1 -0
  18. package/dist/config.d.ts +20 -52
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +17 -46
  21. package/dist/config.js.map +1 -1
  22. package/dist/editable.d.ts +8 -0
  23. package/dist/editable.d.ts.map +1 -0
  24. package/dist/editable.js +26 -0
  25. package/dist/editable.js.map +1 -0
  26. package/dist/errors.d.ts +30 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +135 -0
  29. package/dist/errors.js.map +1 -0
  30. package/dist/fire-event.d.ts +8 -25
  31. package/dist/fire-event.d.ts.map +1 -1
  32. package/dist/fire-event.js +11 -30
  33. package/dist/fire-event.js.map +1 -1
  34. package/dist/frame-sync.d.ts +4 -0
  35. package/dist/frame-sync.d.ts.map +1 -0
  36. package/dist/frame-sync.js +37 -0
  37. package/dist/frame-sync.js.map +1 -0
  38. package/dist/index.d.ts +17 -12
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +11 -7
  41. package/dist/index.js.map +1 -1
  42. package/dist/matchers.d.ts +59 -0
  43. package/dist/matchers.d.ts.map +1 -0
  44. package/dist/matchers.js +117 -0
  45. package/dist/matchers.js.map +1 -0
  46. package/dist/pretty-widget.d.ts +24 -26
  47. package/dist/pretty-widget.d.ts.map +1 -1
  48. package/dist/pretty-widget.js +111 -117
  49. package/dist/pretty-widget.js.map +1 -1
  50. package/dist/queries.d.ts +190 -180
  51. package/dist/queries.d.ts.map +1 -1
  52. package/dist/queries.js +291 -320
  53. package/dist/queries.js.map +1 -1
  54. package/dist/register-test-hooks.d.ts +2 -0
  55. package/dist/register-test-hooks.d.ts.map +1 -0
  56. package/dist/register-test-hooks.js +16 -0
  57. package/dist/register-test-hooks.js.map +1 -0
  58. package/dist/render-hook.d.ts +15 -35
  59. package/dist/render-hook.d.ts.map +1 -1
  60. package/dist/render-hook.js +9 -45
  61. package/dist/render-hook.js.map +1 -1
  62. package/dist/render.d.ts +13 -42
  63. package/dist/render.d.ts.map +1 -1
  64. package/dist/render.js +138 -121
  65. package/dist/render.js.map +1 -1
  66. package/dist/role-helpers.d.ts +19 -53
  67. package/dist/role-helpers.d.ts.map +1 -1
  68. package/dist/role-helpers.js +48 -63
  69. package/dist/role-helpers.js.map +1 -1
  70. package/dist/screen.d.ts +7 -63
  71. package/dist/screen.d.ts.map +1 -1
  72. package/dist/screen.js +24 -110
  73. package/dist/screen.js.map +1 -1
  74. package/dist/screenshot.d.ts +21 -23
  75. package/dist/screenshot.d.ts.map +1 -1
  76. package/dist/screenshot.js +98 -50
  77. package/dist/screenshot.js.map +1 -1
  78. package/dist/suggestions.d.ts +27 -0
  79. package/dist/suggestions.d.ts.map +1 -0
  80. package/dist/suggestions.js +61 -0
  81. package/dist/suggestions.js.map +1 -0
  82. package/dist/traversal.d.ts +12 -10
  83. package/dist/traversal.d.ts.map +1 -1
  84. package/dist/traversal.js +36 -15
  85. package/dist/traversal.js.map +1 -1
  86. package/dist/types.d.ts +115 -169
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js.map +1 -1
  89. package/dist/user-event/adjustment.d.ts +10 -0
  90. package/dist/user-event/adjustment.d.ts.map +1 -0
  91. package/dist/user-event/adjustment.js +35 -0
  92. package/dist/user-event/adjustment.js.map +1 -0
  93. package/dist/user-event/click.d.ts +8 -0
  94. package/dist/user-event/click.d.ts.map +1 -0
  95. package/dist/user-event/click.js +73 -0
  96. package/dist/user-event/click.js.map +1 -0
  97. package/dist/user-event/controller.d.ts +8 -0
  98. package/dist/user-event/controller.d.ts.map +1 -0
  99. package/dist/user-event/controller.js +31 -0
  100. package/dist/user-event/controller.js.map +1 -0
  101. package/dist/user-event/dispatch.d.ts +7 -0
  102. package/dist/user-event/dispatch.d.ts.map +1 -0
  103. package/dist/user-event/dispatch.js +11 -0
  104. package/dist/user-event/dispatch.js.map +1 -0
  105. package/dist/user-event/event-wrapper.d.ts +4 -0
  106. package/dist/user-event/event-wrapper.d.ts.map +1 -0
  107. package/dist/user-event/event-wrapper.js +59 -0
  108. package/dist/user-event/event-wrapper.js.map +1 -0
  109. package/dist/user-event/gesture.d.ts +35 -0
  110. package/dist/user-event/gesture.d.ts.map +1 -0
  111. package/dist/user-event/gesture.js +138 -0
  112. package/dist/user-event/gesture.js.map +1 -0
  113. package/dist/user-event/index.d.ts +51 -0
  114. package/dist/user-event/index.d.ts.map +1 -0
  115. package/dist/user-event/index.js +42 -0
  116. package/dist/user-event/index.js.map +1 -0
  117. package/dist/user-event/keyboard.d.ts +10 -0
  118. package/dist/user-event/keyboard.d.ts.map +1 -0
  119. package/dist/user-event/keyboard.js +204 -0
  120. package/dist/user-event/keyboard.js.map +1 -0
  121. package/dist/user-event/pointer.d.ts +10 -0
  122. package/dist/user-event/pointer.d.ts.map +1 -0
  123. package/dist/user-event/pointer.js +30 -0
  124. package/dist/user-event/pointer.js.map +1 -0
  125. package/dist/user-event/selection.d.ts +5 -0
  126. package/dist/user-event/selection.d.ts.map +1 -0
  127. package/dist/user-event/selection.js +105 -0
  128. package/dist/user-event/selection.js.map +1 -0
  129. package/dist/user-event/state.d.ts +7 -0
  130. package/dist/user-event/state.d.ts.map +1 -0
  131. package/dist/user-event/state.js +3 -0
  132. package/dist/user-event/state.js.map +1 -0
  133. package/dist/user-event/text.d.ts +18 -0
  134. package/dist/user-event/text.d.ts.map +1 -0
  135. package/dist/user-event/text.js +113 -0
  136. package/dist/user-event/text.js.map +1 -0
  137. package/dist/wait-for.d.ts +16 -36
  138. package/dist/wait-for.d.ts.map +1 -1
  139. package/dist/wait-for.js +74 -70
  140. package/dist/wait-for.js.map +1 -1
  141. package/dist/widget-accessible-properties.d.ts +34 -0
  142. package/dist/widget-accessible-properties.d.ts.map +1 -0
  143. package/dist/widget-accessible-properties.js +260 -0
  144. package/dist/widget-accessible-properties.js.map +1 -0
  145. package/dist/within.d.ts +10 -26
  146. package/dist/within.d.ts.map +1 -1
  147. package/dist/within.js +16 -25
  148. package/dist/within.js.map +1 -1
  149. package/package.json +23 -12
  150. package/src/act.ts +77 -0
  151. package/src/bound-queries.ts +37 -0
  152. package/src/build-queries.ts +226 -0
  153. package/src/cleanup-registry.ts +27 -0
  154. package/src/config.ts +35 -62
  155. package/src/editable.ts +37 -0
  156. package/src/errors.ts +191 -0
  157. package/src/fire-event.ts +13 -38
  158. package/src/frame-sync.ts +51 -0
  159. package/src/index.ts +58 -15
  160. package/src/matchers.ts +251 -0
  161. package/src/pretty-widget.ts +163 -130
  162. package/src/queries.ts +485 -396
  163. package/src/register-test-hooks.ts +19 -0
  164. package/src/render-hook.tsx +38 -45
  165. package/src/render.tsx +192 -155
  166. package/src/role-helpers.ts +65 -72
  167. package/src/screen.ts +26 -114
  168. package/src/screenshot.ts +128 -56
  169. package/src/suggestions.ts +106 -0
  170. package/src/traversal.ts +56 -22
  171. package/src/types.ts +144 -172
  172. package/src/user-event/adjustment.ts +62 -0
  173. package/src/user-event/click.ts +99 -0
  174. package/src/user-event/controller.ts +58 -0
  175. package/src/user-event/dispatch.ts +25 -0
  176. package/src/user-event/event-wrapper.ts +80 -0
  177. package/src/user-event/gesture.ts +239 -0
  178. package/src/user-event/index.ts +81 -0
  179. package/src/user-event/keyboard.ts +290 -0
  180. package/src/user-event/pointer.ts +46 -0
  181. package/src/user-event/selection.ts +159 -0
  182. package/src/user-event/state.ts +8 -0
  183. package/src/user-event/text.ts +172 -0
  184. package/src/wait-for.ts +117 -78
  185. package/src/widget-accessible-properties.ts +388 -0
  186. package/src/within.ts +29 -27
  187. package/dist/bind-queries.d.ts +0 -14
  188. package/dist/bind-queries.d.ts.map +0 -1
  189. package/dist/bind-queries.js +0 -29
  190. package/dist/bind-queries.js.map +0 -1
  191. package/dist/error-builder.d.ts +0 -28
  192. package/dist/error-builder.d.ts.map +0 -1
  193. package/dist/error-builder.js +0 -81
  194. package/dist/error-builder.js.map +0 -1
  195. package/dist/timing.d.ts +0 -18
  196. package/dist/timing.d.ts.map +0 -1
  197. package/dist/timing.js +0 -18
  198. package/dist/timing.js.map +0 -1
  199. package/dist/user-event.d.ts +0 -138
  200. package/dist/user-event.d.ts.map +0 -1
  201. package/dist/user-event.js +0 -411
  202. package/dist/user-event.js.map +0 -1
  203. package/dist/widget-text.d.ts +0 -69
  204. package/dist/widget-text.d.ts.map +0 -1
  205. package/dist/widget-text.js +0 -177
  206. package/dist/widget-text.js.map +0 -1
  207. package/dist/widget.d.ts +0 -3
  208. package/dist/widget.d.ts.map +0 -1
  209. package/dist/widget.js +0 -13
  210. package/dist/widget.js.map +0 -1
  211. package/src/bind-queries.ts +0 -52
  212. package/src/error-builder.ts +0 -102
  213. package/src/timing.ts +0 -17
  214. package/src/user-event.ts +0 -492
  215. package/src/widget-text.ts +0 -202
  216. package/src/widget.ts +0 -15
@@ -1,44 +1,24 @@
1
- import type * as Gtk from "@gtkx/ffi/gtk";
1
+ import type * as Gtk from "@gtkx/gi/gtk";
2
2
  import type { WaitForOptions } from "./types.js";
3
+ type RemovalTarget = Gtk.Widget | Gtk.Widget[] | null;
4
+ type ElementOrCallback = Gtk.Widget | Gtk.Widget[] | (() => RemovalTarget);
3
5
  /**
4
- * Waits for a callback to succeed.
6
+ * Repeatedly invokes a callback until it succeeds without throwing or the
7
+ * timeout elapses, retrying on each rejection at a fixed interval.
5
8
  *
6
- * Repeatedly calls the callback until it returns without throwing,
7
- * or until the timeout is reached.
8
- *
9
- * @param callback - Function to execute repeatedly
10
- * @param options - Timeout and interval configuration
11
- * @returns Promise resolving to the callback's return value
12
- *
13
- * @example
14
- * ```tsx
15
- * import { waitFor } from "@gtkx/testing";
16
- *
17
- * await waitFor(() => {
18
- * expect(counter.value).toBe(5);
19
- * }, { timeout: 2000 });
20
- * ```
9
+ * @param callback The assertion or query to retry; its resolved value is returned.
10
+ * @param options Optional timeout, interval, and timeout error customization.
11
+ * @returns The callback's result once it succeeds.
21
12
  */
22
- export declare const waitFor: <T>(callback: () => T | Promise<T>, options?: WaitForOptions) => Promise<T>;
23
- /** @internal */
24
- type ElementOrCallback = Gtk.Widget | (() => Gtk.Widget | null);
13
+ declare const waitFor: <T>(callback: () => T | Promise<T>, options?: WaitForOptions) => Promise<T>;
25
14
  /**
26
- * Waits for an element to be removed from the widget tree.
27
- *
28
- * Polls until the element no longer has a parent or no longer exists.
29
- *
30
- * @param elementOrCallback - Element or function returning element to watch
31
- * @param options - Timeout and interval configuration
32
- *
33
- * @example
34
- * ```tsx
35
- * import { waitForElementToBeRemoved } from "@gtkx/testing";
15
+ * Waits until the given widget or widgets are detached from the tree. Rejects
16
+ * immediately if the target is already absent when called.
36
17
  *
37
- * const loader = await screen.findByRole(Gtk.AccessibleRole.PROGRESS_BAR);
38
- * await waitForElementToBeRemoved(loader);
39
- * // Loader is now gone
40
- * ```
18
+ * @param elementOrCallback The widget, array of widgets, or a function
19
+ * returning them to observe for removal.
20
+ * @param options Optional timeout and interval settings.
41
21
  */
42
- export declare const waitForElementToBeRemoved: (elementOrCallback: ElementOrCallback, options?: WaitForOptions) => Promise<void>;
43
- export {};
22
+ declare const waitForElementToBeRemoved: (elementOrCallback: ElementOrCallback, options?: WaitForOptions) => Promise<void>;
23
+ export { waitFor, waitForElementToBeRemoved };
44
24
  //# sourceMappingURL=wait-for.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wait-for.d.ts","sourceRoot":"","sources":["../src/wait-for.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,eAAe,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,OAAO,GAAU,CAAC,EAAE,UAAU,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,cAAc,KAAG,OAAO,CAAC,CAAC,CAoBpG,CAAC;AAEF,gBAAgB;AAChB,KAAK,iBAAiB,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAoBhE;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,yBAAyB,GAClC,mBAAmB,iBAAiB,EACpC,UAAU,cAAc,KACzB,OAAO,CAAC,IAAI,CA0Bd,CAAC"}
1
+ {"version":3,"file":"wait-for.d.ts","sourceRoot":"","sources":["../src/wait-for.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD,KAAK,aAAa,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;AACtD,KAAK,iBAAiB,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,aAAa,CAAC,CAAC;AA6D3E;;;;;;;GAOG;AACH,QAAA,MAAM,OAAO,GAAI,CAAC,EAAE,UAAU,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,cAAc,KAAG,OAAO,CAAC,CAAC,CAoBvF,CAAC;AAyBF;;;;;;;GAOG;AACH,QAAA,MAAM,yBAAyB,GAC3B,mBAAmB,iBAAiB,EACpC,UAAU,cAAc,KACzB,OAAO,CAAC,IAAI,CAmBd,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
package/dist/wait-for.js CHANGED
@@ -1,98 +1,102 @@
1
+ import { runWithActEnvironment } from "./act.js";
1
2
  import { getConfig } from "./config.js";
2
- import { buildTimeoutError } from "./error-builder.js";
3
+ import { timeoutError } from "./errors.js";
3
4
  const DEFAULT_INTERVAL = 50;
4
- /**
5
- * Waits for a callback to succeed.
6
- *
7
- * Repeatedly calls the callback until it returns without throwing,
8
- * or until the timeout is reached.
9
- *
10
- * @param callback - Function to execute repeatedly
11
- * @param options - Timeout and interval configuration
12
- * @returns Promise resolving to the callback's return value
13
- *
14
- * @example
15
- * ```tsx
16
- * import { waitFor } from "@gtkx/testing";
17
- *
18
- * await waitFor(() => {
19
- * expect(counter.value).toBe(5);
20
- * }, { timeout: 2000 });
21
- * ```
22
- */
23
- export const waitFor = async (callback, options) => {
24
- const config = getConfig();
25
- const { timeout = config.asyncUtilTimeout, interval = DEFAULT_INTERVAL, onTimeout } = options ?? {};
5
+ const ELEMENT_NOT_REMOVED = new Error("Element not yet removed");
6
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
7
+ const copyStackTrace = (target, source) => {
8
+ const { stack } = source;
9
+ if (stack === undefined) {
10
+ return;
11
+ }
12
+ const index = stack.indexOf(source.message);
13
+ if (index === -1) {
14
+ target.stack = stack;
15
+ return;
16
+ }
17
+ target.stack = stack.slice(0, index) + target.message + stack.slice(index + source.message.length);
18
+ };
19
+ const pollUntilSuccess = async (callback, timeout, interval) => {
26
20
  const startTime = Date.now();
27
21
  let lastError = null;
28
22
  while (Date.now() - startTime < timeout) {
29
23
  try {
30
- return await callback();
24
+ const result = await callback();
25
+ await delay(0);
26
+ return { status: "resolved", value: result };
31
27
  }
32
28
  catch (error) {
33
29
  lastError = error;
34
- await new Promise((resolve) => setTimeout(resolve, interval));
30
+ await delay(interval);
35
31
  }
36
32
  }
37
- const timeoutError = buildTimeoutError(timeout, lastError);
38
- if (onTimeout) {
39
- throw onTimeout(timeoutError);
40
- }
41
- throw timeoutError;
33
+ return { status: "timedout", lastError };
42
34
  };
43
- const getElement = (elementOrCallback) => {
44
- if (typeof elementOrCallback === "function") {
45
- return elementOrCallback();
35
+ const buildTimeoutError = (timeout, lastError, stackTraceError, onTimeout) => {
36
+ const error = timeoutError(timeout, lastError);
37
+ const finalError = onTimeout ? onTimeout(error) : error;
38
+ copyStackTrace(finalError, stackTraceError);
39
+ return finalError;
40
+ };
41
+ /**
42
+ * Repeatedly invokes a callback until it succeeds without throwing or the
43
+ * timeout elapses, retrying on each rejection at a fixed interval.
44
+ *
45
+ * @param callback The assertion or query to retry; its resolved value is returned.
46
+ * @param options Optional timeout, interval, and timeout error customization.
47
+ * @returns The callback's result once it succeeds.
48
+ */
49
+ const waitFor = (callback, options) => {
50
+ if (typeof callback !== "function") {
51
+ throw new TypeError("Received `callback` arg must be a function");
46
52
  }
47
- return elementOrCallback;
53
+ const stackTraceError = options?.stackTraceError ?? new Error("STACK_TRACE_MESSAGE");
54
+ return Promise.resolve(runWithActEnvironment(false, async () => {
55
+ const config = getConfig();
56
+ const { timeout = config.asyncUtilTimeout, interval = DEFAULT_INTERVAL, onTimeout } = options ?? {};
57
+ const result = await pollUntilSuccess(callback, timeout, interval);
58
+ if (result.status === "resolved") {
59
+ return result.value;
60
+ }
61
+ throw buildTimeoutError(timeout, result.lastError, stackTraceError, onTimeout);
62
+ }));
48
63
  };
49
- const isElementRemoved = (element) => {
50
- if (element === null)
64
+ const getTarget = (elementOrCallback) => typeof elementOrCallback === "function" ? elementOrCallback() : elementOrCallback;
65
+ const isWidgetRemoved = (widget) => {
66
+ if (widget === null) {
51
67
  return true;
68
+ }
52
69
  try {
53
- const parent = element.getParent();
54
- return parent === null;
70
+ return widget.getRoot() === null;
55
71
  }
56
72
  catch {
57
73
  return true;
58
74
  }
59
75
  };
76
+ const isTargetRemoved = (target) => {
77
+ if (Array.isArray(target)) {
78
+ return target.every((widget) => isWidgetRemoved(widget));
79
+ }
80
+ return isWidgetRemoved(target);
81
+ };
60
82
  /**
61
- * Waits for an element to be removed from the widget tree.
62
- *
63
- * Polls until the element no longer has a parent or no longer exists.
83
+ * Waits until the given widget or widgets are detached from the tree. Rejects
84
+ * immediately if the target is already absent when called.
64
85
  *
65
- * @param elementOrCallback - Element or function returning element to watch
66
- * @param options - Timeout and interval configuration
67
- *
68
- * @example
69
- * ```tsx
70
- * import { waitForElementToBeRemoved } from "@gtkx/testing";
71
- *
72
- * const loader = await screen.findByRole(Gtk.AccessibleRole.PROGRESS_BAR);
73
- * await waitForElementToBeRemoved(loader);
74
- * // Loader is now gone
75
- * ```
86
+ * @param elementOrCallback The widget, array of widgets, or a function
87
+ * returning them to observe for removal.
88
+ * @param options Optional timeout and interval settings.
76
89
  */
77
- export const waitForElementToBeRemoved = async (elementOrCallback, options) => {
78
- const config = getConfig();
79
- const { timeout = config.asyncUtilTimeout, interval = DEFAULT_INTERVAL, onTimeout } = options ?? {};
80
- const initialElement = getElement(elementOrCallback);
81
- if (initialElement === null || isElementRemoved(initialElement)) {
82
- throw new Error("Element already removed: waitForElementToBeRemoved requires the element to be present initially");
90
+ const waitForElementToBeRemoved = (elementOrCallback, options) => {
91
+ const stackTraceError = new Error("STACK_TRACE_MESSAGE");
92
+ if (isTargetRemoved(getTarget(elementOrCallback))) {
93
+ return Promise.reject(new Error("Element already removed: waitForElementToBeRemoved requires the element to be present initially"));
83
94
  }
84
- const startTime = Date.now();
85
- while (Date.now() - startTime < timeout) {
86
- const element = getElement(elementOrCallback);
87
- if (isElementRemoved(element)) {
88
- return;
95
+ return waitFor(() => {
96
+ if (!isTargetRemoved(getTarget(elementOrCallback))) {
97
+ throw ELEMENT_NOT_REMOVED;
89
98
  }
90
- await new Promise((resolve) => setTimeout(resolve, interval));
91
- }
92
- const timeoutError = new Error(`Timed out after ${timeout}ms waiting for element to be removed`);
93
- if (onTimeout) {
94
- throw onTimeout(timeoutError);
95
- }
96
- throw timeoutError;
99
+ }, { ...options, stackTraceError });
97
100
  };
101
+ export { waitFor, waitForElementToBeRemoved };
98
102
  //# sourceMappingURL=wait-for.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wait-for.js","sourceRoot":"","sources":["../src/wait-for.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wait-for.js","sourceRoot":"","sources":["../src/wait-for.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { WaitForOptions } from \"./types.js\";\nimport { runWithActEnvironment } from \"./act.js\";\nimport { getConfig } from \"./config.js\";\nimport { timeoutError } from \"./errors.js\";\n\ntype PollResult<T> = { status: \"resolved\"; value: T } | { status: \"timedout\"; lastError: Error | null };\ntype RemovalTarget = Gtk.Widget | Gtk.Widget[] | null;\ntype ElementOrCallback = Gtk.Widget | Gtk.Widget[] | (() => RemovalTarget);\n\nconst DEFAULT_INTERVAL = 50;\nconst ELEMENT_NOT_REMOVED = new Error(\"Element not yet removed\");\n\nconst delay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst copyStackTrace = (target: Error, source: Error): void => {\n const { stack } = source;\n\n if (stack === undefined) {\n return;\n }\n\n const index = stack.indexOf(source.message);\n\n if (index === -1) {\n target.stack = stack;\n\n return;\n }\n\n target.stack = stack.slice(0, index) + target.message + stack.slice(index + source.message.length);\n};\n\nconst pollUntilSuccess = async <T>(\n callback: () => T | Promise<T>,\n timeout: number,\n interval: number,\n): Promise<PollResult<T>> => {\n const startTime = Date.now();\n let lastError: Error | null = null;\n\n while (Date.now() - startTime < timeout) {\n try {\n const result = await callback();\n await delay(0);\n\n return { status: \"resolved\", value: result };\n } catch (error) {\n lastError = error as Error;\n await delay(interval);\n }\n }\n\n return { status: \"timedout\", lastError };\n};\n\nconst buildTimeoutError = (\n timeout: number,\n lastError: Error | null,\n stackTraceError: Error,\n onTimeout: ((error: Error) => Error) | undefined,\n): Error => {\n const error = timeoutError(timeout, lastError);\n const finalError = onTimeout ? onTimeout(error) : error;\n copyStackTrace(finalError, stackTraceError);\n\n return finalError;\n};\n\n/**\n * Repeatedly invokes a callback until it succeeds without throwing or the\n * timeout elapses, retrying on each rejection at a fixed interval.\n *\n * @param callback The assertion or query to retry; its resolved value is returned.\n * @param options Optional timeout, interval, and timeout error customization.\n * @returns The callback's result once it succeeds.\n */\nconst waitFor = <T>(callback: () => T | Promise<T>, options?: WaitForOptions): Promise<T> => {\n if (typeof callback !== \"function\") {\n throw new TypeError(\"Received `callback` arg must be a function\");\n }\n\n const stackTraceError = options?.stackTraceError ?? new Error(\"STACK_TRACE_MESSAGE\");\n\n return Promise.resolve(\n runWithActEnvironment(false, async () => {\n const config = getConfig();\n const { timeout = config.asyncUtilTimeout, interval = DEFAULT_INTERVAL, onTimeout } = options ?? {};\n const result = await pollUntilSuccess(callback, timeout, interval);\n\n if (result.status === \"resolved\") {\n return result.value;\n }\n\n throw buildTimeoutError(timeout, result.lastError, stackTraceError, onTimeout);\n }),\n );\n};\n\nconst getTarget = (elementOrCallback: ElementOrCallback): RemovalTarget =>\n typeof elementOrCallback === \"function\" ? elementOrCallback() : elementOrCallback;\n\nconst isWidgetRemoved = (widget: Gtk.Widget | null): boolean => {\n if (widget === null) {\n return true;\n }\n\n try {\n return widget.getRoot() === null;\n } catch {\n return true;\n }\n};\n\nconst isTargetRemoved = (target: RemovalTarget): boolean => {\n if (Array.isArray(target)) {\n return target.every((widget) => isWidgetRemoved(widget));\n }\n\n return isWidgetRemoved(target);\n};\n\n/**\n * Waits until the given widget or widgets are detached from the tree. Rejects\n * immediately if the target is already absent when called.\n *\n * @param elementOrCallback The widget, array of widgets, or a function\n * returning them to observe for removal.\n * @param options Optional timeout and interval settings.\n */\nconst waitForElementToBeRemoved = (\n elementOrCallback: ElementOrCallback,\n options?: WaitForOptions,\n): Promise<void> => {\n const stackTraceError = new Error(\"STACK_TRACE_MESSAGE\");\n\n if (isTargetRemoved(getTarget(elementOrCallback))) {\n return Promise.reject(\n new Error(\n \"Element already removed: waitForElementToBeRemoved requires the element to be present initially\",\n ),\n );\n }\n\n return waitFor(\n () => {\n if (!isTargetRemoved(getTarget(elementOrCallback))) {\n throw ELEMENT_NOT_REMOVED;\n }\n },\n { ...options, stackTraceError },\n );\n};\n\nexport { waitFor, waitForElementToBeRemoved };\n"]}
@@ -0,0 +1,34 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ type WidgetValue = {
3
+ now: number | null;
4
+ min: number | null;
5
+ max: number | null;
6
+ text: string | null;
7
+ };
8
+ /**
9
+ * Returns a widget's own text by trying its label, text, and title getters in
10
+ * order, or null when none produce a value.
11
+ *
12
+ * @param widget The widget to read text from.
13
+ */
14
+ declare const getWidgetNodeText: (widget: Gtk.Widget) => string | null;
15
+ declare const getWidgetLabelText: (widget: Gtk.Widget) => string | null;
16
+ declare const getWidgetAccessibleName: (widget: Gtk.Widget) => string | null;
17
+ declare const getWidgetName: (widget: Gtk.Widget) => string | null;
18
+ declare const getWidgetPlaceholderText: (widget: Gtk.Widget) => string | null;
19
+ declare const getWidgetDisplayValue: (widget: Gtk.Widget) => string | null;
20
+ declare const getWidgetCheckedState: (widget: Gtk.Widget) => boolean | null;
21
+ declare const getWidgetPressedState: (widget: Gtk.Widget) => boolean | null;
22
+ declare const getWidgetExpandedState: (widget: Gtk.Widget) => boolean | null;
23
+ declare const getWidgetSelectedState: (widget: Gtk.Widget) => boolean | null;
24
+ declare const getWidgetLevel: (widget: Gtk.Widget) => number | null;
25
+ declare const getWidgetInvalidState: (widget: Gtk.Widget) => Gtk.AccessibleInvalidState | null;
26
+ declare const getWidgetErrorMessage: (widget: Gtk.Widget) => Gtk.Widget[] | null;
27
+ declare const getWidgetBusyState: (widget: Gtk.Widget) => boolean | null;
28
+ declare const getWidgetDescription: (widget: Gtk.Widget) => string | null;
29
+ declare const getWidgetValue: (widget: Gtk.Widget) => WidgetValue;
30
+ declare const getWidgetOwnLabel: (widget: Gtk.Widget) => string | null;
31
+ declare const getWidgetLabelledByText: (widget: Gtk.Widget) => string | null;
32
+ declare const isInaccessible: (widget: Gtk.Widget) => boolean;
33
+ export { getWidgetNodeText, getWidgetLabelText, getWidgetAccessibleName, getWidgetName, getWidgetPlaceholderText, getWidgetDisplayValue, getWidgetCheckedState, getWidgetPressedState, getWidgetExpandedState, getWidgetSelectedState, getWidgetLevel, getWidgetInvalidState, getWidgetErrorMessage, getWidgetBusyState, getWidgetDescription, getWidgetValue, getWidgetOwnLabel, getWidgetLabelledByText, isInaccessible, type WidgetValue, };
34
+ //# sourceMappingURL=widget-accessible-properties.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-accessible-properties.d.ts","sourceRoot":"","sources":["../src/widget-accessible-properties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAKpC,KAAK,WAAW,GAAG;IACf,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AA4DF;;;;;GAKG;AACH,QAAA,MAAM,iBAAiB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IAUxD,CAAC;AAqCF,QAAA,MAAM,kBAAkB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IAMzD,CAAC;AAYF,QAAA,MAAM,uBAAuB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IA0B9D,CAAC;AAEF,QAAA,MAAM,aAAa,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IAEpD,CAAC;AAEF,QAAA,MAAM,wBAAwB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IAM/D,CAAC;AAEF,QAAA,MAAM,qBAAqB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IAM5D,CAAC;AAEF,QAAA,MAAM,qBAAqB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OAAO,GAAG,IAc7D,CAAC;AAEF,QAAA,MAAM,qBAAqB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OAAO,GAAG,IAM7D,CAAC;AAEF,QAAA,MAAM,sBAAsB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OAAO,GAAG,IAU9D,CAAC;AAEF,QAAA,MAAM,sBAAsB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OAAO,GAAG,IAU9D,CAAC;AAEF,QAAA,MAAM,cAAc,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IAErD,CAAC;AAEF,QAAA,MAAM,qBAAqB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,GAAG,CAAC,sBAAsB,GAAG,IAIhF,CAAC;AAEF,QAAA,MAAM,qBAAqB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,GAAG,CAAC,MAAM,EAAE,GAAG,IACR,CAAC;AAE5D,QAAA,MAAM,kBAAkB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OAAO,GAAG,IAE1D,CAAC;AAEF,QAAA,MAAM,oBAAoB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IAE3D,CAAC;AA8CF,QAAA,MAAM,cAAc,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,WAc5C,CAAC;AAEF,QAAA,MAAM,iBAAiB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IAExD,CAAC;AAgBF,QAAA,MAAM,uBAAuB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,MAAM,GAAG,IAU9D,CAAC;AAEF,QAAA,MAAM,cAAc,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OAgB5C,CAAC;AAEF,OAAO,EACH,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,cAAc,EACd,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACd,KAAK,WAAW,GACnB,CAAC"}
@@ -0,0 +1,260 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ import { getAccessibleMetadata } from "@gtkx/react/internal";
3
+ import { EDITABLE_ROLES, isEditable, readEditableText } from "./editable.js";
4
+ import { descendants } from "./traversal.js";
5
+ const DEFAULT_TEXT_GETTERS = ["getLabel", "getText", "getTitle"];
6
+ const callStringGetter = (widget, method) => {
7
+ const fn = Reflect.get(widget, method);
8
+ if (typeof fn !== "function") {
9
+ return null;
10
+ }
11
+ const value = fn.call(widget);
12
+ return value ?? null;
13
+ };
14
+ const readAccessibleString = (widget, key) => {
15
+ const value = getAccessibleMetadata(widget, key);
16
+ return typeof value === "string" ? value : null;
17
+ };
18
+ const readAccessibleNumber = (widget, key) => {
19
+ const value = getAccessibleMetadata(widget, key);
20
+ return typeof value === "number" ? value : null;
21
+ };
22
+ const readAccessibleWidgets = (widget, key) => {
23
+ const value = getAccessibleMetadata(widget, key);
24
+ if (!Array.isArray(value)) {
25
+ return null;
26
+ }
27
+ const widgets = value.filter((item) => item instanceof Gtk.Widget);
28
+ return widgets.length > 0 ? widgets : null;
29
+ };
30
+ const readAccessibleBoolean = (widget, key) => {
31
+ const value = getAccessibleMetadata(widget, key);
32
+ return typeof value === "boolean" ? value : null;
33
+ };
34
+ const getLabelText = (widget) => {
35
+ if (widget instanceof Gtk.Label) {
36
+ return widget.getLabel();
37
+ }
38
+ if (widget instanceof Gtk.Inscription) {
39
+ return widget.getText() ?? null;
40
+ }
41
+ return null;
42
+ };
43
+ /**
44
+ * Returns a widget's own text by trying its label, text, and title getters in
45
+ * order, or null when none produce a value.
46
+ *
47
+ * @param widget The widget to read text from.
48
+ */
49
+ const getWidgetNodeText = (widget) => {
50
+ for (const getter of DEFAULT_TEXT_GETTERS) {
51
+ const value = callStringGetter(widget, getter);
52
+ if (value) {
53
+ return value;
54
+ }
55
+ }
56
+ return null;
57
+ };
58
+ const stripMnemonic = (text) => text.replaceAll(/_(.)/g, "$1");
59
+ const namingLabelText = (widget) => {
60
+ const text = getLabelText(widget);
61
+ if (text === null) {
62
+ return null;
63
+ }
64
+ return widget instanceof Gtk.Label && widget.getUseUnderline() ? stripMnemonic(text) : text;
65
+ };
66
+ const isNamingLabelRole = (role, shouldIncludePresentation) => role === Gtk.AccessibleRole.LABEL ||
67
+ (shouldIncludePresentation && role === Gtk.AccessibleRole.PRESENTATION);
68
+ const collectLabels = (widget) => {
69
+ const isIncludePresentation = widget.getAccessibleRole() === Gtk.AccessibleRole.MENU_ITEM;
70
+ const labels = [];
71
+ for (const descendant of descendants(widget)) {
72
+ if (!isNamingLabelRole(descendant.getAccessibleRole(), isIncludePresentation)) {
73
+ continue;
74
+ }
75
+ const labelText = namingLabelText(descendant);
76
+ if (labelText) {
77
+ labels.push(labelText);
78
+ }
79
+ }
80
+ return labels;
81
+ };
82
+ const getWidgetLabelText = (widget) => {
83
+ if (widget.getAccessibleRole() !== Gtk.AccessibleRole.LABEL) {
84
+ return null;
85
+ }
86
+ return getLabelText(widget);
87
+ };
88
+ const tabPanelTitle = (widget) => {
89
+ const parent = widget.getParent();
90
+ if (parent instanceof Gtk.Stack) {
91
+ return parent.getPage(widget).getTitle() ?? null;
92
+ }
93
+ return null;
94
+ };
95
+ const getWidgetAccessibleName = (widget) => {
96
+ const role = widget.getAccessibleRole();
97
+ if (role === Gtk.AccessibleRole.TAB_PANEL) {
98
+ return tabPanelTitle(widget);
99
+ }
100
+ const accessibleLabel = readAccessibleString(widget, "accessibleLabel");
101
+ if (accessibleLabel) {
102
+ return accessibleLabel;
103
+ }
104
+ const ownText = getWidgetNodeText(widget);
105
+ if (ownText) {
106
+ return ownText;
107
+ }
108
+ const childLabels = collectLabels(widget);
109
+ if (childLabels.length > 0) {
110
+ return childLabels.join(" ");
111
+ }
112
+ return callStringGetter(widget, "getTooltipText");
113
+ };
114
+ const getWidgetName = (widget) => {
115
+ return widget.getName();
116
+ };
117
+ const getWidgetPlaceholderText = (widget) => {
118
+ if (!EDITABLE_ROLES.has(widget.getAccessibleRole()) || !(widget instanceof Gtk.Editable)) {
119
+ return null;
120
+ }
121
+ return callStringGetter(widget, "getPlaceholderText");
122
+ };
123
+ const getWidgetDisplayValue = (widget) => {
124
+ if (EDITABLE_ROLES.has(widget.getAccessibleRole()) && isEditable(widget)) {
125
+ return readEditableText(widget);
126
+ }
127
+ return null;
128
+ };
129
+ const getWidgetCheckedState = (widget) => {
130
+ if (widget instanceof Gtk.CheckButton) {
131
+ return widget.getActive();
132
+ }
133
+ if (widget instanceof Gtk.Switch) {
134
+ return widget.getActive();
135
+ }
136
+ if (widget instanceof Gtk.ToggleButton && widget.getAccessibleRole() === Gtk.AccessibleRole.RADIO) {
137
+ return widget.getActive();
138
+ }
139
+ return null;
140
+ };
141
+ const getWidgetPressedState = (widget) => {
142
+ if (widget instanceof Gtk.ToggleButton) {
143
+ return widget.getActive();
144
+ }
145
+ return null;
146
+ };
147
+ const getWidgetExpandedState = (widget) => {
148
+ if (widget instanceof Gtk.Expander) {
149
+ return widget.getExpanded();
150
+ }
151
+ if (widget instanceof Gtk.TreeExpander) {
152
+ return widget.getListRow()?.getExpanded() ?? null;
153
+ }
154
+ return null;
155
+ };
156
+ const getWidgetSelectedState = (widget) => {
157
+ if (widget instanceof Gtk.ListBoxRow) {
158
+ return widget.isSelected();
159
+ }
160
+ if (widget.getAccessibleRole() === Gtk.AccessibleRole.ROW) {
161
+ return (widget.getStateFlags() & Gtk.StateFlags.SELECTED) !== 0;
162
+ }
163
+ return null;
164
+ };
165
+ const getWidgetLevel = (widget) => {
166
+ return readAccessibleNumber(widget, "accessibleLevel");
167
+ };
168
+ const getWidgetInvalidState = (widget) => {
169
+ const value = readAccessibleNumber(widget, "accessibleInvalid");
170
+ return value ?? null;
171
+ };
172
+ const getWidgetErrorMessage = (widget) => readAccessibleWidgets(widget, "accessibleErrorMessage");
173
+ const getWidgetBusyState = (widget) => {
174
+ return readAccessibleBoolean(widget, "accessibleBusy");
175
+ };
176
+ const getWidgetDescription = (widget) => {
177
+ return readAccessibleString(widget, "accessibleDescription");
178
+ };
179
+ const adjustmentValue = (adjustment) => ({
180
+ now: adjustment.getValue(),
181
+ min: adjustment.getLower(),
182
+ max: adjustment.getUpper(),
183
+ });
184
+ const adjustmentWidgetValue = (widget) => {
185
+ if (widget instanceof Gtk.Range) {
186
+ return adjustmentValue(widget.getAdjustment());
187
+ }
188
+ if (widget instanceof Gtk.Scrollbar) {
189
+ return adjustmentValue(widget.getAdjustment());
190
+ }
191
+ if (widget instanceof Gtk.SpinButton) {
192
+ return adjustmentValue(widget.getAdjustment());
193
+ }
194
+ if (widget instanceof Gtk.ScaleButton) {
195
+ return adjustmentValue(widget.getAdjustment());
196
+ }
197
+ return null;
198
+ };
199
+ const getWidgetLiveValue = (widget) => {
200
+ const adjustmentBased = adjustmentWidgetValue(widget);
201
+ if (adjustmentBased) {
202
+ return adjustmentBased;
203
+ }
204
+ if (widget instanceof Gtk.LevelBar) {
205
+ return { now: widget.getValue(), min: widget.getMinValue(), max: widget.getMaxValue() };
206
+ }
207
+ if (widget instanceof Gtk.ProgressBar) {
208
+ return { now: widget.getFraction(), min: 0, max: 1 };
209
+ }
210
+ return null;
211
+ };
212
+ const getWidgetValue = (widget) => {
213
+ const text = readAccessibleString(widget, "accessibleValueText");
214
+ const live = getWidgetLiveValue(widget);
215
+ if (live) {
216
+ return { ...live, text };
217
+ }
218
+ return {
219
+ now: readAccessibleNumber(widget, "accessibleValueNow"),
220
+ min: readAccessibleNumber(widget, "accessibleValueMin"),
221
+ max: readAccessibleNumber(widget, "accessibleValueMax"),
222
+ text,
223
+ };
224
+ };
225
+ const getWidgetOwnLabel = (widget) => {
226
+ return readAccessibleString(widget, "accessibleLabel");
227
+ };
228
+ const collectAccessibleNames = (targets) => {
229
+ const texts = [];
230
+ for (const target of targets) {
231
+ const text = getWidgetAccessibleName(target);
232
+ if (text !== null) {
233
+ texts.push(text);
234
+ }
235
+ }
236
+ return texts;
237
+ };
238
+ const getWidgetLabelledByText = (widget) => {
239
+ const targets = readAccessibleWidgets(widget, "accessibleLabelledBy");
240
+ if (targets === null) {
241
+ return null;
242
+ }
243
+ const texts = collectAccessibleNames(targets);
244
+ return texts.length > 0 ? texts.join(" ") : null;
245
+ };
246
+ const isInaccessible = (widget) => {
247
+ let current = widget;
248
+ while (current) {
249
+ if (!current.getVisible()) {
250
+ return true;
251
+ }
252
+ if (readAccessibleBoolean(current, "accessibleHidden") === true) {
253
+ return true;
254
+ }
255
+ current = current.getParent();
256
+ }
257
+ return false;
258
+ };
259
+ export { getWidgetNodeText, getWidgetLabelText, getWidgetAccessibleName, getWidgetName, getWidgetPlaceholderText, getWidgetDisplayValue, getWidgetCheckedState, getWidgetPressedState, getWidgetExpandedState, getWidgetSelectedState, getWidgetLevel, getWidgetInvalidState, getWidgetErrorMessage, getWidgetBusyState, getWidgetDescription, getWidgetValue, getWidgetOwnLabel, getWidgetLabelledByText, isInaccessible, };
260
+ //# sourceMappingURL=widget-accessible-properties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget-accessible-properties.js","sourceRoot":"","sources":["../src/widget-accessible-properties.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\nimport { getAccessibleMetadata } from \"@gtkx/react/internal\";\nimport { EDITABLE_ROLES, isEditable, readEditableText } from \"./editable.js\";\nimport { descendants } from \"./traversal.js\";\n\ntype WidgetValue = {\n now: number | null;\n min: number | null;\n max: number | null;\n text: string | null;\n};\n\ntype ValueTriplet = { now: number | null; min: number | null; max: number | null };\n\nconst DEFAULT_TEXT_GETTERS = [\"getLabel\", \"getText\", \"getTitle\"] as const;\n\nconst callStringGetter = (widget: Gtk.Widget, method: string): string | null => {\n const fn: unknown = Reflect.get(widget, method);\n\n if (typeof fn !== \"function\") {\n return null;\n }\n\n const value = (fn as () => string | null).call(widget);\n\n return value ?? null;\n};\n\nconst readAccessibleString = (widget: Gtk.Widget, key: string): string | null => {\n const value = getAccessibleMetadata(widget, key);\n\n return typeof value === \"string\" ? value : null;\n};\n\nconst readAccessibleNumber = (widget: Gtk.Widget, key: string): number | null => {\n const value = getAccessibleMetadata(widget, key);\n\n return typeof value === \"number\" ? value : null;\n};\n\nconst readAccessibleWidgets = (widget: Gtk.Widget, key: string): Gtk.Widget[] | null => {\n const value = getAccessibleMetadata(widget, key);\n\n if (!Array.isArray(value)) {\n return null;\n }\n\n const widgets = value.filter((item): item is Gtk.Widget => item instanceof Gtk.Widget);\n\n return widgets.length > 0 ? widgets : null;\n};\n\nconst readAccessibleBoolean = (widget: Gtk.Widget, key: string): boolean | null => {\n const value = getAccessibleMetadata(widget, key);\n\n return typeof value === \"boolean\" ? value : null;\n};\n\nconst getLabelText = (widget: Gtk.Widget): string | null => {\n if (widget instanceof Gtk.Label) {\n return widget.getLabel();\n }\n\n if (widget instanceof Gtk.Inscription) {\n return widget.getText() ?? null;\n }\n\n return null;\n};\n\n/**\n * Returns a widget's own text by trying its label, text, and title getters in\n * order, or null when none produce a value.\n *\n * @param widget The widget to read text from.\n */\nconst getWidgetNodeText = (widget: Gtk.Widget): string | null => {\n for (const getter of DEFAULT_TEXT_GETTERS) {\n const value = callStringGetter(widget, getter);\n\n if (value) {\n return value;\n }\n }\n\n return null;\n};\n\nconst stripMnemonic = (text: string): string => text.replaceAll(/_(.)/g, \"$1\");\n\nconst namingLabelText = (widget: Gtk.Widget): string | null => {\n const text = getLabelText(widget);\n\n if (text === null) {\n return null;\n }\n\n return widget instanceof Gtk.Label && widget.getUseUnderline() ? stripMnemonic(text) : text;\n};\n\nconst isNamingLabelRole = (role: Gtk.AccessibleRole, shouldIncludePresentation: boolean): boolean =>\n role === Gtk.AccessibleRole.LABEL ||\n (shouldIncludePresentation && role === Gtk.AccessibleRole.PRESENTATION);\n\nconst collectLabels = (widget: Gtk.Widget): string[] => {\n const isIncludePresentation = widget.getAccessibleRole() === Gtk.AccessibleRole.MENU_ITEM;\n const labels: string[] = [];\n\n for (const descendant of descendants(widget)) {\n if (!isNamingLabelRole(descendant.getAccessibleRole(), isIncludePresentation)) {\n continue;\n }\n\n const labelText = namingLabelText(descendant);\n\n if (labelText) {\n labels.push(labelText);\n }\n }\n\n return labels;\n};\n\nconst getWidgetLabelText = (widget: Gtk.Widget): string | null => {\n if (widget.getAccessibleRole() !== Gtk.AccessibleRole.LABEL) {\n return null;\n }\n\n return getLabelText(widget);\n};\n\nconst tabPanelTitle = (widget: Gtk.Widget): string | null => {\n const parent = widget.getParent();\n\n if (parent instanceof Gtk.Stack) {\n return parent.getPage(widget).getTitle() ?? null;\n }\n\n return null;\n};\n\nconst getWidgetAccessibleName = (widget: Gtk.Widget): string | null => {\n const role = widget.getAccessibleRole();\n\n if (role === Gtk.AccessibleRole.TAB_PANEL) {\n return tabPanelTitle(widget);\n }\n\n const accessibleLabel = readAccessibleString(widget, \"accessibleLabel\");\n\n if (accessibleLabel) {\n return accessibleLabel;\n }\n\n const ownText = getWidgetNodeText(widget);\n\n if (ownText) {\n return ownText;\n }\n\n const childLabels = collectLabels(widget);\n\n if (childLabels.length > 0) {\n return childLabels.join(\" \");\n }\n\n return callStringGetter(widget, \"getTooltipText\");\n};\n\nconst getWidgetName = (widget: Gtk.Widget): string | null => {\n return widget.getName();\n};\n\nconst getWidgetPlaceholderText = (widget: Gtk.Widget): string | null => {\n if (!EDITABLE_ROLES.has(widget.getAccessibleRole()) || !(widget instanceof Gtk.Editable)) {\n return null;\n }\n\n return callStringGetter(widget, \"getPlaceholderText\");\n};\n\nconst getWidgetDisplayValue = (widget: Gtk.Widget): string | null => {\n if (EDITABLE_ROLES.has(widget.getAccessibleRole()) && isEditable(widget)) {\n return readEditableText(widget);\n }\n\n return null;\n};\n\nconst getWidgetCheckedState = (widget: Gtk.Widget): boolean | null => {\n if (widget instanceof Gtk.CheckButton) {\n return widget.getActive();\n }\n\n if (widget instanceof Gtk.Switch) {\n return widget.getActive();\n }\n\n if (widget instanceof Gtk.ToggleButton && widget.getAccessibleRole() === Gtk.AccessibleRole.RADIO) {\n return widget.getActive();\n }\n\n return null;\n};\n\nconst getWidgetPressedState = (widget: Gtk.Widget): boolean | null => {\n if (widget instanceof Gtk.ToggleButton) {\n return widget.getActive();\n }\n\n return null;\n};\n\nconst getWidgetExpandedState = (widget: Gtk.Widget): boolean | null => {\n if (widget instanceof Gtk.Expander) {\n return widget.getExpanded();\n }\n\n if (widget instanceof Gtk.TreeExpander) {\n return widget.getListRow()?.getExpanded() ?? null;\n }\n\n return null;\n};\n\nconst getWidgetSelectedState = (widget: Gtk.Widget): boolean | null => {\n if (widget instanceof Gtk.ListBoxRow) {\n return widget.isSelected();\n }\n\n if (widget.getAccessibleRole() === Gtk.AccessibleRole.ROW) {\n return (widget.getStateFlags() & Gtk.StateFlags.SELECTED) !== 0;\n }\n\n return null;\n};\n\nconst getWidgetLevel = (widget: Gtk.Widget): number | null => {\n return readAccessibleNumber(widget, \"accessibleLevel\");\n};\n\nconst getWidgetInvalidState = (widget: Gtk.Widget): Gtk.AccessibleInvalidState | null => {\n const value = readAccessibleNumber(widget, \"accessibleInvalid\");\n\n return value ?? null;\n};\n\nconst getWidgetErrorMessage = (widget: Gtk.Widget): Gtk.Widget[] | null =>\n readAccessibleWidgets(widget, \"accessibleErrorMessage\");\n\nconst getWidgetBusyState = (widget: Gtk.Widget): boolean | null => {\n return readAccessibleBoolean(widget, \"accessibleBusy\");\n};\n\nconst getWidgetDescription = (widget: Gtk.Widget): string | null => {\n return readAccessibleString(widget, \"accessibleDescription\");\n};\n\nconst adjustmentValue = (adjustment: Gtk.Adjustment): ValueTriplet => ({\n now: adjustment.getValue(),\n min: adjustment.getLower(),\n max: adjustment.getUpper(),\n});\n\nconst adjustmentWidgetValue = (widget: Gtk.Widget): ValueTriplet | null => {\n if (widget instanceof Gtk.Range) {\n return adjustmentValue(widget.getAdjustment());\n }\n\n if (widget instanceof Gtk.Scrollbar) {\n return adjustmentValue(widget.getAdjustment());\n }\n\n if (widget instanceof Gtk.SpinButton) {\n return adjustmentValue(widget.getAdjustment());\n }\n\n if (widget instanceof Gtk.ScaleButton) {\n return adjustmentValue(widget.getAdjustment());\n }\n\n return null;\n};\n\nconst getWidgetLiveValue = (widget: Gtk.Widget): ValueTriplet | null => {\n const adjustmentBased = adjustmentWidgetValue(widget);\n\n if (adjustmentBased) {\n return adjustmentBased;\n }\n\n if (widget instanceof Gtk.LevelBar) {\n return { now: widget.getValue(), min: widget.getMinValue(), max: widget.getMaxValue() };\n }\n\n if (widget instanceof Gtk.ProgressBar) {\n return { now: widget.getFraction(), min: 0, max: 1 };\n }\n\n return null;\n};\n\nconst getWidgetValue = (widget: Gtk.Widget): WidgetValue => {\n const text = readAccessibleString(widget, \"accessibleValueText\");\n const live = getWidgetLiveValue(widget);\n\n if (live) {\n return { ...live, text };\n }\n\n return {\n now: readAccessibleNumber(widget, \"accessibleValueNow\"),\n min: readAccessibleNumber(widget, \"accessibleValueMin\"),\n max: readAccessibleNumber(widget, \"accessibleValueMax\"),\n text,\n };\n};\n\nconst getWidgetOwnLabel = (widget: Gtk.Widget): string | null => {\n return readAccessibleString(widget, \"accessibleLabel\");\n};\n\nconst collectAccessibleNames = (targets: Gtk.Widget[]): string[] => {\n const texts: string[] = [];\n\n for (const target of targets) {\n const text = getWidgetAccessibleName(target);\n\n if (text !== null) {\n texts.push(text);\n }\n }\n\n return texts;\n};\n\nconst getWidgetLabelledByText = (widget: Gtk.Widget): string | null => {\n const targets = readAccessibleWidgets(widget, \"accessibleLabelledBy\");\n\n if (targets === null) {\n return null;\n }\n\n const texts = collectAccessibleNames(targets);\n\n return texts.length > 0 ? texts.join(\" \") : null;\n};\n\nconst isInaccessible = (widget: Gtk.Widget): boolean => {\n let current: Gtk.Widget | null = widget;\n\n while (current) {\n if (!current.getVisible()) {\n return true;\n }\n\n if (readAccessibleBoolean(current, \"accessibleHidden\") === true) {\n return true;\n }\n\n current = current.getParent();\n }\n\n return false;\n};\n\nexport {\n getWidgetNodeText,\n getWidgetLabelText,\n getWidgetAccessibleName,\n getWidgetName,\n getWidgetPlaceholderText,\n getWidgetDisplayValue,\n getWidgetCheckedState,\n getWidgetPressedState,\n getWidgetExpandedState,\n getWidgetSelectedState,\n getWidgetLevel,\n getWidgetInvalidState,\n getWidgetErrorMessage,\n getWidgetBusyState,\n getWidgetDescription,\n getWidgetValue,\n getWidgetOwnLabel,\n getWidgetLabelledByText,\n isInaccessible,\n type WidgetValue,\n};\n"]}