@huoshan12345/jqueryx 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE.TXT +21 -0
  2. package/README.md +390 -0
  3. package/dist/extensions/index.d.ts +16 -0
  4. package/dist/extensions/index.d.ts.map +1 -0
  5. package/dist/extensions/jquery.attr.d.ts +30 -0
  6. package/dist/extensions/jquery.attr.d.ts.map +1 -0
  7. package/dist/extensions/jquery.collection.d.ts +22 -0
  8. package/dist/extensions/jquery.collection.d.ts.map +1 -0
  9. package/dist/extensions/jquery.css.d.ts +42 -0
  10. package/dist/extensions/jquery.css.d.ts.map +1 -0
  11. package/dist/extensions/jquery.enumeration.d.ts +12 -0
  12. package/dist/extensions/jquery.enumeration.d.ts.map +1 -0
  13. package/dist/extensions/jquery.events.d.ts +36 -0
  14. package/dist/extensions/jquery.events.d.ts.map +1 -0
  15. package/dist/extensions/jquery.factory.d.ts +20 -0
  16. package/dist/extensions/jquery.factory.d.ts.map +1 -0
  17. package/dist/extensions/jquery.init.d.ts +2 -0
  18. package/dist/extensions/jquery.init.d.ts.map +1 -0
  19. package/dist/extensions/jquery.observe.d.ts +13 -0
  20. package/dist/extensions/jquery.observe.d.ts.map +1 -0
  21. package/dist/extensions/jquery.replace.d.ts +15 -0
  22. package/dist/extensions/jquery.replace.d.ts.map +1 -0
  23. package/dist/extensions/jquery.scroll.d.ts +8 -0
  24. package/dist/extensions/jquery.scroll.d.ts.map +1 -0
  25. package/dist/extensions/jquery.text-nodes.d.ts +17 -0
  26. package/dist/extensions/jquery.text-nodes.d.ts.map +1 -0
  27. package/dist/extensions/jquery.text.d.ts +27 -0
  28. package/dist/extensions/jquery.text.d.ts.map +1 -0
  29. package/dist/extensions/jquery.traversal.d.ts +20 -0
  30. package/dist/extensions/jquery.traversal.d.ts.map +1 -0
  31. package/dist/extensions/jquery.urls.d.ts +9 -0
  32. package/dist/extensions/jquery.urls.d.ts.map +1 -0
  33. package/dist/extensions/jquery.wait.d.ts +12 -0
  34. package/dist/extensions/jquery.wait.d.ts.map +1 -0
  35. package/dist/index.d.ts +5 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +524 -0
  38. package/dist/types/lib.d.ts +65 -0
  39. package/dist/types/lib.d.ts.map +1 -0
  40. package/package.json +63 -0
package/LICENSE.TXT ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2025 huoshan12345 <huoshan12345@hotmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,390 @@
1
+ # @huoshan12345/jqueryx [![NPM Version](https://img.shields.io/npm/v/@huoshan12345/jqueryx)](https://www.npmjs.com/package/@huoshan12345/jqueryx) [![LICENSE](https://img.shields.io/github/license/mashape/apistatus.svg)](LICENSE.TXT) [![Build](https://github.com/huoshan12345/jqueryx/actions/workflows/build.yml/badge.svg)](https://github.com/huoshan12345/jqueryx/actions/workflows/build.yml)
2
+
3
+ Typed jQuery extensions for collections, DOM text, styles, events, observation and asynchronous node discovery.
4
+
5
+ ## Installation and initialization
6
+
7
+ ```sh
8
+ pnpm add @huoshan12345/jqueryx jquery builtinx linqx
9
+ ```
10
+
11
+ The package requires jQuery `^4.0.0`, builtinx `^0.3.3` and linqx `^0.3.4` as shared peers. jQuery types ship as a dependency. Import @huoshan12345/jqueryx once before running application code that uses its extensions:
12
+
13
+ ```ts
14
+ import '@huoshan12345/jqueryx';
15
+
16
+ const button = $('<button>').title('Save').pointer();
17
+ button.onClick(async target => {
18
+ if ($.isElement(target)) {
19
+ target.setAttribute('data-clicked', 'true');
20
+ }
21
+ });
22
+ ```
23
+
24
+ The import installs the shared jQuery instance as global `$` and `jQuery`, registers the extensions and imports `builtinx/dom`. Other application files do not need `import $ from 'jquery'`. Initialization must run before those files use the globals. An explicit jQuery import, when used, shares the same instance.
25
+
26
+ This entry requires a browser DOM or an initialized DOM environment such as jsdom; it is not a DOM-free SSR entry. The package exports option types and `ClickOptions`. It has no default jQuery export or public feature subpaths.
27
+
28
+ ## API conventions
29
+
30
+ - Instance methods use a collection, such as `nodes.ownText()`. Static methods use `$`, such as `$.waitForNodes()`.
31
+ - `this` below means the original collection is returned for chaining. Unless specified otherwise, setters affect every member and return an empty collection unchanged.
32
+ - Attribute and color getters read the first element. `checked()` and `visible()` test whether **any** member matches. Text getters combine content across roots.
33
+ - DOM methods retain their declared constraints: `onClick` accepts HTML elements, `textNodes` accepts Nodes, and `dispatchEvent` accepts EventTargets. Style methods require an inline `style` interface, including HTML and SVG elements.
34
+ - Selectors use jQuery syntax except `$.waitForNodes`, which uses native CSS selectors. Invalid selectors throw when evaluated; `waitForNodes` rejects its promise instead.
35
+ - Native nodes from accessible iframe documents are supported by conversion and guards. Each traversal method specifies whether it searches iframe documents.
36
+
37
+ ## Collections — `jquery.collection.ts`
38
+
39
+ | Method | Return value and behavior |
40
+ | --- | --- |
41
+ | `isEmpty()` | `boolean`: the collection has zero members. |
42
+ | `isNotEmpty()` | `boolean`: the collection has at least one member. |
43
+ | `isNot(selector)` | `boolean`: no member matches the selector; `true` for an empty collection. |
44
+ | `throwIfEmpty()` | `this`; throws `Error('The set is empty')` when empty. |
45
+ | `ifEmpty(selector)` | The same nonempty collection, or `$(selector)` as fallback. The fallback is evaluated only when empty and may itself be empty. |
46
+ | `where(predicate)` | A filtered collection retaining only literal `true` results from `predicate(element, originalIndex)`. `false`, `null` and `undefined` exclude the member. Empty inputs invoke no callbacks. |
47
+ | `tap(action)` | Calls `action(collection)` once, including when empty; returns `this`. |
48
+ | `tapIf(condition, action)` | Evaluates `condition(collection)` once, calls `action(collection)` if true, and returns `this`. |
49
+
50
+ `where` uses element-first arguments, unlike jQuery `filter`. `tap` and `tapIf` operate on the whole collection, ignore return values and do not await asynchronous callbacks. Synchronous callback errors propagate.
51
+
52
+ ```ts
53
+ const items = $('<i></i><b></b>');
54
+ items.where((_element, index) => index === 0)
55
+ .throwIfEmpty().tap(nodes => nodes.addClass('selected'));
56
+ items.tapIf(nodes => nodes.isNot('.disabled'), nodes => nodes.addClass('ready'));
57
+ const fallback = $().ifEmpty('<span>Nothing found</span>');
58
+ console.log(items.isEmpty(), items.isNotEmpty(), fallback.length);
59
+ ```
60
+
61
+ ## Enumeration — `jquery.enumeration.ts`
62
+
63
+ | Method | Return value and behavior |
64
+ | --- | --- |
65
+ | `entries()` | A fresh `IterableIterator<[number, TElement]>` yielding zero-based indexes and raw members in collection order. Each iterator is consumed once. |
66
+ | `asEnumerable()` | A lazy, repeatable linqx `Enumerable.IEnumerable<TElement>`. Each enumeration creates an independent iterator. |
67
+ | `enumerate()` | A lazy, repeatable `Enumerable.IEnumerable<JQuery<TElement>>`, wrapping each member in its own collection on each enumeration. |
68
+
69
+ These methods read stored collection membership at enumeration time. They do not clone nodes or rerun the original selector. Use `.toArray()` to snapshot membership. Empty inputs yield empty sequences.
70
+
71
+ ```ts
72
+ const nodes = $('<i></i><b></b>');
73
+ for (const [index, element] of nodes.entries()) {
74
+ element.setAttribute('data-index', String(index));
75
+ }
76
+ const sequence = nodes.asEnumerable();
77
+ console.log(sequence.count(), sequence.count()); // 2, 2
78
+ const wrapped = nodes.enumerate().select(node => node.title('item')).toArray();
79
+ ```
80
+
81
+ ## Conversion and guards — `jquery.factory.ts`
82
+
83
+ | Method | Return value and behavior |
84
+ | --- | --- |
85
+ | `$.from(null)` / `$.from(undefined)` | An empty collection. |
86
+ | `$.from(node)` | Wraps a native Node, including Element, Text, Comment, Document, DocumentFragment and other native node types. |
87
+ | `$.from(collection)` | Returns a collection from the shared jQuery instance unchanged. Another instance's collection is converted as array-like input. |
88
+ | `$.from(selectorOrHtml)` | Evaluates the string through jQuery. |
89
+ | `$.from(arrayLike)` | Flattens one level of strings, Nodes and jQuery collections through jQuery `add`, including its ordering and deduplication rules for connected nodes. |
90
+ | `$.isJQuery(value)` | Type guard for collections from the shared jQuery instance; does not validate members. |
91
+ | `$.isElement(value)` | Native Element type guard across realms, including documents without a window. |
92
+ | `$.isNode(value)` | Native Node type guard across realms, including non-Element nodes. |
93
+
94
+ `$.from<T extends Node>()` preserves typed Node collections. Arrays and NodeLists are accepted; convert arbitrary iterables such as Sets/generators to arrays first. Unsupported inputs/group members are logged and throw TypeError. Shared jQuery collections are returned as-is without validating contents. Nested arrays are not recursively flattened. Invalid selectors propagate jQuery errors.
95
+
96
+ ```ts
97
+ const text = document.createTextNode('hello');
98
+ const fragment = document.createDocumentFragment();
99
+ fragment.append(text);
100
+ const nodes = $.from<Node>([text, fragment]);
101
+ console.log($.isNode(text), $.isElement(text)); // true, false
102
+ console.log($.isJQuery(nodes), $.from(nodes) === nodes); // true, true
103
+ ```
104
+
105
+ ## Search and ancestors — `jquery.traversal.ts`
106
+
107
+ | Method | Return value and behavior |
108
+ | --- | --- |
109
+ | `ancestor(selector, outermost = false, includeSelf = false)` | Finds one matching ancestor per selected element. Defaults to the nearest matching parent; `outermost` selects the farthest match and `includeSelf` considers the selected element first. Results use jQuery `add` ordering/deduplication. |
110
+ | `search(selector, checkIframesIfEmpty = true)` | Finds descendants of the roots, excluding the roots themselves. Only when the combined result is empty does it search documents of descendant iframes. |
111
+ | `$.search(selector, checkIframesIfEmpty = true)` | Starts with `$(selector)` in the current document; only when empty searches documents of iframes in that document. |
112
+
113
+ Missing matches return an empty collection. The iframe fallback uses jQuery `contents()` and is one level deep. It does not recursively discover nested frames or wait for new content. Pass `false` to disable it; use `$.waitForNodes` for repeated discovery.
114
+
115
+ ```ts
116
+ const root = $('<section><div class="group"><button></button></div></section>');
117
+ const button = root.search('button', false);
118
+ const group = button.ancestor('.group');
119
+ const outer = button.ancestor('section, .group', true);
120
+ const existing = $.search('.loaded', false);
121
+ ```
122
+
123
+ ## Text traversal — `jquery.text-nodes.ts`
124
+
125
+ ### `textNodes(traverseSelector?, excludeSelectors = [])`
126
+
127
+ Returns `JQuery<Text>` containing unique Text nodes. Traversal is depth-first, starting from roots in collection order; the final collection uses `$.from`/jQuery `add` ordering, so nodes in the same tree are sorted in document order even for reversed or overlapping roots. Disconnected trees follow jQuery ordering rules. Text, Document and DocumentFragment roots are supported, and HTML template contents are traversed. Iframe elements and shadow hosts do not implicitly enter their documents/shadow trees; supply those roots explicitly.
128
+
129
+ - `traverseSelector`: every visited Element, including an Element root, must match. Nonmatching elements prune their **whole subtree**; traversal does not search through them for later matches.
130
+ - `excludeSelectors`: readonly jQuery selector array, default `[]`. A match prunes that element and its entire subtree. The array is never mutated.
131
+ - Text, Document and DocumentFragment roots are not tested as Elements. An explicitly selected descendant root can still be visited after its ancestor was pruned.
132
+ - Empty inputs return an empty collection. Invalid selectors throw when evaluated on Elements.
133
+
134
+ ```ts
135
+ const root = $('<div>a<span>b</span><button>skip</button></div>');
136
+ const texts = root.textNodes(undefined, ['button']);
137
+ console.log(texts.asEnumerable().select(node => node.data).toArray()); // ['a', 'b']
138
+ ```
139
+
140
+ ## Text and line breaks — `jquery.text.ts`
141
+
142
+ | Method | Return value and behavior |
143
+ | --- | --- |
144
+ | `textContent()` | Concatenates the Text nodes returned by `textNodes()`, including descendants and template contents. Empty returns `''`. |
145
+ | `textContent(value)` | For each root, puts the string into the first descendant Text node and removes remaining Text nodes. Preserves non-text nodes and the first Text node's position. If no Text exists, inserts at the start of an Element/DocumentFragment; HTML templates insert into `template.content`. Returns `this`. |
146
+ | `ownText()` | Concatenates direct child Text content across roots; a Text root contributes its own value. Empty returns `''`. |
147
+ | `ownText(value)` | For each Element/DocumentFragment root, updates its first direct Text and removes later direct Text nodes, or inserts at the beginning if absent. Updates Text roots directly and skips other root types. Preserves descendant text in child elements; returns `this`. |
148
+ | `collapseBrs()` | Finds descendant `br` elements in each root and removes following sibling `br` elements and newline-only Text nodes until another kind of sibling is reached. Returns `this`. |
149
+ | `isNewLineTextNode()` | Whether the collection is **nonempty** and every root is Text containing only whitespace and at least one `\r` or `\n`. Spaces alone do not match. Empty returns `false`. |
150
+ | `trimLeadingBrs()` | Removes each root's leading `br` elements and newline-only Text nodes. Stops at other children, including comments and spaces without newlines. Returns `this`. |
151
+
152
+ Both text setters accept `''` and preserve non-text node identities, event handlers and data. They do not behave like jQuery `.text(value)`, which replaces element children. `textContent(value)` can change descendant text in a Document but inserts nothing if a non-Element/non-fragment root has no Text. Neither getter includes Comment/CDATA contents as Text. `ownText` does not automatically enter `template.content`. Line-break helpers do not automatically enter templates, shadow trees or iframe documents.
153
+
154
+ ```ts
155
+ const root = $('<div>a<b>b</b>c</div>');
156
+ console.log(root.textContent(), root.ownText()); // 'abc', 'ac'
157
+ root.ownText('direct'); // <div>direct<b>b</b></div>
158
+ root.textContent('all'); // <div>all<b></b></div>
159
+ const lines = $('<div>\n<br>a<br>\n<br>b</div>');
160
+ lines.trimLeadingBrs().collapseBrs(); // <div>a<br>b</div>
161
+ console.log($(document.createTextNode('\n')).isNewLineTextNode()); // true
162
+ ```
163
+
164
+ ## Replacement — `jquery.replace.ts`
165
+
166
+ ### `replaceBy(replacement)`
167
+
168
+ Calls `replacement(wrappedElement, originalIndex)` once per distinct **outermost** selected Element, returning all replacement Elements in callback order. The callback must return a jQuery collection.
169
+
170
+ - Parent/child overlap is resolved before callbacks. Selected descendants are skipped even if their selected parent is kept. Duplicate roots use their first original index.
171
+ - Return the current element to keep it, an empty collection to delete it, or several elements to insert several replacements. Detached sources still contribute their returned replacements.
172
+ - Reusing a replacement, or returning another source whose callback has not run yet, clones it with jQuery events/data rather than moving the earlier result/source.
173
+ - Empty inputs invoke no callbacks and return an empty collection. Callback errors propagate; earlier completed replacements remain. The operation is not transactional.
174
+
175
+ ```ts
176
+ const root = $('<div><i>a</i><i>b</i></div>');
177
+ const replacements = root.find('i').replaceBy((node, index) =>
178
+ $('<b>').textContent(`${index}: ${node.textContent()}`),
179
+ );
180
+ console.log(replacements.textContent()); // '0: a1: b'
181
+ ```
182
+
183
+ ## Attributes and control state — `jquery.attr.ts`
184
+
185
+ | Method | Return value and behavior |
186
+ | --- | --- |
187
+ | `title()` | First raw title attribute; undefined when missing or collection empty. An empty attribute remains `''`. |
188
+ | `title(value)` | Sets every title attribute, including `''`; returns `this`. |
189
+ | `requiredTitle()` | First title; throws Error when missing/empty. Whitespace is not trimmed. |
190
+ | `href()` | First raw href attribute, including relative strings; undefined when missing or collection empty. |
191
+ | `href(value)` | Sets every href to `value.toString()`; accepts string or URL, including an empty string; returns `this`. |
192
+ | `requiredHref()` | First raw href; throws Error when missing/empty, without searching later members. |
193
+ | `voidHref()` | Sets every href to `javascript:;`; returns `this`. |
194
+ | `hasUrlHref()` | Tests the first raw href for a nonempty string not starting with exact lowercase `javascript:`. Empty returns false. Does not trim, parse or validate URLs; not a security filter. |
195
+ | `targetBlank(onlyUpdate = true)` | Sets every target to `_blank`; default skips attribute writes for already-matching targets. `false` writes those too. Returns the original collection. |
196
+ | `disable()` / `enable()` | Sets every live `disabled` property to true / false; returns `this`. |
197
+ | `checked()` | Whether any member matches jQuery `:checked`, including selected options. Uses current state; empty returns false. |
198
+
199
+ ```ts
200
+ const link = $('<a>').title('Details').href('/details').targetBlank();
201
+ console.log(link.requiredTitle(), link.requiredHref(), link.hasUrlHref());
202
+ link.voidHref();
203
+ const control = $('<input type="checkbox" checked>').disable().enable();
204
+ console.log(control.checked()); // true
205
+ ```
206
+
207
+ ## Styles — `jquery.css.ts`
208
+
209
+ All style setters affect every selected element and return `this`.
210
+
211
+ | Method | Behavior |
212
+ | --- | --- |
213
+ | `pointer()` | Sets `cursor: pointer`. |
214
+ | `underline()` | Sets `text-decoration: underline`. |
215
+ | `flex()` | Sets `display: flex`. |
216
+ | `inlineFlex()` | Sets `display: inline-flex`. |
217
+ | `inlineBlock()` | Sets `display: inline-block`. |
218
+ | `flexWrap(value = 'wrap')` | Sets flex-wrap without changing display. |
219
+ | `padding(value)` | Sets padding via jQuery css; accepts a CSS string or a number in pixels. |
220
+ | `cssImportant(propertyName, value)` | Sets a CSS property (such as `background-color` or `--gap`) to a string with `!important`. Include units where needed. `''` removes it; non-string values throw TypeError. |
221
+ | `cssIfNotEmpty(propertyName, value?)` | Calls jQuery css for nonempty strings. Skips undefined/`''`; applies `'0'`. Does not catch errors. |
222
+ | `addClassIfNotEmpty(classNames?)` | Calls jQuery addClass for a nonempty string or string array. Skips undefined, `''`, `[]`; does not catch errors. |
223
+ | `color()` | First computed color string, or undefined for an empty collection. |
224
+ | `color(value, important = false)` | Sets color via jQuery css, or cssImportant when requested. `''` clears inline color. |
225
+ | `colorHex(uppercase = false)` | Converts first computed comma-separated rgb()/rgba() to `#rrggbb` or `#rrggbbaa` when alpha is below 1, rounding components to bytes. Empty/unsupported formats (such as `color(display-p3 ...)`) return undefined. |
226
+ | `visible()` | Whether any member matches jQuery `:visible` (has a layout box). Empty returns false. Does not test opacity or viewport intersection. |
227
+ | `visible(value)` | Uses jQuery show/hide, restoring previous display where supported. Does not force hidden ancestors to become visible. |
228
+
229
+ ```ts
230
+ const panel = $('<div>').flex().flexWrap().padding(12).visible(true);
231
+ panel.cssImportant('--gap', '1rem').cssIfNotEmpty('opacity', '0.8');
232
+ panel.addClassIfNotEmpty(['panel', 'ready']).color('rgba(255, 0, 0, 0.5)');
233
+ console.log(panel.colorHex(true)); // '#FF000080'
234
+ const label = $('<span>').inlineBlock().underline().pointer();
235
+ const badge = $('<span>').inlineFlex();
236
+ ```
237
+
238
+ ## Scrolling — `jquery.scroll.ts`
239
+
240
+ ### `$.scrollToNode(element, options?)`
241
+
242
+ Accepts an Element, selector string or jQuery Element collection. Calls the **first** matched element's native `scrollIntoView` with `{ block: 'start', inline: 'nearest', ...options }`. Native `ScrollIntoViewOptions` override alignment and can set behavior. Returns void. Empty matches do nothing; unsupported inputs throw TypeError, and native errors propagate. Uses the element's own scrolling implementation, including iframe elements, without calculating page coordinates.
243
+
244
+ ```ts
245
+ $.scrollToNode('#results', { behavior: 'smooth', block: 'center' });
246
+ ```
247
+
248
+ ## Events — `jquery.events.ts`
249
+
250
+ ### `onClick(handler, options?)`
251
+
252
+ Binds clicks to selected HTML elements and returns `this`. The callback receives `(target: EventTarget, originalEvent?: MouseEvent)` and may return a value or promise. Target is the event origin, possibly a descendant such as SVG; narrow it before accessing element-specific members. `originalEvent` is absent for jQuery-triggered clicks.
253
+
254
+ Cancellation happens synchronously before the callback, even for async handlers. Return values, including false, are ignored. Options accept `Partial<ClickOptions>`:
255
+
256
+ | Option | Default | Behavior |
257
+ | --- | --- | --- |
258
+ | `preventDefault` | true | Cancels the default browser click action. |
259
+ | `stopPropagation` | false | Stops propagation to ancestors. |
260
+ | `stopImmediatePropagation` | false | Also stops subsequent listeners on the same element. |
261
+ | `disableWhileProcessing` | true | Skips reentrant clicks per binding and bound element until the handler settles; temporarily sets `pointer-events: none !important`. |
262
+ | `onError` | undefined | Receives synchronous errors and promise rejections; defaults to console.error. Errors/rejections from onError itself are reported to console.error. |
263
+
264
+ Different selected elements can run concurrently. Overlapping bindings share pointer-style ownership until all finish; previous value/priority are restored even on failure. This does not set a control's disabled property. Setting disableWhileProcessing to false permits overlap and leaves pointer styles alone.
265
+
266
+ ```ts
267
+ import { ClickOptions } from '@huoshan12345/jqueryx';
268
+
269
+ const options = new ClickOptions({ stopPropagation: true, onError: error => console.error(error) });
270
+ $('button.save').onClick(async target => {
271
+ if ($.isElement(target)) {
272
+ target.setAttribute('data-saved', 'true');
273
+ }
274
+ }, options);
275
+ ```
276
+
277
+ `new ClickOptions(init?)` creates independent defaults and copies supplied overrides without changing the input object.
278
+
279
+ ### Keyboard and dispatch helpers
280
+
281
+ | Method | Return value and behavior |
282
+ | --- | --- |
283
+ | `onKeyDown(handler, options?)` | Binds `(target: EventTarget, key: string) => value or Promise`. Stops immediate propagation before the handler, preserves default behavior and uses EventHandlerOptions.onError as above. Returns `this`. |
284
+ | `onEnterDown(handler, options?)` | Like onKeyDown, but receives only target and runs only for `key === 'Enter'`. Other keys are not intercepted. Returns `this`. |
285
+ | `onClickGotoHref(openNew?)` | For anchors, removes jQuery click handlers/inline onclick attributes and stops propagation during capture at each anchor so native href navigation can proceed. `true` sets target=_blank; otherwise preserves targets. Returns `this`. |
286
+ | `triggerClick()` | Calls native click() for every HTML element, including normal default actions. Disabled controls obey native rules. Returns `this`. |
287
+ | `triggerChange()` | Triggers jQuery change on every member, including jQuery bubbling. Does not edit the control value. Returns `this`. |
288
+ | `dispatchEvent(event)` | Dispatches the same native Event sequentially to every EventTarget. Its bubbling/cancelable options apply; cancellation does not stop iteration. Returns `this`. |
289
+
290
+ `onClickGotoHref` skips non-anchors. It does not remove arbitrary native listeners, undo earlier capture-phase cancellation or set href. Keyboard bindings have no processing lock. Empty collections invoke no handlers. `triggerChange` uses jQuery dispatch; do not rely on it to invoke native addEventListener('change', ...) listeners.
291
+
292
+ ```ts
293
+ const input = $('<input>').onKeyDown((_target, key) => console.log(key));
294
+ const searchInput = $('<input>').onEnterDown(target => console.log(target));
295
+ input.triggerChange();
296
+ searchInput.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
297
+ const checkbox = $('<input type="checkbox">').triggerClick();
298
+ const link = $('<a href="#details">').onClickGotoHref(true);
299
+ ```
300
+
301
+ ## Observation — `jquery.observe.ts`
302
+
303
+ ### `observe(callback, options?)` and `subscription.disconnect()`
304
+
305
+ Creates one MutationObserver per selected Node and returns a `JQueryObservation` subscription instead of a chainable collection. The callback receives `(mutations, observer, originalCollection)` for each delivery. The third argument is the entire original collection, not only the changed node.
306
+
307
+ Options are builtinx `MutationObserverOptionsInit`: native observer settings, `callOnStart`, `debounce`, `exclusions`, `beforeCallback`, `afterCallback`, `onSkipped`. With the installed builtinx defaults, childList/subtree are enabled, attributes/characterData disabled, a startup callback runs synchronously per node, and debounce uses 1000 ms with leading/trailing callbacks and a 1000 ms maximum wait. Host changes to `MutationObserverOptions.default` apply. Use `callOnStart: false, debounce: false` for native deliveries without startup/debounce scheduling.
308
+
309
+ `subscription.disconnect()` returns void, disconnects the group and suppresses pending callbacks/hooks. Repeated calls are safe, including for empty subscriptions. Independent subscriptions remain independent. If registration or a startup callback fails, the call disconnects observers already created and rethrows. This wrapper does not provide event handlers' async error routing.
310
+
311
+ ```ts
312
+ const root = $('<div>');
313
+ const subscription = root.observe((records, _observer, nodes) => {
314
+ console.log(records.length, nodes.length);
315
+ }, { childList: true, subtree: true, callOnStart: false, debounce: false });
316
+ root.append('<span>new</span>');
317
+ await Promise.resolve(); // allow native observer delivery
318
+ subscription.disconnect();
319
+ ```
320
+
321
+ ## Waiting for asynchronously loaded nodes — `jquery.wait.ts`
322
+
323
+ ### `$.waitForNodes<TMatch extends Element = HTMLElement>(selector, options?)`
324
+
325
+ Returns `Promise<JQuery<TMatch>>`. Queries the current document immediately with native CSS selectors, then polls until at least one match exists. Resolves with all matches from that query. Requires no pre-existing collection and installs no MutationObserver. The generic specifies the expected element type without validating it at runtime.
326
+
327
+ | WaitForNodesOptions | Default | Behavior |
328
+ | --- | --- | --- |
329
+ | `timeoutMs` | 30000 | Finite non-negative milliseconds. Zero checks once. Rejects with a DOMException named TimeoutError if no match appears before the deadline. |
330
+ | `pollIntervalMs` | 100 | Finite positive milliseconds between queries. Timeout is enforced even between polls; long native timer delays are split. |
331
+ | `signal` | absent | Cancels with exact signal.reason, including when already aborted. An already-aborted signal takes precedence over existing matches. |
332
+ | `includeIframes` | false | Rediscovers accessible iframe documents recursively every query, including newly added/navigated frames; skips inaccessible documents. |
333
+
334
+ Empty/non-string selectors reject with TypeError; invalid CSS rejects with the native selector error. Invalid numeric options reject with RangeError. All timers/abort listeners are removed on success, timeout, cancellation or errors. Matches appearing/disappearing between polls can be missed. Shadow trees are not searched automatically.
335
+
336
+ ```ts
337
+ const controller = new AbortController();
338
+ try {
339
+ const nodes = await $.waitForNodes<HTMLButtonElement>('.ajax-content button', {
340
+ timeoutMs: 5000,
341
+ pollIntervalMs: 100,
342
+ includeIframes: true,
343
+ signal: controller.signal,
344
+ });
345
+ nodes.enable();
346
+ } catch (error) {
347
+ console.error(error);
348
+ }
349
+ ```
350
+
351
+ ## URL rewriting — `jquery.urls.ts`
352
+
353
+ ### `refineUrls(hosts, baseUrl, options?)`
354
+
355
+ Rewrites selected HTML anchors' href and images' src attributes without selecting descendants automatically. Returns `this`; unsupported tags are logged/skipped. `hosts` is an array of builtinx `MatchPattern` (`string` or `RegExp`) values matched against URL host, including port. `baseUrl` supplies replacement protocol, hostname and port.
356
+
357
+ Only explicit HTTP(S) and protocol-relative strings are candidates, with trimming for parsing and case-insensitive protocol matching. Protocol-relative strings resolve against the element's base URI. Ordinary relative URLs, non-HTTP URLs, local URLs already matching baseUrl.host, unmatched hosts and missing attributes remain unchanged. Malformed candidates are logged/skipped. The base pathname is not prepended; query/fragment components are preserved.
358
+
359
+ | RefineUrlsOptions | Default | Behavior |
360
+ | --- | --- | --- |
361
+ | `pathRewrite` | absent | Receives a matching URL's pathname and returns a new pathname before its origin changes. Errors propagate; earlier changes remain. |
362
+ | `addImageFallbackLinks` | false | Adds/reuses a _blank, noreferrer link after every selected image with src, including unmatched URLs. Omitting/disabling removes links/listeners previously managed here. |
363
+
364
+ The third argument also accepts the legacy `(path: string) => string` callback. Complete occurrences of the old URL inside each Text node are replaced literally and repeatedly. URLs split across Text nodes are not joined/replaced as visible text. Child elements, events and data remain intact.
365
+
366
+ Fallback links use the final src, remain visible for pending/failed images, and hide when `complete && naturalHeight > 0`. Load/error events update visibility. Repeated calls reuse links/listeners; disabling preserves unrelated links.
367
+
368
+ ```ts
369
+ const nodes = $('<a href="https://old.example/files/a?q=1#top">download</a><img src="https://old.example/pic.png">');
370
+ nodes.refineUrls(['old.example', /^cdn\./], new URL('https://new.example:8443/'), {
371
+ pathRewrite: path => path.replace('/files/', '/archive/'),
372
+ addImageFallbackLinks: true,
373
+ });
374
+ console.log(nodes.eq(0).href()); // 'https://new.example:8443/archive/a?q=1#top'
375
+ ```
376
+
377
+ ## Development and tests
378
+
379
+ ```sh
380
+ pnpm install
381
+ pnpm test
382
+ pnpm run type-check
383
+ pnpm build
384
+ ```
385
+
386
+ `pnpm dev` watches type checking; `pnpm test:watch` watches tests. Full build cleans output, checks types, builds JavaScript and generates declarations.
387
+
388
+ Each `src/extensions/jquery.<feature>.ts` has a matching `test/jquery.<feature>.test.ts`: init, collection, enumeration, factory, traversal, text-nodes, text, replace, attr, css, scroll, events, observe, wait and urls. Shared fixtures are in `test/helpers`.
389
+
390
+ `extensions.integration.test.ts` verifies cross-feature chains. `package.test.ts` checks shared peer initialization/published declarations and compiles every TypeScript example in this README against the built package in Bundler and NodeNext modes. `build-workflow.test.ts` checks workflow triggers. DOM tests use jsdom; focused layout/scroll tests supply metrics or native scrolling stubs where jsdom has no implementation.
@@ -0,0 +1,16 @@
1
+ import './jquery.init.js';
2
+ import './jquery.collection.js';
3
+ import './jquery.enumeration.js';
4
+ import './jquery.factory.js';
5
+ import './jquery.traversal.js';
6
+ import './jquery.text-nodes.js';
7
+ import './jquery.text.js';
8
+ import './jquery.replace.js';
9
+ import './jquery.attr.js';
10
+ import './jquery.css.js';
11
+ import './jquery.scroll.js';
12
+ import './jquery.events.js';
13
+ import './jquery.observe.js';
14
+ import './jquery.wait.js';
15
+ import './jquery.urls.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/extensions/index.ts"],"names":[],"mappings":"AACA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,wBAAwB,CAAC;AAChC,OAAO,yBAAyB,CAAC;AACjC,OAAO,qBAAqB,CAAC;AAC7B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,wBAAwB,CAAC;AAChC,OAAO,kBAAkB,CAAC;AAC1B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,kBAAkB,CAAC;AAC1B,OAAO,iBAAiB,CAAC;AACzB,OAAO,oBAAoB,CAAC;AAC5B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,kBAAkB,CAAC;AAC1B,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { URLLike } from 'builtinx';
2
+ declare global {
3
+ interface JQuery<TElement = HTMLElement> {
4
+ /** Reads the first element's title attribute; undefined for a missing attribute or empty collection. */
5
+ title(this: this & JQuery<Element>): string | undefined;
6
+ /** Sets every title attribute, including empty strings, and returns this. */
7
+ title(this: this & JQuery<Element>, value: string): this;
8
+ /** Reads the first title attribute; throws Error if missing or empty. Does not trim whitespace. */
9
+ requiredTitle(this: this & JQuery<Element>): string;
10
+ /** Sets target="_blank" on every element; onlyUpdate defaults to true and skips already matching attributes. */
11
+ targetBlank(this: this & JQuery<Element>, onlyUpdate?: boolean): this;
12
+ /** Reads the first raw href attribute; throws Error if missing or empty. */
13
+ requiredHref(this: this & JQuery<Element>): string;
14
+ /** Reads the first raw href attribute without resolving relative URLs; undefined when missing or empty collection. */
15
+ href(this: this & JQuery<Element>): string | undefined;
16
+ /** Sets every href attribute to value.toString() and returns this. An empty string is retained. */
17
+ href(this: this & JQuery<Element>, value: URLLike): this;
18
+ /** Sets every href to "javascript:;" and returns this. */
19
+ voidHref(this: this & JQuery<Element>): this;
20
+ /** Tests the first raw href for a nonempty value not starting with lowercase "javascript:"; not URL validation. */
21
+ hasUrlHref(this: this & JQuery<Element>): boolean;
22
+ /** Sets the live disabled property to true for every selected element and returns this. */
23
+ disable(this: this & JQuery<Element>): this;
24
+ /** Sets the live disabled property to false for every selected element and returns this. */
25
+ enable(this: this & JQuery<Element>): this;
26
+ /** Returns whether any member matches jQuery :checked, including selected options; false when empty. */
27
+ checked(): boolean;
28
+ }
29
+ }
30
+ //# sourceMappingURL=jquery.attr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jquery.attr.d.ts","sourceRoot":"","sources":["../../src/extensions/jquery.attr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM,CAAC,QAAQ,GAAG,WAAW;QACrC,wGAAwG;QACxG,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;QACxD,6EAA6E;QAC7E,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACzD,mGAAmG;QACnG,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;QACpD,gHAAgH;QAChH,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QACtE,4EAA4E;QAC5E,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;QACnD,sHAAsH;QACtH,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;QACvD,mGAAmG;QACnG,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;QACzD,0DAA0D;QAC1D,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;QAC7C,mHAAmH;QACnH,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;QAClD,2FAA2F;QAC3F,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;QAC5C,4FAA4F;QAC5F,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;QAC3C,wGAAwG;QACxG,OAAO,IAAI,OAAO,CAAC;KACpB;CACF"}
@@ -0,0 +1,22 @@
1
+ import type { Nullishable } from 'builtinx';
2
+ declare global {
3
+ interface JQuery<TElement = HTMLElement> {
4
+ /** Returns true when no member matches the jQuery selector; true for an empty collection. */
5
+ isNot(selector: string): boolean;
6
+ /** Returns this collection, or throws Error when it has no members. */
7
+ throwIfEmpty(): this;
8
+ /** Returns whether the collection has zero members. */
9
+ isEmpty(): boolean;
10
+ /** Returns whether the collection has at least one member. */
11
+ isNotEmpty(): boolean;
12
+ /** Returns this nonempty collection; otherwise evaluates $(selector) as the fallback. */
13
+ ifEmpty(selector: string): JQuery<TElement | HTMLElement>;
14
+ /** Filters by (element, originalIndex), retaining only literal true results. Nullish results are false. */
15
+ where(predicate: (e: TElement, index: number) => Nullishable<boolean>): JQuery<TElement>;
16
+ /** Calls action once with the entire collection, even when empty, and returns this. Errors propagate. */
17
+ tap(action: (node: this) => void): this;
18
+ /** Evaluates condition once with this collection, calls action if true, and returns this. Errors propagate. */
19
+ tapIf(condition: (node: this) => boolean, action: (node: this) => void): this;
20
+ }
21
+ }
22
+ //# sourceMappingURL=jquery.collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jquery.collection.d.ts","sourceRoot":"","sources":["../../src/extensions/jquery.collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM,CAAC,QAAQ,GAAG,WAAW;QACrC,6FAA6F;QAC7F,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QACjC,uEAAuE;QACvE,YAAY,IAAI,IAAI,CAAC;QACrB,uDAAuD;QACvD,OAAO,IAAI,OAAO,CAAC;QACnB,8DAA8D;QAC9D,UAAU,IAAI,OAAO,CAAC;QACtB,yFAAyF;QACzF,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,QAAQ,GAAG,WAAW,CAAC,CAAC;QAC1D,2GAA2G;QAC3G,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzF,yGAAyG;QACzG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;QACxC,+GAA+G;QAC/G,KAAK,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;KAC/E;CACF"}
@@ -0,0 +1,42 @@
1
+ type StyledElement = Element & ElementCSSInlineStyle;
2
+ declare global {
3
+ interface JQuery<TElement = HTMLElement> {
4
+ /** Sets cursor: pointer on every element and returns this. */
5
+ pointer(this: this & JQuery<StyledElement>): this;
6
+ /** Sets text-decoration: underline on every element and returns this. */
7
+ underline(this: this & JQuery<StyledElement>): this;
8
+ /** Sets display: flex on every element and returns this. */
9
+ flex(this: this & JQuery<StyledElement>): this;
10
+ /** Sets flex-wrap on every element (default "wrap") and returns this. */
11
+ flexWrap(this: this & JQuery<StyledElement>, value?: string): this;
12
+ /** Sets display: inline-block on every element and returns this. */
13
+ inlineBlock(this: this & JQuery<StyledElement>): this;
14
+ /** Sets display: inline-flex on every element and returns this. */
15
+ inlineFlex(this: this & JQuery<StyledElement>): this;
16
+ /** Sets a CSS property with !important. Use a CSS property name and an explicit CSS value, including units. */
17
+ cssImportant(this: this & JQuery<StyledElement>, propertyName: string, value: string): this;
18
+ /** Sets CSS unless value is undefined or an empty string. Does not catch errors. */
19
+ cssIfNotEmpty(this: this & JQuery<StyledElement>, propertyName: string, value?: string): this;
20
+ /** Adds classes unless the input is undefined or empty. Does not catch errors. */
21
+ addClassIfNotEmpty(this: this & JQuery<Element>, classNames?: string | string[]): this;
22
+ /** Sets padding on every element via jQuery.css; numeric values use px. Returns this. */
23
+ padding(this: this & JQuery<StyledElement>, value: string | number): this;
24
+ /** Sets every color; important defaults to false. An empty string removes the inline color. Returns this. */
25
+ color(this: this & JQuery<StyledElement>, value: string, important?: boolean): this;
26
+ /** Reads the first computed color via jQuery.css; undefined for an empty collection. */
27
+ color(this: this & JQuery<StyledElement>): string | undefined;
28
+ /**
29
+ * Converts the first element's computed rgb()/rgba() color to #rrggbb or
30
+ * #rrggbbaa for non-opaque colors, rounding each component to one byte.
31
+ * Empty collections and unsupported color formats return undefined.
32
+ * @param uppercase Uses uppercase hex digits. Defaults to false.
33
+ */
34
+ colorHex(this: this & JQuery<StyledElement>, uppercase?: boolean): string | undefined;
35
+ /** Returns whether any element matches jQuery :visible (has a layout box); false for an empty collection. */
36
+ visible(this: this & JQuery<Element>): boolean;
37
+ /** Shows or hides every element via jQuery.show/hide and returns this; does not override hidden ancestors. */
38
+ visible(this: this & JQuery<Element>, value: boolean): this;
39
+ }
40
+ }
41
+ export {};
42
+ //# sourceMappingURL=jquery.css.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jquery.css.d.ts","sourceRoot":"","sources":["../../src/extensions/jquery.css.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,GAAG,OAAO,GAAG,qBAAqB,CAAC;AAErD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM,CAAC,QAAQ,GAAG,WAAW;QACrC,8DAA8D;QAC9D,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;QAClD,yEAAyE;QACzE,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;QACpD,4DAA4D;QAC5D,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;QAC/C,yEAAyE;QACzE,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACnE,oEAAoE;QACpE,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;QACtD,mEAAmE;QACnE,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;QACrD,+GAA+G;QAC/G,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5F,oFAAoF;QACpF,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9F,kFAAkF;QAClF,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC;QACvF,yFAAyF;QACzF,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;QAC1E,6GAA6G;QAC7G,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QACpF,wFAAwF;QACxF,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;QAC9D;;;;;WAKG;QACH,QAAQ,CACN,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,EAClC,SAAS,CAAC,EAAE,OAAO,GAClB,MAAM,GAAG,SAAS,CAAC;QACtB,6GAA6G;QAC7G,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;QAC/C,8GAA8G;QAC9G,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;KAC7D;CACF"}
@@ -0,0 +1,12 @@
1
+ import { Enumerable } from 'linqx';
2
+ declare global {
3
+ interface JQuery<TElement = HTMLElement> {
4
+ /** Creates a fresh one-shot iterator of [zeroBasedIndex, element] pairs in collection order. */
5
+ entries(): IterableIterator<[number, TElement]>;
6
+ /** Returns a lazy, repeatable LINQ sequence over this collection; does not snapshot or rerun its selector. */
7
+ asEnumerable(): Enumerable.IEnumerable<TElement>;
8
+ /** Like asEnumerable, wrapping each member in its own JQuery collection on each enumeration. */
9
+ enumerate(): Enumerable.IEnumerable<JQuery<TElement>>;
10
+ }
11
+ }
12
+ //# sourceMappingURL=jquery.enumeration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jquery.enumeration.d.ts","sourceRoot":"","sources":["../../src/extensions/jquery.enumeration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEnC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM,CAAC,QAAQ,GAAG,WAAW;QACrC,gGAAgG;QAChG,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QAChD,8GAA8G;QAC9G,YAAY,IAAI,UAAU,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACjD,gGAAgG;QAChG,SAAS,IAAI,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;KACvD;CACF"}
@@ -0,0 +1,36 @@
1
+ import { ClickOptions, type EventHandlerOptions } from '../types/lib.js';
2
+ import type { Awaitable } from 'builtinx';
3
+ declare global {
4
+ interface JQuery<TElement = HTMLElement> {
5
+ /**
6
+ * Cancels events synchronously according to options, then invokes the handler.
7
+ * Processing is guarded per binding and bound element; target is event.target
8
+ * and may be a descendant of the bound element. Narrow its type before using
9
+ * element-specific members. originalEvent is the native
10
+ * MouseEvent, or undefined for a jQuery-triggered click.
11
+ * Handler return values are ignored. Errors go to onError, or console.error if omitted.
12
+ */
13
+ onClick(this: this & JQuery<HTMLElement>, handler: (target: EventTarget, originalEvent?: MouseEvent) => Awaitable<unknown>, options?: Partial<ClickOptions>): this;
14
+ /**
15
+ * Restores native anchor navigation by removing jQuery click handlers and inline onclick attributes,
16
+ * and stopping click propagation during capture at each anchor. Non-anchors are skipped.
17
+ * openNew=true sets target="_blank"; otherwise existing targets remain. Returns this.
18
+ * Does not remove arbitrary native listeners or undo earlier capture-phase cancellation.
19
+ */
20
+ onClickGotoHref(this: this & JQuery<Element>, openNew?: boolean): this;
21
+ /**
22
+ * Stops propagation immediately, preserves default behavior, and reports handler errors.
23
+ * target is event.target (possibly a descendant); key is the event's key value.
24
+ */
25
+ onKeyDown(this: this & JQuery<HTMLElement>, handler: (target: EventTarget, key: string) => Awaitable<unknown>, options?: EventHandlerOptions): this;
26
+ /** Like onKeyDown, but only handles and stops propagation for Enter. */
27
+ onEnterDown(this: this & JQuery<HTMLElement>, handler: (target: EventTarget) => Awaitable<unknown>, options?: EventHandlerOptions): this;
28
+ /** Calls each element's native click(), including its default action, and returns this. Disabled controls obey native rules. */
29
+ triggerClick(this: this & JQuery<HTMLElement>): this;
30
+ /** Triggers a jQuery change event on every member, including jQuery bubbling, and returns this. */
31
+ triggerChange(): this;
32
+ /** Dispatches the same native Event sequentially to every target and returns this, ignoring cancellation return values. */
33
+ dispatchEvent(this: this & JQuery<EventTarget>, event: Event): this;
34
+ }
35
+ }
36
+ //# sourceMappingURL=jquery.events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jquery.events.d.ts","sourceRoot":"","sources":["../../src/extensions/jquery.events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM,CAAC,QAAQ,GAAG,WAAW;QACrC;;;;;;;WAOG;QACH,OAAO,CACL,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,EAChC,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,EAAE,UAAU,KAAK,SAAS,CAAC,OAAO,CAAC,EAChF,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC9B,IAAI,CAAC;QACR;;;;;WAKG;QACH,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QACvE;;;WAGG;QACH,SAAS,CACP,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,EAChC,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC,OAAO,CAAC,EACjE,OAAO,CAAC,EAAE,mBAAmB,GAC5B,IAAI,CAAC;QACR,wEAAwE;QACxE,WAAW,CACT,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,EAChC,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,SAAS,CAAC,OAAO,CAAC,EACpD,OAAO,CAAC,EAAE,mBAAmB,GAC5B,IAAI,CAAC;QACR,gIAAgI;QAChI,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;QACrD,mGAAmG;QACnG,aAAa,IAAI,IAAI,CAAC;QACtB,2HAA2H;QAC3H,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;KACrE;CACF"}