jj 2.7.2 → 2.9.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/SKILL.md +20 -2
- package/lib/bundle.cjs +85 -17
- package/lib/bundle.cjs.map +1 -1
- package/lib/bundle.d.cts +69 -18
- package/lib/bundle.d.ts +69 -18
- package/lib/bundle.global.js +85 -17
- package/lib/bundle.global.js.map +1 -1
- package/lib/bundle.js +85 -17
- package/lib/bundle.js.map +1 -1
- package/lib/bundle.min.cjs +1 -1
- package/lib/bundle.min.cjs.map +1 -1
- package/lib/bundle.min.d.cts +69 -18
- package/lib/bundle.min.d.ts +69 -18
- package/lib/bundle.min.global.js +1 -1
- package/lib/bundle.min.global.js.map +1 -1
- package/lib/bundle.min.js +1 -1
- package/lib/bundle.min.js.map +1 -1
- package/package.json +12 -6
package/SKILL.md
CHANGED
|
@@ -60,6 +60,8 @@ const nav = h(
|
|
|
60
60
|
|
|
61
61
|
// Append to document body
|
|
62
62
|
doc.body.ref.append(nav.ref)
|
|
63
|
+
// Or using the wrapper API
|
|
64
|
+
doc.body.addChild(nav.ref)
|
|
63
65
|
```
|
|
64
66
|
|
|
65
67
|
For batch DOM operations, use `JJDF` (DocumentFragment) to avoid multiple reflows:
|
|
@@ -173,6 +175,20 @@ el.style('background-color', 'blue').style('padding', '10px')
|
|
|
173
175
|
el.setAria('hidden', 'true').rmAria('label')
|
|
174
176
|
```
|
|
175
177
|
|
|
178
|
+
Node traversal and detach helpers on `JJN`:
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
const item = doc.find('#item', true)
|
|
182
|
+
const parent = item.parent // wrapped parent or null
|
|
183
|
+
const children = item.children // wrapped child nodes
|
|
184
|
+
|
|
185
|
+
children.forEach((child) => {
|
|
186
|
+
console.log(child.ref)
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
item.rm() // detach from its current parent
|
|
190
|
+
```
|
|
191
|
+
|
|
176
192
|
### 3. Type-Safe Element Creation
|
|
177
193
|
|
|
178
194
|
JJ leverages TypeScript generics to ensure type safety and prevent LLM hallucinations:
|
|
@@ -614,8 +630,10 @@ Output: `doc/` folder with HTML documentation
|
|
|
614
630
|
1. **Accessing the Native Node**: Always use `.ref` to access the underlying DOM node for operations not exposed by JJ
|
|
615
631
|
2. **Event Listeners**: Use `.on()` and `.off()` for proper cleanup. Event handlers are automatically bound to the JJ\* instance, so `this` refers to the wrapper, not the DOM element. Use `function` instead of arrow functions (`=>`) for `.bind()` to work correctly. Use `this.ref` to access the native element.
|
|
616
632
|
3. **Type Safety**: Use `JJHE.create()` for automatic type inference instead of generic parameters
|
|
617
|
-
4. **
|
|
618
|
-
5. **
|
|
633
|
+
4. **Tree Navigation**: Use `node.parent` and `node.children` to stay in JJ wrappers while traversing the DOM tree
|
|
634
|
+
5. **Detaching Nodes**: Use `node.rm()` instead of reaching for native removal APIs unless you specifically need them
|
|
635
|
+
6. **Fragments**: Use JJDF for batch operations before appending
|
|
636
|
+
7. **Error Messages**: Read them carefully—they suggest the correct approach
|
|
619
637
|
|
|
620
638
|
## Anti-patterns to Avoid
|
|
621
639
|
|
package/lib/bundle.cjs
CHANGED
|
@@ -354,9 +354,9 @@ var JJN = class _JJN extends JJET {
|
|
|
354
354
|
* This is useful for filtering the array that is passed to `append()`, `prepend()` or `setChildren()`
|
|
355
355
|
*
|
|
356
356
|
* @param x an unknown value
|
|
357
|
-
* @returns true if `x` is a string, Node (or its
|
|
357
|
+
* @returns true if `x` is a string, Node (or its descendent), JJN (or its descendent)
|
|
358
358
|
*/
|
|
359
|
-
static
|
|
359
|
+
static isWrappable(x) {
|
|
360
360
|
return isStr(x) || isA(x, Node) || isA(x, _JJN);
|
|
361
361
|
}
|
|
362
362
|
/**
|
|
@@ -365,6 +365,7 @@ var JJN = class _JJN extends JJET {
|
|
|
365
365
|
* @remarks
|
|
366
366
|
* This function acts as a factory, inspecting the input type and returning the appropriate
|
|
367
367
|
* subclass of `JJN` (e.g., `JJHE` for `HTMLElement`, `JJT` for `Text`).
|
|
368
|
+
* JJN.ts overrides this method to a richer version that handles all subclasses of JJN.
|
|
368
369
|
*
|
|
369
370
|
* @example
|
|
370
371
|
* ```ts
|
|
@@ -377,7 +378,15 @@ var JJN = class _JJN extends JJET {
|
|
|
377
378
|
* @throws {TypeError} If the input is not a Node, string, or JJ wrapper.
|
|
378
379
|
*/
|
|
379
380
|
static wrap(raw) {
|
|
380
|
-
|
|
381
|
+
if (isObj(raw)) {
|
|
382
|
+
if (isA(raw, _JJN)) {
|
|
383
|
+
return raw;
|
|
384
|
+
}
|
|
385
|
+
if (isA(raw, Node)) {
|
|
386
|
+
return new _JJN(raw);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
throw typeErr("raw", "a Node", raw);
|
|
381
390
|
}
|
|
382
391
|
/**
|
|
383
392
|
* Extracts the underlying native DOM node from a wrapper.
|
|
@@ -454,6 +463,44 @@ var JJN = class _JJN extends JJET {
|
|
|
454
463
|
}
|
|
455
464
|
super(ref);
|
|
456
465
|
}
|
|
466
|
+
/**
|
|
467
|
+
* Gets the parent node wrapped in the most specific JJ wrapper available.
|
|
468
|
+
*
|
|
469
|
+
* @remarks
|
|
470
|
+
* Returns `null` when this node is detached and therefore has no parent.
|
|
471
|
+
*
|
|
472
|
+
* @example
|
|
473
|
+
* ```ts
|
|
474
|
+
* const text = JJT.fromStr('hello')
|
|
475
|
+
* JJHE.create('div').addChild(text)
|
|
476
|
+
* const parent = text.parent // JJHE
|
|
477
|
+
* ```
|
|
478
|
+
*
|
|
479
|
+
* @returns The wrapped parent node, or `null` if this node has no parent.
|
|
480
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode | Node.parentNode}
|
|
481
|
+
*/
|
|
482
|
+
get parent() {
|
|
483
|
+
const { parentNode } = this.ref;
|
|
484
|
+
return parentNode ? _JJN.wrap(parentNode) : null;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Gets the child nodes wrapped in the most specific JJ wrappers available.
|
|
488
|
+
*
|
|
489
|
+
* @remarks
|
|
490
|
+
* Returns an empty array when this node has no children.
|
|
491
|
+
*
|
|
492
|
+
* @example
|
|
493
|
+
* ```ts
|
|
494
|
+
* const el = JJHE.create('div').addChild('hello', JJHE.create('span'))
|
|
495
|
+
* const children = el.children // [JJT, JJHE]
|
|
496
|
+
* ```
|
|
497
|
+
*
|
|
498
|
+
* @returns The wrapped child nodes.
|
|
499
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes | Node.childNodes}
|
|
500
|
+
*/
|
|
501
|
+
get children() {
|
|
502
|
+
return _JJN.wrapAll(this.ref.childNodes);
|
|
503
|
+
}
|
|
457
504
|
/**
|
|
458
505
|
* Clones the Node.
|
|
459
506
|
*
|
|
@@ -464,6 +511,29 @@ var JJN = class _JJN extends JJET {
|
|
|
464
511
|
clone(deep) {
|
|
465
512
|
return _JJN.wrap(this.ref.cloneNode(deep));
|
|
466
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
* Removes this node from its parent.
|
|
516
|
+
*
|
|
517
|
+
* @remarks
|
|
518
|
+
* If the node has no parent, this method does nothing.
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* ```ts
|
|
522
|
+
* const el = JJHE.create('div')
|
|
523
|
+
* doc.body.addChild(el)
|
|
524
|
+
* el.rm()
|
|
525
|
+
* ```
|
|
526
|
+
*
|
|
527
|
+
* @returns This instance for chaining.
|
|
528
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild | Node.removeChild}
|
|
529
|
+
*/
|
|
530
|
+
rm() {
|
|
531
|
+
const { parentNode } = this.ref;
|
|
532
|
+
if (parentNode) {
|
|
533
|
+
parentNode.removeChild(this.ref);
|
|
534
|
+
}
|
|
535
|
+
return this;
|
|
536
|
+
}
|
|
467
537
|
/**
|
|
468
538
|
* Creates a Text node from a string and appends it to this Node.
|
|
469
539
|
*
|
|
@@ -480,9 +550,9 @@ var JJN = class _JJN extends JJET {
|
|
|
480
550
|
* @returns This instance for chaining.
|
|
481
551
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode | document.createTextNode}
|
|
482
552
|
*/
|
|
483
|
-
addText(
|
|
484
|
-
if (
|
|
485
|
-
this.ref.appendChild(document.createTextNode(
|
|
553
|
+
addText(...textArr) {
|
|
554
|
+
if (textArr) {
|
|
555
|
+
this.ref.appendChild(document.createTextNode(textArr.join("")));
|
|
486
556
|
}
|
|
487
557
|
return this;
|
|
488
558
|
}
|
|
@@ -547,7 +617,7 @@ var JJNx = class extends JJN {
|
|
|
547
617
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/append | Element.append}
|
|
548
618
|
*/
|
|
549
619
|
addChild(...children) {
|
|
550
|
-
const nodes = JJN.unwrapAll(children.filter(JJN.
|
|
620
|
+
const nodes = JJN.unwrapAll(children.filter(JJN.isWrappable));
|
|
551
621
|
this.ref.append(...nodes);
|
|
552
622
|
return this;
|
|
553
623
|
}
|
|
@@ -567,7 +637,7 @@ var JJNx = class extends JJN {
|
|
|
567
637
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/prepend | Element.prepend}
|
|
568
638
|
*/
|
|
569
639
|
preChild(...children) {
|
|
570
|
-
const nodes = JJN.unwrapAll(children.filter(JJN.
|
|
640
|
+
const nodes = JJN.unwrapAll(children.filter(JJN.isWrappable));
|
|
571
641
|
this.ref.prepend(...nodes);
|
|
572
642
|
return this;
|
|
573
643
|
}
|
|
@@ -623,7 +693,7 @@ var JJNx = class extends JJN {
|
|
|
623
693
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/replaceChildren | Element.replaceChildren}
|
|
624
694
|
*/
|
|
625
695
|
setChildren(...children) {
|
|
626
|
-
const nodes = JJN.unwrapAll(children.filter(JJN.
|
|
696
|
+
const nodes = JJN.unwrapAll(children.filter(JJN.isWrappable));
|
|
627
697
|
this.ref.replaceChildren(...nodes);
|
|
628
698
|
return this;
|
|
629
699
|
}
|
|
@@ -1385,7 +1455,7 @@ var JJHE = class _JJHE extends JJEx {
|
|
|
1385
1455
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText | HTMLElement.innerText}
|
|
1386
1456
|
*/
|
|
1387
1457
|
setText(text) {
|
|
1388
|
-
this.ref.innerText = text
|
|
1458
|
+
this.ref.innerText = text;
|
|
1389
1459
|
return this;
|
|
1390
1460
|
}
|
|
1391
1461
|
};
|
|
@@ -1457,7 +1527,7 @@ var JJT = class _JJT extends JJN {
|
|
|
1457
1527
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent | Node.textContent}
|
|
1458
1528
|
*/
|
|
1459
1529
|
setText(text) {
|
|
1460
|
-
this.ref.textContent = text
|
|
1530
|
+
this.ref.textContent = text;
|
|
1461
1531
|
return this;
|
|
1462
1532
|
}
|
|
1463
1533
|
/**
|
|
@@ -1470,14 +1540,12 @@ var JJT = class _JJT extends JJN {
|
|
|
1470
1540
|
* console.log(text.getText()) // 'hello world'
|
|
1471
1541
|
* ```
|
|
1472
1542
|
*
|
|
1473
|
-
* @param
|
|
1543
|
+
* @param textArr - The string to add to the existing contents. If null or undefined, nothing is added.
|
|
1474
1544
|
* @returns This instance for chaining.
|
|
1475
1545
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent | Node.textContent}
|
|
1476
1546
|
*/
|
|
1477
|
-
addText(
|
|
1478
|
-
|
|
1479
|
-
this.ref.textContent += text;
|
|
1480
|
-
}
|
|
1547
|
+
addText(...textArr) {
|
|
1548
|
+
this.setText(this.getText() + textArr.join(""));
|
|
1481
1549
|
return this;
|
|
1482
1550
|
}
|
|
1483
1551
|
/**
|
|
@@ -1636,7 +1704,7 @@ var JJSE = class _JJSE extends JJEx {
|
|
|
1636
1704
|
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent | Node.textContent}
|
|
1637
1705
|
*/
|
|
1638
1706
|
setText(text) {
|
|
1639
|
-
this.ref.textContent = text
|
|
1707
|
+
this.ref.textContent = text;
|
|
1640
1708
|
return this;
|
|
1641
1709
|
}
|
|
1642
1710
|
/**
|