@gtkx/testing 1.0.0-rc.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/accessible-native.d.ts +16 -0
- package/dist/accessible-native.d.ts.map +1 -0
- package/dist/accessible-native.js +206 -0
- package/dist/accessible-native.js.map +1 -0
- package/dist/act.d.ts +1 -3
- package/dist/act.d.ts.map +1 -1
- package/dist/act.js +1 -1
- package/dist/act.js.map +1 -1
- package/dist/build-queries.d.ts +27 -10
- package/dist/build-queries.d.ts.map +1 -1
- package/dist/build-queries.js +22 -24
- package/dist/build-queries.js.map +1 -1
- package/dist/cleanup-registry.d.ts +1 -1
- package/dist/cleanup-registry.d.ts.map +1 -1
- package/dist/cleanup-registry.js.map +1 -1
- package/dist/config.d.ts +8 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +10 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -1
- package/dist/errors.js.map +1 -1
- package/dist/fire-event.d.ts +35 -6
- package/dist/fire-event.d.ts.map +1 -1
- package/dist/fire-event.js +23 -7
- package/dist/fire-event.js.map +1 -1
- package/dist/frame-sync.d.ts +3 -2
- package/dist/frame-sync.d.ts.map +1 -1
- package/dist/frame-sync.js +19 -9
- package/dist/frame-sync.js.map +1 -1
- package/dist/harness-window.d.ts +5 -0
- package/dist/harness-window.d.ts.map +1 -0
- package/dist/harness-window.js +17 -0
- package/dist/harness-window.js.map +1 -0
- package/dist/index.d.ts +14 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +5 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +5 -0
- package/dist/internal.js.map +1 -0
- package/dist/matchers.d.ts +88 -46
- package/dist/matchers.d.ts.map +1 -1
- package/dist/matchers.js +178 -20
- package/dist/matchers.js.map +1 -1
- package/dist/pretty-format.d.ts +2 -0
- package/dist/pretty-format.d.ts.map +1 -0
- package/dist/pretty-format.js +2 -0
- package/dist/pretty-format.js.map +1 -0
- package/dist/pretty-widget.d.ts +5 -2
- package/dist/pretty-widget.d.ts.map +1 -1
- package/dist/pretty-widget.js +75 -57
- package/dist/pretty-widget.js.map +1 -1
- package/dist/production.d.ts +8 -0
- package/dist/production.d.ts.map +1 -0
- package/dist/production.js +34 -0
- package/dist/production.js.map +1 -0
- package/dist/queries.d.ts +98 -56
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +123 -83
- package/dist/queries.js.map +1 -1
- package/dist/query-helpers.d.ts +44 -0
- package/dist/query-helpers.d.ts.map +1 -0
- package/dist/query-helpers.js +57 -0
- package/dist/query-helpers.js.map +1 -0
- package/dist/render-children.d.ts +9 -0
- package/dist/render-children.d.ts.map +1 -0
- package/dist/render-children.js +11 -0
- package/dist/render-children.js.map +1 -0
- package/dist/render.d.ts +12 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +52 -16
- package/dist/render.js.map +1 -1
- package/dist/role-helpers.d.ts +12 -3
- package/dist/role-helpers.d.ts.map +1 -1
- package/dist/role-helpers.js +15 -5
- package/dist/role-helpers.js.map +1 -1
- package/dist/role-naming.d.ts +5 -0
- package/dist/role-naming.d.ts.map +1 -0
- package/dist/role-naming.js +96 -0
- package/dist/role-naming.js.map +1 -0
- package/dist/screenshot.d.ts +12 -20
- package/dist/screenshot.d.ts.map +1 -1
- package/dist/screenshot.js +179 -93
- package/dist/screenshot.js.map +1 -1
- package/dist/timers.d.ts +9 -0
- package/dist/timers.d.ts.map +1 -0
- package/dist/timers.js +21 -0
- package/dist/timers.js.map +1 -0
- package/dist/traversal.d.ts +7 -1
- package/dist/traversal.d.ts.map +1 -1
- package/dist/traversal.js +40 -6
- package/dist/traversal.js.map +1 -1
- package/dist/types.d.ts +32 -15
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/user-event/adjustment.d.ts +3 -0
- package/dist/user-event/adjustment.d.ts.map +1 -1
- package/dist/user-event/adjustment.js +25 -3
- package/dist/user-event/adjustment.js.map +1 -1
- package/dist/user-event/click.d.ts +44 -8
- package/dist/user-event/click.d.ts.map +1 -1
- package/dist/user-event/click.js +176 -44
- package/dist/user-event/click.js.map +1 -1
- package/dist/user-event/column-header-click.d.ts +4 -0
- package/dist/user-event/column-header-click.d.ts.map +1 -0
- package/dist/user-event/column-header-click.js +55 -0
- package/dist/user-event/column-header-click.js.map +1 -0
- package/dist/user-event/event-wrapper.d.ts.map +1 -1
- package/dist/user-event/event-wrapper.js +34 -20
- package/dist/user-event/event-wrapper.js.map +1 -1
- package/dist/user-event/index.d.ts +80 -13
- package/dist/user-event/index.d.ts.map +1 -1
- package/dist/user-event/index.js +44 -26
- package/dist/user-event/index.js.map +1 -1
- package/dist/user-event/indexed-children.d.ts +10 -0
- package/dist/user-event/indexed-children.d.ts.map +1 -0
- package/dist/user-event/indexed-children.js +50 -0
- package/dist/user-event/indexed-children.js.map +1 -0
- package/dist/user-event/keyboard.d.ts.map +1 -1
- package/dist/user-event/keyboard.js +115 -31
- package/dist/user-event/keyboard.js.map +1 -1
- package/dist/user-event/list-row-click.d.ts +4 -0
- package/dist/user-event/list-row-click.d.ts.map +1 -0
- package/dist/user-event/list-row-click.js +38 -0
- package/dist/user-event/list-row-click.js.map +1 -0
- package/dist/user-event/native-click.d.ts +6 -0
- package/dist/user-event/native-click.d.ts.map +1 -0
- package/dist/user-event/native-click.js +36 -0
- package/dist/user-event/native-click.js.map +1 -0
- package/dist/user-event/notebook-tab-click.d.ts +5 -0
- package/dist/user-event/notebook-tab-click.d.ts.map +1 -0
- package/dist/user-event/notebook-tab-click.js +39 -0
- package/dist/user-event/notebook-tab-click.js.map +1 -0
- package/dist/user-event/pointer.d.ts +1 -1
- package/dist/user-event/pointer.d.ts.map +1 -1
- package/dist/user-event/pointer.js +33 -9
- package/dist/user-event/pointer.js.map +1 -1
- package/dist/user-event/selection.d.ts +11 -8
- package/dist/user-event/selection.d.ts.map +1 -1
- package/dist/user-event/selection.js +49 -38
- package/dist/user-event/selection.js.map +1 -1
- package/dist/user-event/text.d.ts +12 -5
- package/dist/user-event/text.d.ts.map +1 -1
- package/dist/user-event/text.js +151 -46
- package/dist/user-event/text.js.map +1 -1
- package/dist/wait-for.d.ts.map +1 -1
- package/dist/wait-for.js +4 -3
- package/dist/wait-for.js.map +1 -1
- package/dist/widget-accessible-properties.d.ts +14 -26
- package/dist/widget-accessible-properties.d.ts.map +1 -1
- package/dist/widget-accessible-properties.js +135 -190
- package/dist/widget-accessible-properties.js.map +1 -1
- package/dist/widget-getters.d.ts +11 -0
- package/dist/widget-getters.d.ts.map +1 -0
- package/dist/widget-getters.js +46 -0
- package/dist/widget-getters.js.map +1 -0
- package/dist/window-state.d.ts +10 -0
- package/dist/window-state.d.ts.map +1 -0
- package/dist/window-state.js +41 -0
- package/dist/window-state.js.map +1 -0
- package/dist/within.d.ts +3 -2
- package/dist/within.d.ts.map +1 -1
- package/dist/within.js +3 -2
- package/dist/within.js.map +1 -1
- package/package.json +21 -8
- package/src/accessible-native.ts +333 -0
- package/src/act.ts +1 -1
- package/src/build-queries.ts +47 -41
- package/src/cleanup-registry.ts +1 -1
- package/src/config.ts +10 -1
- package/src/errors.ts +12 -1
- package/src/fire-event.ts +61 -8
- package/src/frame-sync.ts +30 -9
- package/src/harness-window.ts +23 -0
- package/src/index.ts +18 -11
- package/src/internal.ts +12 -0
- package/src/matchers.ts +457 -72
- package/src/pretty-format.ts +1 -0
- package/src/pretty-widget.ts +98 -70
- package/src/production.ts +51 -0
- package/src/queries.ts +127 -89
- package/src/query-helpers.ts +97 -0
- package/src/render-children.ts +25 -0
- package/src/render.tsx +77 -17
- package/src/role-helpers.ts +16 -5
- package/src/role-naming.ts +99 -0
- package/src/screenshot.ts +266 -104
- package/src/timers.ts +31 -0
- package/src/traversal.ts +66 -6
- package/src/types.ts +34 -17
- package/src/user-event/adjustment.ts +31 -3
- package/src/user-event/click.ts +248 -52
- package/src/user-event/column-header-click.ts +76 -0
- package/src/user-event/event-wrapper.ts +41 -23
- package/src/user-event/index.ts +130 -40
- package/src/user-event/indexed-children.ts +75 -0
- package/src/user-event/keyboard.ts +161 -43
- package/src/user-event/list-row-click.ts +54 -0
- package/src/user-event/native-click.ts +51 -0
- package/src/user-event/notebook-tab-click.ts +57 -0
- package/src/user-event/pointer.ts +48 -9
- package/src/user-event/selection.ts +67 -41
- package/src/user-event/text.ts +192 -46
- package/src/wait-for.ts +4 -4
- package/src/widget-accessible-properties.ts +183 -230
- package/src/widget-getters.ts +85 -0
- package/src/window-state.ts +70 -0
- package/src/within.ts +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/user-event/selection.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\nimport { formatRoleList } from \"../role-helpers.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\n\ntype CollectionWidget = Gtk.ListView | Gtk.GridView | Gtk.ColumnView;\ntype ListBoxRowAction = (listBox: Gtk.ListBox, row: Gtk.ListBoxRow) => void;\n\nconst SELECTABLE_ROLES: Set<Gtk.AccessibleRole> = new Set([Gtk.AccessibleRole.COMBO_BOX, Gtk.AccessibleRole.LIST]);\n\nconst isSelectable = (widget: Gtk.Widget): boolean => {\n return SELECTABLE_ROLES.has(widget.getAccessibleRole());\n};\n\nconst selectListViewItems = (\n selectionModel: Gtk.SelectionModel,\n positions: number[],\n isExclusive: boolean,\n): void => {\n if (positions.length === 0) {\n selectionModel.unselectRange(0, selectionModel.getNItems());\n\n return;\n }\n\n const [first] = positions;\n\n if (isExclusive && first !== undefined && positions.length === 1) {\n selectionModel.selectItem(first, true);\n\n return;\n }\n\n const nItems = selectionModel.getNItems();\n const selected = Gtk.Bitset.newEmpty();\n const mask = Gtk.Bitset.newRange(0, nItems);\n\n for (const pos of positions) {\n selected.add(pos);\n }\n\n selectionModel.setSelection(selected, mask);\n};\n\nconst isListView = (widget: Gtk.Widget): widget is CollectionWidget =>\n widget instanceof Gtk.ListView || widget instanceof Gtk.GridView || widget instanceof Gtk.ColumnView;\n\nconst selectComboBoxOption = (widget: Gtk.Widget, valueArray: number[]): void => {\n if (valueArray.length > 1) {\n throw new Error(\"Cannot select multiple options: ComboBox only supports single selection\");\n }\n\n const [selection] = valueArray;\n\n if (selection === undefined) {\n return;\n }\n\n if (widget instanceof Gtk.DropDown) {\n widget.setSelected(selection);\n } else if (widget instanceof Gtk.ComboBox) {\n widget.setActive(selection);\n }\n};\n\nconst selectListBoxRow = (listBox: Gtk.ListBox, row: Gtk.ListBoxRow): void => {\n listBox.selectRow(row);\n row.activate();\n};\n\nconst unselectListBoxRow = (listBox: Gtk.ListBox, row: Gtk.ListBoxRow): void => {\n listBox.unselectRow(row);\n};\n\nconst applyListBoxRows = (listBox: Gtk.ListBox, valueArray: number[], apply: ListBoxRowAction): void => {\n for (const value of valueArray) {\n const row = listBox.getRowAtIndex(value);\n\n if (!row) {\n continue;\n }\n\n apply(listBox, row);\n }\n};\n\nconst requireSelectionModel = (\n widget: CollectionWidget,\n verb: string,\n): Gtk.SelectionModel => {\n const selectionModel = widget.getModel();\n\n if (selectionModel === null) {\n throw new Error(`Cannot ${verb} options: list view has no selection model`);\n }\n\n return selectionModel;\n};\n\nconst selectInListView = (widget: CollectionWidget, valueArray: number[]): void => {\n const selectionModel = requireSelectionModel(widget, \"select\");\n const isMultiSelection = selectionModel instanceof Gtk.MultiSelection;\n selectListViewItems(selectionModel, valueArray, !isMultiSelection);\n};\n\nconst selectByRole = (widget: Gtk.Widget, valueArray: number[]): void => {\n if (!isSelectable(widget)) {\n throw new Error(`Cannot select options: expected selectable widget (${formatRoleList(SELECTABLE_ROLES)})`);\n }\n\n const role = widget.getAccessibleRole();\n\n if (role === Gtk.AccessibleRole.COMBO_BOX) {\n selectComboBoxOption(widget, valueArray);\n } else if (widget instanceof Gtk.ListBox) {\n applyListBoxRows(widget, valueArray, selectListBoxRow);\n }\n};\n\nconst runSelectionEvent = (\n widget: Gtk.Widget,\n values: number | number[],\n inListView: (view: Gtk.ListView | Gtk.GridView | Gtk.ColumnView, valueArray: number[]) => void,\n byRole: (widget: Gtk.Widget, valueArray: number[]) => void,\n): Promise<void> =>\n wrapEvent(widget, () => {\n const valueArray = Array.isArray(values) ? values : [values];\n\n if (isListView(widget)) {\n inListView(widget, valueArray);\n\n return;\n }\n\n byRole(widget, valueArray);\n });\n\n/**\n * Selects the items at the given positions through a list, grid, or column view's selection model,\n * by setting the active item of a drop-down or combo box, or by selecting list box rows. An empty\n * array clears a view's selection.\n *\n * @throws When a view has no selection model, when a combo box is given more than one position, or\n * when the widget is neither a view nor something with the combo box or list role.\n */\nconst selectOptions = (widget: Gtk.Widget, values: number | number[]): Promise<void> =>\n runSelectionEvent(widget, values, selectInListView, selectByRole);\n\nconst deselectInListView = (widget: Gtk.ListView | Gtk.GridView | Gtk.ColumnView, valueArray: number[]): void => {\n const selectionModel = requireSelectionModel(widget, \"deselect\");\n\n for (const pos of valueArray) {\n selectionModel.unselectItem(pos);\n }\n};\n\nconst deselectByRole = (widget: Gtk.Widget, valueArray: number[]): void => {\n if (!(widget instanceof Gtk.ListBox)) {\n throw new TypeError(\"Cannot deselect options: only ListBox supports deselection\");\n }\n\n applyListBoxRows(widget, valueArray, unselectListBoxRow);\n};\n\n/**\n * Unselects the items at the given positions in a list, grid, or column view, or the rows at those\n * indices in a Gtk.ListBox.\n *\n * @throws When a view has no selection model, or when the widget is neither one of those views nor\n * a Gtk.ListBox.\n */\nconst deselectOptions = (widget: Gtk.Widget, values: number | number[]): Promise<void> =>\n runSelectionEvent(widget, values, deselectInListView, deselectByRole);\n\nexport { selectOptions, deselectOptions };\n"]}
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../src/user-event/selection.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\nimport { formatRoleList } from \"../role-helpers.js\";\nimport { getCallableMethod } from \"../widget-getters.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\nimport {\n getChildAtIndex,\n hasIndexedChildren,\n isChildSelected,\n selectContainerChild,\n unselectContainerChild,\n} from \"./indexed-children.js\";\n\ntype CollectionWidget = Gtk.ListView | Gtk.GridView | Gtk.ColumnView;\ntype IndexedChildAction = (container: Gtk.Widget, child: Gtk.Widget) => void;\n\nconst SELECTABLE_ROLES: Set<Gtk.AccessibleRole> = new Set([\n Gtk.AccessibleRole.COMBO_BOX,\n Gtk.AccessibleRole.GRID,\n Gtk.AccessibleRole.LIST,\n]);\n\nconst isSelectable = (widget: Gtk.Widget): boolean => {\n return SELECTABLE_ROLES.has(widget.getAccessibleRole());\n};\n\nconst selectListViewItems = (\n selectionModel: Gtk.SelectionModel,\n positions: number[],\n isExclusive: boolean,\n): void => {\n if (positions.length === 0) {\n selectionModel.unselectRange(0, selectionModel.getNItems());\n\n return;\n }\n\n const [first] = positions;\n\n if (isExclusive && first !== undefined && positions.length === 1) {\n selectionModel.selectItem(first, true);\n\n return;\n }\n\n const nItems = selectionModel.getNItems();\n const selected = Gtk.Bitset.newEmpty();\n const mask = Gtk.Bitset.newRange(0, nItems);\n\n for (const pos of positions) {\n selected.add(pos);\n }\n\n selectionModel.setSelection(selected, mask);\n};\n\nconst isListView = (widget: Gtk.Widget): widget is CollectionWidget =>\n widget instanceof Gtk.ListView || widget instanceof Gtk.GridView || widget instanceof Gtk.ColumnView;\n\nconst getIndexSelector = (widget: Gtk.Widget): ((position: number) => void) | null =>\n getCallableMethod<[number], unknown>(widget, \"setSelected\");\n\nconst selectDropDownOption = (widget: Gtk.Widget, valueArray: number[]): void => {\n const setSelected = getIndexSelector(widget);\n\n if (!setSelected) {\n throw new TypeError(\"Cannot select options: the COMBO_BOX role needs a widget exposing setSelected\");\n }\n\n if (valueArray.length > 1) {\n throw new Error(\"Cannot select multiple options: a drop-down only supports single selection\");\n }\n\n const [selection] = valueArray;\n\n if (selection !== undefined) {\n setSelected(selection);\n }\n};\n\nconst unselectChildRow = (container: Gtk.Widget, child: Gtk.Widget): void => {\n if (isChildSelected(child)) {\n unselectContainerChild(container, child);\n }\n};\n\nconst applyIndexedChildren = (widget: Gtk.Widget, valueArray: number[], apply: IndexedChildAction): void => {\n for (const value of valueArray) {\n const child = getChildAtIndex(widget, value);\n\n if (child) {\n apply(widget, child);\n }\n }\n};\n\nconst requireSelectionModel = (\n widget: CollectionWidget,\n verb: string,\n): Gtk.SelectionModel => {\n const selectionModel = widget.getModel();\n\n if (selectionModel === null) {\n throw new Error(`Cannot ${verb} options: list view has no selection model`);\n }\n\n return selectionModel;\n};\n\nconst selectInListView = (widget: CollectionWidget, valueArray: number[]): void => {\n const selectionModel = requireSelectionModel(widget, \"select\");\n const isMultiSelection = selectionModel instanceof Gtk.MultiSelection;\n selectListViewItems(selectionModel, valueArray, !isMultiSelection);\n};\n\nconst requireSelectableRole = (widget: Gtk.Widget, verb: string): void => {\n if (!isSelectable(widget)) {\n throw new Error(\n `Cannot ${verb} options: expected selectable widget (${formatRoleList(SELECTABLE_ROLES)})`,\n );\n }\n};\n\nconst selectByRole = (widget: Gtk.Widget, valueArray: number[]): void => {\n requireSelectableRole(widget, \"select\");\n const role = widget.getAccessibleRole();\n\n if (role === Gtk.AccessibleRole.COMBO_BOX) {\n selectDropDownOption(widget, valueArray);\n\n return;\n }\n\n if (!hasIndexedChildren(widget)) {\n throw new TypeError(\"Cannot select options: the widget exposes no children to select by index\");\n }\n\n applyIndexedChildren(widget, valueArray, selectContainerChild);\n};\n\nconst runSelectionEvent = (\n widget: Gtk.Widget,\n values: number | number[],\n inListView: (view: Gtk.ListView | Gtk.GridView | Gtk.ColumnView, valueArray: number[]) => void,\n byRole: (widget: Gtk.Widget, valueArray: number[]) => void,\n): Promise<void> =>\n wrapEvent(widget, () => {\n const valueArray = Array.isArray(values) ? values : [values];\n\n if (isListView(widget)) {\n inListView(widget, valueArray);\n\n return;\n }\n\n byRole(widget, valueArray);\n });\n\n/**\n * Selects the items at the given positions through a list, grid, or column view's selection model,\n * by setting the selected position of a widget with the COMBO_BOX role, or by selecting the indexed\n * children of a list box or flow box through their container. An empty array clears a view's\n * selection. The children are never activated, so no row-activated handler runs.\n *\n * @throws When a view has no selection model, when a COMBO_BOX-role widget is given more than one\n * position or exposes no `setSelected`, or when the widget's role is none of COMBO_BOX, GRID, or\n * LIST.\n */\nconst selectOptions = (widget: Gtk.Widget, values: number | number[]): Promise<void> =>\n runSelectionEvent(widget, values, selectInListView, selectByRole);\n\nconst deselectInListView = (widget: Gtk.ListView | Gtk.GridView | Gtk.ColumnView, valueArray: number[]): void => {\n const selectionModel = requireSelectionModel(widget, \"deselect\");\n\n for (const pos of valueArray) {\n selectionModel.unselectItem(pos);\n }\n};\n\nconst deselectByRole = (widget: Gtk.Widget, valueArray: number[]): void => {\n requireSelectableRole(widget, \"deselect\");\n\n if (!hasIndexedChildren(widget)) {\n throw new TypeError(\"Cannot deselect options: the widget exposes no children to deselect by index\");\n }\n\n applyIndexedChildren(widget, valueArray, unselectChildRow);\n};\n\n/**\n * Unselects the items at the given positions in a list, grid, or column view, or unselects the\n * indexed children of a list box or flow box through their container. A child that is not selected\n * is left alone, and no child is activated.\n *\n * @throws When a view has no selection model, when the widget's role is none of COMBO_BOX, GRID, or\n * LIST, or when it exposes no indexed children.\n */\nconst deselectOptions = (widget: Gtk.Widget, values: number | number[]): Promise<void> =>\n runSelectionEvent(widget, values, deselectInListView, deselectByRole);\n\nexport { selectOptions, deselectOptions };\n"]}
|
|
@@ -10,16 +10,23 @@ type TypeOptions = {
|
|
|
10
10
|
};
|
|
11
11
|
declare const resetClipboard: () => void;
|
|
12
12
|
/**
|
|
13
|
-
* Focuses the widget unless `shouldFocus` is false, applies any initial selection, and inserts the
|
|
14
|
-
* at the cursor
|
|
13
|
+
* Focuses the widget unless `shouldFocus` is false, applies any initial selection, and inserts the
|
|
14
|
+
* text at the cursor, deleting the text the widget has selected first, the way typing over a
|
|
15
|
+
* selection does in GTK4. Focusing works the way clicking into the widget does, leaving its text
|
|
16
|
+
* unselected: a `Gtk.Editable` takes its caret to the end of its text, a `Gtk.TextView` keeps the
|
|
17
|
+
* caret where it stands, and the replaced text stays on the widget's undo stack either way.
|
|
15
18
|
*
|
|
16
19
|
* @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.
|
|
17
20
|
*/
|
|
18
21
|
declare const type: (widget: Gtk.Widget, text: string, options?: TypeOptions) => Promise<void>;
|
|
19
22
|
/**
|
|
20
|
-
*
|
|
23
|
+
* Focuses an editable widget and deletes its whole text through the widget's own editing API, so the
|
|
24
|
+
* deletion emits the signals an edit made by hand emits. Text a tag protects is detected before the
|
|
25
|
+
* deletion runs, leaving such a widget untouched. A widget that writes a new value back in response
|
|
26
|
+
* to the deletion, as an input mask does, is cleared successfully and keeps whatever it wrote.
|
|
21
27
|
*
|
|
22
|
-
* @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView
|
|
28
|
+
* @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView, when it refuses edits, when
|
|
29
|
+
* a tag protects part of its text, or when a handler blocks the deletion.
|
|
23
30
|
*/
|
|
24
31
|
declare const clear: (widget: Gtk.Widget) => Promise<void>;
|
|
25
32
|
/**
|
|
@@ -36,7 +43,7 @@ declare const copy: (widget: Gtk.Widget) => Promise<void>;
|
|
|
36
43
|
declare const cut: (widget: Gtk.Widget) => Promise<void>;
|
|
37
44
|
/**
|
|
38
45
|
* Inserts the given text at an editable widget's cursor, reading the clipboard instead when no text
|
|
39
|
-
* is given.
|
|
46
|
+
* is given, and deleting the text the widget has selected first, the way a paste does in GTK4.
|
|
40
47
|
*
|
|
41
48
|
* @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.
|
|
42
49
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/user-event/text.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../src/user-event/text.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AAcpC,oCAAoC;AACpC,KAAK,WAAW,GAAG;IACf,wDAAwD;IACxD,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,+FAA+F;IAC/F,qBAAqB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,0EAA0E;IAC1E,mBAAmB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C,CAAC;AAoKF,QAAA,MAAM,cAAc,QAAO,IAE1B,CAAC;AAeF;;;;;;;;GAQG;AACH,QAAA,MAAM,IAAI,GAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,MAAM,MAAM,EAAE,UAAU,WAAW,KAAG,OAAO,CAAC,IAAI,CAQ9E,CAAC;AAuEP;;;;;;;;GAQG;AACH,QAAA,MAAM,KAAK,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OAAO,CAAC,IAAI,CACmB,CAAC;AAEpE;;;;GAIG;AACH,QAAA,MAAM,IAAI,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OAAO,CAAC,IAAI,CAGzC,CAAC;AAEP;;;;GAIG;AACH,QAAA,MAAM,GAAG,GAAI,QAAQ,GAAG,CAAC,MAAM,KAAG,OAAO,CAAC,IAAI,CAIxC,CAAC;AAEP;;;;;GAKG;AACH,QAAA,MAAM,KAAK,GAAU,QAAQ,GAAG,CAAC,MAAM,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAUpE,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,WAAW,EAAE,CAAC"}
|
package/dist/user-event/text.js
CHANGED
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
import * as Gdk from "@gtkx/gi/gdk";
|
|
2
2
|
import * as GObject from "@gtkx/gi/gobject";
|
|
3
3
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
4
|
-
import { EDITABLE_ROLES, getEditableDelegate, isEditable } from "../editable.js";
|
|
4
|
+
import { EDITABLE_ROLES, getEditableDelegate, isEditable, readEditableText } from "../editable.js";
|
|
5
5
|
import { formatRoleList } from "../role-helpers.js";
|
|
6
|
+
import { getWidgetSelection } from "../widget-accessible-properties.js";
|
|
7
|
+
import { callBooleanGetter } from "../widget-getters.js";
|
|
6
8
|
import { wrapEvent } from "./event-wrapper.js";
|
|
7
9
|
const EDITABLE_REQUIRED = `expected editable widget (${formatRoleList(EDITABLE_ROLES)})`;
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const position = widget.getPosition();
|
|
19
|
-
const newPosition = widget.insertText(text, text.length, position);
|
|
20
|
-
widget.setPosition(newPosition);
|
|
10
|
+
const CLEAR_REFUSED = "Cannot clear element: the widget refuses to delete part of its text";
|
|
11
|
+
const SELECTION_DELETE_COUNT = 1;
|
|
12
|
+
const SINGLE_CHARACTER_LENGTH = 1;
|
|
13
|
+
const TEXT_END_POSITION = -1;
|
|
14
|
+
const isWidgetEditable = (widget) => callBooleanGetter(widget, "getEditable") ?? true;
|
|
15
|
+
const readSelection = (widget) => getWidgetSelection(widget) ?? "";
|
|
16
|
+
const hasSelectedText = (widget) => widget.getSelectionBounds()[0];
|
|
17
|
+
const getDelegateText = (widget) => {
|
|
18
|
+
const delegate = getEditableDelegate(widget) ?? widget;
|
|
19
|
+
return delegate instanceof Gtk.Text ? delegate : null;
|
|
21
20
|
};
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const [hasSelection, start, end] = buffer.getSelectionBounds();
|
|
26
|
-
return hasSelection ? buffer.getText(start, end, true) : "";
|
|
27
|
-
}
|
|
28
|
-
const [hasSelection, start, end] = widget.getSelectionBounds();
|
|
29
|
-
return hasSelection ? widget.getChars(start, end) : "";
|
|
21
|
+
const getSelectionLength = (buffer) => {
|
|
22
|
+
const [isSelected, start, end] = buffer.getSelectionBounds();
|
|
23
|
+
return isSelected ? end.getOffset() - start.getOffset() : 0;
|
|
30
24
|
};
|
|
31
25
|
const deleteSelection = (widget) => {
|
|
32
26
|
if (widget instanceof Gtk.TextView) {
|
|
@@ -35,26 +29,80 @@ const deleteSelection = (widget) => {
|
|
|
35
29
|
}
|
|
36
30
|
widget.deleteSelection();
|
|
37
31
|
};
|
|
38
|
-
const
|
|
32
|
+
const focusPlainEditable = (widget) => {
|
|
33
|
+
const [isSelected, start, end] = widget.getSelectionBounds();
|
|
34
|
+
widget.grabFocus();
|
|
35
|
+
if (isSelected) {
|
|
36
|
+
widget.selectRegion(start, end);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
widget.setPosition(TEXT_END_POSITION);
|
|
40
|
+
};
|
|
41
|
+
const focusEditable = (widget) => {
|
|
39
42
|
if (widget instanceof Gtk.TextView) {
|
|
40
|
-
widget.
|
|
43
|
+
widget.grabFocus();
|
|
41
44
|
return;
|
|
42
45
|
}
|
|
43
|
-
widget
|
|
46
|
+
const target = getDelegateText(widget);
|
|
47
|
+
if (target === null) {
|
|
48
|
+
focusPlainEditable(widget);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
target.grabFocusWithoutSelecting();
|
|
52
|
+
if (!hasSelectedText(widget)) {
|
|
53
|
+
widget.setPosition(TEXT_END_POSITION);
|
|
54
|
+
}
|
|
44
55
|
};
|
|
45
|
-
const
|
|
56
|
+
const insertTextViewText = (widget, text, kind) => {
|
|
46
57
|
const buffer = widget.getBuffer();
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
const length = getSelectionLength(buffer);
|
|
59
|
+
buffer.beginUserAction();
|
|
60
|
+
if (length > 0) {
|
|
61
|
+
widget.emit("delete-from-cursor", Gtk.DeleteType.CHARS, SELECTION_DELETE_COUNT);
|
|
62
|
+
if (kind === "typing" && length > SINGLE_CHARACTER_LENGTH) {
|
|
63
|
+
buffer.endUserAction();
|
|
64
|
+
buffer.beginUserAction();
|
|
65
|
+
}
|
|
50
66
|
}
|
|
67
|
+
widget.emit("insert-at-cursor", text);
|
|
68
|
+
buffer.endUserAction();
|
|
51
69
|
};
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
70
|
+
const insertDelegateText = (target, text) => {
|
|
71
|
+
if (hasSelectedText(target)) {
|
|
72
|
+
target.emit("delete-from-cursor", Gtk.DeleteType.CHARS, SELECTION_DELETE_COUNT);
|
|
73
|
+
}
|
|
74
|
+
target.emit("insert-at-cursor", text);
|
|
75
|
+
};
|
|
76
|
+
const insertPlainText = (widget, text) => {
|
|
77
|
+
if (!isWidgetEditable(widget)) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (hasSelectedText(widget)) {
|
|
55
81
|
widget.deleteSelection();
|
|
56
82
|
}
|
|
57
|
-
widget.
|
|
83
|
+
const position = widget.getPosition();
|
|
84
|
+
const newPosition = widget.insertText(text, text.length, position);
|
|
85
|
+
widget.setPosition(newPosition);
|
|
86
|
+
};
|
|
87
|
+
const insertEditableText = (widget, text, kind) => {
|
|
88
|
+
if (widget instanceof Gtk.TextView) {
|
|
89
|
+
insertTextViewText(widget, text, kind);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const target = getDelegateText(widget);
|
|
93
|
+
if (target === null) {
|
|
94
|
+
insertPlainText(widget, text);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
insertDelegateText(target, text);
|
|
98
|
+
};
|
|
99
|
+
const deleteAllText = (widget) => {
|
|
100
|
+
if (widget instanceof Gtk.TextView) {
|
|
101
|
+
const buffer = widget.getBuffer();
|
|
102
|
+
buffer.deleteInteractive(buffer.getStartIter(), buffer.getEndIter(), widget.getEditable());
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
widget.deleteText(0, -1);
|
|
58
106
|
};
|
|
59
107
|
const applyInitialSelection = (widget, options) => {
|
|
60
108
|
if (options.initialSelectionStart === undefined) {
|
|
@@ -63,10 +111,11 @@ const applyInitialSelection = (widget, options) => {
|
|
|
63
111
|
const start = options.initialSelectionStart;
|
|
64
112
|
const end = options.initialSelectionEnd ?? start;
|
|
65
113
|
if (widget instanceof Gtk.TextView) {
|
|
66
|
-
|
|
114
|
+
const buffer = widget.getBuffer();
|
|
115
|
+
buffer.selectRange(buffer.getIterAtOffset(start), buffer.getIterAtOffset(end));
|
|
67
116
|
return;
|
|
68
117
|
}
|
|
69
|
-
|
|
118
|
+
widget.selectRegion(start, end);
|
|
70
119
|
};
|
|
71
120
|
const writeClipboardText = (widget, text) => {
|
|
72
121
|
const value = GObject.buildValue(GObject.TYPE_STRING, (v) => {
|
|
@@ -84,26 +133,82 @@ const runEditableEvent = (widget, failure, action) => wrapEvent(widget, () => {
|
|
|
84
133
|
action(widget);
|
|
85
134
|
});
|
|
86
135
|
/**
|
|
87
|
-
* Focuses the widget unless `shouldFocus` is false, applies any initial selection, and inserts the
|
|
88
|
-
* at the cursor
|
|
136
|
+
* Focuses the widget unless `shouldFocus` is false, applies any initial selection, and inserts the
|
|
137
|
+
* text at the cursor, deleting the text the widget has selected first, the way typing over a
|
|
138
|
+
* selection does in GTK4. Focusing works the way clicking into the widget does, leaving its text
|
|
139
|
+
* unselected: a `Gtk.Editable` takes its caret to the end of its text, a `Gtk.TextView` keeps the
|
|
140
|
+
* caret where it stands, and the replaced text stays on the widget's undo stack either way.
|
|
89
141
|
*
|
|
90
142
|
* @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.
|
|
91
143
|
*/
|
|
92
144
|
const type = (widget, text, options) => runEditableEvent(widget, "Cannot type into element", (editable) => {
|
|
93
145
|
if (options?.shouldFocus ?? true) {
|
|
94
|
-
editable
|
|
146
|
+
focusEditable(editable);
|
|
95
147
|
}
|
|
96
148
|
applyInitialSelection(editable, options ?? {});
|
|
97
|
-
insertEditableText(editable, text);
|
|
149
|
+
insertEditableText(editable, text, "typing");
|
|
98
150
|
});
|
|
151
|
+
const hasNonEditableChar = (iter, isDefaultEditable) => {
|
|
152
|
+
while (!iter.isEnd()) {
|
|
153
|
+
if (!iter.editable(isDefaultEditable)) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
if (!iter.forwardChar()) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
};
|
|
162
|
+
const hasProtectedText = (widget) => widget instanceof Gtk.TextView && hasNonEditableChar(widget.getBuffer().getStartIter(), widget.getEditable());
|
|
163
|
+
const requireClearableText = (editable) => {
|
|
164
|
+
if (!isWidgetEditable(editable)) {
|
|
165
|
+
throw new Error("Cannot clear element: the widget is not editable");
|
|
166
|
+
}
|
|
167
|
+
if (hasProtectedText(editable)) {
|
|
168
|
+
throw new Error(CLEAR_REFUSED);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const deletionSignalFor = (widget) => widget instanceof Gtk.TextView ? [widget.getBuffer(), "delete-range"] : [widget, "delete-text"];
|
|
172
|
+
const isDeletionApplied = (emitter, signal, apply) => {
|
|
173
|
+
let isApplied = false;
|
|
174
|
+
const watch = () => {
|
|
175
|
+
isApplied = true;
|
|
176
|
+
};
|
|
177
|
+
emitter.on(signal, watch, true);
|
|
178
|
+
try {
|
|
179
|
+
apply();
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
emitter.off(signal, watch);
|
|
183
|
+
}
|
|
184
|
+
return isApplied;
|
|
185
|
+
};
|
|
186
|
+
const didDeleteAllText = (widget) => {
|
|
187
|
+
const [emitter, signal] = deletionSignalFor(widget);
|
|
188
|
+
return isDeletionApplied(emitter, signal, () => {
|
|
189
|
+
deleteAllText(widget);
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
const clearEditable = (editable) => {
|
|
193
|
+
requireClearableText(editable);
|
|
194
|
+
focusEditable(editable);
|
|
195
|
+
if (readEditableText(editable) === "") {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (!didDeleteAllText(editable)) {
|
|
199
|
+
throw new Error(CLEAR_REFUSED);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
99
202
|
/**
|
|
100
|
-
*
|
|
203
|
+
* Focuses an editable widget and deletes its whole text through the widget's own editing API, so the
|
|
204
|
+
* deletion emits the signals an edit made by hand emits. Text a tag protects is detected before the
|
|
205
|
+
* deletion runs, leaving such a widget untouched. A widget that writes a new value back in response
|
|
206
|
+
* to the deletion, as an input mask does, is cleared successfully and keeps whatever it wrote.
|
|
101
207
|
*
|
|
102
|
-
* @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView
|
|
208
|
+
* @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView, when it refuses edits, when
|
|
209
|
+
* a tag protects part of its text, or when a handler blocks the deletion.
|
|
103
210
|
*/
|
|
104
|
-
const clear = (widget) => runEditableEvent(widget, "Cannot clear element",
|
|
105
|
-
setEditableText(editable, "");
|
|
106
|
-
});
|
|
211
|
+
const clear = (widget) => runEditableEvent(widget, "Cannot clear element", clearEditable);
|
|
107
212
|
/**
|
|
108
213
|
* Writes an editable widget's selected text to its clipboard, or the empty string when nothing is selected.
|
|
109
214
|
*
|
|
@@ -123,7 +228,7 @@ const cut = (widget) => runEditableEvent(widget, "Cannot cut", (editable) => {
|
|
|
123
228
|
});
|
|
124
229
|
/**
|
|
125
230
|
* Inserts the given text at an editable widget's cursor, reading the clipboard instead when no text
|
|
126
|
-
* is given.
|
|
231
|
+
* is given, and deleting the text the widget has selected first, the way a paste does in GTK4.
|
|
127
232
|
*
|
|
128
233
|
* @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.
|
|
129
234
|
*/
|
|
@@ -133,7 +238,7 @@ const paste = async (widget, text) => {
|
|
|
133
238
|
}
|
|
134
239
|
const content = text ?? (await widget.getClipboard().readTextAsync(null)) ?? "";
|
|
135
240
|
await wrapEvent(widget, () => {
|
|
136
|
-
insertEditableText(widget, content);
|
|
241
|
+
insertEditableText(widget, content, "pasting");
|
|
137
242
|
});
|
|
138
243
|
};
|
|
139
244
|
export { resetClipboard, type, clear, copy, cut, paste };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/user-event/text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,cAAc,EAAuB,mBAAmB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAY/C,MAAM,iBAAiB,GAAG,6BAA6B,cAAc,CAAC,cAAc,CAAC,GAAG,CAAC;AAEzF,MAAM,kBAAkB,GAAG,CAAC,MAAsB,EAAE,IAAY,EAAQ,EAAE;IACtE,IAAI,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAEtC,OAAO;IACX,CAAC;IAED,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;IAErD,IAAI,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAEtC,OAAO;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACtC,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,MAAsB,EAAU,EAAE;IACrD,IAAI,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QAClC,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAE/D,OAAO,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC;IAE/D,OAAO,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3D,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,MAAsB,EAAQ,EAAE;IACrD,IAAI,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,SAAS,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAEhD,OAAO;IACX,CAAC;IAED,MAAM,CAAC,eAAe,EAAE,CAAC;AAC7B,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,MAAsB,EAAE,IAAY,EAAQ,EAAE;IACnE,IAAI,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAE9C,OAAO;IACX,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,MAAoB,EAAE,KAAa,EAAE,GAAW,EAAQ,EAAE;IACtF,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;IAE/E,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAChB,eAAe,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,sBAAsB,GAAG,CAAC,MAAoB,EAAE,KAAa,EAAE,GAAW,EAAQ,EAAE;IACtF,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAEhC,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAChB,MAAM,CAAC,eAAe,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAAC,MAAsB,EAAE,OAAoB,EAAQ,EAAE;IACjF,IAAI,OAAO,CAAC,qBAAqB,KAAK,SAAS,EAAE,CAAC;QAC9C,OAAO;IACX,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAC5C,MAAM,GAAG,GAAG,OAAO,CAAC,mBAAmB,IAAI,KAAK,CAAC;IAEjD,IAAI,MAAM,YAAY,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,sBAAsB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAE3C,OAAO;IACX,CAAC;IAED,sBAAsB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,MAAkB,EAAE,IAAY,EAAQ,EAAE;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE;QACxD,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,GAAS,EAAE;IAC9B,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,YAAY,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAC9D,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CACrB,MAAkB,EAClB,OAAe,EACf,MAA0C,EAC7B,EAAE,CACf,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE;IACnB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,KAAK,iBAAiB,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,CAAC;AACnB,CAAC,CAAC,CAAC;AAEP;;;;;GAKG;AACH,MAAM,IAAI,GAAG,CAAC,MAAkB,EAAE,IAAY,EAAE,OAAqB,EAAiB,EAAE,CACpF,gBAAgB,CAAC,MAAM,EAAE,0BAA0B,EAAE,CAAC,QAAQ,EAAE,EAAE;IAC9D,IAAI,OAAO,EAAE,WAAW,IAAI,IAAI,EAAE,CAAC;QAC/B,QAAQ,CAAC,SAAS,EAAE,CAAC;IACzB,CAAC;IAED,qBAAqB,CAAC,QAAQ,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;IAC/C,kBAAkB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC;AAEP;;;;GAIG;AACH,MAAM,KAAK,GAAG,CAAC,MAAkB,EAAiB,EAAE,CAChD,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,EAAE,CAAC,QAAQ,EAAE,EAAE;IAC1D,eAAe,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEP;;;;GAIG;AACH,MAAM,IAAI,GAAG,CAAC,MAAkB,EAAiB,EAAE,CAC/C,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,QAAQ,EAAE,EAAE;IACjD,kBAAkB,CAAC,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC1D,CAAC,CAAC,CAAC;AAEP;;;;GAIG;AACH,MAAM,GAAG,GAAG,CAAC,MAAkB,EAAiB,EAAE,CAC9C,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,QAAQ,EAAE,EAAE;IAChD,kBAAkB,CAAC,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtD,eAAe,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC;AAEP;;;;;GAKG;AACH,MAAM,KAAK,GAAG,KAAK,EAAE,MAAkB,EAAE,IAAa,EAAiB,EAAE;IACrE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,iBAAiB,iBAAiB,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAEhF,MAAM,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE;QACzB,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAoB,CAAC","sourcesContent":["import * as Gdk from \"@gtkx/gi/gdk\";\nimport * as GObject from \"@gtkx/gi/gobject\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { EDITABLE_ROLES, type EditableTarget, getEditableDelegate, isEditable } from \"../editable.js\";\nimport { formatRoleList } from \"../role-helpers.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\n\n/** Options for `userEvent.type`. */\ntype TypeOptions = {\n /** Focus the widget before typing; defaults to true. */\n shouldFocus?: boolean | undefined;\n /** Select from this offset before typing, replacing the selected range with the typed text. */\n initialSelectionStart?: number | undefined;\n /** End offset of the initial selection (defaults to the start offset). */\n initialSelectionEnd?: number | undefined;\n};\n\nconst EDITABLE_REQUIRED = `expected editable widget (${formatRoleList(EDITABLE_ROLES)})`;\n\nconst insertEditableText = (widget: EditableTarget, text: string): void => {\n if (widget instanceof Gtk.TextView) {\n widget.emit(\"insert-at-cursor\", text);\n\n return;\n }\n\n const target = getEditableDelegate(widget) ?? widget;\n\n if (target instanceof Gtk.Text) {\n target.emit(\"insert-at-cursor\", text);\n\n return;\n }\n\n const position = widget.getPosition();\n const newPosition = widget.insertText(text, text.length, position);\n widget.setPosition(newPosition);\n};\n\nconst readSelection = (widget: EditableTarget): string => {\n if (widget instanceof Gtk.TextView) {\n const buffer = widget.getBuffer();\n const [hasSelection, start, end] = buffer.getSelectionBounds();\n\n return hasSelection ? buffer.getText(start, end, true) : \"\";\n }\n\n const [hasSelection, start, end] = widget.getSelectionBounds();\n\n return hasSelection ? widget.getChars(start, end) : \"\";\n};\n\nconst deleteSelection = (widget: EditableTarget): void => {\n if (widget instanceof Gtk.TextView) {\n widget.getBuffer().deleteSelection(false, true);\n\n return;\n }\n\n widget.deleteSelection();\n};\n\nconst setEditableText = (widget: EditableTarget, text: string): void => {\n if (widget instanceof Gtk.TextView) {\n widget.getBuffer().setText(text, text.length);\n\n return;\n }\n\n widget.setText(text);\n};\n\nconst applyTextViewSelection = (widget: Gtk.TextView, start: number, end: number): void => {\n const buffer = widget.getBuffer();\n buffer.selectRange(buffer.getIterAtOffset(start), buffer.getIterAtOffset(end));\n\n if (end !== start) {\n deleteSelection(widget);\n }\n};\n\nconst applyEditableSelection = (widget: Gtk.Editable, start: number, end: number): void => {\n widget.selectRegion(start, end);\n\n if (end !== start) {\n widget.deleteSelection();\n }\n\n widget.setPosition(start);\n};\n\nconst applyInitialSelection = (widget: EditableTarget, options: TypeOptions): void => {\n if (options.initialSelectionStart === undefined) {\n return;\n }\n\n const start = options.initialSelectionStart;\n const end = options.initialSelectionEnd ?? start;\n\n if (widget instanceof Gtk.TextView) {\n applyTextViewSelection(widget, start, end);\n\n return;\n }\n\n applyEditableSelection(widget, start, end);\n};\n\nconst writeClipboardText = (widget: Gtk.Widget, text: string): void => {\n const value = GObject.buildValue(GObject.TYPE_STRING, (v) => {\n v.setString(text);\n });\n\n widget.getClipboard().set(value);\n};\n\nconst resetClipboard = (): void => {\n Gdk.Display.getDefault()?.getClipboard().setContent(null);\n};\n\nconst runEditableEvent = (\n widget: Gtk.Widget,\n failure: string,\n action: (editable: EditableTarget) => void,\n): Promise<void> =>\n wrapEvent(widget, () => {\n if (!isEditable(widget)) {\n throw new Error(`${failure}: ${EDITABLE_REQUIRED}`);\n }\n\n action(widget);\n });\n\n/**\n * Focuses the widget unless `shouldFocus` is false, applies any initial selection, and inserts the text\n * at the cursor.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.\n */\nconst type = (widget: Gtk.Widget, text: string, options?: TypeOptions): Promise<void> =>\n runEditableEvent(widget, \"Cannot type into element\", (editable) => {\n if (options?.shouldFocus ?? true) {\n editable.grabFocus();\n }\n\n applyInitialSelection(editable, options ?? {});\n insertEditableText(editable, text);\n });\n\n/**\n * Replaces an editable widget's text with the empty string.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.\n */\nconst clear = (widget: Gtk.Widget): Promise<void> =>\n runEditableEvent(widget, \"Cannot clear element\", (editable) => {\n setEditableText(editable, \"\");\n });\n\n/**\n * Writes an editable widget's selected text to its clipboard, or the empty string when nothing is selected.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.\n */\nconst copy = (widget: Gtk.Widget): Promise<void> =>\n runEditableEvent(widget, \"Cannot copy\", (editable) => {\n writeClipboardText(editable, readSelection(editable));\n });\n\n/**\n * Writes an editable widget's selected text to its clipboard, then deletes that selection.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.\n */\nconst cut = (widget: Gtk.Widget): Promise<void> =>\n runEditableEvent(widget, \"Cannot cut\", (editable) => {\n writeClipboardText(editable, readSelection(editable));\n deleteSelection(editable);\n });\n\n/**\n * Inserts the given text at an editable widget's cursor, reading the clipboard instead when no text\n * is given.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.\n */\nconst paste = async (widget: Gtk.Widget, text?: string): Promise<void> => {\n if (!isEditable(widget)) {\n throw new Error(`Cannot paste: ${EDITABLE_REQUIRED}`);\n }\n\n const content = text ?? (await widget.getClipboard().readTextAsync(null)) ?? \"\";\n\n await wrapEvent(widget, () => {\n insertEditableText(widget, content);\n });\n};\n\nexport { resetClipboard, type, clear, copy, cut, paste, type TypeOptions };\n"]}
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/user-event/text.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gdk from \"@gtkx/gi/gdk\";\nimport * as GObject from \"@gtkx/gi/gobject\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { EDITABLE_ROLES, type EditableTarget, getEditableDelegate, isEditable, readEditableText } from \"../editable.js\";\nimport { formatRoleList } from \"../role-helpers.js\";\nimport { getWidgetSelection } from \"../widget-accessible-properties.js\";\nimport { callBooleanGetter } from \"../widget-getters.js\";\nimport { wrapEvent } from \"./event-wrapper.js\";\n\ntype SignalWatchTarget = {\n on(signal: string, handler: (...args: unknown[]) => unknown, isAfter?: boolean): unknown;\n off(signal: string, handler: (...args: unknown[]) => unknown): unknown;\n};\n\ntype InsertKind = \"typing\" | \"pasting\";\n\n/** Options for `userEvent.type`. */\ntype TypeOptions = {\n /** Focus the widget before typing; defaults to true. */\n shouldFocus?: boolean | undefined;\n /** Select from this offset before typing, replacing the selected range with the typed text. */\n initialSelectionStart?: number | undefined;\n /** End offset of the initial selection (defaults to the start offset). */\n initialSelectionEnd?: number | undefined;\n};\n\nconst EDITABLE_REQUIRED = `expected editable widget (${formatRoleList(EDITABLE_ROLES)})`;\nconst CLEAR_REFUSED = \"Cannot clear element: the widget refuses to delete part of its text\";\nconst SELECTION_DELETE_COUNT = 1;\nconst SINGLE_CHARACTER_LENGTH = 1;\nconst TEXT_END_POSITION = -1;\n\nconst isWidgetEditable = (widget: Gtk.Widget): boolean => callBooleanGetter(widget, \"getEditable\") ?? true;\nconst readSelection = (widget: EditableTarget): string => getWidgetSelection(widget) ?? \"\";\nconst hasSelectedText = (widget: Gtk.Editable): boolean => widget.getSelectionBounds()[0];\n\nconst getDelegateText = (widget: Gtk.Editable): Gtk.Text | null => {\n const delegate = getEditableDelegate(widget) ?? widget;\n\n return delegate instanceof Gtk.Text ? delegate : null;\n};\n\nconst getSelectionLength = (buffer: Gtk.TextBuffer): number => {\n const [isSelected, start, end] = buffer.getSelectionBounds();\n\n return isSelected ? end.getOffset() - start.getOffset() : 0;\n};\n\nconst deleteSelection = (widget: EditableTarget): void => {\n if (widget instanceof Gtk.TextView) {\n widget.getBuffer().deleteSelection(false, true);\n\n return;\n }\n\n widget.deleteSelection();\n};\n\nconst focusPlainEditable = (widget: Gtk.Editable): void => {\n const [isSelected, start, end] = widget.getSelectionBounds();\n widget.grabFocus();\n\n if (isSelected) {\n widget.selectRegion(start, end);\n\n return;\n }\n\n widget.setPosition(TEXT_END_POSITION);\n};\n\nconst focusEditable = (widget: EditableTarget): void => {\n if (widget instanceof Gtk.TextView) {\n widget.grabFocus();\n\n return;\n }\n\n const target = getDelegateText(widget);\n\n if (target === null) {\n focusPlainEditable(widget);\n\n return;\n }\n\n target.grabFocusWithoutSelecting();\n\n if (!hasSelectedText(widget)) {\n widget.setPosition(TEXT_END_POSITION);\n }\n};\n\nconst insertTextViewText = (widget: Gtk.TextView, text: string, kind: InsertKind): void => {\n const buffer = widget.getBuffer();\n const length = getSelectionLength(buffer);\n buffer.beginUserAction();\n\n if (length > 0) {\n widget.emit(\"delete-from-cursor\", Gtk.DeleteType.CHARS, SELECTION_DELETE_COUNT);\n\n if (kind === \"typing\" && length > SINGLE_CHARACTER_LENGTH) {\n buffer.endUserAction();\n buffer.beginUserAction();\n }\n }\n\n widget.emit(\"insert-at-cursor\", text);\n buffer.endUserAction();\n};\n\nconst insertDelegateText = (target: Gtk.Text, text: string): void => {\n if (hasSelectedText(target)) {\n target.emit(\"delete-from-cursor\", Gtk.DeleteType.CHARS, SELECTION_DELETE_COUNT);\n }\n\n target.emit(\"insert-at-cursor\", text);\n};\n\nconst insertPlainText = (widget: Gtk.Editable, text: string): void => {\n if (!isWidgetEditable(widget)) {\n return;\n }\n\n if (hasSelectedText(widget)) {\n widget.deleteSelection();\n }\n\n const position = widget.getPosition();\n const newPosition = widget.insertText(text, text.length, position);\n widget.setPosition(newPosition);\n};\n\nconst insertEditableText = (widget: EditableTarget, text: string, kind: InsertKind): void => {\n if (widget instanceof Gtk.TextView) {\n insertTextViewText(widget, text, kind);\n\n return;\n }\n\n const target = getDelegateText(widget);\n\n if (target === null) {\n insertPlainText(widget, text);\n\n return;\n }\n\n insertDelegateText(target, text);\n};\n\nconst deleteAllText = (widget: EditableTarget): void => {\n if (widget instanceof Gtk.TextView) {\n const buffer = widget.getBuffer();\n buffer.deleteInteractive(buffer.getStartIter(), buffer.getEndIter(), widget.getEditable());\n\n return;\n }\n\n widget.deleteText(0, -1);\n};\n\nconst applyInitialSelection = (widget: EditableTarget, options: TypeOptions): void => {\n if (options.initialSelectionStart === undefined) {\n return;\n }\n\n const start = options.initialSelectionStart;\n const end = options.initialSelectionEnd ?? start;\n\n if (widget instanceof Gtk.TextView) {\n const buffer = widget.getBuffer();\n buffer.selectRange(buffer.getIterAtOffset(start), buffer.getIterAtOffset(end));\n\n return;\n }\n\n widget.selectRegion(start, end);\n};\n\nconst writeClipboardText = (widget: Gtk.Widget, text: string): void => {\n const value = GObject.buildValue(GObject.TYPE_STRING, (v) => {\n v.setString(text);\n });\n\n widget.getClipboard().set(value);\n};\n\nconst resetClipboard = (): void => {\n Gdk.Display.getDefault()?.getClipboard().setContent(null);\n};\n\nconst runEditableEvent = (\n widget: Gtk.Widget,\n failure: string,\n action: (editable: EditableTarget) => void,\n): Promise<void> =>\n wrapEvent(widget, () => {\n if (!isEditable(widget)) {\n throw new Error(`${failure}: ${EDITABLE_REQUIRED}`);\n }\n\n action(widget);\n });\n\n/**\n * Focuses the widget unless `shouldFocus` is false, applies any initial selection, and inserts the\n * text at the cursor, deleting the text the widget has selected first, the way typing over a\n * selection does in GTK4. Focusing works the way clicking into the widget does, leaving its text\n * unselected: a `Gtk.Editable` takes its caret to the end of its text, a `Gtk.TextView` keeps the\n * caret where it stands, and the replaced text stays on the widget's undo stack either way.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.\n */\nconst type = (widget: Gtk.Widget, text: string, options?: TypeOptions): Promise<void> =>\n runEditableEvent(widget, \"Cannot type into element\", (editable) => {\n if (options?.shouldFocus ?? true) {\n focusEditable(editable);\n }\n\n applyInitialSelection(editable, options ?? {});\n insertEditableText(editable, text, \"typing\");\n });\n\nconst hasNonEditableChar = (iter: Gtk.TextIter, isDefaultEditable: boolean): boolean => {\n while (!iter.isEnd()) {\n if (!iter.editable(isDefaultEditable)) {\n return true;\n }\n\n if (!iter.forwardChar()) {\n return false;\n }\n }\n\n return false;\n};\n\nconst hasProtectedText = (widget: EditableTarget): boolean =>\n widget instanceof Gtk.TextView && hasNonEditableChar(widget.getBuffer().getStartIter(), widget.getEditable());\n\nconst requireClearableText = (editable: EditableTarget): void => {\n if (!isWidgetEditable(editable)) {\n throw new Error(\"Cannot clear element: the widget is not editable\");\n }\n\n if (hasProtectedText(editable)) {\n throw new Error(CLEAR_REFUSED);\n }\n};\n\nconst deletionSignalFor = (widget: EditableTarget): [SignalWatchTarget, string] =>\n widget instanceof Gtk.TextView ? [widget.getBuffer(), \"delete-range\"] : [widget, \"delete-text\"];\n\nconst isDeletionApplied = (emitter: SignalWatchTarget, signal: string, apply: () => void): boolean => {\n let isApplied = false;\n\n const watch = (): void => {\n isApplied = true;\n };\n\n emitter.on(signal, watch, true);\n\n try {\n apply();\n } finally {\n emitter.off(signal, watch);\n }\n\n return isApplied;\n};\n\nconst didDeleteAllText = (widget: EditableTarget): boolean => {\n const [emitter, signal] = deletionSignalFor(widget);\n\n return isDeletionApplied(emitter, signal, () => {\n deleteAllText(widget);\n });\n};\n\nconst clearEditable = (editable: EditableTarget): void => {\n requireClearableText(editable);\n focusEditable(editable);\n\n if (readEditableText(editable) === \"\") {\n return;\n }\n\n if (!didDeleteAllText(editable)) {\n throw new Error(CLEAR_REFUSED);\n }\n};\n\n/**\n * Focuses an editable widget and deletes its whole text through the widget's own editing API, so the\n * deletion emits the signals an edit made by hand emits. Text a tag protects is detected before the\n * deletion runs, leaving such a widget untouched. A widget that writes a new value back in response\n * to the deletion, as an input mask does, is cleared successfully and keeps whatever it wrote.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView, when it refuses edits, when\n * a tag protects part of its text, or when a handler blocks the deletion.\n */\nconst clear = (widget: Gtk.Widget): Promise<void> =>\n runEditableEvent(widget, \"Cannot clear element\", clearEditable);\n\n/**\n * Writes an editable widget's selected text to its clipboard, or the empty string when nothing is selected.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.\n */\nconst copy = (widget: Gtk.Widget): Promise<void> =>\n runEditableEvent(widget, \"Cannot copy\", (editable) => {\n writeClipboardText(editable, readSelection(editable));\n });\n\n/**\n * Writes an editable widget's selected text to its clipboard, then deletes that selection.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.\n */\nconst cut = (widget: Gtk.Widget): Promise<void> =>\n runEditableEvent(widget, \"Cannot cut\", (editable) => {\n writeClipboardText(editable, readSelection(editable));\n deleteSelection(editable);\n });\n\n/**\n * Inserts the given text at an editable widget's cursor, reading the clipboard instead when no text\n * is given, and deleting the text the widget has selected first, the way a paste does in GTK4.\n *\n * @throws When the widget is neither a Gtk.Editable nor a Gtk.TextView.\n */\nconst paste = async (widget: Gtk.Widget, text?: string): Promise<void> => {\n if (!isEditable(widget)) {\n throw new Error(`Cannot paste: ${EDITABLE_REQUIRED}`);\n }\n\n const content = text ?? (await widget.getClipboard().readTextAsync(null)) ?? \"\";\n\n await wrapEvent(widget, () => {\n insertEditableText(widget, content, \"pasting\");\n });\n};\n\nexport { resetClipboard, type, clear, copy, cut, paste, type TypeOptions };\n"]}
|
package/dist/wait-for.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAOjD,mEAAmE;AACnE,KAAK,aAAa,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;AACtD,4FAA4F;AAC5F,KAAK,iBAAiB,GAAG,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,aAAa,CAAC,CAAC;AA4D3E;;;;;;;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,9 +1,9 @@
|
|
|
1
1
|
import { runWithActEnvironment } from "./act.js";
|
|
2
2
|
import { getConfig } from "./config.js";
|
|
3
3
|
import { timeoutError } from "./errors.js";
|
|
4
|
+
import { advanceFakeClock, delay, now } from "./timers.js";
|
|
4
5
|
const DEFAULT_INTERVAL = 50;
|
|
5
6
|
const ELEMENT_NOT_REMOVED = new Error("Element not yet removed");
|
|
6
|
-
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
7
7
|
const copyStackTrace = (target, source) => {
|
|
8
8
|
const { stack } = source;
|
|
9
9
|
if (stack === undefined) {
|
|
@@ -17,9 +17,9 @@ const copyStackTrace = (target, source) => {
|
|
|
17
17
|
target.stack = stack.slice(0, index) + target.message + stack.slice(index + source.message.length);
|
|
18
18
|
};
|
|
19
19
|
const pollUntilSuccess = async (callback, timeout, interval) => {
|
|
20
|
-
const startTime =
|
|
20
|
+
const startTime = now();
|
|
21
21
|
let lastError = null;
|
|
22
|
-
while (
|
|
22
|
+
while (now() - startTime < timeout) {
|
|
23
23
|
try {
|
|
24
24
|
const result = await callback();
|
|
25
25
|
await delay(0);
|
|
@@ -27,6 +27,7 @@ const pollUntilSuccess = async (callback, timeout, interval) => {
|
|
|
27
27
|
}
|
|
28
28
|
catch (error) {
|
|
29
29
|
lastError = error;
|
|
30
|
+
await advanceFakeClock(interval);
|
|
30
31
|
await delay(interval);
|
|
31
32
|
}
|
|
32
33
|
}
|
package/dist/wait-for.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wait-for.js","sourceRoot":"","sources":["../src/wait-for.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
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\";\nimport { advanceFakeClock, delay, now } from \"./timers.js\";\n\ntype PollResult<T> = { status: \"resolved\"; value: T } | { status: \"timedout\"; lastError: Error | null };\n/** Widgets watched for removal; null counts as already removed. */\ntype RemovalTarget = Gtk.Widget | Gtk.Widget[] | null;\n/** The widgets to watch for removal, or a function re-read on every poll to locate them. */\ntype ElementOrCallback = Gtk.Widget | Gtk.Widget[] | (() => RemovalTarget);\n\nconst DEFAULT_INTERVAL = 50;\nconst ELEMENT_NOT_REMOVED = new Error(\"Element not yet removed\");\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 = now();\n let lastError: Error | null = null;\n\n while (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 advanceFakeClock(interval);\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"]}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
2
|
-
type
|
|
3
|
-
now: number | null;
|
|
4
|
-
min: number | null;
|
|
5
|
-
max: number | null;
|
|
6
|
-
text: string | null;
|
|
7
|
-
};
|
|
2
|
+
type WidgetValueField = "now" | "min" | "max";
|
|
8
3
|
type CheckedState = "checked" | "unchecked" | "mixed";
|
|
9
4
|
/**
|
|
10
5
|
* Returns a widget's own text by trying its label, text, and title getters in
|
|
@@ -12,14 +7,9 @@ type CheckedState = "checked" | "unchecked" | "mixed";
|
|
|
12
7
|
*
|
|
13
8
|
* @param widget The widget to read text from.
|
|
14
9
|
*/
|
|
15
|
-
declare const
|
|
10
|
+
declare const getWidgetText: (widget: Gtk.Widget) => string | null;
|
|
11
|
+
declare const namingLabelText: (widget: Gtk.Widget) => string | null;
|
|
16
12
|
declare const getWidgetLabelText: (widget: Gtk.Widget) => string | null;
|
|
17
|
-
/**
|
|
18
|
-
* Returns a widget's own text, or the space-joined text of its descendants when it has none of its
|
|
19
|
-
* own, or null when neither produces a value.
|
|
20
|
-
*
|
|
21
|
-
* @param widget The widget whose subtree is read.
|
|
22
|
-
*/
|
|
23
13
|
declare const getWidgetTextContent: (widget: Gtk.Widget) => string | null;
|
|
24
14
|
declare const getWidgetAccessibleName: (widget: Gtk.Widget) => string | null;
|
|
25
15
|
declare const getWidgetName: (widget: Gtk.Widget) => string | null;
|
|
@@ -36,25 +26,23 @@ declare const getWidgetPressedState: (widget: Gtk.Widget) => boolean | null;
|
|
|
36
26
|
declare const getWidgetExpandedState: (widget: Gtk.Widget) => boolean | null;
|
|
37
27
|
declare const getWidgetSelectedState: (widget: Gtk.Widget) => boolean | null;
|
|
38
28
|
declare const getWidgetLevel: (widget: Gtk.Widget) => number | null;
|
|
39
|
-
/**
|
|
40
|
-
* Returns the accessible invalid state declared on a widget, or null when it declares none.
|
|
41
|
-
*
|
|
42
|
-
* @param widget The widget to read the state from.
|
|
43
|
-
*/
|
|
44
29
|
declare const getWidgetInvalidState: (widget: Gtk.Widget) => Gtk.AccessibleInvalidState | null;
|
|
45
|
-
/**
|
|
46
|
-
* Returns the widgets a widget's accessible error-message relation points at, or null when it
|
|
47
|
-
* declares none.
|
|
48
|
-
*
|
|
49
|
-
* @param widget The widget to read the relation from.
|
|
50
|
-
*/
|
|
51
30
|
declare const getWidgetErrorMessage: (widget: Gtk.Widget) => Gtk.Widget[] | null;
|
|
52
31
|
declare const getWidgetBusyState: (widget: Gtk.Widget) => boolean | null;
|
|
53
32
|
declare const getWidgetDescription: (widget: Gtk.Widget) => string | null;
|
|
54
|
-
declare const
|
|
33
|
+
declare const getWidgetValueNow: (widget: Gtk.Widget) => number | null;
|
|
34
|
+
declare const getWidgetValueText: (widget: Gtk.Widget) => string | null;
|
|
35
|
+
declare const isWidgetValueMatch: (widget: Gtk.Widget, field: WidgetValueField, expected: number) => boolean;
|
|
55
36
|
declare const getWidgetOwnLabel: (widget: Gtk.Widget) => string | null;
|
|
56
37
|
declare const getWidgetLabelledByText: (widget: Gtk.Widget) => string | null;
|
|
38
|
+
declare const getWidgetExternalLabelText: (widget: Gtk.Widget) => string | null;
|
|
57
39
|
declare const getWidgetDescribedByText: (widget: Gtk.Widget) => string | null;
|
|
40
|
+
/**
|
|
41
|
+
* Returns whether a widget is excluded from the accessibility tree, because it or one of its
|
|
42
|
+
* ancestors is marked hidden.
|
|
43
|
+
*
|
|
44
|
+
* @param widget The widget to test.
|
|
45
|
+
*/
|
|
58
46
|
declare const isInaccessible: (widget: Gtk.Widget) => boolean;
|
|
59
|
-
export {
|
|
47
|
+
export { namingLabelText, getWidgetText, getWidgetTextContent, getWidgetLabelText, getWidgetAccessibleName, getWidgetName, getWidgetPlaceholderText, getWidgetDisplayValue, hasDisplayValue, isWidgetDisabled, isWidgetVisible, getWidgetRequiredState, getWidgetSelection, getWidgetDescribedByText, getWidgetCheckedState, isWidgetChecked, getWidgetPressedState, getWidgetExpandedState, getWidgetSelectedState, getWidgetLevel, getWidgetInvalidState, getWidgetErrorMessage, getWidgetBusyState, getWidgetDescription, getWidgetValueNow, getWidgetValueText, getWidgetOwnLabel, getWidgetExternalLabelText, getWidgetLabelledByText, isInaccessible, isWidgetValueMatch, type CheckedState, type WidgetValueField, };
|
|
60
48
|
//# sourceMappingURL=widget-accessible-properties.d.ts.map
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"widget-accessible-properties.d.ts","sourceRoot":"","sources":["../src/widget-accessible-properties.ts"],"names":[],"mappings":"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"}
|