@gtkx/testing 1.0.0-rc.3 → 1.0.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 (215) hide show
  1. package/README.md +8 -9
  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 +2 -0
  7. package/dist/act.d.ts.map +1 -1
  8. package/dist/act.js.map +1 -1
  9. package/dist/build-queries.d.ts +27 -10
  10. package/dist/build-queries.d.ts.map +1 -1
  11. package/dist/build-queries.js +39 -30
  12. package/dist/build-queries.js.map +1 -1
  13. package/dist/cleanup-registry.d.ts +1 -1
  14. package/dist/cleanup-registry.d.ts.map +1 -1
  15. package/dist/cleanup-registry.js.map +1 -1
  16. package/dist/config.d.ts +1 -0
  17. package/dist/config.d.ts.map +1 -1
  18. package/dist/config.js +3 -3
  19. package/dist/config.js.map +1 -1
  20. package/dist/errors.d.ts +10 -1
  21. package/dist/errors.d.ts.map +1 -1
  22. package/dist/errors.js +12 -3
  23. package/dist/errors.js.map +1 -1
  24. package/dist/fire-event.d.ts +35 -6
  25. package/dist/fire-event.d.ts.map +1 -1
  26. package/dist/fire-event.js +23 -7
  27. package/dist/fire-event.js.map +1 -1
  28. package/dist/frame-sync.d.ts +2 -1
  29. package/dist/frame-sync.d.ts.map +1 -1
  30. package/dist/frame-sync.js +15 -5
  31. package/dist/frame-sync.js.map +1 -1
  32. package/dist/harness-window.d.ts +4 -0
  33. package/dist/harness-window.d.ts.map +1 -0
  34. package/dist/harness-window.js +6 -0
  35. package/dist/harness-window.js.map +1 -0
  36. package/dist/index.d.ts +14 -7
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +9 -5
  39. package/dist/index.js.map +1 -1
  40. package/dist/internal.d.ts +4 -0
  41. package/dist/internal.d.ts.map +1 -0
  42. package/dist/internal.js +4 -0
  43. package/dist/internal.js.map +1 -0
  44. package/dist/matchers.d.ts +125 -39
  45. package/dist/matchers.d.ts.map +1 -1
  46. package/dist/matchers.js +156 -18
  47. package/dist/matchers.js.map +1 -1
  48. package/dist/pretty-format.d.ts +2 -0
  49. package/dist/pretty-format.d.ts.map +1 -0
  50. package/dist/pretty-format.js +2 -0
  51. package/dist/pretty-format.js.map +1 -0
  52. package/dist/pretty-widget.d.ts +7 -3
  53. package/dist/pretty-widget.d.ts.map +1 -1
  54. package/dist/pretty-widget.js +74 -57
  55. package/dist/pretty-widget.js.map +1 -1
  56. package/dist/production.d.ts +8 -0
  57. package/dist/production.d.ts.map +1 -0
  58. package/dist/production.js +34 -0
  59. package/dist/production.js.map +1 -0
  60. package/dist/queries.d.ts +99 -56
  61. package/dist/queries.d.ts.map +1 -1
  62. package/dist/queries.js +123 -83
  63. package/dist/queries.js.map +1 -1
  64. package/dist/query-helpers.d.ts +44 -0
  65. package/dist/query-helpers.d.ts.map +1 -0
  66. package/dist/query-helpers.js +57 -0
  67. package/dist/query-helpers.js.map +1 -0
  68. package/dist/render-children.d.ts +9 -0
  69. package/dist/render-children.d.ts.map +1 -0
  70. package/dist/render-children.js +11 -0
  71. package/dist/render-children.js.map +1 -0
  72. package/dist/render.d.ts.map +1 -1
  73. package/dist/render.js +13 -11
  74. package/dist/render.js.map +1 -1
  75. package/dist/role-helpers.d.ts +12 -3
  76. package/dist/role-helpers.d.ts.map +1 -1
  77. package/dist/role-helpers.js +13 -4
  78. package/dist/role-helpers.js.map +1 -1
  79. package/dist/role-naming.d.ts +5 -0
  80. package/dist/role-naming.d.ts.map +1 -0
  81. package/dist/role-naming.js +96 -0
  82. package/dist/role-naming.js.map +1 -0
  83. package/dist/screenshot.d.ts +12 -20
  84. package/dist/screenshot.d.ts.map +1 -1
  85. package/dist/screenshot.js +183 -91
  86. package/dist/screenshot.js.map +1 -1
  87. package/dist/suggestions.d.ts +3 -0
  88. package/dist/suggestions.d.ts.map +1 -1
  89. package/dist/suggestions.js.map +1 -1
  90. package/dist/traversal.d.ts +9 -1
  91. package/dist/traversal.d.ts.map +1 -1
  92. package/dist/traversal.js +26 -6
  93. package/dist/traversal.js.map +1 -1
  94. package/dist/types.d.ts +67 -17
  95. package/dist/types.d.ts.map +1 -1
  96. package/dist/types.js.map +1 -1
  97. package/dist/user-event/adjustment.d.ts +16 -0
  98. package/dist/user-event/adjustment.d.ts.map +1 -1
  99. package/dist/user-event/adjustment.js +34 -2
  100. package/dist/user-event/adjustment.js.map +1 -1
  101. package/dist/user-event/click.d.ts +45 -3
  102. package/dist/user-event/click.d.ts.map +1 -1
  103. package/dist/user-event/click.js +177 -39
  104. package/dist/user-event/click.js.map +1 -1
  105. package/dist/user-event/column-header-click.d.ts +4 -0
  106. package/dist/user-event/column-header-click.d.ts.map +1 -0
  107. package/dist/user-event/column-header-click.js +65 -0
  108. package/dist/user-event/column-header-click.js.map +1 -0
  109. package/dist/user-event/controller.d.ts +29 -0
  110. package/dist/user-event/controller.d.ts.map +1 -1
  111. package/dist/user-event/controller.js +28 -0
  112. package/dist/user-event/controller.js.map +1 -1
  113. package/dist/user-event/event-wrapper.d.ts.map +1 -1
  114. package/dist/user-event/event-wrapper.js +2 -1
  115. package/dist/user-event/event-wrapper.js.map +1 -1
  116. package/dist/user-event/gesture.d.ts +51 -0
  117. package/dist/user-event/gesture.d.ts.map +1 -1
  118. package/dist/user-event/gesture.js +47 -4
  119. package/dist/user-event/gesture.js.map +1 -1
  120. package/dist/user-event/index.d.ts +70 -2
  121. package/dist/user-event/index.d.ts.map +1 -1
  122. package/dist/user-event/index.js +43 -26
  123. package/dist/user-event/index.js.map +1 -1
  124. package/dist/user-event/indexed-children.d.ts +10 -0
  125. package/dist/user-event/indexed-children.d.ts.map +1 -0
  126. package/dist/user-event/indexed-children.js +50 -0
  127. package/dist/user-event/indexed-children.js.map +1 -0
  128. package/dist/user-event/keyboard.d.ts +4 -2
  129. package/dist/user-event/keyboard.d.ts.map +1 -1
  130. package/dist/user-event/keyboard.js +46 -16
  131. package/dist/user-event/keyboard.js.map +1 -1
  132. package/dist/user-event/list-row-click.d.ts +4 -0
  133. package/dist/user-event/list-row-click.d.ts.map +1 -0
  134. package/dist/user-event/list-row-click.js +39 -0
  135. package/dist/user-event/list-row-click.js.map +1 -0
  136. package/dist/user-event/native-click.d.ts +6 -0
  137. package/dist/user-event/native-click.d.ts.map +1 -0
  138. package/dist/user-event/native-click.js +32 -0
  139. package/dist/user-event/native-click.js.map +1 -0
  140. package/dist/user-event/pointer.d.ts +1 -1
  141. package/dist/user-event/pointer.d.ts.map +1 -1
  142. package/dist/user-event/pointer.js +37 -13
  143. package/dist/user-event/pointer.js.map +1 -1
  144. package/dist/user-event/selection.d.ts +18 -0
  145. package/dist/user-event/selection.d.ts.map +1 -1
  146. package/dist/user-event/selection.js +56 -30
  147. package/dist/user-event/selection.js.map +1 -1
  148. package/dist/user-event/state.d.ts +1 -1
  149. package/dist/user-event/state.d.ts.map +1 -1
  150. package/dist/user-event/state.js +1 -1
  151. package/dist/user-event/state.js.map +1 -1
  152. package/dist/user-event/text.d.ts +34 -3
  153. package/dist/user-event/text.d.ts.map +1 -1
  154. package/dist/user-event/text.js +94 -17
  155. package/dist/user-event/text.js.map +1 -1
  156. package/dist/wait-for.d.ts +2 -0
  157. package/dist/wait-for.d.ts.map +1 -1
  158. package/dist/wait-for.js.map +1 -1
  159. package/dist/widget-accessible-properties.d.ts +14 -10
  160. package/dist/widget-accessible-properties.d.ts.map +1 -1
  161. package/dist/widget-accessible-properties.js +135 -173
  162. package/dist/widget-accessible-properties.js.map +1 -1
  163. package/dist/widget-getters.d.ts +8 -0
  164. package/dist/widget-getters.d.ts.map +1 -0
  165. package/dist/widget-getters.js +19 -0
  166. package/dist/widget-getters.js.map +1 -0
  167. package/dist/within.d.ts +3 -2
  168. package/dist/within.d.ts.map +1 -1
  169. package/dist/within.js +3 -2
  170. package/dist/within.js.map +1 -1
  171. package/package.json +13 -8
  172. package/src/accessible-native.ts +333 -0
  173. package/src/act.ts +2 -0
  174. package/src/build-queries.ts +66 -48
  175. package/src/cleanup-registry.ts +1 -1
  176. package/src/config.ts +4 -3
  177. package/src/errors.ts +14 -3
  178. package/src/fire-event.ts +61 -8
  179. package/src/frame-sync.ts +21 -5
  180. package/src/harness-window.ts +9 -0
  181. package/src/index.ts +18 -11
  182. package/src/internal.ts +11 -0
  183. package/src/matchers.ts +466 -64
  184. package/src/pretty-format.ts +1 -0
  185. package/src/pretty-widget.ts +100 -72
  186. package/src/production.ts +52 -0
  187. package/src/queries.ts +128 -89
  188. package/src/query-helpers.ts +97 -0
  189. package/src/render-children.ts +25 -0
  190. package/src/render.tsx +18 -13
  191. package/src/role-helpers.ts +14 -4
  192. package/src/role-naming.ts +99 -0
  193. package/src/screenshot.ts +272 -103
  194. package/src/suggestions.ts +3 -0
  195. package/src/traversal.ts +49 -6
  196. package/src/types.ts +69 -19
  197. package/src/user-event/adjustment.ts +42 -2
  198. package/src/user-event/click.ts +248 -46
  199. package/src/user-event/column-header-click.ts +90 -0
  200. package/src/user-event/controller.ts +29 -0
  201. package/src/user-event/event-wrapper.ts +3 -1
  202. package/src/user-event/gesture.ts +57 -6
  203. package/src/user-event/index.ts +119 -29
  204. package/src/user-event/indexed-children.ts +75 -0
  205. package/src/user-event/keyboard.ts +70 -20
  206. package/src/user-event/list-row-click.ts +57 -0
  207. package/src/user-event/native-click.ts +46 -0
  208. package/src/user-event/pointer.ts +52 -13
  209. package/src/user-event/selection.ts +74 -33
  210. package/src/user-event/state.ts +2 -2
  211. package/src/user-event/text.ts +121 -23
  212. package/src/wait-for.ts +2 -0
  213. package/src/widget-accessible-properties.ts +183 -214
  214. package/src/widget-getters.ts +32 -0
  215. package/src/within.ts +3 -2
@@ -1,4 +1,5 @@
1
1
  import * as Gdk from "@gtkx/gi/gdk";
2
+ import * as Gio from "@gtkx/gi/gio";
2
3
  import * as Gtk from "@gtkx/gi/gtk";
3
4
  import { getEditableDelegate } from "../editable.js";
4
5
  import { fireEvent } from "../fire-event.js";
@@ -46,8 +47,9 @@ const MODIFIER_KEYVAL_TO_MASK = {
46
47
  [Gdk.KEY_Meta_L]: Gdk.ModifierType.META_MASK,
47
48
  [Gdk.KEY_Meta_R]: Gdk.ModifierType.META_MASK,
48
49
  };
50
+ /** Moves focus within the widget's root, forward by default and backward when `isShiftHeld` is set. */
49
51
  const tab = (widget, options) => wrapEvent(widget, () => {
50
- const direction = options?.shift ? Gtk.DirectionType.TAB_BACKWARD : Gtk.DirectionType.TAB_FORWARD;
52
+ const direction = options?.isShiftHeld ? Gtk.DirectionType.TAB_BACKWARD : Gtk.DirectionType.TAB_FORWARD;
51
53
  const root = widget.getRoot();
52
54
  if (root) {
53
55
  root.childFocus(direction);
@@ -69,14 +71,14 @@ const parseKeyToken = (token) => {
69
71
  if (keyval === undefined) {
70
72
  throw new Error(`Unknown key: {${keyName}}`);
71
73
  }
72
- return { keyval, press: isPress, release: isRelease };
74
+ return { keyval, isPress, isRelease };
73
75
  };
74
76
  const parseCharAt = (input, i) => {
75
77
  const keyval = input.codePointAt(i) ?? 0;
76
78
  return {
77
79
  actions: [
78
- { keyval, press: true },
79
- { keyval, press: false },
80
+ { keyval, isPress: true },
81
+ { keyval, isPress: false },
80
82
  ],
81
83
  next: i + 1,
82
84
  };
@@ -86,13 +88,13 @@ const parseBraceAt = (input, i) => {
86
88
  if (endBrace === -1) {
87
89
  return null;
88
90
  }
89
- const { keyval, press, release } = parseKeyToken(input.slice(i + 1, endBrace));
91
+ const { keyval, isPress, isRelease } = parseKeyToken(input.slice(i + 1, endBrace));
90
92
  const actions = [];
91
- if (press) {
92
- actions.push({ keyval, press: true });
93
+ if (isPress) {
94
+ actions.push({ keyval, isPress: true });
93
95
  }
94
- if (release) {
95
- actions.push({ keyval, press: false });
96
+ if (isRelease) {
97
+ actions.push({ keyval, isPress: false });
96
98
  }
97
99
  return { actions, next: endBrace + 1 };
98
100
  };
@@ -115,7 +117,7 @@ const updateModifierState = (state, action) => {
115
117
  if (!mask) {
116
118
  return;
117
119
  }
118
- if (action.press) {
120
+ if (action.isPress) {
119
121
  state.modifierState |= mask;
120
122
  }
121
123
  else {
@@ -166,11 +168,36 @@ const didDispatchShortcutsOnWidget = (widget, keyval, modifiers) => {
166
168
  }
167
169
  return false;
168
170
  };
169
- const didDispatchShortcuts = (widget, keyval, modifiers) => {
170
- const delegate = getEditableDelegate(widget);
171
- if (delegate && didDispatchShortcutsOnWidget(delegate, keyval, modifiers)) {
172
- return true;
171
+ const isAccelMatch = (accel, keyval, modifiers) => {
172
+ const [isParsed, accelKeyval, accelModifiers] = Gtk.acceleratorParse(accel);
173
+ return isParsed && accelKeyval === keyval && accelModifiers === modifiers;
174
+ };
175
+ const hasMatchingAccel = (application, detailedActionName, keyval, modifiers) => application.getAccelsForAction(detailedActionName).some((accel) => isAccelMatch(accel, keyval, modifiers));
176
+ const didActivateDetailedAction = (window, detailedActionName) => {
177
+ const [isParsed, actionName, target] = Gio.Action.parseDetailedName(detailedActionName);
178
+ return isParsed && window.activateAction(actionName, target);
179
+ };
180
+ const didDispatchAccelsOnWindow = (window, keyval, modifiers) => {
181
+ const application = window.getApplication();
182
+ if (!application) {
183
+ return false;
184
+ }
185
+ for (const detailedActionName of application.listActionDescriptions()) {
186
+ if (hasMatchingAccel(application, detailedActionName, keyval, modifiers)) {
187
+ return didActivateDetailedAction(window, detailedActionName);
188
+ }
173
189
  }
190
+ return false;
191
+ };
192
+ const didDispatchApplicationAccels = (widget, keyval, modifiers) => {
193
+ const root = widget.getRoot();
194
+ return root instanceof Gtk.Window && didDispatchAccelsOnWindow(root, keyval, modifiers);
195
+ };
196
+ const didDispatchDelegateShortcuts = (widget, keyval, modifiers) => {
197
+ const delegate = getEditableDelegate(widget);
198
+ return delegate !== null && didDispatchShortcutsOnWidget(delegate, keyval, modifiers);
199
+ };
200
+ const didDispatchShortcutsOnAncestors = (widget, keyval, modifiers) => {
174
201
  for (let current = widget; current; current = current.getParent()) {
175
202
  if (didDispatchShortcutsOnWidget(current, keyval, modifiers)) {
176
203
  return true;
@@ -178,6 +205,9 @@ const didDispatchShortcuts = (widget, keyval, modifiers) => {
178
205
  }
179
206
  return false;
180
207
  };
208
+ const didDispatchShortcuts = (widget, keyval, modifiers) => didDispatchApplicationAccels(widget, keyval, modifiers) ||
209
+ didDispatchDelegateShortcuts(widget, keyval, modifiers) ||
210
+ didDispatchShortcutsOnAncestors(widget, keyval, modifiers);
181
211
  const handleKeyPress = async (widget, keyval, modifiers) => {
182
212
  const isHandled = didDispatchShortcuts(widget, keyval, modifiers);
183
213
  if (!isHandled && keyval === Gdk.KEY_Return && widget instanceof Gtk.Editable) {
@@ -186,11 +216,11 @@ const handleKeyPress = async (widget, keyval, modifiers) => {
186
216
  };
187
217
  const applyKeyAction = async (widget, controllers, state, action) => {
188
218
  updateModifierState(state, action);
189
- const signalName = action.press ? "key-pressed" : "key-released";
219
+ const signalName = action.isPress ? "key-pressed" : "key-released";
190
220
  for (const controller of controllers) {
191
221
  controller.emit(signalName, action.keyval, 0, state.modifierState);
192
222
  }
193
- if (action.press) {
223
+ if (action.isPress) {
194
224
  await handleKeyPress(widget, action.keyval, state.modifierState);
195
225
  }
196
226
  };
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../src/user-event/keyboard.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gdk from \"@gtkx/gi/gdk\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport type { UserEventState } from \"./state.js\";\nimport { getEditableDelegate } from \"../editable.js\";\nimport { fireEvent } from \"../fire-event.js\";\nimport { getOrCreateControllers } from \"./controller.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\n\n/** Options for {@link tab}: when `shift` is set, move focus backward instead of forward. */\ntype TabOptions = {\n shift?: boolean;\n};\n\ntype KeyAction = { keyval: number; press: boolean };\ntype ParseStep = { actions: KeyAction[]; next: number };\n\nconst KEY_MAP: Record<string, number> = {\n Enter: Gdk.KEY_Return,\n Tab: Gdk.KEY_Tab,\n Escape: Gdk.KEY_Escape,\n Backspace: Gdk.KEY_BackSpace,\n Delete: Gdk.KEY_Delete,\n ArrowUp: Gdk.KEY_Up,\n ArrowDown: Gdk.KEY_Down,\n ArrowLeft: Gdk.KEY_Left,\n ArrowRight: Gdk.KEY_Right,\n Home: Gdk.KEY_Home,\n End: Gdk.KEY_End,\n PageUp: Gdk.KEY_Page_Up,\n PageDown: Gdk.KEY_Page_Down,\n Space: Gdk.KEY_space,\n Shift: Gdk.KEY_Shift_L,\n Control: Gdk.KEY_Control_L,\n Alt: Gdk.KEY_Alt_L,\n Meta: Gdk.KEY_Meta_L,\n F1: Gdk.KEY_F1,\n F2: Gdk.KEY_F2,\n F3: Gdk.KEY_F3,\n F4: Gdk.KEY_F4,\n F5: Gdk.KEY_F5,\n F6: Gdk.KEY_F6,\n F7: Gdk.KEY_F7,\n F8: Gdk.KEY_F8,\n F9: Gdk.KEY_F9,\n F10: Gdk.KEY_F10,\n F11: Gdk.KEY_F11,\n F12: Gdk.KEY_F12,\n};\n\nconst MODIFIER_KEYVAL_TO_MASK: Record<number, number> = {\n [Gdk.KEY_Shift_L]: Gdk.ModifierType.SHIFT_MASK,\n [Gdk.KEY_Shift_R]: Gdk.ModifierType.SHIFT_MASK,\n [Gdk.KEY_Control_L]: Gdk.ModifierType.CONTROL_MASK,\n [Gdk.KEY_Control_R]: Gdk.ModifierType.CONTROL_MASK,\n [Gdk.KEY_Alt_L]: Gdk.ModifierType.ALT_MASK,\n [Gdk.KEY_Alt_R]: Gdk.ModifierType.ALT_MASK,\n [Gdk.KEY_Meta_L]: Gdk.ModifierType.META_MASK,\n [Gdk.KEY_Meta_R]: Gdk.ModifierType.META_MASK,\n};\n\nconst tab = (widget: Gtk.Widget, options?: TabOptions): Promise<void> =>\n wrapEvent(widget, () => {\n const direction = options?.shift ? Gtk.DirectionType.TAB_BACKWARD : Gtk.DirectionType.TAB_FORWARD;\n const root = widget.getRoot();\n\n if (root) {\n root.childFocus(direction);\n }\n });\n\nconst parseKeyToken = (token: string): { keyval: number; press: boolean; release: boolean } => {\n let keyName = token;\n let isPress = true;\n let isRelease = true;\n\n if (keyName.startsWith(\"/\")) {\n keyName = keyName.slice(1);\n isPress = false;\n } else if (keyName.endsWith(\">\")) {\n keyName = keyName.slice(0, -1);\n isRelease = false;\n }\n\n const keyval = KEY_MAP[keyName];\n\n if (keyval === undefined) {\n throw new Error(`Unknown key: {${keyName}}`);\n }\n\n return { keyval, press: isPress, release: isRelease };\n};\n\nconst parseCharAt = (input: string, i: number): ParseStep => {\n const keyval = input.codePointAt(i) ?? 0;\n\n return {\n actions: [\n { keyval, press: true },\n { keyval, press: false },\n ],\n next: i + 1,\n };\n};\n\nconst parseBraceAt = (input: string, i: number): ParseStep | null => {\n const endBrace = input.indexOf(\"}\", i);\n\n if (endBrace === -1) {\n return null;\n }\n\n const { keyval, press, release } = parseKeyToken(input.slice(i + 1, endBrace));\n const actions: KeyAction[] = [];\n\n if (press) {\n actions.push({ keyval, press: true });\n }\n\n if (release) {\n actions.push({ keyval, press: false });\n }\n\n return { actions, next: endBrace + 1 };\n};\n\nconst parseStepAt = (input: string, i: number): ParseStep | null =>\n input[i] === \"{\" ? parseBraceAt(input, i) : parseCharAt(input, i);\n\nconst parseKeyboardInput = (input: string): KeyAction[] => {\n const actions: KeyAction[] = [];\n let i = 0;\n\n while (i < input.length) {\n const step = parseStepAt(input, i);\n\n if (step === null) {\n break;\n }\n\n actions.push(...step.actions);\n i = step.next;\n }\n\n return actions;\n};\n\nconst updateModifierState = (state: UserEventState, action: KeyAction): void => {\n const mask = MODIFIER_KEYVAL_TO_MASK[action.keyval];\n\n if (!mask) {\n return;\n }\n\n if (action.press) {\n state.modifierState |= mask;\n } else {\n state.modifierState &= ~mask;\n }\n};\n\nconst isTriggerMatch = (\n trigger: Gtk.ShortcutTrigger | null,\n keyval: number,\n modifiers: Gdk.ModifierType,\n): boolean => {\n if (trigger instanceof Gtk.KeyvalTrigger) {\n return trigger.getKeyval() === keyval && trigger.getModifiers() === modifiers;\n }\n\n if (trigger instanceof Gtk.AlternativeTrigger) {\n return (\n isTriggerMatch(trigger.getFirst(), keyval, modifiers) ||\n isTriggerMatch(trigger.getSecond(), keyval, modifiers)\n );\n }\n\n return false;\n};\n\nconst didActivateShortcut = (\n shortcut: Gtk.Shortcut,\n widget: Gtk.Widget,\n keyval: number,\n modifiers: Gdk.ModifierType,\n): boolean => {\n if (!isTriggerMatch(shortcut.getTrigger(), keyval, modifiers)) {\n return false;\n }\n\n const action = shortcut.getAction();\n\n if (action instanceof Gtk.SignalAction && action.getSignalName() === \"move-focus\") {\n return false;\n }\n\n return action?.activate(0 as Gtk.ShortcutActionFlags, widget, shortcut.getArguments()) ?? false;\n};\n\nconst didActivateMatchingShortcut = (\n controller: Gtk.ShortcutController,\n widget: Gtk.Widget,\n keyval: number,\n modifiers: number,\n): boolean => {\n const count = controller.getNItems();\n\n for (let j = 0; j < count; j++) {\n const shortcut = controller.getItem(j);\n\n if (!(shortcut instanceof Gtk.Shortcut)) {\n continue;\n }\n\n if (didActivateShortcut(shortcut, widget, keyval, modifiers)) {\n return true;\n }\n }\n\n return false;\n};\n\nconst didDispatchShortcutsOnWidget = (widget: Gtk.Widget, keyval: number, modifiers: number): boolean => {\n const controllers = widget.observeControllers();\n\n for (let i = 0; i < controllers.getNItems(); i++) {\n const controller = controllers.getItem(i);\n\n if (\n controller instanceof Gtk.ShortcutController &&\n didActivateMatchingShortcut(controller, widget, keyval, modifiers)\n ) {\n return true;\n }\n }\n\n return false;\n};\n\nconst didDispatchShortcuts = (widget: Gtk.Widget, keyval: number, modifiers: number): boolean => {\n const delegate = getEditableDelegate(widget);\n\n if (delegate && didDispatchShortcutsOnWidget(delegate, keyval, modifiers)) {\n return true;\n }\n\n for (let current: Gtk.Widget | null = widget; current; current = current.getParent()) {\n if (didDispatchShortcutsOnWidget(current, keyval, modifiers)) {\n return true;\n }\n }\n\n return false;\n};\n\nconst handleKeyPress = async (widget: Gtk.Widget, keyval: number, modifiers: number): Promise<void> => {\n const isHandled = didDispatchShortcuts(widget, keyval, modifiers);\n\n if (!isHandled && keyval === Gdk.KEY_Return && widget instanceof Gtk.Editable) {\n await fireEvent(widget, \"activate\");\n }\n};\n\nconst applyKeyAction = async (\n widget: Gtk.Widget,\n controllers: Gtk.EventControllerKey[],\n state: UserEventState,\n action: KeyAction,\n): Promise<void> => {\n updateModifierState(state, action);\n const signalName = action.press ? \"key-pressed\" : \"key-released\";\n\n for (const controller of controllers) {\n controller.emit(signalName, action.keyval, 0, state.modifierState);\n }\n\n if (action.press) {\n await handleKeyPress(widget, action.keyval, state.modifierState);\n }\n};\n\nconst keyboard = (state: UserEventState, widget: Gtk.Widget, input: string): Promise<void> =>\n wrapEvent(widget, async () => {\n const controllers = getOrCreateControllers(widget, Gtk.EventControllerKey);\n\n for (const action of parseKeyboardInput(input)) {\n await applyKeyAction(widget, controllers, state, action);\n }\n });\n\nexport { tab, keyboard, type TabOptions };\n"]}
1
+ {"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../src/user-event/keyboard.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gdk from \"@gtkx/gi/gdk\";\nimport * as Gio from \"@gtkx/gi/gio\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport type { UserEventState } from \"./state.js\";\nimport { getEditableDelegate } from \"../editable.js\";\nimport { fireEvent } from \"../fire-event.js\";\nimport { getOrCreateControllers } from \"./controller.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\n\n/** Options for `userEvent.tab`. */\ntype TabOptions = {\n /** Move focus backward instead of forward. */\n isShiftHeld?: boolean;\n};\n\ntype KeyAction = { keyval: number; isPress: boolean };\ntype ParseStep = { actions: KeyAction[]; next: number };\n\nconst KEY_MAP: Record<string, number> = {\n Enter: Gdk.KEY_Return,\n Tab: Gdk.KEY_Tab,\n Escape: Gdk.KEY_Escape,\n Backspace: Gdk.KEY_BackSpace,\n Delete: Gdk.KEY_Delete,\n ArrowUp: Gdk.KEY_Up,\n ArrowDown: Gdk.KEY_Down,\n ArrowLeft: Gdk.KEY_Left,\n ArrowRight: Gdk.KEY_Right,\n Home: Gdk.KEY_Home,\n End: Gdk.KEY_End,\n PageUp: Gdk.KEY_Page_Up,\n PageDown: Gdk.KEY_Page_Down,\n Space: Gdk.KEY_space,\n Shift: Gdk.KEY_Shift_L,\n Control: Gdk.KEY_Control_L,\n Alt: Gdk.KEY_Alt_L,\n Meta: Gdk.KEY_Meta_L,\n F1: Gdk.KEY_F1,\n F2: Gdk.KEY_F2,\n F3: Gdk.KEY_F3,\n F4: Gdk.KEY_F4,\n F5: Gdk.KEY_F5,\n F6: Gdk.KEY_F6,\n F7: Gdk.KEY_F7,\n F8: Gdk.KEY_F8,\n F9: Gdk.KEY_F9,\n F10: Gdk.KEY_F10,\n F11: Gdk.KEY_F11,\n F12: Gdk.KEY_F12,\n};\n\nconst MODIFIER_KEYVAL_TO_MASK: Record<number, number> = {\n [Gdk.KEY_Shift_L]: Gdk.ModifierType.SHIFT_MASK,\n [Gdk.KEY_Shift_R]: Gdk.ModifierType.SHIFT_MASK,\n [Gdk.KEY_Control_L]: Gdk.ModifierType.CONTROL_MASK,\n [Gdk.KEY_Control_R]: Gdk.ModifierType.CONTROL_MASK,\n [Gdk.KEY_Alt_L]: Gdk.ModifierType.ALT_MASK,\n [Gdk.KEY_Alt_R]: Gdk.ModifierType.ALT_MASK,\n [Gdk.KEY_Meta_L]: Gdk.ModifierType.META_MASK,\n [Gdk.KEY_Meta_R]: Gdk.ModifierType.META_MASK,\n};\n\n/** Moves focus within the widget's root, forward by default and backward when `isShiftHeld` is set. */\nconst tab = (widget: Gtk.Widget, options?: TabOptions): Promise<void> =>\n wrapEvent(widget, () => {\n const direction = options?.isShiftHeld ? Gtk.DirectionType.TAB_BACKWARD : Gtk.DirectionType.TAB_FORWARD;\n const root = widget.getRoot();\n\n if (root) {\n root.childFocus(direction);\n }\n });\n\nconst parseKeyToken = (token: string): { keyval: number; isPress: boolean; isRelease: boolean } => {\n let keyName = token;\n let isPress = true;\n let isRelease = true;\n\n if (keyName.startsWith(\"/\")) {\n keyName = keyName.slice(1);\n isPress = false;\n } else if (keyName.endsWith(\">\")) {\n keyName = keyName.slice(0, -1);\n isRelease = false;\n }\n\n const keyval = KEY_MAP[keyName];\n\n if (keyval === undefined) {\n throw new Error(`Unknown key: {${keyName}}`);\n }\n\n return { keyval, isPress, isRelease };\n};\n\nconst parseCharAt = (input: string, i: number): ParseStep => {\n const keyval = input.codePointAt(i) ?? 0;\n\n return {\n actions: [\n { keyval, isPress: true },\n { keyval, isPress: false },\n ],\n next: i + 1,\n };\n};\n\nconst parseBraceAt = (input: string, i: number): ParseStep | null => {\n const endBrace = input.indexOf(\"}\", i);\n\n if (endBrace === -1) {\n return null;\n }\n\n const { keyval, isPress, isRelease } = parseKeyToken(input.slice(i + 1, endBrace));\n const actions: KeyAction[] = [];\n\n if (isPress) {\n actions.push({ keyval, isPress: true });\n }\n\n if (isRelease) {\n actions.push({ keyval, isPress: false });\n }\n\n return { actions, next: endBrace + 1 };\n};\n\nconst parseStepAt = (input: string, i: number): ParseStep | null =>\n input[i] === \"{\" ? parseBraceAt(input, i) : parseCharAt(input, i);\n\nconst parseKeyboardInput = (input: string): KeyAction[] => {\n const actions: KeyAction[] = [];\n let i = 0;\n\n while (i < input.length) {\n const step = parseStepAt(input, i);\n\n if (step === null) {\n break;\n }\n\n actions.push(...step.actions);\n i = step.next;\n }\n\n return actions;\n};\n\nconst updateModifierState = (state: UserEventState, action: KeyAction): void => {\n const mask = MODIFIER_KEYVAL_TO_MASK[action.keyval];\n\n if (!mask) {\n return;\n }\n\n if (action.isPress) {\n state.modifierState |= mask;\n } else {\n state.modifierState &= ~mask;\n }\n};\n\nconst isTriggerMatch = (\n trigger: Gtk.ShortcutTrigger | null,\n keyval: number,\n modifiers: Gdk.ModifierType,\n): boolean => {\n if (trigger instanceof Gtk.KeyvalTrigger) {\n return trigger.getKeyval() === keyval && trigger.getModifiers() === modifiers;\n }\n\n if (trigger instanceof Gtk.AlternativeTrigger) {\n return (\n isTriggerMatch(trigger.getFirst(), keyval, modifiers) ||\n isTriggerMatch(trigger.getSecond(), keyval, modifiers)\n );\n }\n\n return false;\n};\n\nconst didActivateShortcut = (\n shortcut: Gtk.Shortcut,\n widget: Gtk.Widget,\n keyval: number,\n modifiers: Gdk.ModifierType,\n): boolean => {\n if (!isTriggerMatch(shortcut.getTrigger(), keyval, modifiers)) {\n return false;\n }\n\n const action = shortcut.getAction();\n\n if (action instanceof Gtk.SignalAction && action.getSignalName() === \"move-focus\") {\n return false;\n }\n\n return action?.activate(0 as Gtk.ShortcutActionFlags, widget, shortcut.getArguments()) ?? false;\n};\n\nconst didActivateMatchingShortcut = (\n controller: Gtk.ShortcutController,\n widget: Gtk.Widget,\n keyval: number,\n modifiers: number,\n): boolean => {\n const count = controller.getNItems();\n\n for (let j = 0; j < count; j++) {\n const shortcut = controller.getItem(j);\n\n if (!(shortcut instanceof Gtk.Shortcut)) {\n continue;\n }\n\n if (didActivateShortcut(shortcut, widget, keyval, modifiers)) {\n return true;\n }\n }\n\n return false;\n};\n\nconst didDispatchShortcutsOnWidget = (widget: Gtk.Widget, keyval: number, modifiers: number): boolean => {\n const controllers = widget.observeControllers();\n\n for (let i = 0; i < controllers.getNItems(); i++) {\n const controller = controllers.getItem(i);\n\n if (\n controller instanceof Gtk.ShortcutController &&\n didActivateMatchingShortcut(controller, widget, keyval, modifiers)\n ) {\n return true;\n }\n }\n\n return false;\n};\n\nconst isAccelMatch = (accel: string, keyval: number, modifiers: Gdk.ModifierType): boolean => {\n const [isParsed, accelKeyval, accelModifiers] = Gtk.acceleratorParse(accel);\n\n return isParsed && accelKeyval === keyval && accelModifiers === modifiers;\n};\n\nconst hasMatchingAccel = (\n application: Gtk.Application,\n detailedActionName: string,\n keyval: number,\n modifiers: number,\n): boolean =>\n application.getAccelsForAction(detailedActionName).some((accel) => isAccelMatch(accel, keyval, modifiers));\n\nconst didActivateDetailedAction = (window: Gtk.Window, detailedActionName: string): boolean => {\n const [isParsed, actionName, target] = Gio.Action.parseDetailedName(detailedActionName);\n\n return isParsed && window.activateAction(actionName, target);\n};\n\nconst didDispatchAccelsOnWindow = (window: Gtk.Window, keyval: number, modifiers: number): boolean => {\n const application = window.getApplication();\n\n if (!application) {\n return false;\n }\n\n for (const detailedActionName of application.listActionDescriptions()) {\n if (hasMatchingAccel(application, detailedActionName, keyval, modifiers)) {\n return didActivateDetailedAction(window, detailedActionName);\n }\n }\n\n return false;\n};\n\nconst didDispatchApplicationAccels = (widget: Gtk.Widget, keyval: number, modifiers: number): boolean => {\n const root = widget.getRoot();\n\n return root instanceof Gtk.Window && didDispatchAccelsOnWindow(root, keyval, modifiers);\n};\n\nconst didDispatchDelegateShortcuts = (widget: Gtk.Widget, keyval: number, modifiers: number): boolean => {\n const delegate = getEditableDelegate(widget);\n\n return delegate !== null && didDispatchShortcutsOnWidget(delegate, keyval, modifiers);\n};\n\nconst didDispatchShortcutsOnAncestors = (widget: Gtk.Widget, keyval: number, modifiers: number): boolean => {\n for (let current: Gtk.Widget | null = widget; current; current = current.getParent()) {\n if (didDispatchShortcutsOnWidget(current, keyval, modifiers)) {\n return true;\n }\n }\n\n return false;\n};\n\nconst didDispatchShortcuts = (widget: Gtk.Widget, keyval: number, modifiers: number): boolean =>\n didDispatchApplicationAccels(widget, keyval, modifiers) ||\n didDispatchDelegateShortcuts(widget, keyval, modifiers) ||\n didDispatchShortcutsOnAncestors(widget, keyval, modifiers);\n\nconst handleKeyPress = async (widget: Gtk.Widget, keyval: number, modifiers: number): Promise<void> => {\n const isHandled = didDispatchShortcuts(widget, keyval, modifiers);\n\n if (!isHandled && keyval === Gdk.KEY_Return && widget instanceof Gtk.Editable) {\n await fireEvent(widget, \"activate\");\n }\n};\n\nconst applyKeyAction = async (\n widget: Gtk.Widget,\n controllers: Gtk.EventControllerKey[],\n state: UserEventState,\n action: KeyAction,\n): Promise<void> => {\n updateModifierState(state, action);\n const signalName = action.isPress ? \"key-pressed\" : \"key-released\";\n\n for (const controller of controllers) {\n controller.emit(signalName, action.keyval, 0, state.modifierState);\n }\n\n if (action.isPress) {\n await handleKeyPress(widget, action.keyval, state.modifierState);\n }\n};\n\nconst keyboard = (state: UserEventState, widget: Gtk.Widget, input: string): Promise<void> =>\n wrapEvent(widget, async () => {\n const controllers = getOrCreateControllers(widget, Gtk.EventControllerKey);\n\n for (const action of parseKeyboardInput(input)) {\n await applyKeyAction(widget, controllers, state, action);\n }\n });\n\nexport { tab, keyboard, type TabOptions };\n"]}
@@ -0,0 +1,4 @@
1
+ import type * as Gtk from "@gtkx/gi/gtk";
2
+ declare const applyRowClick: (row: Gtk.Widget, nPress: number) => void;
3
+ export { applyRowClick };
4
+ //# sourceMappingURL=list-row-click.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-row-click.d.ts","sourceRoot":"","sources":["../../src/user-event/list-row-click.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AAkDzC,QAAA,MAAM,aAAa,GAAI,KAAK,GAAG,CAAC,MAAM,EAAE,QAAQ,MAAM,KAAG,IAIxD,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,39 @@
1
+ import * as GLib from "@gtkx/gi/glib";
2
+ import { callBooleanGetter, hasWidgetMethod } from "../widget-getters.js";
3
+ const SELECT_ACTION = "listitem.select";
4
+ const SINGLE_CLICK_ACTIVATE_GETTER = "getSingleClickActivate";
5
+ const DOUBLE_CLICK_PRESS = 2;
6
+ const viewFor = (row) => {
7
+ let current = row.getParent();
8
+ while (current !== null) {
9
+ if (hasWidgetMethod(current, SINGLE_CLICK_ACTIVATE_GETTER)) {
10
+ return current;
11
+ }
12
+ current = current.getParent();
13
+ }
14
+ return null;
15
+ };
16
+ const isViewSingleClickActivating = (row) => {
17
+ const view = viewFor(row);
18
+ return view === null ? false : callBooleanGetter(view, SINGLE_CLICK_ACTIVATE_GETTER) ?? false;
19
+ };
20
+ const selectRow = (row) => {
21
+ row.activateAction(SELECT_ACTION, GLib.Variant.newTuple([GLib.Variant.newBoolean(false), GLib.Variant.newBoolean(false)]));
22
+ };
23
+ const isRowActivatedByPress = (row, press) => press === DOUBLE_CLICK_PRESS || isViewSingleClickActivating(row);
24
+ const applyRowPress = (row, press) => {
25
+ if (row.getFocusOnClick()) {
26
+ row.grabFocus();
27
+ }
28
+ selectRow(row);
29
+ if (isRowActivatedByPress(row, press)) {
30
+ row.activate();
31
+ }
32
+ };
33
+ const applyRowClick = (row, nPress) => {
34
+ for (let press = 1; press <= nPress; press++) {
35
+ applyRowPress(row, press);
36
+ }
37
+ };
38
+ export { applyRowClick };
39
+ //# sourceMappingURL=list-row-click.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-row-click.js","sourceRoot":"","sources":["../../src/user-event/list-row-click.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE1E,MAAM,aAAa,GAAG,iBAAiB,CAAC;AACxC,MAAM,4BAA4B,GAAG,wBAAwB,CAAC;AAC9D,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,MAAM,OAAO,GAAG,CAAC,GAAe,EAAqB,EAAE;IACnD,IAAI,OAAO,GAAsB,GAAG,CAAC,SAAS,EAAE,CAAC;IAEjD,OAAO,OAAO,KAAK,IAAI,EAAE,CAAC;QACtB,IAAI,eAAe,CAAC,OAAO,EAAE,4BAA4B,CAAC,EAAE,CAAC;YACzD,OAAO,OAAO,CAAC;QACnB,CAAC;QAED,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAClC,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,2BAA2B,GAAG,CAAC,GAAe,EAAW,EAAE;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE1B,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,4BAA4B,CAAC,IAAI,KAAK,CAAC;AAClG,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,GAAe,EAAQ,EAAE;IACxC,GAAG,CAAC,cAAc,CACd,aAAa,EACb,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAC1F,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,GAAe,EAAE,KAAa,EAAW,EAAE,CACtE,KAAK,KAAK,kBAAkB,IAAI,2BAA2B,CAAC,GAAG,CAAC,CAAC;AAErE,MAAM,aAAa,GAAG,CAAC,GAAe,EAAE,KAAa,EAAQ,EAAE;IAC3D,IAAI,GAAG,CAAC,eAAe,EAAE,EAAE,CAAC;QACxB,GAAG,CAAC,SAAS,EAAE,CAAC;IACpB,CAAC;IAED,SAAS,CAAC,GAAG,CAAC,CAAC;IAEf,IAAI,qBAAqB,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;QACpC,GAAG,CAAC,QAAQ,EAAE,CAAC;IACnB,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,GAAe,EAAE,MAAc,EAAQ,EAAE;IAC5D,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3C,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport * as GLib from \"@gtkx/gi/glib\";\nimport { callBooleanGetter, hasWidgetMethod } from \"../widget-getters.js\";\n\nconst SELECT_ACTION = \"listitem.select\";\nconst SINGLE_CLICK_ACTIVATE_GETTER = \"getSingleClickActivate\";\nconst DOUBLE_CLICK_PRESS = 2;\n\nconst viewFor = (row: Gtk.Widget): Gtk.Widget | null => {\n let current: Gtk.Widget | null = row.getParent();\n\n while (current !== null) {\n if (hasWidgetMethod(current, SINGLE_CLICK_ACTIVATE_GETTER)) {\n return current;\n }\n\n current = current.getParent();\n }\n\n return null;\n};\n\nconst isViewSingleClickActivating = (row: Gtk.Widget): boolean => {\n const view = viewFor(row);\n\n return view === null ? false : callBooleanGetter(view, SINGLE_CLICK_ACTIVATE_GETTER) ?? false;\n};\n\nconst selectRow = (row: Gtk.Widget): void => {\n row.activateAction(\n SELECT_ACTION,\n GLib.Variant.newTuple([GLib.Variant.newBoolean(false), GLib.Variant.newBoolean(false)]),\n );\n};\n\nconst isRowActivatedByPress = (row: Gtk.Widget, press: number): boolean =>\n press === DOUBLE_CLICK_PRESS || isViewSingleClickActivating(row);\n\nconst applyRowPress = (row: Gtk.Widget, press: number): void => {\n if (row.getFocusOnClick()) {\n row.grabFocus();\n }\n\n selectRow(row);\n\n if (isRowActivatedByPress(row, press)) {\n row.activate();\n }\n};\n\nconst applyRowClick = (row: Gtk.Widget, nPress: number): void => {\n for (let press = 1; press <= nPress; press++) {\n applyRowPress(row, press);\n }\n};\n\nexport { applyRowClick };\n"]}
@@ -0,0 +1,6 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ type NativeClick = (widget: Gtk.Widget, nPress: number) => void;
3
+ declare const isClickTransparent: (widget: Gtk.Widget) => boolean;
4
+ declare const nativeClickFor: (widget: Gtk.Widget, isClicked: boolean) => NativeClick | null;
5
+ export { isClickTransparent, type NativeClick, nativeClickFor };
6
+ //# sourceMappingURL=native-click.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-click.d.ts","sourceRoot":"","sources":["../../src/user-event/native-click.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAKpC,KAAK,WAAW,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAWhE,QAAA,MAAM,kBAAkB,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OACsB,CAAC;AAgBxE,QAAA,MAAM,cAAc,GAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,WAAW,OAAO,KAAG,WAAW,GAAG,IAU9E,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAE,KAAK,WAAW,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,32 @@
1
+ import * as Gtk from "@gtkx/gi/gtk";
2
+ import { getWidgetTypeName } from "../widget-getters.js";
3
+ import { applyHeaderClick } from "./column-header-click.js";
4
+ import { applyRowClick } from "./list-row-click.js";
5
+ const COLUMN_ROW_TYPE_NAME = "GtkColumnViewRowWidget";
6
+ const ROW_TYPE_NAMES = new Set([COLUMN_ROW_TYPE_NAME, "GtkListItemWidget"]);
7
+ const CELL_TYPE_NAME = "GtkColumnViewCellWidget";
8
+ const TITLE_TYPE_NAME = "GtkColumnViewTitle";
9
+ const TOGGLE_EXPAND_ACTION = "listitem.toggle-expand";
10
+ const isHeaderRow = (widget) => getWidgetTypeName(widget) === COLUMN_ROW_TYPE_NAME && widget.getParent() instanceof Gtk.ColumnView;
11
+ const isClickTransparent = (widget) => getWidgetTypeName(widget) === CELL_TYPE_NAME || isHeaderRow(widget);
12
+ const isExpanderToggling = (widget) => widget instanceof Gtk.TreeExpander &&
13
+ widget.getListRow()?.isExpandable() === true &&
14
+ !widget.getHideExpander();
15
+ const isColumnHeader = (widget) => getWidgetTypeName(widget) === TITLE_TYPE_NAME;
16
+ const isFactoryRow = (widget) => ROW_TYPE_NAMES.has(getWidgetTypeName(widget) ?? "");
17
+ const toggleExpander = (widget, nPress) => {
18
+ for (let press = 1; press <= nPress; press++) {
19
+ widget.activateAction(TOGGLE_EXPAND_ACTION, null);
20
+ }
21
+ };
22
+ const nativeClickFor = (widget, isClicked) => {
23
+ if (isClicked && isExpanderToggling(widget)) {
24
+ return toggleExpander;
25
+ }
26
+ if (isColumnHeader(widget)) {
27
+ return applyHeaderClick;
28
+ }
29
+ return isFactoryRow(widget) ? applyRowClick : null;
30
+ };
31
+ export { isClickTransparent, nativeClickFor };
32
+ //# sourceMappingURL=native-click.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-click.js","sourceRoot":"","sources":["../../src/user-event/native-click.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AACtD,MAAM,cAAc,GAAgB,IAAI,GAAG,CAAC,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,CAAC,CAAC;AACzF,MAAM,cAAc,GAAG,yBAAyB,CAAC;AACjD,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAC7C,MAAM,oBAAoB,GAAG,wBAAwB,CAAC;AAEtD,MAAM,WAAW,GAAG,CAAC,MAAkB,EAAW,EAAE,CAChD,iBAAiB,CAAC,MAAM,CAAC,KAAK,oBAAoB,IAAI,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,CAAC,UAAU,CAAC;AAEvG,MAAM,kBAAkB,GAAG,CAAC,MAAkB,EAAW,EAAE,CACvD,iBAAiB,CAAC,MAAM,CAAC,KAAK,cAAc,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;AAExE,MAAM,kBAAkB,GAAG,CAAC,MAAkB,EAAW,EAAE,CACvD,MAAM,YAAY,GAAG,CAAC,YAAY;IAClC,MAAM,CAAC,UAAU,EAAE,EAAE,YAAY,EAAE,KAAK,IAAI;IAC5C,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;AAE9B,MAAM,cAAc,GAAG,CAAC,MAAkB,EAAW,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,eAAe,CAAC;AACtG,MAAM,YAAY,GAAG,CAAC,MAAkB,EAAW,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AAE1G,MAAM,cAAc,GAAG,CAAC,MAAkB,EAAE,MAAc,EAAQ,EAAE;IAChE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3C,MAAM,CAAC,cAAc,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;IACtD,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,MAAkB,EAAE,SAAkB,EAAsB,EAAE;IAClF,IAAI,SAAS,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,OAAO,cAAc,CAAC;IAC1B,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,gBAAgB,CAAC;IAC5B,CAAC;IAED,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;AACvD,CAAC,CAAC;AAEF,OAAO,EAAE,kBAAkB,EAAoB,cAAc,EAAE,CAAC","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\nimport { getWidgetTypeName } from \"../widget-getters.js\";\nimport { applyHeaderClick } from \"./column-header-click.js\";\nimport { applyRowClick } from \"./list-row-click.js\";\n\ntype NativeClick = (widget: Gtk.Widget, nPress: number) => void;\n\nconst COLUMN_ROW_TYPE_NAME = \"GtkColumnViewRowWidget\";\nconst ROW_TYPE_NAMES: Set<string> = new Set([COLUMN_ROW_TYPE_NAME, \"GtkListItemWidget\"]);\nconst CELL_TYPE_NAME = \"GtkColumnViewCellWidget\";\nconst TITLE_TYPE_NAME = \"GtkColumnViewTitle\";\nconst TOGGLE_EXPAND_ACTION = \"listitem.toggle-expand\";\n\nconst isHeaderRow = (widget: Gtk.Widget): boolean =>\n getWidgetTypeName(widget) === COLUMN_ROW_TYPE_NAME && widget.getParent() instanceof Gtk.ColumnView;\n\nconst isClickTransparent = (widget: Gtk.Widget): boolean =>\n getWidgetTypeName(widget) === CELL_TYPE_NAME || isHeaderRow(widget);\n\nconst isExpanderToggling = (widget: Gtk.Widget): boolean =>\n widget instanceof Gtk.TreeExpander &&\n widget.getListRow()?.isExpandable() === true &&\n !widget.getHideExpander();\n\nconst isColumnHeader = (widget: Gtk.Widget): boolean => getWidgetTypeName(widget) === TITLE_TYPE_NAME;\nconst isFactoryRow = (widget: Gtk.Widget): boolean => ROW_TYPE_NAMES.has(getWidgetTypeName(widget) ?? \"\");\n\nconst toggleExpander = (widget: Gtk.Widget, nPress: number): void => {\n for (let press = 1; press <= nPress; press++) {\n widget.activateAction(TOGGLE_EXPAND_ACTION, null);\n }\n};\n\nconst nativeClickFor = (widget: Gtk.Widget, isClicked: boolean): NativeClick | null => {\n if (isClicked && isExpanderToggling(widget)) {\n return toggleExpander;\n }\n\n if (isColumnHeader(widget)) {\n return applyHeaderClick;\n }\n\n return isFactoryRow(widget) ? applyRowClick : null;\n};\n\nexport { isClickTransparent, type NativeClick, nativeClickFor };\n"]}
@@ -1,4 +1,4 @@
1
- import * as Gtk from "@gtkx/gi/gtk";
1
+ import type * as Gtk from "@gtkx/gi/gtk";
2
2
  import type { UserEventState } from "./state.js";
3
3
  /**
4
4
  * A pointer action token: a full click (`click`, `[MouseLeft]`), a button press (`down`,
@@ -1 +1 @@
1
- {"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../../src/user-event/pointer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjD;;;GAGG;AACH,KAAK,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc,CAAC;AA8B9F,QAAA,MAAM,OAAO,GAAI,OAAO,cAAc,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,OAAO,YAAY,KAAG,OAAO,CAAC,IAAI,CAGxF,CAAC;AAEP,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../../src/user-event/pointer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjD;;;GAGG;AACH,KAAK,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc,CAAC;AAoE9F,QAAA,MAAM,OAAO,GAAI,OAAO,cAAc,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,OAAO,YAAY,KAAG,OAAO,CAAC,IAAI,CAGxF,CAAC;AAEP,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,CAAC"}
@@ -1,26 +1,50 @@
1
- import * as Gtk from "@gtkx/gi/gtk";
2
- import { emitPress, emitRelease } from "./click.js";
3
- import { getOrCreateControllers } from "./controller.js";
1
+ import { clickGestures, emitClickPhase, getAuthoredClickGestures } from "./click.js";
4
2
  import { wrapEvent } from "./event-wrapper.js";
3
+ import { isClickTransparent, nativeClickFor } from "./native-click.js";
5
4
  const PRESS_INPUTS = new Set(["[MouseLeft>]", "down"]);
6
5
  const RELEASE_INPUTS = new Set(["[/MouseLeft]", "up"]);
7
6
  const CLICK_INPUTS = new Set(["[MouseLeft]", "click"]);
7
+ const pointerWidgetFor = (widget) => {
8
+ let current = widget;
9
+ while (isClickTransparent(current)) {
10
+ const parent = current.getParent();
11
+ if (parent === null) {
12
+ return current;
13
+ }
14
+ current = parent;
15
+ }
16
+ return current;
17
+ };
18
+ const pointerGesturesFor = (widget, native) => native === null ? clickGestures(widget) : getAuthoredClickGestures(widget);
19
+ const pointerTargetFor = (widget) => {
20
+ const target = pointerWidgetFor(widget);
21
+ const native = nativeClickFor(target, true);
22
+ return { widget: target, gestures: pointerGesturesFor(target, native), native };
23
+ };
24
+ const pressPointer = ({ widget, gestures }) => {
25
+ emitClickPhase(widget, gestures, 1, "pressed");
26
+ };
27
+ const releasePointer = ({ widget, gestures, native }) => {
28
+ emitClickPhase(widget, gestures, 1, "released");
29
+ native?.(widget, 1);
30
+ };
31
+ const isPointerPressable = (target) => target.native !== null || target.gestures.length > 0;
8
32
  const applyPointerInput = (widget, state, input) => {
9
- const controllers = getOrCreateControllers(widget, Gtk.GestureClick);
33
+ const target = pointerTargetFor(widget);
10
34
  if (CLICK_INPUTS.has(input)) {
11
- emitPress(widget, controllers, 1);
12
- emitRelease(widget, controllers, 1);
13
- state.mouseLeftDown = false;
35
+ pressPointer(target);
36
+ releasePointer(target);
37
+ state.isMouseLeftDown = false;
14
38
  return;
15
39
  }
16
- if (PRESS_INPUTS.has(input) && !state.mouseLeftDown) {
17
- emitPress(widget, controllers, 1);
18
- state.mouseLeftDown = true;
40
+ if (PRESS_INPUTS.has(input) && !state.isMouseLeftDown && isPointerPressable(target)) {
41
+ pressPointer(target);
42
+ state.isMouseLeftDown = true;
19
43
  return;
20
44
  }
21
- if (RELEASE_INPUTS.has(input) && state.mouseLeftDown) {
22
- emitRelease(widget, controllers, 1);
23
- state.mouseLeftDown = false;
45
+ if (RELEASE_INPUTS.has(input) && state.isMouseLeftDown) {
46
+ releasePointer(target);
47
+ state.isMouseLeftDown = false;
24
48
  }
25
49
  };
26
50
  const pointer = (state, widget, input) => wrapEvent(widget, () => {
@@ -1 +1 @@
1
- {"version":3,"file":"pointer.js","sourceRoot":"","sources":["../../src/user-event/pointer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAQ/C,MAAM,YAAY,GAAsB,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;AAC1E,MAAM,cAAc,GAAsB,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;AAC1E,MAAM,YAAY,GAAsB,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1E,MAAM,iBAAiB,GAAG,CAAC,MAAkB,EAAE,KAAqB,EAAE,KAAmB,EAAQ,EAAE;IAC/F,MAAM,WAAW,GAAG,sBAAsB,CAAC,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC;IAErE,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QAClC,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QACpC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;QAE5B,OAAO;IACX,CAAC;IAED,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QAClD,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QAClC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;QAE3B,OAAO;IACX,CAAC;IAED,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACnD,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QACpC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;IAChC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,OAAO,GAAG,CAAC,KAAqB,EAAE,MAAkB,EAAE,KAAmB,EAAiB,EAAE,CAC9F,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE;IACnB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEP,OAAO,EAAE,OAAO,EAAqB,CAAC","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\nimport type { UserEventState } from \"./state.js\";\nimport { emitPress, emitRelease } from \"./click.js\";\nimport { getOrCreateControllers } from \"./controller.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\n\n/**\n * A pointer action token: a full click (`click`, `[MouseLeft]`), a button press (`down`,\n * `[MouseLeft>]`), or a button release (`up`, `[/MouseLeft]`).\n */\ntype PointerInput = \"click\" | \"down\" | \"up\" | \"[MouseLeft]\" | \"[MouseLeft>]\" | \"[/MouseLeft]\";\n\nconst PRESS_INPUTS: Set<PointerInput> = new Set([\"[MouseLeft>]\", \"down\"]);\nconst RELEASE_INPUTS: Set<PointerInput> = new Set([\"[/MouseLeft]\", \"up\"]);\nconst CLICK_INPUTS: Set<PointerInput> = new Set([\"[MouseLeft]\", \"click\"]);\n\nconst applyPointerInput = (widget: Gtk.Widget, state: UserEventState, input: PointerInput): void => {\n const controllers = getOrCreateControllers(widget, Gtk.GestureClick);\n\n if (CLICK_INPUTS.has(input)) {\n emitPress(widget, controllers, 1);\n emitRelease(widget, controllers, 1);\n state.mouseLeftDown = false;\n\n return;\n }\n\n if (PRESS_INPUTS.has(input) && !state.mouseLeftDown) {\n emitPress(widget, controllers, 1);\n state.mouseLeftDown = true;\n\n return;\n }\n\n if (RELEASE_INPUTS.has(input) && state.mouseLeftDown) {\n emitRelease(widget, controllers, 1);\n state.mouseLeftDown = false;\n }\n};\n\nconst pointer = (state: UserEventState, widget: Gtk.Widget, input: PointerInput): Promise<void> =>\n wrapEvent(widget, () => {\n applyPointerInput(widget, state, input);\n });\n\nexport { pointer, type PointerInput };\n"]}
1
+ {"version":3,"file":"pointer.js","sourceRoot":"","sources":["../../src/user-event/pointer.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as Gtk from \"@gtkx/gi/gtk\";\nimport type { NativeClick } from \"./native-click.js\";\nimport type { UserEventState } from \"./state.js\";\nimport { clickGestures, emitClickPhase, getAuthoredClickGestures } from \"./click.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\nimport { isClickTransparent, nativeClickFor } from \"./native-click.js\";\n\n/**\n * A pointer action token: a full click (`click`, `[MouseLeft]`), a button press (`down`,\n * `[MouseLeft>]`), or a button release (`up`, `[/MouseLeft]`).\n */\ntype PointerInput = \"click\" | \"down\" | \"up\" | \"[MouseLeft]\" | \"[MouseLeft>]\" | \"[/MouseLeft]\";\ntype PointerTarget = { widget: Gtk.Widget; gestures: Gtk.GestureClick[]; native: NativeClick | null };\n\nconst PRESS_INPUTS: Set<PointerInput> = new Set([\"[MouseLeft>]\", \"down\"]);\nconst RELEASE_INPUTS: Set<PointerInput> = new Set([\"[/MouseLeft]\", \"up\"]);\nconst CLICK_INPUTS: Set<PointerInput> = new Set([\"[MouseLeft]\", \"click\"]);\n\nconst pointerWidgetFor = (widget: Gtk.Widget): Gtk.Widget => {\n let current = widget;\n\n while (isClickTransparent(current)) {\n const parent = current.getParent();\n\n if (parent === null) {\n return current;\n }\n\n current = parent;\n }\n\n return current;\n};\n\nconst pointerGesturesFor = (widget: Gtk.Widget, native: NativeClick | null): Gtk.GestureClick[] =>\n native === null ? clickGestures(widget) : getAuthoredClickGestures(widget);\n\nconst pointerTargetFor = (widget: Gtk.Widget): PointerTarget => {\n const target = pointerWidgetFor(widget);\n const native = nativeClickFor(target, true);\n\n return { widget: target, gestures: pointerGesturesFor(target, native), native };\n};\n\nconst pressPointer = ({ widget, gestures }: PointerTarget): void => {\n emitClickPhase(widget, gestures, 1, \"pressed\");\n};\n\nconst releasePointer = ({ widget, gestures, native }: PointerTarget): void => {\n emitClickPhase(widget, gestures, 1, \"released\");\n native?.(widget, 1);\n};\n\nconst isPointerPressable = (target: PointerTarget): boolean => target.native !== null || target.gestures.length > 0;\n\nconst applyPointerInput = (widget: Gtk.Widget, state: UserEventState, input: PointerInput): void => {\n const target = pointerTargetFor(widget);\n\n if (CLICK_INPUTS.has(input)) {\n pressPointer(target);\n releasePointer(target);\n state.isMouseLeftDown = false;\n\n return;\n }\n\n if (PRESS_INPUTS.has(input) && !state.isMouseLeftDown && isPointerPressable(target)) {\n pressPointer(target);\n state.isMouseLeftDown = true;\n\n return;\n }\n\n if (RELEASE_INPUTS.has(input) && state.isMouseLeftDown) {\n releasePointer(target);\n state.isMouseLeftDown = false;\n }\n};\n\nconst pointer = (state: UserEventState, widget: Gtk.Widget, input: PointerInput): Promise<void> =>\n wrapEvent(widget, () => {\n applyPointerInput(widget, state, input);\n });\n\nexport { pointer, type PointerInput };\n"]}
@@ -1,5 +1,23 @@
1
1
  import * as Gtk from "@gtkx/gi/gtk";
2
+ /**
3
+ * Selects the items at the given positions through a list, grid, or column view's selection model,
4
+ * by setting the selected position of a widget with the COMBO_BOX role, or by selecting the indexed
5
+ * children of a list box or flow box through their container. An empty array clears a view's
6
+ * selection. The children are never activated, so no row-activated handler runs.
7
+ *
8
+ * @throws When a view has no selection model, when a COMBO_BOX-role widget is given more than one
9
+ * position or exposes no `setSelected`, or when the widget's role is none of COMBO_BOX, GRID, or
10
+ * LIST.
11
+ */
2
12
  declare const selectOptions: (widget: Gtk.Widget, values: number | number[]) => Promise<void>;
13
+ /**
14
+ * Unselects the items at the given positions in a list, grid, or column view, or unselects the
15
+ * indexed children of a list box or flow box through their container. A child that is not selected
16
+ * is left alone, and no child is activated.
17
+ *
18
+ * @throws When a view has no selection model, when the widget's role is none of COMBO_BOX, GRID, or
19
+ * LIST, or when it exposes no indexed children.
20
+ */
3
21
  declare const deselectOptions: (widget: Gtk.Widget, values: number | number[]) => Promise<void>;
4
22
  export { selectOptions, deselectOptions };
5
23
  //# sourceMappingURL=selection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../src/user-event/selection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAwIpC,QAAA,MAAM,aAAa,GAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,QAAQ,MAAM,GAAG,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CACd,CAAC;AAkBtE,QAAA,MAAM,eAAe,GAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,QAAQ,MAAM,GAAG,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CACZ,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../src/user-event/selection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AA6JpC;;;;;;;;;GASG;AACH,QAAA,MAAM,aAAa,GAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,QAAQ,MAAM,GAAG,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CACd,CAAC;AAoBtE;;;;;;;GAOG;AACH,QAAA,MAAM,eAAe,GAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,QAAQ,MAAM,GAAG,MAAM,EAAE,KAAG,OAAO,CAAC,IAAI,CACZ,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC"}
@@ -1,7 +1,13 @@
1
1
  import * as Gtk from "@gtkx/gi/gtk";
2
2
  import { formatRoleList } from "../role-helpers.js";
3
+ import { getCallableMethod } from "../widget-getters.js";
3
4
  import { wrapEvent } from "./event-wrapper.js";
4
- const SELECTABLE_ROLES = new Set([Gtk.AccessibleRole.COMBO_BOX, Gtk.AccessibleRole.LIST]);
5
+ import { getChildAtIndex, hasIndexedChildren, isChildSelected, selectContainerChild, unselectContainerChild, } from "./indexed-children.js";
6
+ const SELECTABLE_ROLES = new Set([
7
+ Gtk.AccessibleRole.COMBO_BOX,
8
+ Gtk.AccessibleRole.GRID,
9
+ Gtk.AccessibleRole.LIST,
10
+ ]);
5
11
  const isSelectable = (widget) => {
6
12
  return SELECTABLE_ROLES.has(widget.getAccessibleRole());
7
13
  };
@@ -24,35 +30,31 @@ const selectListViewItems = (selectionModel, positions, isExclusive) => {
24
30
  selectionModel.setSelection(selected, mask);
25
31
  };
26
32
  const isListView = (widget) => widget instanceof Gtk.ListView || widget instanceof Gtk.GridView || widget instanceof Gtk.ColumnView;
27
- const selectComboBoxOption = (widget, valueArray) => {
33
+ const getIndexSelector = (widget) => getCallableMethod(widget, "setSelected");
34
+ const selectDropDownOption = (widget, valueArray) => {
35
+ const setSelected = getIndexSelector(widget);
36
+ if (!setSelected) {
37
+ throw new TypeError("Cannot select options: the COMBO_BOX role needs a widget exposing setSelected");
38
+ }
28
39
  if (valueArray.length > 1) {
29
- throw new Error("Cannot select multiple options: ComboBox only supports single selection");
40
+ throw new Error("Cannot select multiple options: a drop-down only supports single selection");
30
41
  }
31
42
  const [selection] = valueArray;
32
- if (selection === undefined) {
33
- return;
34
- }
35
- if (widget instanceof Gtk.DropDown) {
36
- widget.setSelected(selection);
43
+ if (selection !== undefined) {
44
+ setSelected(selection);
37
45
  }
38
- else if (widget instanceof Gtk.ComboBox) {
39
- widget.setActive(selection);
40
- }
41
- };
42
- const selectListBoxRow = (listBox, row) => {
43
- listBox.selectRow(row);
44
- row.activate();
45
46
  };
46
- const unselectListBoxRow = (listBox, row) => {
47
- listBox.unselectRow(row);
47
+ const unselectChildRow = (container, child) => {
48
+ if (isChildSelected(child)) {
49
+ unselectContainerChild(container, child);
50
+ }
48
51
  };
49
- const applyListBoxRows = (listBox, valueArray, apply) => {
52
+ const applyIndexedChildren = (widget, valueArray, apply) => {
50
53
  for (const value of valueArray) {
51
- const row = listBox.getRowAtIndex(value);
52
- if (!row) {
53
- continue;
54
+ const child = getChildAtIndex(widget, value);
55
+ if (child) {
56
+ apply(widget, child);
54
57
  }
55
- apply(listBox, row);
56
58
  }
57
59
  };
58
60
  const requireSelectionModel = (widget, verb) => {
@@ -67,17 +69,22 @@ const selectInListView = (widget, valueArray) => {
67
69
  const isMultiSelection = selectionModel instanceof Gtk.MultiSelection;
68
70
  selectListViewItems(selectionModel, valueArray, !isMultiSelection);
69
71
  };
70
- const selectByRole = (widget, valueArray) => {
72
+ const requireSelectableRole = (widget, verb) => {
71
73
  if (!isSelectable(widget)) {
72
- throw new Error(`Cannot select options: expected selectable widget (${formatRoleList(SELECTABLE_ROLES)})`);
74
+ throw new Error(`Cannot ${verb} options: expected selectable widget (${formatRoleList(SELECTABLE_ROLES)})`);
73
75
  }
76
+ };
77
+ const selectByRole = (widget, valueArray) => {
78
+ requireSelectableRole(widget, "select");
74
79
  const role = widget.getAccessibleRole();
75
80
  if (role === Gtk.AccessibleRole.COMBO_BOX) {
76
- selectComboBoxOption(widget, valueArray);
81
+ selectDropDownOption(widget, valueArray);
82
+ return;
77
83
  }
78
- else if (widget instanceof Gtk.ListBox) {
79
- applyListBoxRows(widget, valueArray, selectListBoxRow);
84
+ if (!hasIndexedChildren(widget)) {
85
+ throw new TypeError("Cannot select options: the widget exposes no children to select by index");
80
86
  }
87
+ applyIndexedChildren(widget, valueArray, selectContainerChild);
81
88
  };
82
89
  const runSelectionEvent = (widget, values, inListView, byRole) => wrapEvent(widget, () => {
83
90
  const valueArray = Array.isArray(values) ? values : [values];
@@ -87,6 +94,16 @@ const runSelectionEvent = (widget, values, inListView, byRole) => wrapEvent(widg
87
94
  }
88
95
  byRole(widget, valueArray);
89
96
  });
97
+ /**
98
+ * Selects the items at the given positions through a list, grid, or column view's selection model,
99
+ * by setting the selected position of a widget with the COMBO_BOX role, or by selecting the indexed
100
+ * children of a list box or flow box through their container. An empty array clears a view's
101
+ * selection. The children are never activated, so no row-activated handler runs.
102
+ *
103
+ * @throws When a view has no selection model, when a COMBO_BOX-role widget is given more than one
104
+ * position or exposes no `setSelected`, or when the widget's role is none of COMBO_BOX, GRID, or
105
+ * LIST.
106
+ */
90
107
  const selectOptions = (widget, values) => runSelectionEvent(widget, values, selectInListView, selectByRole);
91
108
  const deselectInListView = (widget, valueArray) => {
92
109
  const selectionModel = requireSelectionModel(widget, "deselect");
@@ -95,11 +112,20 @@ const deselectInListView = (widget, valueArray) => {
95
112
  }
96
113
  };
97
114
  const deselectByRole = (widget, valueArray) => {
98
- if (!(widget instanceof Gtk.ListBox)) {
99
- throw new TypeError("Cannot deselect options: only ListBox supports deselection");
115
+ requireSelectableRole(widget, "deselect");
116
+ if (!hasIndexedChildren(widget)) {
117
+ throw new TypeError("Cannot deselect options: the widget exposes no children to deselect by index");
100
118
  }
101
- applyListBoxRows(widget, valueArray, unselectListBoxRow);
119
+ applyIndexedChildren(widget, valueArray, unselectChildRow);
102
120
  };
121
+ /**
122
+ * Unselects the items at the given positions in a list, grid, or column view, or unselects the
123
+ * indexed children of a list box or flow box through their container. A child that is not selected
124
+ * is left alone, and no child is activated.
125
+ *
126
+ * @throws When a view has no selection model, when the widget's role is none of COMBO_BOX, GRID, or
127
+ * LIST, or when it exposes no indexed children.
128
+ */
103
129
  const deselectOptions = (widget, values) => runSelectionEvent(widget, values, deselectInListView, deselectByRole);
104
130
  export { selectOptions, deselectOptions };
105
131
  //# sourceMappingURL=selection.js.map