zero-query 0.9.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -31
- package/cli/args.js +1 -1
- package/cli/commands/build.js +2 -2
- package/cli/commands/bundle.js +15 -15
- package/cli/commands/create.js +41 -7
- package/cli/commands/dev/devtools/index.js +1 -1
- package/cli/commands/dev/devtools/js/core.js +14 -14
- package/cli/commands/dev/devtools/js/elements.js +4 -4
- package/cli/commands/dev/devtools/js/stats.js +1 -1
- package/cli/commands/dev/devtools/styles.css +2 -2
- package/cli/commands/dev/index.js +2 -2
- package/cli/commands/dev/logger.js +1 -1
- package/cli/commands/dev/overlay.js +21 -14
- package/cli/commands/dev/server.js +5 -5
- package/cli/commands/dev/validator.js +7 -7
- package/cli/commands/dev/watcher.js +6 -6
- package/cli/help.js +4 -2
- package/cli/index.js +2 -2
- package/cli/scaffold/default/app/app.js +17 -18
- package/cli/scaffold/default/app/components/about.js +9 -9
- package/cli/scaffold/default/app/components/api-demo.js +6 -6
- package/cli/scaffold/default/app/components/contact-card.js +4 -4
- package/cli/scaffold/default/app/components/contacts/contacts.css +2 -2
- package/cli/scaffold/default/app/components/contacts/contacts.html +3 -3
- package/cli/scaffold/default/app/components/contacts/contacts.js +11 -11
- package/cli/scaffold/default/app/components/counter.js +8 -8
- package/cli/scaffold/default/app/components/home.js +13 -13
- package/cli/scaffold/default/app/components/not-found.js +1 -1
- package/cli/scaffold/default/app/components/playground/playground.css +1 -1
- package/cli/scaffold/default/app/components/playground/playground.html +11 -11
- package/cli/scaffold/default/app/components/playground/playground.js +11 -11
- package/cli/scaffold/default/app/components/todos.js +8 -8
- package/cli/scaffold/default/app/components/toolkit/toolkit.css +1 -1
- package/cli/scaffold/default/app/components/toolkit/toolkit.html +4 -4
- package/cli/scaffold/default/app/components/toolkit/toolkit.js +7 -7
- package/cli/scaffold/default/app/routes.js +1 -1
- package/cli/scaffold/default/app/store.js +1 -1
- package/cli/scaffold/default/global.css +2 -2
- package/cli/scaffold/default/index.html +2 -2
- package/cli/scaffold/minimal/app/app.js +6 -7
- package/cli/scaffold/minimal/app/components/about.js +5 -5
- package/cli/scaffold/minimal/app/components/counter.js +6 -6
- package/cli/scaffold/minimal/app/components/home.js +8 -8
- package/cli/scaffold/minimal/app/components/not-found.js +1 -1
- package/cli/scaffold/minimal/app/routes.js +1 -1
- package/cli/scaffold/minimal/app/store.js +1 -1
- package/cli/scaffold/minimal/global.css +2 -2
- package/cli/scaffold/minimal/index.html +1 -1
- package/cli/scaffold/ssr/app/app.js +29 -0
- package/cli/scaffold/ssr/app/components/about.js +28 -0
- package/cli/scaffold/ssr/app/components/home.js +37 -0
- package/cli/scaffold/ssr/app/components/not-found.js +15 -0
- package/cli/scaffold/ssr/app/routes.js +6 -0
- package/cli/scaffold/ssr/global.css +113 -0
- package/cli/scaffold/ssr/index.html +31 -0
- package/cli/scaffold/ssr/package.json +8 -0
- package/cli/scaffold/ssr/server/index.js +118 -0
- package/cli/utils.js +6 -6
- package/dist/zquery.dist.zip +0 -0
- package/dist/zquery.js +565 -228
- package/dist/zquery.min.js +2 -2
- package/index.d.ts +25 -12
- package/index.js +11 -7
- package/package.json +9 -3
- package/src/component.js +64 -63
- package/src/core.js +15 -15
- package/src/diff.js +38 -38
- package/src/errors.js +72 -18
- package/src/expression.js +15 -17
- package/src/http.js +4 -4
- package/src/package.json +1 -0
- package/src/reactive.js +75 -9
- package/src/router.js +104 -24
- package/src/ssr.js +133 -39
- package/src/store.js +103 -21
- package/src/utils.js +64 -12
- package/tests/audit.test.js +143 -15
- package/tests/cli.test.js +20 -20
- package/tests/component.test.js +121 -121
- package/tests/core.test.js +56 -56
- package/tests/diff.test.js +42 -42
- package/tests/errors.test.js +425 -147
- package/tests/expression.test.js +58 -53
- package/tests/http.test.js +20 -20
- package/tests/reactive.test.js +185 -24
- package/tests/router.test.js +501 -74
- package/tests/ssr.test.js +444 -10
- package/tests/store.test.js +264 -23
- package/tests/utils.test.js +163 -26
- package/types/collection.d.ts +2 -2
- package/types/component.d.ts +5 -5
- package/types/errors.d.ts +36 -4
- package/types/http.d.ts +3 -3
- package/types/misc.d.ts +9 -9
- package/types/reactive.d.ts +25 -3
- package/types/router.d.ts +10 -6
- package/types/ssr.d.ts +22 -2
- package/types/store.d.ts +40 -5
- package/types/utils.d.ts +1 -1
package/tests/core.test.js
CHANGED
|
@@ -25,7 +25,7 @@ beforeEach(() => {
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
28
|
-
// query()
|
|
28
|
+
// query() - single selector
|
|
29
29
|
// ---------------------------------------------------------------------------
|
|
30
30
|
|
|
31
31
|
describe('query()', () => {
|
|
@@ -79,7 +79,7 @@ describe('query()', () => {
|
|
|
79
79
|
|
|
80
80
|
|
|
81
81
|
// ---------------------------------------------------------------------------
|
|
82
|
-
// queryAll()
|
|
82
|
+
// queryAll() - collection selector
|
|
83
83
|
// ---------------------------------------------------------------------------
|
|
84
84
|
|
|
85
85
|
describe('queryAll()', () => {
|
|
@@ -362,7 +362,7 @@ describe('ZQueryCollection', () => {
|
|
|
362
362
|
const ref = main.children[0]; // grab DOM reference
|
|
363
363
|
const col = queryAll('#main');
|
|
364
364
|
col.html('<p id="preserved">new text</p>');
|
|
365
|
-
// Same DOM node preserved
|
|
365
|
+
// Same DOM node preserved - morph, not innerHTML replace
|
|
366
366
|
expect(main.children[0]).toBe(ref);
|
|
367
367
|
expect(main.children[0].textContent).toBe('new text');
|
|
368
368
|
});
|
|
@@ -381,7 +381,7 @@ describe('ZQueryCollection', () => {
|
|
|
381
381
|
const ref = main.children[0];
|
|
382
382
|
const col = queryAll('#main');
|
|
383
383
|
col.empty().html('<p id="old">replaced</p>');
|
|
384
|
-
// NOT the same node
|
|
384
|
+
// NOT the same node - empty() cleared children, so html() used innerHTML
|
|
385
385
|
expect(main.children[0]).not.toBe(ref);
|
|
386
386
|
expect(main.children[0].textContent).toBe('replaced');
|
|
387
387
|
});
|
|
@@ -547,7 +547,7 @@ describe('query quick refs', () => {
|
|
|
547
547
|
expect(el.textContent).toBe('text');
|
|
548
548
|
});
|
|
549
549
|
|
|
550
|
-
// qs / qsa
|
|
550
|
+
// qs / qsa - raw DOM shortcuts
|
|
551
551
|
it('$.qs() returns raw element by CSS selector', () => {
|
|
552
552
|
const el = query.qs('#main');
|
|
553
553
|
expect(el).toBe(document.getElementById('main'));
|
|
@@ -792,7 +792,7 @@ describe('CSS dimension methods', () => {
|
|
|
792
792
|
// prop() method
|
|
793
793
|
// ---------------------------------------------------------------------------
|
|
794
794
|
|
|
795
|
-
describe('ZQueryCollection
|
|
795
|
+
describe('ZQueryCollection - prop()', () => {
|
|
796
796
|
it('gets a DOM property', () => {
|
|
797
797
|
document.body.innerHTML = '<input type="checkbox" checked>';
|
|
798
798
|
const col = queryAll('input');
|
|
@@ -821,7 +821,7 @@ describe('ZQueryCollection — prop()', () => {
|
|
|
821
821
|
// css() method
|
|
822
822
|
// ---------------------------------------------------------------------------
|
|
823
823
|
|
|
824
|
-
describe('ZQueryCollection
|
|
824
|
+
describe('ZQueryCollection - css()', () => {
|
|
825
825
|
beforeEach(() => {
|
|
826
826
|
document.body.innerHTML = '<div id="styled">test</div>';
|
|
827
827
|
});
|
|
@@ -843,7 +843,7 @@ describe('ZQueryCollection — css()', () => {
|
|
|
843
843
|
// val() method
|
|
844
844
|
// ---------------------------------------------------------------------------
|
|
845
845
|
|
|
846
|
-
describe('ZQueryCollection
|
|
846
|
+
describe('ZQueryCollection - val()', () => {
|
|
847
847
|
it('gets input value', () => {
|
|
848
848
|
document.body.innerHTML = '<input value="test">';
|
|
849
849
|
expect(queryAll('input').val()).toBe('test');
|
|
@@ -871,7 +871,7 @@ describe('ZQueryCollection — val()', () => {
|
|
|
871
871
|
// after(), before() methods
|
|
872
872
|
// ---------------------------------------------------------------------------
|
|
873
873
|
|
|
874
|
-
describe('ZQueryCollection
|
|
874
|
+
describe('ZQueryCollection - after() / before()', () => {
|
|
875
875
|
beforeEach(() => {
|
|
876
876
|
document.body.innerHTML = '<div id="container"><p id="target">target</p></div>';
|
|
877
877
|
});
|
|
@@ -894,7 +894,7 @@ describe('ZQueryCollection — after() / before()', () => {
|
|
|
894
894
|
// wrap() method
|
|
895
895
|
// ---------------------------------------------------------------------------
|
|
896
896
|
|
|
897
|
-
describe('ZQueryCollection
|
|
897
|
+
describe('ZQueryCollection - wrap()', () => {
|
|
898
898
|
it('wraps element in new parent', () => {
|
|
899
899
|
document.body.innerHTML = '<div id="container"><p id="target">text</p></div>';
|
|
900
900
|
queryAll('#target').wrap('<div class="wrapper"></div>');
|
|
@@ -909,7 +909,7 @@ describe('ZQueryCollection — wrap()', () => {
|
|
|
909
909
|
// replaceWith() method
|
|
910
910
|
// ---------------------------------------------------------------------------
|
|
911
911
|
|
|
912
|
-
describe('ZQueryCollection
|
|
912
|
+
describe('ZQueryCollection - replaceWith()', () => {
|
|
913
913
|
it('replaces element with new content', () => {
|
|
914
914
|
document.body.innerHTML = '<div id="container"><p id="old">old</p></div>';
|
|
915
915
|
queryAll('#old').replaceWith('<span id="new">new</span>');
|
|
@@ -921,7 +921,7 @@ describe('ZQueryCollection — replaceWith()', () => {
|
|
|
921
921
|
document.body.innerHTML = '<div id="container"><p id="target" class="old">old text</p></div>';
|
|
922
922
|
const target = document.querySelector('#target');
|
|
923
923
|
queryAll('#target').replaceWith('<p id="target" class="new">new text</p>');
|
|
924
|
-
// Same DOM node
|
|
924
|
+
// Same DOM node - morphed, not replaced
|
|
925
925
|
expect(document.querySelector('#target')).toBe(target);
|
|
926
926
|
expect(target.className).toBe('new');
|
|
927
927
|
expect(target.textContent).toBe('new text');
|
|
@@ -941,7 +941,7 @@ describe('ZQueryCollection — replaceWith()', () => {
|
|
|
941
941
|
// offset() and position()
|
|
942
942
|
// ---------------------------------------------------------------------------
|
|
943
943
|
|
|
944
|
-
describe('ZQueryCollection
|
|
944
|
+
describe('ZQueryCollection - offset() / position()', () => {
|
|
945
945
|
it('offset() returns object with top and left', () => {
|
|
946
946
|
document.body.innerHTML = '<div id="box">box</div>';
|
|
947
947
|
const off = queryAll('#box').offset();
|
|
@@ -963,7 +963,7 @@ describe('ZQueryCollection — offset() / position()', () => {
|
|
|
963
963
|
// width() and height()
|
|
964
964
|
// ---------------------------------------------------------------------------
|
|
965
965
|
|
|
966
|
-
describe('ZQueryCollection
|
|
966
|
+
describe('ZQueryCollection - width() / height()', () => {
|
|
967
967
|
it('width() returns a number', () => {
|
|
968
968
|
document.body.innerHTML = '<div id="box" style="width:100px">box</div>';
|
|
969
969
|
const val = queryAll('#box').width();
|
|
@@ -982,7 +982,7 @@ describe('ZQueryCollection — width() / height()', () => {
|
|
|
982
982
|
// animate()
|
|
983
983
|
// ---------------------------------------------------------------------------
|
|
984
984
|
|
|
985
|
-
describe('ZQueryCollection
|
|
985
|
+
describe('ZQueryCollection - animate()', () => {
|
|
986
986
|
it('returns a promise', () => {
|
|
987
987
|
document.body.innerHTML = '<div id="box">box</div>';
|
|
988
988
|
const result = queryAll('#box').animate({ opacity: 0 }, 100);
|
|
@@ -1019,10 +1019,10 @@ describe('hover()', () => {
|
|
|
1019
1019
|
|
|
1020
1020
|
|
|
1021
1021
|
// ---------------------------------------------------------------------------
|
|
1022
|
-
// ZQueryCollection
|
|
1022
|
+
// ZQueryCollection - empty collection safety
|
|
1023
1023
|
// ---------------------------------------------------------------------------
|
|
1024
1024
|
|
|
1025
|
-
describe('ZQueryCollection
|
|
1025
|
+
describe('ZQueryCollection - empty collection operations', () => {
|
|
1026
1026
|
it('first() returns null on empty', () => {
|
|
1027
1027
|
expect(queryAll('.nonexistent').first()).toBeNull();
|
|
1028
1028
|
});
|
|
@@ -1076,7 +1076,7 @@ describe('ZQueryCollection — empty collection operations', () => {
|
|
|
1076
1076
|
// Collection wrapping edge cases
|
|
1077
1077
|
// ---------------------------------------------------------------------------
|
|
1078
1078
|
|
|
1079
|
-
describe('query
|
|
1079
|
+
describe('query - wrapping edge cases', () => {
|
|
1080
1080
|
it('wraps an HTMLCollection', () => {
|
|
1081
1081
|
const col = queryAll(document.getElementsByClassName('text'));
|
|
1082
1082
|
expect(col).toBeInstanceOf(ZQueryCollection);
|
|
@@ -1115,7 +1115,7 @@ describe('query — wrapping edge cases', () => {
|
|
|
1115
1115
|
// html() morphing advanced
|
|
1116
1116
|
// ---------------------------------------------------------------------------
|
|
1117
1117
|
|
|
1118
|
-
describe('ZQueryCollection
|
|
1118
|
+
describe('ZQueryCollection - html() morphing advanced', () => {
|
|
1119
1119
|
it('morphs complex nested structure', () => {
|
|
1120
1120
|
document.body.innerHTML = '<div id="m"><ul><li id="i1">old1</li><li id="i2">old2</li></ul></div>';
|
|
1121
1121
|
const li1 = document.getElementById('i1');
|
|
@@ -1139,7 +1139,7 @@ describe('ZQueryCollection — html() morphing advanced', () => {
|
|
|
1139
1139
|
// Event delegation
|
|
1140
1140
|
// ---------------------------------------------------------------------------
|
|
1141
1141
|
|
|
1142
|
-
describe('ZQueryCollection
|
|
1142
|
+
describe('ZQueryCollection - event delegation', () => {
|
|
1143
1143
|
it('on() with selector delegates to matching children', () => {
|
|
1144
1144
|
let clicked = null;
|
|
1145
1145
|
queryAll('#nav').on('click', '.nav-item', function() { clicked = this.textContent; });
|
|
@@ -1160,7 +1160,7 @@ describe('ZQueryCollection — event delegation', () => {
|
|
|
1160
1160
|
// Multiple class operations
|
|
1161
1161
|
// ---------------------------------------------------------------------------
|
|
1162
1162
|
|
|
1163
|
-
describe('ZQueryCollection
|
|
1163
|
+
describe('ZQueryCollection - multiple class operations', () => {
|
|
1164
1164
|
it('addClass with space-separated classes', () => {
|
|
1165
1165
|
const col = queryAll('#main');
|
|
1166
1166
|
col.addClass('a', 'b', 'c');
|
|
@@ -1184,7 +1184,7 @@ describe('ZQueryCollection — multiple class operations', () => {
|
|
|
1184
1184
|
// Traversal edge cases
|
|
1185
1185
|
// ---------------------------------------------------------------------------
|
|
1186
1186
|
|
|
1187
|
-
describe('ZQueryCollection
|
|
1187
|
+
describe('ZQueryCollection - traversal edge cases', () => {
|
|
1188
1188
|
it('find() returns empty when no descendants match', () => {
|
|
1189
1189
|
expect(queryAll('#main').find('.nonexistent').length).toBe(0);
|
|
1190
1190
|
});
|
|
@@ -1230,7 +1230,7 @@ describe('ZQueryCollection — traversal edge cases', () => {
|
|
|
1230
1230
|
// DOM manipulation edge cases
|
|
1231
1231
|
// ---------------------------------------------------------------------------
|
|
1232
1232
|
|
|
1233
|
-
describe('ZQueryCollection
|
|
1233
|
+
describe('ZQueryCollection - DOM manipulation edge cases', () => {
|
|
1234
1234
|
it('append with element node', () => {
|
|
1235
1235
|
const newEl = document.createElement('div');
|
|
1236
1236
|
newEl.id = 'appended-el';
|
|
@@ -1272,7 +1272,7 @@ describe('ZQueryCollection — DOM manipulation edge cases', () => {
|
|
|
1272
1272
|
// Attribute edge cases
|
|
1273
1273
|
// ---------------------------------------------------------------------------
|
|
1274
1274
|
|
|
1275
|
-
describe('ZQueryCollection
|
|
1275
|
+
describe('ZQueryCollection - attribute edge cases', () => {
|
|
1276
1276
|
it('attr() set with sequential calls sets multiple attributes', () => {
|
|
1277
1277
|
document.body.innerHTML = '<div id="a"></div>';
|
|
1278
1278
|
queryAll('#a').attr('data-x', '1').attr('data-y', '2').attr('title', 'test');
|
|
@@ -1296,7 +1296,7 @@ describe('ZQueryCollection — attribute edge cases', () => {
|
|
|
1296
1296
|
// css() advanced
|
|
1297
1297
|
// ---------------------------------------------------------------------------
|
|
1298
1298
|
|
|
1299
|
-
describe('ZQueryCollection
|
|
1299
|
+
describe('ZQueryCollection - css() advanced', () => {
|
|
1300
1300
|
it('sets a single style property via object', () => {
|
|
1301
1301
|
document.body.innerHTML = '<div id="s">test</div>';
|
|
1302
1302
|
queryAll('#s').css({ color: 'green' });
|
|
@@ -1317,7 +1317,7 @@ describe('ZQueryCollection — css() advanced', () => {
|
|
|
1317
1317
|
// $.create advanced
|
|
1318
1318
|
// ---------------------------------------------------------------------------
|
|
1319
1319
|
|
|
1320
|
-
describe('query.create
|
|
1320
|
+
describe('query.create - advanced', () => {
|
|
1321
1321
|
it('creates element with no attributes', () => {
|
|
1322
1322
|
const col = query.create('span');
|
|
1323
1323
|
expect(col.length).toBe(1);
|
|
@@ -1345,7 +1345,7 @@ describe('query.create — advanced', () => {
|
|
|
1345
1345
|
// Prop edge cases
|
|
1346
1346
|
// ---------------------------------------------------------------------------
|
|
1347
1347
|
|
|
1348
|
-
describe('ZQueryCollection
|
|
1348
|
+
describe('ZQueryCollection - prop() edge cases', () => {
|
|
1349
1349
|
it('gets defaultValue property', () => {
|
|
1350
1350
|
document.body.innerHTML = '<input value="initial">';
|
|
1351
1351
|
const col = queryAll('input');
|
|
@@ -1367,7 +1367,7 @@ describe('ZQueryCollection — prop() edge cases', () => {
|
|
|
1367
1367
|
// BUG FIX: siblings() with selector filtering + null parent guard
|
|
1368
1368
|
// ---------------------------------------------------------------------------
|
|
1369
1369
|
|
|
1370
|
-
describe('ZQueryCollection
|
|
1370
|
+
describe('ZQueryCollection - siblings() fixes', () => {
|
|
1371
1371
|
it('filters siblings by selector', () => {
|
|
1372
1372
|
document.body.innerHTML = '<div><p class="a">1</p><p class="b">2</p><p class="a">3</p></div>';
|
|
1373
1373
|
const sibs = queryAll('.b').siblings('.a');
|
|
@@ -1393,7 +1393,7 @@ describe('ZQueryCollection — siblings() fixes', () => {
|
|
|
1393
1393
|
// BUG FIX: ZQueryCollection constructor null safety
|
|
1394
1394
|
// ---------------------------------------------------------------------------
|
|
1395
1395
|
|
|
1396
|
-
describe('ZQueryCollection
|
|
1396
|
+
describe('ZQueryCollection - constructor null/undefined safety', () => {
|
|
1397
1397
|
it('creates empty collection from null', () => {
|
|
1398
1398
|
const col = new ZQueryCollection(null);
|
|
1399
1399
|
expect(col.length).toBe(0);
|
|
@@ -1417,7 +1417,7 @@ describe('ZQueryCollection — constructor null/undefined safety', () => {
|
|
|
1417
1417
|
// BUG FIX: attr() with object syntax
|
|
1418
1418
|
// ---------------------------------------------------------------------------
|
|
1419
1419
|
|
|
1420
|
-
describe('ZQueryCollection
|
|
1420
|
+
describe('ZQueryCollection - attr() object set', () => {
|
|
1421
1421
|
it('sets multiple attributes with object', () => {
|
|
1422
1422
|
document.body.innerHTML = '<div id="at"></div>';
|
|
1423
1423
|
queryAll('#at').attr({ 'data-x': '1', 'data-y': '2', title: 'hello' });
|
|
@@ -1433,7 +1433,7 @@ describe('ZQueryCollection — attr() object set', () => {
|
|
|
1433
1433
|
// BUG FIX: css() two-argument setter
|
|
1434
1434
|
// ---------------------------------------------------------------------------
|
|
1435
1435
|
|
|
1436
|
-
describe('ZQueryCollection
|
|
1436
|
+
describe('ZQueryCollection - css() two-argument setter', () => {
|
|
1437
1437
|
it('sets a CSS property with key-value arguments', () => {
|
|
1438
1438
|
document.body.innerHTML = '<div id="cs">text</div>';
|
|
1439
1439
|
queryAll('#cs').css('color', 'green');
|
|
@@ -1460,7 +1460,7 @@ describe('ZQueryCollection — css() two-argument setter', () => {
|
|
|
1460
1460
|
// BUG FIX: wrap() does not crash on empty/invalid wrapper
|
|
1461
1461
|
// ---------------------------------------------------------------------------
|
|
1462
1462
|
|
|
1463
|
-
describe('ZQueryCollection
|
|
1463
|
+
describe('ZQueryCollection - wrap() safety', () => {
|
|
1464
1464
|
it('does not crash if wrapper string is empty', () => {
|
|
1465
1465
|
document.body.innerHTML = '<div id="w"><p>inside</p></div>';
|
|
1466
1466
|
expect(() => queryAll('#w p').wrap('')).not.toThrow();
|
|
@@ -1478,7 +1478,7 @@ describe('ZQueryCollection — wrap() safety', () => {
|
|
|
1478
1478
|
// BUG FIX: index() does not crash on detached element
|
|
1479
1479
|
// ---------------------------------------------------------------------------
|
|
1480
1480
|
|
|
1481
|
-
describe('ZQueryCollection
|
|
1481
|
+
describe('ZQueryCollection - index() null parent safety', () => {
|
|
1482
1482
|
it('returns -1 for detached element', () => {
|
|
1483
1483
|
const detached = document.createElement('div');
|
|
1484
1484
|
const col = new ZQueryCollection([detached]);
|
|
@@ -1491,7 +1491,7 @@ describe('ZQueryCollection — index() null parent safety', () => {
|
|
|
1491
1491
|
// BUG FIX: delegated on() / off() handler removal
|
|
1492
1492
|
// ---------------------------------------------------------------------------
|
|
1493
1493
|
|
|
1494
|
-
describe('ZQueryCollection
|
|
1494
|
+
describe('ZQueryCollection - delegated on/off', () => {
|
|
1495
1495
|
it('off() removes delegated event handlers', () => {
|
|
1496
1496
|
document.body.innerHTML = '<div id="parent"><button class="btn">click</button></div>';
|
|
1497
1497
|
const parent = new ZQueryCollection([document.getElementById('parent')]);
|
|
@@ -1513,7 +1513,7 @@ describe('ZQueryCollection — delegated on/off', () => {
|
|
|
1513
1513
|
// BUG FIX: animate() resolves immediately on empty collection
|
|
1514
1514
|
// ---------------------------------------------------------------------------
|
|
1515
1515
|
|
|
1516
|
-
describe('ZQueryCollection
|
|
1516
|
+
describe('ZQueryCollection - animate() empty collection', () => {
|
|
1517
1517
|
it('resolves immediately when collection is empty', async () => {
|
|
1518
1518
|
const col = new ZQueryCollection([]);
|
|
1519
1519
|
const result = await col.animate({ opacity: '0' }, 50);
|
|
@@ -1523,10 +1523,10 @@ describe('ZQueryCollection — animate() empty collection', () => {
|
|
|
1523
1523
|
|
|
1524
1524
|
|
|
1525
1525
|
// ===========================================================================
|
|
1526
|
-
// one()
|
|
1526
|
+
// one() - single-fire event listener
|
|
1527
1527
|
// ===========================================================================
|
|
1528
1528
|
|
|
1529
|
-
describe('ZQueryCollection
|
|
1529
|
+
describe('ZQueryCollection - one()', () => {
|
|
1530
1530
|
it('fires handler only once', () => {
|
|
1531
1531
|
const handler = vi.fn();
|
|
1532
1532
|
document.body.innerHTML = '<button id="one-btn">click</button>';
|
|
@@ -1540,10 +1540,10 @@ describe('ZQueryCollection — one()', () => {
|
|
|
1540
1540
|
|
|
1541
1541
|
|
|
1542
1542
|
// ===========================================================================
|
|
1543
|
-
// toggle()
|
|
1543
|
+
// toggle() - show/hide toggle
|
|
1544
1544
|
// ===========================================================================
|
|
1545
1545
|
|
|
1546
|
-
describe('ZQueryCollection
|
|
1546
|
+
describe('ZQueryCollection - toggle()', () => {
|
|
1547
1547
|
it('hides a visible element', () => {
|
|
1548
1548
|
const el = document.querySelector('#main');
|
|
1549
1549
|
el.style.display = '';
|
|
@@ -1574,7 +1574,7 @@ describe('ZQueryCollection — toggle()', () => {
|
|
|
1574
1574
|
// serialize() and serializeObject()
|
|
1575
1575
|
// ===========================================================================
|
|
1576
1576
|
|
|
1577
|
-
describe('ZQueryCollection
|
|
1577
|
+
describe('ZQueryCollection - serialize()', () => {
|
|
1578
1578
|
it('serializes form inputs to URL-encoded string', () => {
|
|
1579
1579
|
document.body.innerHTML = '<form id="f"><input name="user" value="Alice"><input name="age" value="30"></form>';
|
|
1580
1580
|
const result = query('#f').serialize();
|
|
@@ -1587,7 +1587,7 @@ describe('ZQueryCollection — serialize()', () => {
|
|
|
1587
1587
|
});
|
|
1588
1588
|
});
|
|
1589
1589
|
|
|
1590
|
-
describe('ZQueryCollection
|
|
1590
|
+
describe('ZQueryCollection - serializeObject()', () => {
|
|
1591
1591
|
it('builds an object from form fields', () => {
|
|
1592
1592
|
document.body.innerHTML = '<form id="f"><input name="user" value="Alice"><input name="age" value="30"></form>';
|
|
1593
1593
|
expect(query('#f').serializeObject()).toEqual({ user: 'Alice', age: '30' });
|
|
@@ -1681,10 +1681,10 @@ describe('$.create', () => {
|
|
|
1681
1681
|
|
|
1682
1682
|
|
|
1683
1683
|
// ===========================================================================
|
|
1684
|
-
// data()
|
|
1684
|
+
// data() - no key returns full dataset
|
|
1685
1685
|
// ===========================================================================
|
|
1686
1686
|
|
|
1687
|
-
describe('ZQueryCollection
|
|
1687
|
+
describe('ZQueryCollection - data() full dataset', () => {
|
|
1688
1688
|
it('returns the full dataset when no key is given', () => {
|
|
1689
1689
|
document.body.innerHTML = '<div id="d" data-x="1" data-y="2"></div>';
|
|
1690
1690
|
const ds = query('#d').data();
|
|
@@ -1698,7 +1698,7 @@ describe('ZQueryCollection — data() full dataset', () => {
|
|
|
1698
1698
|
// css() getter on empty collection
|
|
1699
1699
|
// ===========================================================================
|
|
1700
1700
|
|
|
1701
|
-
describe('ZQueryCollection
|
|
1701
|
+
describe('ZQueryCollection - css() empty collection', () => {
|
|
1702
1702
|
it('returns undefined when collection is empty', () => {
|
|
1703
1703
|
const col = new ZQueryCollection([]);
|
|
1704
1704
|
expect(col.css('color')).toBeUndefined();
|
|
@@ -1710,7 +1710,7 @@ describe('ZQueryCollection — css() empty collection', () => {
|
|
|
1710
1710
|
// append/prepend/after/before with Node
|
|
1711
1711
|
// ===========================================================================
|
|
1712
1712
|
|
|
1713
|
-
describe('ZQueryCollection
|
|
1713
|
+
describe('ZQueryCollection - append/prepend with Node', () => {
|
|
1714
1714
|
it('appends a Node element', () => {
|
|
1715
1715
|
document.body.innerHTML = '<div id="container"><p>existing</p></div>';
|
|
1716
1716
|
const newNode = document.createElement('span');
|
|
@@ -1736,7 +1736,7 @@ describe('ZQueryCollection — append/prepend with Node', () => {
|
|
|
1736
1736
|
});
|
|
1737
1737
|
});
|
|
1738
1738
|
|
|
1739
|
-
describe('ZQueryCollection
|
|
1739
|
+
describe('ZQueryCollection - after/before with Node', () => {
|
|
1740
1740
|
it('inserts Node after element', () => {
|
|
1741
1741
|
document.body.innerHTML = '<div id="anchor"></div>';
|
|
1742
1742
|
const newNode = document.createElement('span');
|
|
@@ -1759,7 +1759,7 @@ describe('ZQueryCollection — after/before with Node', () => {
|
|
|
1759
1759
|
// replaceWith using Node
|
|
1760
1760
|
// ===========================================================================
|
|
1761
1761
|
|
|
1762
|
-
describe('ZQueryCollection
|
|
1762
|
+
describe('ZQueryCollection - replaceWith(Node)', () => {
|
|
1763
1763
|
it('replaces element with a Node', () => {
|
|
1764
1764
|
document.body.innerHTML = '<div id="old">old</div>';
|
|
1765
1765
|
const newNode = document.createElement('span');
|
|
@@ -1776,7 +1776,7 @@ describe('ZQueryCollection — replaceWith(Node)', () => {
|
|
|
1776
1776
|
// nextUntil/prevUntil/parentsUntil with filter
|
|
1777
1777
|
// ===========================================================================
|
|
1778
1778
|
|
|
1779
|
-
describe('ZQueryCollection
|
|
1779
|
+
describe('ZQueryCollection - nextUntil with filter', () => {
|
|
1780
1780
|
it('collects siblings until stop selector, applying filter', () => {
|
|
1781
1781
|
document.body.innerHTML = '<div id="start"></div><span class="a">A</span><p>P</p><span class="a">A2</span><div id="stop"></div>';
|
|
1782
1782
|
const result = query('#start').nextUntil('#stop', 'span');
|
|
@@ -1784,7 +1784,7 @@ describe('ZQueryCollection — nextUntil with filter', () => {
|
|
|
1784
1784
|
});
|
|
1785
1785
|
});
|
|
1786
1786
|
|
|
1787
|
-
describe('ZQueryCollection
|
|
1787
|
+
describe('ZQueryCollection - prevUntil with filter', () => {
|
|
1788
1788
|
it('collects previous siblings until stop selector, applying filter', () => {
|
|
1789
1789
|
document.body.innerHTML = '<div id="stop"></div><span>A</span><p>P</p><span>B</span><div id="end"></div>';
|
|
1790
1790
|
const result = query('#end').prevUntil('#stop', 'span');
|
|
@@ -1792,7 +1792,7 @@ describe('ZQueryCollection — prevUntil with filter', () => {
|
|
|
1792
1792
|
});
|
|
1793
1793
|
});
|
|
1794
1794
|
|
|
1795
|
-
describe('ZQueryCollection
|
|
1795
|
+
describe('ZQueryCollection - parentsUntil with filter', () => {
|
|
1796
1796
|
it('collects parent elements until stop selector, applying filter', () => {
|
|
1797
1797
|
document.body.innerHTML = '<section><article><div><span id="target"></span></div></article></section>';
|
|
1798
1798
|
const result = query('#target').parentsUntil('section', 'div');
|
|
@@ -1806,7 +1806,7 @@ describe('ZQueryCollection — parentsUntil with filter', () => {
|
|
|
1806
1806
|
// delegated on() at document level
|
|
1807
1807
|
// ===========================================================================
|
|
1808
1808
|
|
|
1809
|
-
describe('ZQueryCollection
|
|
1809
|
+
describe('ZQueryCollection - delegated on()', () => {
|
|
1810
1810
|
it('delegates event to matching child selector', () => {
|
|
1811
1811
|
document.body.innerHTML = '<div id="container"><button class="action">click</button></div>';
|
|
1812
1812
|
const handler = vi.fn();
|
|
@@ -1829,7 +1829,7 @@ describe('ZQueryCollection — delegated on()', () => {
|
|
|
1829
1829
|
// Multi-event on/off
|
|
1830
1830
|
// ===========================================================================
|
|
1831
1831
|
|
|
1832
|
-
describe('ZQueryCollection
|
|
1832
|
+
describe('ZQueryCollection - multi-event on()', () => {
|
|
1833
1833
|
it('binds handler to multiple space-separated events', () => {
|
|
1834
1834
|
document.body.innerHTML = '<input id="inp" type="text">';
|
|
1835
1835
|
const handler = vi.fn();
|
|
@@ -1845,7 +1845,7 @@ describe('ZQueryCollection — multi-event on()', () => {
|
|
|
1845
1845
|
// scrollTop/scrollLeft getters
|
|
1846
1846
|
// ===========================================================================
|
|
1847
1847
|
|
|
1848
|
-
describe('ZQueryCollection
|
|
1848
|
+
describe('ZQueryCollection - scrollTop/scrollLeft', () => {
|
|
1849
1849
|
it('gets and sets scrollTop', () => {
|
|
1850
1850
|
document.body.innerHTML = '<div id="scr" style="overflow:auto; height: 50px;"><div style="height:200px;">x</div></div>';
|
|
1851
1851
|
const el = document.querySelector('#scr');
|
|
@@ -1865,7 +1865,7 @@ describe('ZQueryCollection — scrollTop/scrollLeft', () => {
|
|
|
1865
1865
|
// slideDown/slideUp set styles
|
|
1866
1866
|
// ===========================================================================
|
|
1867
1867
|
|
|
1868
|
-
describe('ZQueryCollection
|
|
1868
|
+
describe('ZQueryCollection - slideDown/slideUp', () => {
|
|
1869
1869
|
it('slideDown sets overflow hidden and maxHeight initially', () => {
|
|
1870
1870
|
vi.useFakeTimers();
|
|
1871
1871
|
document.body.innerHTML = '<div id="slide" style="display:none;">content</div>';
|
|
@@ -1893,7 +1893,7 @@ describe('ZQueryCollection — slideDown/slideUp', () => {
|
|
|
1893
1893
|
// fadeIn/fadeOut set opacity
|
|
1894
1894
|
// ===========================================================================
|
|
1895
1895
|
|
|
1896
|
-
describe('ZQueryCollection
|
|
1896
|
+
describe('ZQueryCollection - fadeIn/fadeOut', () => {
|
|
1897
1897
|
it('fadeIn sets initial opacity to 0', () => {
|
|
1898
1898
|
document.body.innerHTML = '<div id="fade" style="display:none;">content</div>';
|
|
1899
1899
|
query('#fade').fadeIn(100);
|
|
@@ -1904,7 +1904,7 @@ describe('ZQueryCollection — fadeIn/fadeOut', () => {
|
|
|
1904
1904
|
it('fadeTo animates to specified opacity', () => {
|
|
1905
1905
|
document.body.innerHTML = '<div id="fade">content</div>';
|
|
1906
1906
|
query('#fade').fadeTo(100, 0.5);
|
|
1907
|
-
// Animation starts
|
|
1907
|
+
// Animation starts - just verify no throw
|
|
1908
1908
|
expect(document.querySelector('#fade')).not.toBeNull();
|
|
1909
1909
|
});
|
|
1910
1910
|
});
|