zero-query 0.5.2 → 0.7.5
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 +12 -10
- package/cli/commands/build.js +7 -5
- package/cli/commands/bundle.js +286 -8
- package/cli/commands/dev/index.js +82 -0
- package/cli/commands/dev/logger.js +70 -0
- package/cli/commands/dev/overlay.js +366 -0
- package/cli/commands/dev/server.js +158 -0
- package/cli/commands/dev/validator.js +94 -0
- package/cli/commands/dev/watcher.js +147 -0
- package/cli/scaffold/favicon.ico +0 -0
- package/cli/scaffold/index.html +1 -0
- package/cli/scaffold/scripts/app.js +15 -22
- package/cli/scaffold/scripts/components/about.js +14 -2
- package/cli/scaffold/scripts/components/contacts/contacts.css +0 -7
- package/cli/scaffold/scripts/components/contacts/contacts.html +8 -7
- package/cli/scaffold/scripts/components/contacts/contacts.js +17 -1
- package/cli/scaffold/scripts/components/counter.js +30 -10
- package/cli/scaffold/scripts/components/home.js +3 -3
- package/cli/scaffold/scripts/components/todos.js +6 -5
- package/cli/scaffold/styles/styles.css +1 -0
- package/cli/utils.js +111 -6
- package/dist/zquery.dist.zip +0 -0
- package/dist/zquery.js +2005 -216
- package/dist/zquery.min.js +3 -13
- package/index.d.ts +149 -1080
- package/index.js +18 -7
- package/package.json +9 -3
- package/src/component.js +186 -45
- package/src/core.js +327 -35
- package/src/diff.js +280 -0
- package/src/errors.js +155 -0
- package/src/expression.js +806 -0
- package/src/http.js +18 -10
- package/src/reactive.js +29 -4
- package/src/router.js +59 -6
- package/src/ssr.js +224 -0
- package/src/store.js +24 -8
- package/tests/component.test.js +304 -0
- package/tests/core.test.js +726 -0
- package/tests/diff.test.js +194 -0
- package/tests/errors.test.js +162 -0
- package/tests/expression.test.js +334 -0
- package/tests/http.test.js +181 -0
- package/tests/reactive.test.js +191 -0
- package/tests/router.test.js +332 -0
- package/tests/store.test.js +253 -0
- package/tests/utils.test.js +353 -0
- package/types/collection.d.ts +368 -0
- package/types/component.d.ts +210 -0
- package/types/errors.d.ts +103 -0
- package/types/http.d.ts +81 -0
- package/types/misc.d.ts +166 -0
- package/types/reactive.d.ts +76 -0
- package/types/router.d.ts +132 -0
- package/types/ssr.d.ts +49 -0
- package/types/store.d.ts +107 -0
- package/types/utils.d.ts +142 -0
- /package/cli/commands/{dev.js → dev.old.js} +0 -0
package/src/core.js
CHANGED
|
@@ -26,6 +26,11 @@ export class ZQueryCollection {
|
|
|
26
26
|
return this.elements.map((el, i) => fn.call(el, i, el));
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
forEach(fn) {
|
|
30
|
+
this.elements.forEach((el, i) => fn(el, i, this.elements));
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
|
|
29
34
|
first() { return this.elements[0] || null; }
|
|
30
35
|
last() { return this.elements[this.length - 1] || null; }
|
|
31
36
|
eq(i) { return new ZQueryCollection(this.elements[i] ? [this.elements[i]] : []); }
|
|
@@ -70,8 +75,96 @@ export class ZQueryCollection {
|
|
|
70
75
|
return new ZQueryCollection(sibs);
|
|
71
76
|
}
|
|
72
77
|
|
|
73
|
-
next() {
|
|
74
|
-
|
|
78
|
+
next(selector) {
|
|
79
|
+
const els = this.elements.map(el => el.nextElementSibling).filter(Boolean);
|
|
80
|
+
return new ZQueryCollection(selector ? els.filter(el => el.matches(selector)) : els);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
prev(selector) {
|
|
84
|
+
const els = this.elements.map(el => el.previousElementSibling).filter(Boolean);
|
|
85
|
+
return new ZQueryCollection(selector ? els.filter(el => el.matches(selector)) : els);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
nextAll(selector) {
|
|
89
|
+
const result = [];
|
|
90
|
+
this.elements.forEach(el => {
|
|
91
|
+
let sib = el.nextElementSibling;
|
|
92
|
+
while (sib) {
|
|
93
|
+
if (!selector || sib.matches(selector)) result.push(sib);
|
|
94
|
+
sib = sib.nextElementSibling;
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return new ZQueryCollection(result);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
nextUntil(selector, filter) {
|
|
101
|
+
const result = [];
|
|
102
|
+
this.elements.forEach(el => {
|
|
103
|
+
let sib = el.nextElementSibling;
|
|
104
|
+
while (sib) {
|
|
105
|
+
if (selector && sib.matches(selector)) break;
|
|
106
|
+
if (!filter || sib.matches(filter)) result.push(sib);
|
|
107
|
+
sib = sib.nextElementSibling;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
return new ZQueryCollection(result);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
prevAll(selector) {
|
|
114
|
+
const result = [];
|
|
115
|
+
this.elements.forEach(el => {
|
|
116
|
+
let sib = el.previousElementSibling;
|
|
117
|
+
while (sib) {
|
|
118
|
+
if (!selector || sib.matches(selector)) result.push(sib);
|
|
119
|
+
sib = sib.previousElementSibling;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
return new ZQueryCollection(result);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
prevUntil(selector, filter) {
|
|
126
|
+
const result = [];
|
|
127
|
+
this.elements.forEach(el => {
|
|
128
|
+
let sib = el.previousElementSibling;
|
|
129
|
+
while (sib) {
|
|
130
|
+
if (selector && sib.matches(selector)) break;
|
|
131
|
+
if (!filter || sib.matches(filter)) result.push(sib);
|
|
132
|
+
sib = sib.previousElementSibling;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
return new ZQueryCollection(result);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
parents(selector) {
|
|
139
|
+
const result = [];
|
|
140
|
+
this.elements.forEach(el => {
|
|
141
|
+
let parent = el.parentElement;
|
|
142
|
+
while (parent) {
|
|
143
|
+
if (!selector || parent.matches(selector)) result.push(parent);
|
|
144
|
+
parent = parent.parentElement;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
return new ZQueryCollection([...new Set(result)]);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
parentsUntil(selector, filter) {
|
|
151
|
+
const result = [];
|
|
152
|
+
this.elements.forEach(el => {
|
|
153
|
+
let parent = el.parentElement;
|
|
154
|
+
while (parent) {
|
|
155
|
+
if (selector && parent.matches(selector)) break;
|
|
156
|
+
if (!filter || parent.matches(filter)) result.push(parent);
|
|
157
|
+
parent = parent.parentElement;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
return new ZQueryCollection([...new Set(result)]);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
contents() {
|
|
164
|
+
const result = [];
|
|
165
|
+
this.elements.forEach(el => result.push(...el.childNodes));
|
|
166
|
+
return new ZQueryCollection(result);
|
|
167
|
+
}
|
|
75
168
|
|
|
76
169
|
filter(selector) {
|
|
77
170
|
if (typeof selector === 'function') {
|
|
@@ -91,6 +184,42 @@ export class ZQueryCollection {
|
|
|
91
184
|
return new ZQueryCollection(this.elements.filter(el => el.querySelector(selector)));
|
|
92
185
|
}
|
|
93
186
|
|
|
187
|
+
is(selector) {
|
|
188
|
+
if (typeof selector === 'function') {
|
|
189
|
+
return this.elements.some((el, i) => selector.call(el, i, el));
|
|
190
|
+
}
|
|
191
|
+
return this.elements.some(el => el.matches(selector));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
slice(start, end) {
|
|
195
|
+
return new ZQueryCollection(this.elements.slice(start, end));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
add(selector, context) {
|
|
199
|
+
const toAdd = (selector instanceof ZQueryCollection)
|
|
200
|
+
? selector.elements
|
|
201
|
+
: (selector instanceof Node)
|
|
202
|
+
? [selector]
|
|
203
|
+
: Array.from((context || document).querySelectorAll(selector));
|
|
204
|
+
return new ZQueryCollection([...this.elements, ...toAdd]);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
get(index) {
|
|
208
|
+
if (index === undefined) return [...this.elements];
|
|
209
|
+
return index < 0 ? this.elements[this.length + index] : this.elements[index];
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
index(selector) {
|
|
213
|
+
if (selector === undefined) {
|
|
214
|
+
const el = this.first();
|
|
215
|
+
return el ? Array.from(el.parentElement.children).indexOf(el) : -1;
|
|
216
|
+
}
|
|
217
|
+
const target = (typeof selector === 'string')
|
|
218
|
+
? document.querySelector(selector)
|
|
219
|
+
: selector;
|
|
220
|
+
return this.elements.indexOf(target);
|
|
221
|
+
}
|
|
222
|
+
|
|
94
223
|
// --- Classes -------------------------------------------------------------
|
|
95
224
|
|
|
96
225
|
addClass(...names) {
|
|
@@ -103,8 +232,12 @@ export class ZQueryCollection {
|
|
|
103
232
|
return this.each((_, el) => el.classList.remove(...classes));
|
|
104
233
|
}
|
|
105
234
|
|
|
106
|
-
toggleClass(
|
|
107
|
-
|
|
235
|
+
toggleClass(...args) {
|
|
236
|
+
const force = typeof args[args.length - 1] === 'boolean' ? args.pop() : undefined;
|
|
237
|
+
const classes = args.flatMap(n => n.split(/\s+/));
|
|
238
|
+
return this.each((_, el) => {
|
|
239
|
+
classes.forEach(c => force !== undefined ? el.classList.toggle(c, force) : el.classList.toggle(c));
|
|
240
|
+
});
|
|
108
241
|
}
|
|
109
242
|
|
|
110
243
|
hasClass(name) {
|
|
@@ -158,6 +291,60 @@ export class ZQueryCollection {
|
|
|
158
291
|
return el ? { top: el.offsetTop, left: el.offsetLeft } : null;
|
|
159
292
|
}
|
|
160
293
|
|
|
294
|
+
scrollTop(value) {
|
|
295
|
+
if (value === undefined) {
|
|
296
|
+
const el = this.first();
|
|
297
|
+
return el === window ? window.scrollY : el?.scrollTop;
|
|
298
|
+
}
|
|
299
|
+
return this.each((_, el) => {
|
|
300
|
+
if (el === window) window.scrollTo(window.scrollX, value);
|
|
301
|
+
else el.scrollTop = value;
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
scrollLeft(value) {
|
|
306
|
+
if (value === undefined) {
|
|
307
|
+
const el = this.first();
|
|
308
|
+
return el === window ? window.scrollX : el?.scrollLeft;
|
|
309
|
+
}
|
|
310
|
+
return this.each((_, el) => {
|
|
311
|
+
if (el === window) window.scrollTo(value, window.scrollY);
|
|
312
|
+
else el.scrollLeft = value;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
innerWidth() {
|
|
317
|
+
const el = this.first();
|
|
318
|
+
return el?.clientWidth;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
innerHeight() {
|
|
322
|
+
const el = this.first();
|
|
323
|
+
return el?.clientHeight;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
outerWidth(includeMargin = false) {
|
|
327
|
+
const el = this.first();
|
|
328
|
+
if (!el) return undefined;
|
|
329
|
+
let w = el.offsetWidth;
|
|
330
|
+
if (includeMargin) {
|
|
331
|
+
const style = getComputedStyle(el);
|
|
332
|
+
w += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
|
|
333
|
+
}
|
|
334
|
+
return w;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
outerHeight(includeMargin = false) {
|
|
338
|
+
const el = this.first();
|
|
339
|
+
if (!el) return undefined;
|
|
340
|
+
let h = el.offsetHeight;
|
|
341
|
+
if (includeMargin) {
|
|
342
|
+
const style = getComputedStyle(el);
|
|
343
|
+
h += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
|
|
344
|
+
}
|
|
345
|
+
return h;
|
|
346
|
+
}
|
|
347
|
+
|
|
161
348
|
// --- Content -------------------------------------------------------------
|
|
162
349
|
|
|
163
350
|
html(content) {
|
|
@@ -237,6 +424,73 @@ export class ZQueryCollection {
|
|
|
237
424
|
});
|
|
238
425
|
}
|
|
239
426
|
|
|
427
|
+
appendTo(target) {
|
|
428
|
+
const dest = typeof target === 'string' ? document.querySelector(target) : target instanceof ZQueryCollection ? target.first() : target;
|
|
429
|
+
if (dest) this.each((_, el) => dest.appendChild(el));
|
|
430
|
+
return this;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
prependTo(target) {
|
|
434
|
+
const dest = typeof target === 'string' ? document.querySelector(target) : target instanceof ZQueryCollection ? target.first() : target;
|
|
435
|
+
if (dest) this.each((_, el) => dest.insertBefore(el, dest.firstChild));
|
|
436
|
+
return this;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
insertAfter(target) {
|
|
440
|
+
const ref = typeof target === 'string' ? document.querySelector(target) : target instanceof ZQueryCollection ? target.first() : target;
|
|
441
|
+
if (ref && ref.parentNode) this.each((_, el) => ref.parentNode.insertBefore(el, ref.nextSibling));
|
|
442
|
+
return this;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
insertBefore(target) {
|
|
446
|
+
const ref = typeof target === 'string' ? document.querySelector(target) : target instanceof ZQueryCollection ? target.first() : target;
|
|
447
|
+
if (ref && ref.parentNode) this.each((_, el) => ref.parentNode.insertBefore(el, ref));
|
|
448
|
+
return this;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
replaceAll(target) {
|
|
452
|
+
const targets = typeof target === 'string'
|
|
453
|
+
? Array.from(document.querySelectorAll(target))
|
|
454
|
+
: target instanceof ZQueryCollection ? target.elements : [target];
|
|
455
|
+
targets.forEach((t, i) => {
|
|
456
|
+
const nodes = i === 0 ? this.elements : this.elements.map(el => el.cloneNode(true));
|
|
457
|
+
nodes.forEach(el => t.parentNode.insertBefore(el, t));
|
|
458
|
+
t.remove();
|
|
459
|
+
});
|
|
460
|
+
return this;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
unwrap(selector) {
|
|
464
|
+
this.elements.forEach(el => {
|
|
465
|
+
const parent = el.parentElement;
|
|
466
|
+
if (!parent || parent === document.body) return;
|
|
467
|
+
if (selector && !parent.matches(selector)) return;
|
|
468
|
+
parent.replaceWith(...parent.childNodes);
|
|
469
|
+
});
|
|
470
|
+
return this;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
wrapAll(wrapper) {
|
|
474
|
+
const w = typeof wrapper === 'string' ? createFragment(wrapper).firstElementChild : wrapper.cloneNode(true);
|
|
475
|
+
const first = this.first();
|
|
476
|
+
if (!first) return this;
|
|
477
|
+
first.parentNode.insertBefore(w, first);
|
|
478
|
+
this.each((_, el) => w.appendChild(el));
|
|
479
|
+
return this;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
wrapInner(wrapper) {
|
|
483
|
+
return this.each((_, el) => {
|
|
484
|
+
const w = typeof wrapper === 'string' ? createFragment(wrapper).firstElementChild : wrapper.cloneNode(true);
|
|
485
|
+
while (el.firstChild) w.appendChild(el.firstChild);
|
|
486
|
+
el.appendChild(w);
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
detach() {
|
|
491
|
+
return this.each((_, el) => el.remove());
|
|
492
|
+
}
|
|
493
|
+
|
|
240
494
|
// --- Visibility ----------------------------------------------------------
|
|
241
495
|
|
|
242
496
|
show(display = '') {
|
|
@@ -262,9 +516,10 @@ export class ZQueryCollection {
|
|
|
262
516
|
events.forEach(evt => {
|
|
263
517
|
if (typeof selectorOrHandler === 'function') {
|
|
264
518
|
el.addEventListener(evt, selectorOrHandler);
|
|
265
|
-
} else {
|
|
266
|
-
// Delegated event
|
|
519
|
+
} else if (typeof selectorOrHandler === 'string') {
|
|
520
|
+
// Delegated event — only works on elements that support closest()
|
|
267
521
|
el.addEventListener(evt, (e) => {
|
|
522
|
+
if (!e.target || typeof e.target.closest !== 'function') return;
|
|
268
523
|
const target = e.target.closest(selectorOrHandler);
|
|
269
524
|
if (target && el.contains(target)) handler.call(target, e);
|
|
270
525
|
});
|
|
@@ -297,6 +552,10 @@ export class ZQueryCollection {
|
|
|
297
552
|
submit(fn) { return fn ? this.on('submit', fn) : this.trigger('submit'); }
|
|
298
553
|
focus() { this.first()?.focus(); return this; }
|
|
299
554
|
blur() { this.first()?.blur(); return this; }
|
|
555
|
+
hover(enterFn, leaveFn) {
|
|
556
|
+
this.on('mouseenter', enterFn);
|
|
557
|
+
return this.on('mouseleave', leaveFn || enterFn);
|
|
558
|
+
}
|
|
300
559
|
|
|
301
560
|
// --- Animation -----------------------------------------------------------
|
|
302
561
|
|
|
@@ -328,6 +587,40 @@ export class ZQueryCollection {
|
|
|
328
587
|
return this.animate({ opacity: '0' }, duration).then(col => col.hide());
|
|
329
588
|
}
|
|
330
589
|
|
|
590
|
+
fadeToggle(duration = 300) {
|
|
591
|
+
return Promise.all(this.elements.map(el => {
|
|
592
|
+
const visible = getComputedStyle(el).opacity !== '0' && getComputedStyle(el).display !== 'none';
|
|
593
|
+
const col = new ZQueryCollection([el]);
|
|
594
|
+
return visible ? col.fadeOut(duration) : col.fadeIn(duration);
|
|
595
|
+
})).then(() => this);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
fadeTo(duration, opacity) {
|
|
599
|
+
return this.animate({ opacity: String(opacity) }, duration);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
slideDown(duration = 300) {
|
|
603
|
+
return this.each((_, el) => {
|
|
604
|
+
el.style.display = '';
|
|
605
|
+
el.style.overflow = 'hidden';
|
|
606
|
+
const h = el.scrollHeight + 'px';
|
|
607
|
+
el.style.maxHeight = '0';
|
|
608
|
+
el.style.transition = `max-height ${duration}ms ease`;
|
|
609
|
+
requestAnimationFrame(() => { el.style.maxHeight = h; });
|
|
610
|
+
setTimeout(() => { el.style.maxHeight = ''; el.style.overflow = ''; el.style.transition = ''; }, duration);
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
slideUp(duration = 300) {
|
|
615
|
+
return this.each((_, el) => {
|
|
616
|
+
el.style.overflow = 'hidden';
|
|
617
|
+
el.style.maxHeight = el.scrollHeight + 'px';
|
|
618
|
+
el.style.transition = `max-height ${duration}ms ease`;
|
|
619
|
+
requestAnimationFrame(() => { el.style.maxHeight = '0'; });
|
|
620
|
+
setTimeout(() => { el.style.display = 'none'; el.style.maxHeight = ''; el.style.overflow = ''; el.style.transition = ''; }, duration);
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
|
|
331
624
|
slideToggle(duration = 300) {
|
|
332
625
|
return this.each((_, el) => {
|
|
333
626
|
if (el.style.display === 'none' || getComputedStyle(el).display === 'none') {
|
|
@@ -384,42 +677,40 @@ function createFragment(html) {
|
|
|
384
677
|
|
|
385
678
|
|
|
386
679
|
// ---------------------------------------------------------------------------
|
|
387
|
-
// $() — main selector / creator
|
|
680
|
+
// $() — main selector / creator (returns ZQueryCollection, like jQuery)
|
|
388
681
|
// ---------------------------------------------------------------------------
|
|
389
682
|
export function query(selector, context) {
|
|
390
683
|
// null / undefined
|
|
391
|
-
if (!selector) return
|
|
684
|
+
if (!selector) return new ZQueryCollection([]);
|
|
392
685
|
|
|
393
|
-
// Already a collection — return
|
|
394
|
-
if (selector instanceof ZQueryCollection) return selector
|
|
686
|
+
// Already a collection — return as-is
|
|
687
|
+
if (selector instanceof ZQueryCollection) return selector;
|
|
395
688
|
|
|
396
|
-
// DOM element or Window —
|
|
689
|
+
// DOM element or Window — wrap in collection
|
|
397
690
|
if (selector instanceof Node || selector === window) {
|
|
398
|
-
return selector;
|
|
691
|
+
return new ZQueryCollection([selector]);
|
|
399
692
|
}
|
|
400
693
|
|
|
401
|
-
// NodeList / HTMLCollection / Array —
|
|
694
|
+
// NodeList / HTMLCollection / Array — wrap in collection
|
|
402
695
|
if (selector instanceof NodeList || selector instanceof HTMLCollection || Array.isArray(selector)) {
|
|
403
|
-
|
|
404
|
-
return arr[0] || null;
|
|
696
|
+
return new ZQueryCollection(Array.from(selector));
|
|
405
697
|
}
|
|
406
698
|
|
|
407
|
-
// HTML string → create elements,
|
|
699
|
+
// HTML string → create elements, wrap in collection
|
|
408
700
|
if (typeof selector === 'string' && selector.trim().startsWith('<')) {
|
|
409
701
|
const fragment = createFragment(selector);
|
|
410
|
-
|
|
411
|
-
return els[0] || null;
|
|
702
|
+
return new ZQueryCollection([...fragment.childNodes].filter(n => n.nodeType === 1));
|
|
412
703
|
}
|
|
413
704
|
|
|
414
|
-
// CSS selector string →
|
|
705
|
+
// CSS selector string → querySelectorAll (collection)
|
|
415
706
|
if (typeof selector === 'string') {
|
|
416
707
|
const root = context
|
|
417
708
|
? (typeof context === 'string' ? document.querySelector(context) : context)
|
|
418
709
|
: document;
|
|
419
|
-
return root.
|
|
710
|
+
return new ZQueryCollection([...root.querySelectorAll(selector)]);
|
|
420
711
|
}
|
|
421
712
|
|
|
422
|
-
return
|
|
713
|
+
return new ZQueryCollection([]);
|
|
423
714
|
}
|
|
424
715
|
|
|
425
716
|
|
|
@@ -466,24 +757,18 @@ export function queryAll(selector, context) {
|
|
|
466
757
|
// ---------------------------------------------------------------------------
|
|
467
758
|
query.id = (id) => document.getElementById(id);
|
|
468
759
|
query.class = (name) => document.querySelector(`.${name}`);
|
|
469
|
-
query.classes = (name) => Array.from(document.getElementsByClassName(name));
|
|
470
|
-
query.tag = (name) => Array.from(document.getElementsByTagName(name));
|
|
760
|
+
query.classes = (name) => new ZQueryCollection(Array.from(document.getElementsByClassName(name)));
|
|
761
|
+
query.tag = (name) => new ZQueryCollection(Array.from(document.getElementsByTagName(name)));
|
|
471
762
|
Object.defineProperty(query, 'name', {
|
|
472
|
-
value: (name) => Array.from(document.getElementsByName(name)),
|
|
763
|
+
value: (name) => new ZQueryCollection(Array.from(document.getElementsByName(name))),
|
|
473
764
|
writable: true, configurable: true
|
|
474
765
|
});
|
|
475
|
-
query.attr = (attr, value) => Array.from(
|
|
476
|
-
document.querySelectorAll(value !== undefined ? `[${attr}="${value}"]` : `[${attr}]`)
|
|
477
|
-
);
|
|
478
|
-
query.data = (key, value) => Array.from(
|
|
479
|
-
document.querySelectorAll(value !== undefined ? `[data-${key}="${value}"]` : `[data-${key}]`)
|
|
480
|
-
);
|
|
481
766
|
query.children = (parentId) => {
|
|
482
767
|
const p = document.getElementById(parentId);
|
|
483
|
-
return p ? Array.from(p.children) : [];
|
|
768
|
+
return new ZQueryCollection(p ? Array.from(p.children) : []);
|
|
484
769
|
};
|
|
485
770
|
|
|
486
|
-
// Create element shorthand
|
|
771
|
+
// Create element shorthand — returns ZQueryCollection for chaining
|
|
487
772
|
query.create = (tag, attrs = {}, ...children) => {
|
|
488
773
|
const el = document.createElement(tag);
|
|
489
774
|
for (const [k, v] of Object.entries(attrs)) {
|
|
@@ -497,7 +782,7 @@ query.create = (tag, attrs = {}, ...children) => {
|
|
|
497
782
|
if (typeof child === 'string') el.appendChild(document.createTextNode(child));
|
|
498
783
|
else if (child instanceof Node) el.appendChild(child);
|
|
499
784
|
});
|
|
500
|
-
return el;
|
|
785
|
+
return new ZQueryCollection(el);
|
|
501
786
|
};
|
|
502
787
|
|
|
503
788
|
// DOM ready
|
|
@@ -506,17 +791,24 @@ query.ready = (fn) => {
|
|
|
506
791
|
else document.addEventListener('DOMContentLoaded', fn);
|
|
507
792
|
};
|
|
508
793
|
|
|
509
|
-
// Global event listeners — supports direct and
|
|
794
|
+
// Global event listeners — supports direct, delegated, and target-bound forms
|
|
510
795
|
// $.on('keydown', handler) → direct listener on document
|
|
511
796
|
// $.on('click', '.btn', handler) → delegated via closest()
|
|
797
|
+
// $.on('scroll', window, handler) → direct listener on target
|
|
512
798
|
query.on = (event, selectorOrHandler, handler) => {
|
|
513
799
|
if (typeof selectorOrHandler === 'function') {
|
|
514
800
|
// 2-arg: direct document listener (keydown, resize, etc.)
|
|
515
801
|
document.addEventListener(event, selectorOrHandler);
|
|
516
802
|
return;
|
|
517
803
|
}
|
|
518
|
-
//
|
|
804
|
+
// EventTarget (window, element, etc.) — direct listener on target
|
|
805
|
+
if (typeof selectorOrHandler === 'object' && typeof selectorOrHandler.addEventListener === 'function') {
|
|
806
|
+
selectorOrHandler.addEventListener(event, handler);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
// 3-arg string: delegated
|
|
519
810
|
document.addEventListener(event, (e) => {
|
|
811
|
+
if (!e.target || typeof e.target.closest !== 'function') return;
|
|
520
812
|
const target = e.target.closest(selectorOrHandler);
|
|
521
813
|
if (target) handler.call(target, e);
|
|
522
814
|
});
|