@ktjs/core 0.17.1 → 0.17.3
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/dist/index.d.ts +2 -1
- package/dist/index.iife.js +149 -31
- package/dist/index.legacy.js +149 -31
- package/dist/index.mjs +149 -31
- package/dist/jsx/index.d.ts +2 -1
- package/dist/jsx/index.mjs +8 -3
- package/dist/jsx/jsx-runtime.d.ts +2 -1
- package/dist/jsx/jsx-runtime.mjs +8 -3
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -69,6 +69,7 @@ interface KTBaseAttribute {
|
|
|
69
69
|
// # normal HTML attributes
|
|
70
70
|
id?: string;
|
|
71
71
|
class?: string;
|
|
72
|
+
className?: string;
|
|
72
73
|
style?: string | Partial<CSSStyleDeclaration>;
|
|
73
74
|
|
|
74
75
|
type?:
|
|
@@ -171,7 +172,7 @@ type HTML<T extends (HTMLTag | SVGTag) & otherstring> = T extends SVGTag ? SVGEl
|
|
|
171
172
|
* ## About
|
|
172
173
|
* @package @ktjs/core
|
|
173
174
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
174
|
-
* @version 0.17.
|
|
175
|
+
* @version 0.17.3 (Last Update: 2026.01.28 16:50:39.470)
|
|
175
176
|
* @license MIT
|
|
176
177
|
* @link https://github.com/baendlorel/kt.js
|
|
177
178
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
package/dist/index.iife.js
CHANGED
|
@@ -56,7 +56,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
56
56
|
|
|
57
57
|
const defaultHandler = (element, key, value) => element.setAttribute(key, value);
|
|
58
58
|
function attrIsObject(element, attr) {
|
|
59
|
-
const classValue = attr.class;
|
|
59
|
+
const classValue = attr.class || attr.className;
|
|
60
60
|
if (classValue !== undefined) {
|
|
61
61
|
element.setAttribute('class', classValue);
|
|
62
62
|
}
|
|
@@ -72,7 +72,12 @@ var __ktjs_core__ = (function (exports) {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
for (const key in attr) {
|
|
75
|
-
if (key === 'class' ||
|
|
75
|
+
if (key === 'class' ||
|
|
76
|
+
key === 'className' ||
|
|
77
|
+
key === 'style' ||
|
|
78
|
+
key === 'children' ||
|
|
79
|
+
key === 'k-if' ||
|
|
80
|
+
key === 'ref') {
|
|
76
81
|
continue;
|
|
77
82
|
}
|
|
78
83
|
const o = attr[key];
|
|
@@ -211,7 +216,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
211
216
|
* ## About
|
|
212
217
|
* @package @ktjs/core
|
|
213
218
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
214
|
-
* @version 0.17.
|
|
219
|
+
* @version 0.17.3 (Last Update: 2026.01.28 16:50:39.470)
|
|
215
220
|
* @license MIT
|
|
216
221
|
* @link https://github.com/baendlorel/kt.js
|
|
217
222
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -422,6 +427,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
422
427
|
if (!parent) {
|
|
423
428
|
// If not in DOM yet, just rebuild the list
|
|
424
429
|
const newElements = [];
|
|
430
|
+
nodeMap.clear();
|
|
425
431
|
for (let index = 0; index < currentList.length; index++) {
|
|
426
432
|
const item = currentList[index];
|
|
427
433
|
const itemKey = currentKey(item, index, currentList);
|
|
@@ -432,46 +438,116 @@ var __ktjs_core__ = (function (exports) {
|
|
|
432
438
|
anchor.__kt_for_list__ = newElements;
|
|
433
439
|
return anchor;
|
|
434
440
|
}
|
|
435
|
-
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
441
|
+
const oldLength = anchor.__kt_for_list__.length;
|
|
442
|
+
const newLength = newList.length;
|
|
443
|
+
// Fast path: empty list
|
|
444
|
+
if (newLength === 0) {
|
|
445
|
+
nodeMap.forEach((node) => node.remove());
|
|
446
|
+
nodeMap.clear();
|
|
447
|
+
anchor.__kt_for_list__ = [];
|
|
448
|
+
return anchor;
|
|
449
|
+
}
|
|
450
|
+
// Fast path: all new items
|
|
451
|
+
if (oldLength === 0) {
|
|
452
|
+
const newElements = [];
|
|
453
|
+
const fragment = document.createDocumentFragment();
|
|
454
|
+
for (let i = 0; i < newLength; i++) {
|
|
455
|
+
const item = newList[i];
|
|
456
|
+
const itemKey = newKey(item, i, newList);
|
|
457
|
+
const node = newMap(item, i, newList);
|
|
458
|
+
nodeMap.set(itemKey, node);
|
|
459
|
+
newElements.push(node);
|
|
460
|
+
fragment.appendChild(node);
|
|
461
|
+
}
|
|
462
|
+
parent.insertBefore(fragment, anchor.nextSibling);
|
|
463
|
+
anchor.__kt_for_list__ = newElements;
|
|
464
|
+
return anchor;
|
|
465
|
+
}
|
|
466
|
+
// Build key index map and new elements array in one pass
|
|
467
|
+
const newKeyToNewIndex = new Map();
|
|
468
|
+
const newElements = new Array(newLength);
|
|
469
|
+
let maxNewIndexSoFar = 0;
|
|
470
|
+
let moved = false;
|
|
471
|
+
for (let i = 0; i < newLength; i++) {
|
|
472
|
+
const item = newList[i];
|
|
473
|
+
const itemKey = newKey(item, i, newList);
|
|
474
|
+
newKeyToNewIndex.set(itemKey, i);
|
|
444
475
|
if (nodeMap.has(itemKey)) {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
newElements
|
|
476
|
+
// Reuse existing node
|
|
477
|
+
const node = nodeMap.get(itemKey);
|
|
478
|
+
newElements[i] = node;
|
|
479
|
+
// Track if items moved
|
|
480
|
+
if (i < maxNewIndexSoFar) {
|
|
481
|
+
moved = true;
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
maxNewIndexSoFar = i;
|
|
485
|
+
}
|
|
448
486
|
}
|
|
449
487
|
else {
|
|
450
488
|
// Create new node
|
|
451
|
-
|
|
452
|
-
newNodeMap.set(itemKey, node);
|
|
453
|
-
newElements.push(node);
|
|
489
|
+
newElements[i] = newMap(item, i, newList);
|
|
454
490
|
}
|
|
455
491
|
}
|
|
456
|
-
// Remove nodes
|
|
492
|
+
// Remove nodes not in new list
|
|
493
|
+
const toRemove = [];
|
|
457
494
|
nodeMap.forEach((node, key) => {
|
|
458
|
-
if (!
|
|
459
|
-
|
|
495
|
+
if (!newKeyToNewIndex.has(key)) {
|
|
496
|
+
toRemove.push(node);
|
|
460
497
|
}
|
|
461
498
|
});
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
499
|
+
for (let i = 0; i < toRemove.length; i++) {
|
|
500
|
+
toRemove[i].remove();
|
|
501
|
+
}
|
|
502
|
+
// Update DOM with minimal operations
|
|
503
|
+
if (moved) {
|
|
504
|
+
// Use longest increasing subsequence to minimize moves
|
|
505
|
+
const seq = getSequence(newElements.map((el, i) => (nodeMap.has(newKey(newList[i], i, newList)) ? i : -1)));
|
|
506
|
+
let j = seq.length - 1;
|
|
507
|
+
let anchor = null;
|
|
508
|
+
// Traverse from end to start for stable insertions
|
|
509
|
+
for (let i = newLength - 1; i >= 0; i--) {
|
|
510
|
+
const node = newElements[i];
|
|
511
|
+
if (j < 0 || i !== seq[j]) {
|
|
512
|
+
// Node needs to be moved or inserted
|
|
513
|
+
if (anchor) {
|
|
514
|
+
parent.insertBefore(node, anchor);
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
// Insert at end
|
|
518
|
+
let nextSibling = anchor.nextSibling;
|
|
519
|
+
let temp = nextSibling;
|
|
520
|
+
while (temp && newElements.includes(temp)) {
|
|
521
|
+
temp = temp.nextSibling;
|
|
522
|
+
}
|
|
523
|
+
parent.insertBefore(node, temp);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
else {
|
|
527
|
+
j--;
|
|
528
|
+
}
|
|
529
|
+
anchor = node;
|
|
469
530
|
}
|
|
470
|
-
referenceNode = node.nextSibling;
|
|
471
531
|
}
|
|
472
|
-
|
|
532
|
+
else {
|
|
533
|
+
// No moves needed, just insert new nodes
|
|
534
|
+
let currentNode = anchor.nextSibling;
|
|
535
|
+
for (let i = 0; i < newLength; i++) {
|
|
536
|
+
const node = newElements[i];
|
|
537
|
+
if (currentNode !== node) {
|
|
538
|
+
parent.insertBefore(node, currentNode);
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
currentNode = currentNode.nextSibling;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
// Update maps
|
|
473
546
|
nodeMap.clear();
|
|
474
|
-
|
|
547
|
+
for (let i = 0; i < newLength; i++) {
|
|
548
|
+
const itemKey = newKey(newList[i], i, newList);
|
|
549
|
+
nodeMap.set(itemKey, newElements[i]);
|
|
550
|
+
}
|
|
475
551
|
anchor.__kt_for_list__ = newElements;
|
|
476
552
|
return anchor;
|
|
477
553
|
};
|
|
@@ -481,6 +557,48 @@ var __ktjs_core__ = (function (exports) {
|
|
|
481
557
|
}
|
|
482
558
|
return anchor;
|
|
483
559
|
}
|
|
560
|
+
// Longest Increasing Subsequence algorithm (optimized for diff)
|
|
561
|
+
function getSequence(arr) {
|
|
562
|
+
const p = arr.slice();
|
|
563
|
+
const result = [0];
|
|
564
|
+
let i, j, u, v, c;
|
|
565
|
+
const len = arr.length;
|
|
566
|
+
for (i = 0; i < len; i++) {
|
|
567
|
+
const arrI = arr[i];
|
|
568
|
+
if (arrI === -1)
|
|
569
|
+
continue;
|
|
570
|
+
j = result[result.length - 1];
|
|
571
|
+
if (arr[j] < arrI) {
|
|
572
|
+
p[i] = j;
|
|
573
|
+
result.push(i);
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
u = 0;
|
|
577
|
+
v = result.length - 1;
|
|
578
|
+
while (u < v) {
|
|
579
|
+
c = ((u + v) / 2) | 0;
|
|
580
|
+
if (arr[result[c]] < arrI) {
|
|
581
|
+
u = c + 1;
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
v = c;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
if (arrI < arr[result[u]]) {
|
|
588
|
+
if (u > 0) {
|
|
589
|
+
p[i] = result[u - 1];
|
|
590
|
+
}
|
|
591
|
+
result[u] = i;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
u = result.length;
|
|
595
|
+
v = result[u - 1];
|
|
596
|
+
while (u-- > 0) {
|
|
597
|
+
result[u] = v;
|
|
598
|
+
v = p[v];
|
|
599
|
+
}
|
|
600
|
+
return result;
|
|
601
|
+
}
|
|
484
602
|
|
|
485
603
|
exports.Fragment = Fragment;
|
|
486
604
|
exports.KTAsync = KTAsync;
|
package/dist/index.legacy.js
CHANGED
|
@@ -68,7 +68,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
68
68
|
|
|
69
69
|
var defaultHandler = function (element, key, value) { return element.setAttribute(key, value); };
|
|
70
70
|
function attrIsObject(element, attr) {
|
|
71
|
-
var classValue = attr.class;
|
|
71
|
+
var classValue = attr.class || attr.className;
|
|
72
72
|
if (classValue !== undefined) {
|
|
73
73
|
element.setAttribute('class', classValue);
|
|
74
74
|
}
|
|
@@ -84,7 +84,12 @@ var __ktjs_core__ = (function (exports) {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
for (var key in attr) {
|
|
87
|
-
if (key === 'class' ||
|
|
87
|
+
if (key === 'class' ||
|
|
88
|
+
key === 'className' ||
|
|
89
|
+
key === 'style' ||
|
|
90
|
+
key === 'children' ||
|
|
91
|
+
key === 'k-if' ||
|
|
92
|
+
key === 'ref') {
|
|
88
93
|
continue;
|
|
89
94
|
}
|
|
90
95
|
var o = attr[key];
|
|
@@ -236,7 +241,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
236
241
|
* ## About
|
|
237
242
|
* @package @ktjs/core
|
|
238
243
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
239
|
-
* @version 0.17.
|
|
244
|
+
* @version 0.17.3 (Last Update: 2026.01.28 16:50:39.470)
|
|
240
245
|
* @license MIT
|
|
241
246
|
* @link https://github.com/baendlorel/kt.js
|
|
242
247
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -490,6 +495,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
490
495
|
if (!parent) {
|
|
491
496
|
// If not in DOM yet, just rebuild the list
|
|
492
497
|
var newElements_1 = [];
|
|
498
|
+
nodeMap.clear();
|
|
493
499
|
for (var index = 0; index < currentList.length; index++) {
|
|
494
500
|
var item = currentList[index];
|
|
495
501
|
var itemKey = currentKey(item, index, currentList);
|
|
@@ -500,46 +506,116 @@ var __ktjs_core__ = (function (exports) {
|
|
|
500
506
|
anchor.__kt_for_list__ = newElements_1;
|
|
501
507
|
return anchor;
|
|
502
508
|
}
|
|
503
|
-
|
|
504
|
-
var
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
509
|
+
var oldLength = anchor.__kt_for_list__.length;
|
|
510
|
+
var newLength = newList.length;
|
|
511
|
+
// Fast path: empty list
|
|
512
|
+
if (newLength === 0) {
|
|
513
|
+
nodeMap.forEach(function (node) { return node.remove(); });
|
|
514
|
+
nodeMap.clear();
|
|
515
|
+
anchor.__kt_for_list__ = [];
|
|
516
|
+
return anchor;
|
|
517
|
+
}
|
|
518
|
+
// Fast path: all new items
|
|
519
|
+
if (oldLength === 0) {
|
|
520
|
+
var newElements_2 = [];
|
|
521
|
+
var fragment = document.createDocumentFragment();
|
|
522
|
+
for (var i = 0; i < newLength; i++) {
|
|
523
|
+
var item = newList[i];
|
|
524
|
+
var itemKey = newKey(item, i, newList);
|
|
525
|
+
var node = newMap(item, i, newList);
|
|
526
|
+
nodeMap.set(itemKey, node);
|
|
527
|
+
newElements_2.push(node);
|
|
528
|
+
fragment.appendChild(node);
|
|
529
|
+
}
|
|
530
|
+
parent.insertBefore(fragment, anchor.nextSibling);
|
|
531
|
+
anchor.__kt_for_list__ = newElements_2;
|
|
532
|
+
return anchor;
|
|
533
|
+
}
|
|
534
|
+
// Build key index map and new elements array in one pass
|
|
535
|
+
var newKeyToNewIndex = new Map();
|
|
536
|
+
var newElements = new Array(newLength);
|
|
537
|
+
var maxNewIndexSoFar = 0;
|
|
538
|
+
var moved = false;
|
|
539
|
+
for (var i = 0; i < newLength; i++) {
|
|
540
|
+
var item = newList[i];
|
|
541
|
+
var itemKey = newKey(item, i, newList);
|
|
542
|
+
newKeyToNewIndex.set(itemKey, i);
|
|
512
543
|
if (nodeMap.has(itemKey)) {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
newElements
|
|
544
|
+
// Reuse existing node
|
|
545
|
+
var node = nodeMap.get(itemKey);
|
|
546
|
+
newElements[i] = node;
|
|
547
|
+
// Track if items moved
|
|
548
|
+
if (i < maxNewIndexSoFar) {
|
|
549
|
+
moved = true;
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
maxNewIndexSoFar = i;
|
|
553
|
+
}
|
|
516
554
|
}
|
|
517
555
|
else {
|
|
518
556
|
// Create new node
|
|
519
|
-
|
|
520
|
-
newNodeMap.set(itemKey, node);
|
|
521
|
-
newElements.push(node);
|
|
557
|
+
newElements[i] = newMap(item, i, newList);
|
|
522
558
|
}
|
|
523
559
|
}
|
|
524
|
-
// Remove nodes
|
|
560
|
+
// Remove nodes not in new list
|
|
561
|
+
var toRemove = [];
|
|
525
562
|
nodeMap.forEach(function (node, key) {
|
|
526
|
-
if (!
|
|
527
|
-
|
|
563
|
+
if (!newKeyToNewIndex.has(key)) {
|
|
564
|
+
toRemove.push(node);
|
|
528
565
|
}
|
|
529
566
|
});
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
567
|
+
for (var i = 0; i < toRemove.length; i++) {
|
|
568
|
+
toRemove[i].remove();
|
|
569
|
+
}
|
|
570
|
+
// Update DOM with minimal operations
|
|
571
|
+
if (moved) {
|
|
572
|
+
// Use longest increasing subsequence to minimize moves
|
|
573
|
+
var seq = getSequence(newElements.map(function (el, i) { return (nodeMap.has(newKey(newList[i], i, newList)) ? i : -1); }));
|
|
574
|
+
var j = seq.length - 1;
|
|
575
|
+
var anchor_1 = null;
|
|
576
|
+
// Traverse from end to start for stable insertions
|
|
577
|
+
for (var i = newLength - 1; i >= 0; i--) {
|
|
578
|
+
var node = newElements[i];
|
|
579
|
+
if (j < 0 || i !== seq[j]) {
|
|
580
|
+
// Node needs to be moved or inserted
|
|
581
|
+
if (anchor_1) {
|
|
582
|
+
parent.insertBefore(node, anchor_1);
|
|
583
|
+
}
|
|
584
|
+
else {
|
|
585
|
+
// Insert at end
|
|
586
|
+
var nextSibling = anchor_1.nextSibling;
|
|
587
|
+
var temp = nextSibling;
|
|
588
|
+
while (temp && newElements.includes(temp)) {
|
|
589
|
+
temp = temp.nextSibling;
|
|
590
|
+
}
|
|
591
|
+
parent.insertBefore(node, temp);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
j--;
|
|
596
|
+
}
|
|
597
|
+
anchor_1 = node;
|
|
537
598
|
}
|
|
538
|
-
referenceNode = node.nextSibling;
|
|
539
599
|
}
|
|
540
|
-
|
|
600
|
+
else {
|
|
601
|
+
// No moves needed, just insert new nodes
|
|
602
|
+
var currentNode = anchor.nextSibling;
|
|
603
|
+
for (var i = 0; i < newLength; i++) {
|
|
604
|
+
var node = newElements[i];
|
|
605
|
+
if (currentNode !== node) {
|
|
606
|
+
parent.insertBefore(node, currentNode);
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
currentNode = currentNode.nextSibling;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
// Update maps
|
|
541
614
|
nodeMap.clear();
|
|
542
|
-
|
|
615
|
+
for (var i = 0; i < newLength; i++) {
|
|
616
|
+
var itemKey = newKey(newList[i], i, newList);
|
|
617
|
+
nodeMap.set(itemKey, newElements[i]);
|
|
618
|
+
}
|
|
543
619
|
anchor.__kt_for_list__ = newElements;
|
|
544
620
|
return anchor;
|
|
545
621
|
};
|
|
@@ -549,6 +625,48 @@ var __ktjs_core__ = (function (exports) {
|
|
|
549
625
|
}
|
|
550
626
|
return anchor;
|
|
551
627
|
}
|
|
628
|
+
// Longest Increasing Subsequence algorithm (optimized for diff)
|
|
629
|
+
function getSequence(arr) {
|
|
630
|
+
var p = arr.slice();
|
|
631
|
+
var result = [0];
|
|
632
|
+
var i, j, u, v, c;
|
|
633
|
+
var len = arr.length;
|
|
634
|
+
for (i = 0; i < len; i++) {
|
|
635
|
+
var arrI = arr[i];
|
|
636
|
+
if (arrI === -1)
|
|
637
|
+
continue;
|
|
638
|
+
j = result[result.length - 1];
|
|
639
|
+
if (arr[j] < arrI) {
|
|
640
|
+
p[i] = j;
|
|
641
|
+
result.push(i);
|
|
642
|
+
continue;
|
|
643
|
+
}
|
|
644
|
+
u = 0;
|
|
645
|
+
v = result.length - 1;
|
|
646
|
+
while (u < v) {
|
|
647
|
+
c = ((u + v) / 2) | 0;
|
|
648
|
+
if (arr[result[c]] < arrI) {
|
|
649
|
+
u = c + 1;
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
v = c;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
if (arrI < arr[result[u]]) {
|
|
656
|
+
if (u > 0) {
|
|
657
|
+
p[i] = result[u - 1];
|
|
658
|
+
}
|
|
659
|
+
result[u] = i;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
u = result.length;
|
|
663
|
+
v = result[u - 1];
|
|
664
|
+
while (u-- > 0) {
|
|
665
|
+
result[u] = v;
|
|
666
|
+
v = p[v];
|
|
667
|
+
}
|
|
668
|
+
return result;
|
|
669
|
+
}
|
|
552
670
|
|
|
553
671
|
exports.Fragment = Fragment;
|
|
554
672
|
exports.KTAsync = KTAsync;
|
package/dist/index.mjs
CHANGED
|
@@ -53,7 +53,7 @@ const ktEventHandlers = {
|
|
|
53
53
|
|
|
54
54
|
const defaultHandler = (element, key, value) => element.setAttribute(key, value);
|
|
55
55
|
function attrIsObject(element, attr) {
|
|
56
|
-
const classValue = attr.class;
|
|
56
|
+
const classValue = attr.class || attr.className;
|
|
57
57
|
if (classValue !== undefined) {
|
|
58
58
|
element.setAttribute('class', classValue);
|
|
59
59
|
}
|
|
@@ -69,7 +69,12 @@ function attrIsObject(element, attr) {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
for (const key in attr) {
|
|
72
|
-
if (key === 'class' ||
|
|
72
|
+
if (key === 'class' ||
|
|
73
|
+
key === 'className' ||
|
|
74
|
+
key === 'style' ||
|
|
75
|
+
key === 'children' ||
|
|
76
|
+
key === 'k-if' ||
|
|
77
|
+
key === 'ref') {
|
|
73
78
|
continue;
|
|
74
79
|
}
|
|
75
80
|
const o = attr[key];
|
|
@@ -208,7 +213,7 @@ let creator = defaultCreator;
|
|
|
208
213
|
* ## About
|
|
209
214
|
* @package @ktjs/core
|
|
210
215
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
211
|
-
* @version 0.17.
|
|
216
|
+
* @version 0.17.3 (Last Update: 2026.01.28 16:50:39.470)
|
|
212
217
|
* @license MIT
|
|
213
218
|
* @link https://github.com/baendlorel/kt.js
|
|
214
219
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -419,6 +424,7 @@ function KTFor(props) {
|
|
|
419
424
|
if (!parent) {
|
|
420
425
|
// If not in DOM yet, just rebuild the list
|
|
421
426
|
const newElements = [];
|
|
427
|
+
nodeMap.clear();
|
|
422
428
|
for (let index = 0; index < currentList.length; index++) {
|
|
423
429
|
const item = currentList[index];
|
|
424
430
|
const itemKey = currentKey(item, index, currentList);
|
|
@@ -429,46 +435,116 @@ function KTFor(props) {
|
|
|
429
435
|
anchor.__kt_for_list__ = newElements;
|
|
430
436
|
return anchor;
|
|
431
437
|
}
|
|
432
|
-
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
438
|
+
const oldLength = anchor.__kt_for_list__.length;
|
|
439
|
+
const newLength = newList.length;
|
|
440
|
+
// Fast path: empty list
|
|
441
|
+
if (newLength === 0) {
|
|
442
|
+
nodeMap.forEach((node) => node.remove());
|
|
443
|
+
nodeMap.clear();
|
|
444
|
+
anchor.__kt_for_list__ = [];
|
|
445
|
+
return anchor;
|
|
446
|
+
}
|
|
447
|
+
// Fast path: all new items
|
|
448
|
+
if (oldLength === 0) {
|
|
449
|
+
const newElements = [];
|
|
450
|
+
const fragment = document.createDocumentFragment();
|
|
451
|
+
for (let i = 0; i < newLength; i++) {
|
|
452
|
+
const item = newList[i];
|
|
453
|
+
const itemKey = newKey(item, i, newList);
|
|
454
|
+
const node = newMap(item, i, newList);
|
|
455
|
+
nodeMap.set(itemKey, node);
|
|
456
|
+
newElements.push(node);
|
|
457
|
+
fragment.appendChild(node);
|
|
458
|
+
}
|
|
459
|
+
parent.insertBefore(fragment, anchor.nextSibling);
|
|
460
|
+
anchor.__kt_for_list__ = newElements;
|
|
461
|
+
return anchor;
|
|
462
|
+
}
|
|
463
|
+
// Build key index map and new elements array in one pass
|
|
464
|
+
const newKeyToNewIndex = new Map();
|
|
465
|
+
const newElements = new Array(newLength);
|
|
466
|
+
let maxNewIndexSoFar = 0;
|
|
467
|
+
let moved = false;
|
|
468
|
+
for (let i = 0; i < newLength; i++) {
|
|
469
|
+
const item = newList[i];
|
|
470
|
+
const itemKey = newKey(item, i, newList);
|
|
471
|
+
newKeyToNewIndex.set(itemKey, i);
|
|
441
472
|
if (nodeMap.has(itemKey)) {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
newElements
|
|
473
|
+
// Reuse existing node
|
|
474
|
+
const node = nodeMap.get(itemKey);
|
|
475
|
+
newElements[i] = node;
|
|
476
|
+
// Track if items moved
|
|
477
|
+
if (i < maxNewIndexSoFar) {
|
|
478
|
+
moved = true;
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
maxNewIndexSoFar = i;
|
|
482
|
+
}
|
|
445
483
|
}
|
|
446
484
|
else {
|
|
447
485
|
// Create new node
|
|
448
|
-
|
|
449
|
-
newNodeMap.set(itemKey, node);
|
|
450
|
-
newElements.push(node);
|
|
486
|
+
newElements[i] = newMap(item, i, newList);
|
|
451
487
|
}
|
|
452
488
|
}
|
|
453
|
-
// Remove nodes
|
|
489
|
+
// Remove nodes not in new list
|
|
490
|
+
const toRemove = [];
|
|
454
491
|
nodeMap.forEach((node, key) => {
|
|
455
|
-
if (!
|
|
456
|
-
|
|
492
|
+
if (!newKeyToNewIndex.has(key)) {
|
|
493
|
+
toRemove.push(node);
|
|
457
494
|
}
|
|
458
495
|
});
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
496
|
+
for (let i = 0; i < toRemove.length; i++) {
|
|
497
|
+
toRemove[i].remove();
|
|
498
|
+
}
|
|
499
|
+
// Update DOM with minimal operations
|
|
500
|
+
if (moved) {
|
|
501
|
+
// Use longest increasing subsequence to minimize moves
|
|
502
|
+
const seq = getSequence(newElements.map((el, i) => (nodeMap.has(newKey(newList[i], i, newList)) ? i : -1)));
|
|
503
|
+
let j = seq.length - 1;
|
|
504
|
+
let anchor = null;
|
|
505
|
+
// Traverse from end to start for stable insertions
|
|
506
|
+
for (let i = newLength - 1; i >= 0; i--) {
|
|
507
|
+
const node = newElements[i];
|
|
508
|
+
if (j < 0 || i !== seq[j]) {
|
|
509
|
+
// Node needs to be moved or inserted
|
|
510
|
+
if (anchor) {
|
|
511
|
+
parent.insertBefore(node, anchor);
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
// Insert at end
|
|
515
|
+
let nextSibling = anchor.nextSibling;
|
|
516
|
+
let temp = nextSibling;
|
|
517
|
+
while (temp && newElements.includes(temp)) {
|
|
518
|
+
temp = temp.nextSibling;
|
|
519
|
+
}
|
|
520
|
+
parent.insertBefore(node, temp);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
else {
|
|
524
|
+
j--;
|
|
525
|
+
}
|
|
526
|
+
anchor = node;
|
|
466
527
|
}
|
|
467
|
-
referenceNode = node.nextSibling;
|
|
468
528
|
}
|
|
469
|
-
|
|
529
|
+
else {
|
|
530
|
+
// No moves needed, just insert new nodes
|
|
531
|
+
let currentNode = anchor.nextSibling;
|
|
532
|
+
for (let i = 0; i < newLength; i++) {
|
|
533
|
+
const node = newElements[i];
|
|
534
|
+
if (currentNode !== node) {
|
|
535
|
+
parent.insertBefore(node, currentNode);
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
currentNode = currentNode.nextSibling;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
// Update maps
|
|
470
543
|
nodeMap.clear();
|
|
471
|
-
|
|
544
|
+
for (let i = 0; i < newLength; i++) {
|
|
545
|
+
const itemKey = newKey(newList[i], i, newList);
|
|
546
|
+
nodeMap.set(itemKey, newElements[i]);
|
|
547
|
+
}
|
|
472
548
|
anchor.__kt_for_list__ = newElements;
|
|
473
549
|
return anchor;
|
|
474
550
|
};
|
|
@@ -478,5 +554,47 @@ function KTFor(props) {
|
|
|
478
554
|
}
|
|
479
555
|
return anchor;
|
|
480
556
|
}
|
|
557
|
+
// Longest Increasing Subsequence algorithm (optimized for diff)
|
|
558
|
+
function getSequence(arr) {
|
|
559
|
+
const p = arr.slice();
|
|
560
|
+
const result = [0];
|
|
561
|
+
let i, j, u, v, c;
|
|
562
|
+
const len = arr.length;
|
|
563
|
+
for (i = 0; i < len; i++) {
|
|
564
|
+
const arrI = arr[i];
|
|
565
|
+
if (arrI === -1)
|
|
566
|
+
continue;
|
|
567
|
+
j = result[result.length - 1];
|
|
568
|
+
if (arr[j] < arrI) {
|
|
569
|
+
p[i] = j;
|
|
570
|
+
result.push(i);
|
|
571
|
+
continue;
|
|
572
|
+
}
|
|
573
|
+
u = 0;
|
|
574
|
+
v = result.length - 1;
|
|
575
|
+
while (u < v) {
|
|
576
|
+
c = ((u + v) / 2) | 0;
|
|
577
|
+
if (arr[result[c]] < arrI) {
|
|
578
|
+
u = c + 1;
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
v = c;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
if (arrI < arr[result[u]]) {
|
|
585
|
+
if (u > 0) {
|
|
586
|
+
p[i] = result[u - 1];
|
|
587
|
+
}
|
|
588
|
+
result[u] = i;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
u = result.length;
|
|
592
|
+
v = result[u - 1];
|
|
593
|
+
while (u-- > 0) {
|
|
594
|
+
result[u] = v;
|
|
595
|
+
v = p[v];
|
|
596
|
+
}
|
|
597
|
+
return result;
|
|
598
|
+
}
|
|
481
599
|
|
|
482
600
|
export { Fragment, KTAsync, KTFor, h as createElement, createRedrawable, createRedrawableNoref, h, jsx, jsxDEV, jsxs, ref };
|
package/dist/jsx/index.d.ts
CHANGED
|
@@ -63,6 +63,7 @@ interface KTBaseAttribute {
|
|
|
63
63
|
// # normal HTML attributes
|
|
64
64
|
id?: string;
|
|
65
65
|
class?: string;
|
|
66
|
+
className?: string;
|
|
66
67
|
style?: string | Partial<CSSStyleDeclaration>;
|
|
67
68
|
|
|
68
69
|
type?:
|
|
@@ -157,7 +158,7 @@ type HTML<T extends (HTMLTag | SVGTag) & otherstring> = T extends SVGTag ? SVGEl
|
|
|
157
158
|
* ## About
|
|
158
159
|
* @package @ktjs/core
|
|
159
160
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
160
|
-
* @version 0.17.
|
|
161
|
+
* @version 0.17.3 (Last Update: 2026.01.28 16:50:39.470)
|
|
161
162
|
* @license MIT
|
|
162
163
|
* @link https://github.com/baendlorel/kt.js
|
|
163
164
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
package/dist/jsx/index.mjs
CHANGED
|
@@ -53,7 +53,7 @@ const ktEventHandlers = {
|
|
|
53
53
|
|
|
54
54
|
const defaultHandler = (element, key, value) => element.setAttribute(key, value);
|
|
55
55
|
function attrIsObject(element, attr) {
|
|
56
|
-
const classValue = attr.class;
|
|
56
|
+
const classValue = attr.class || attr.className;
|
|
57
57
|
if (classValue !== undefined) {
|
|
58
58
|
element.setAttribute('class', classValue);
|
|
59
59
|
}
|
|
@@ -69,7 +69,12 @@ function attrIsObject(element, attr) {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
for (const key in attr) {
|
|
72
|
-
if (key === 'class' ||
|
|
72
|
+
if (key === 'class' ||
|
|
73
|
+
key === 'className' ||
|
|
74
|
+
key === 'style' ||
|
|
75
|
+
key === 'children' ||
|
|
76
|
+
key === 'k-if' ||
|
|
77
|
+
key === 'ref') {
|
|
73
78
|
continue;
|
|
74
79
|
}
|
|
75
80
|
const o = attr[key];
|
|
@@ -208,7 +213,7 @@ let creator = defaultCreator;
|
|
|
208
213
|
* ## About
|
|
209
214
|
* @package @ktjs/core
|
|
210
215
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
211
|
-
* @version 0.17.
|
|
216
|
+
* @version 0.17.3 (Last Update: 2026.01.28 16:50:39.470)
|
|
212
217
|
* @license MIT
|
|
213
218
|
* @link https://github.com/baendlorel/kt.js
|
|
214
219
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -57,6 +57,7 @@ interface KTBaseAttribute {
|
|
|
57
57
|
// # normal HTML attributes
|
|
58
58
|
id?: string;
|
|
59
59
|
class?: string;
|
|
60
|
+
className?: string;
|
|
60
61
|
style?: string | Partial<CSSStyleDeclaration>;
|
|
61
62
|
|
|
62
63
|
type?:
|
|
@@ -151,7 +152,7 @@ type HTML<T extends (HTMLTag | SVGTag) & otherstring> = T extends SVGTag ? SVGEl
|
|
|
151
152
|
* ## About
|
|
152
153
|
* @package @ktjs/core
|
|
153
154
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
154
|
-
* @version 0.17.
|
|
155
|
+
* @version 0.17.3 (Last Update: 2026.01.28 16:50:39.470)
|
|
155
156
|
* @license MIT
|
|
156
157
|
* @link https://github.com/baendlorel/kt.js
|
|
157
158
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
package/dist/jsx/jsx-runtime.mjs
CHANGED
|
@@ -53,7 +53,7 @@ const ktEventHandlers = {
|
|
|
53
53
|
|
|
54
54
|
const defaultHandler = (element, key, value) => element.setAttribute(key, value);
|
|
55
55
|
function attrIsObject(element, attr) {
|
|
56
|
-
const classValue = attr.class;
|
|
56
|
+
const classValue = attr.class || attr.className;
|
|
57
57
|
if (classValue !== undefined) {
|
|
58
58
|
element.setAttribute('class', classValue);
|
|
59
59
|
}
|
|
@@ -69,7 +69,12 @@ function attrIsObject(element, attr) {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
for (const key in attr) {
|
|
72
|
-
if (key === 'class' ||
|
|
72
|
+
if (key === 'class' ||
|
|
73
|
+
key === 'className' ||
|
|
74
|
+
key === 'style' ||
|
|
75
|
+
key === 'children' ||
|
|
76
|
+
key === 'k-if' ||
|
|
77
|
+
key === 'ref') {
|
|
73
78
|
continue;
|
|
74
79
|
}
|
|
75
80
|
const o = attr[key];
|
|
@@ -208,7 +213,7 @@ let creator = defaultCreator;
|
|
|
208
213
|
* ## About
|
|
209
214
|
* @package @ktjs/core
|
|
210
215
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
211
|
-
* @version 0.17.
|
|
216
|
+
* @version 0.17.3 (Last Update: 2026.01.28 16:50:39.470)
|
|
212
217
|
* @license MIT
|
|
213
218
|
* @link https://github.com/baendlorel/kt.js
|
|
214
219
|
* @link https://baendlorel.github.io/ Welcome to my site!
|