@ktjs/core 0.22.5 → 0.24.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/dist/index.d.ts +227 -298
- package/dist/index.iife.js +295 -145
- package/dist/index.legacy.js +291 -143
- package/dist/index.mjs +290 -145
- package/dist/jsx/index.d.ts +180 -322
- package/dist/jsx/index.mjs +145 -145
- package/dist/jsx/jsx-runtime.d.ts +20 -8
- package/dist/jsx/jsx-runtime.mjs +144 -98
- package/package.json +2 -2
package/dist/jsx/jsx-runtime.mjs
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
|
+
// Shared constants
|
|
2
|
+
// Empty for now - can be extended with framework-wide constants
|
|
3
|
+
/**
|
|
4
|
+
* Mark the attribute as SVG to handle special cases during rendering.
|
|
5
|
+
*/
|
|
6
|
+
const SVG_ATTR_FLAG = '__kt_svg__';
|
|
7
|
+
/**
|
|
8
|
+
* Mark the attribute as MathML to handle special cases during rendering.
|
|
9
|
+
*/
|
|
10
|
+
const MATHML_ATTR_FLAG = '__kt_mathml__';
|
|
11
|
+
|
|
1
12
|
// Cached native methods for performance optimization
|
|
2
13
|
const $isArray = Array.isArray;
|
|
3
|
-
const $
|
|
14
|
+
const $is = Object.is;
|
|
15
|
+
const $random = Math.random;
|
|
16
|
+
const $isThenable = (o) => typeof o?.then === 'function';
|
|
4
17
|
|
|
5
18
|
// DOM manipulation utilities
|
|
6
19
|
// # dom natives
|
|
20
|
+
const $isNode = (x) => x?.nodeType > 0;
|
|
21
|
+
/**
|
|
22
|
+
* Safe replace `oldNode` With `newNode`
|
|
23
|
+
*/
|
|
24
|
+
const $replaceNode = (oldNode, newNode) => {
|
|
25
|
+
if ($isNode(oldNode) && $isNode(newNode)) {
|
|
26
|
+
if (newNode.contains(oldNode)) {
|
|
27
|
+
newNode.remove();
|
|
28
|
+
}
|
|
29
|
+
oldNode.replaceWith(newNode);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
7
32
|
/**
|
|
8
33
|
* & Remove `bind` because it is shockingly slower than wrapper
|
|
9
34
|
* & `window.document` is safe because it is not configurable and its setter is undefined
|
|
@@ -49,84 +74,21 @@ const applyModel = (element, valueRef, propName, eventName) => {
|
|
|
49
74
|
element.addEventListener(eventName, () => (valueRef.value = element[propName]));
|
|
50
75
|
};
|
|
51
76
|
|
|
77
|
+
if (typeof Symbol === 'undefined') {
|
|
78
|
+
window.Symbol = function Symbol(description) {
|
|
79
|
+
return `@@SYMBOL_${description || ''}_${$random().toString(36).slice(2)}`;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
52
83
|
// Shared utilities and cached native methods for kt.js framework
|
|
53
|
-
|
|
54
|
-
Object.defineProperty(window, '__ktjs__', { value: '0.22.2' });
|
|
84
|
+
Object.defineProperty(window, '__ktjs__', { value: '0.22.6' });
|
|
55
85
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
* @internal
|
|
63
|
-
*/
|
|
64
|
-
_value;
|
|
65
|
-
/**
|
|
66
|
-
* @internal
|
|
67
|
-
*/
|
|
68
|
-
_onChanges;
|
|
69
|
-
constructor(_value, _onChanges) {
|
|
70
|
-
this._value = _value;
|
|
71
|
-
this._onChanges = _onChanges;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
75
|
-
*/
|
|
76
|
-
get value() {
|
|
77
|
-
return this._value;
|
|
78
|
-
}
|
|
79
|
-
set value(newValue) {
|
|
80
|
-
if (newValue === this._value) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
// replace the old node with the new one in the DOM if both are nodes
|
|
84
|
-
if (this._value instanceof Node && newValue instanceof Node) {
|
|
85
|
-
if (newValue.contains(this._value)) {
|
|
86
|
-
this._value.remove();
|
|
87
|
-
}
|
|
88
|
-
this._value.replaceWith(newValue);
|
|
89
|
-
}
|
|
90
|
-
const oldValue = this._value;
|
|
91
|
-
this._value = newValue;
|
|
92
|
-
for (let i = 0; i < this._onChanges.length; i++) {
|
|
93
|
-
this._onChanges[i](newValue, oldValue);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Register a callback when the value changes
|
|
98
|
-
* @param callback (newValue, oldValue) => xxx
|
|
99
|
-
*/
|
|
100
|
-
addOnChange(callback) {
|
|
101
|
-
if (typeof callback !== 'function') {
|
|
102
|
-
throw new Error('[kt.js error] KTRef.addOnChange: callback must be a function');
|
|
103
|
-
}
|
|
104
|
-
this._onChanges.push(callback);
|
|
105
|
-
}
|
|
106
|
-
removeOnChange(callback) {
|
|
107
|
-
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
108
|
-
if (this._onChanges[i] === callback) {
|
|
109
|
-
this._onChanges.splice(i, 1);
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
const isKTRef = (obj) => obj?.isKT === true;
|
|
117
|
-
/**
|
|
118
|
-
* Reference to the created HTML element.
|
|
119
|
-
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
120
|
-
* - can alse be used to store normal values, but it is not reactive.
|
|
121
|
-
* - if the value is already a `KTRef`, it will be returned **directly**.
|
|
122
|
-
* @param value mostly an HTMLElement
|
|
123
|
-
*/
|
|
124
|
-
function ref(value, onChange) {
|
|
125
|
-
if (isKTRef(value)) {
|
|
126
|
-
return value;
|
|
127
|
-
}
|
|
128
|
-
return new KTRef(value, []);
|
|
129
|
-
}
|
|
86
|
+
// export const KT_TYPE_REF = 1 as const;
|
|
87
|
+
// export const KT_TYPE_COMPUTED = 2 as const;
|
|
88
|
+
// export type KTReactiveTypeEnum = typeof KT_TYPE_REF | typeof KT_TYPE_COMPUTED;
|
|
89
|
+
const isKT = (obj) => obj?.isKT;
|
|
90
|
+
const isRef = (obj) => obj?.ktType === 1 /* KTReactiveType.REF */;
|
|
91
|
+
const isComputed = (obj) => obj?.ktType === 2 /* KTReactiveType.COMPUTED */;
|
|
130
92
|
|
|
131
93
|
const booleanHandler = (element, key, value) => {
|
|
132
94
|
if (key in element) {
|
|
@@ -186,14 +148,25 @@ function attrIsObject(element, attr) {
|
|
|
186
148
|
}
|
|
187
149
|
}
|
|
188
150
|
}
|
|
151
|
+
if ('k-html' in attr) {
|
|
152
|
+
const html = attr['k-html'];
|
|
153
|
+
if (isKT(html)) {
|
|
154
|
+
element.innerHTML = html.value;
|
|
155
|
+
html.addOnChange((v) => (element.innerHTML = v));
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
element.innerHTML = html;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
189
161
|
for (const key in attr) {
|
|
190
|
-
if (key === '
|
|
162
|
+
if (key === 'k-if' ||
|
|
163
|
+
key === 'k-model' ||
|
|
164
|
+
key === 'ref' ||
|
|
165
|
+
key === 'class' ||
|
|
191
166
|
key === 'className' ||
|
|
192
167
|
key === 'style' ||
|
|
193
168
|
key === 'children' ||
|
|
194
|
-
key === 'k-
|
|
195
|
-
key.startsWith('k-model') ||
|
|
196
|
-
key === 'ref') {
|
|
169
|
+
key === 'k-html') {
|
|
197
170
|
continue;
|
|
198
171
|
}
|
|
199
172
|
const o = attr[key];
|
|
@@ -203,6 +176,7 @@ function attrIsObject(element, attr) {
|
|
|
203
176
|
}
|
|
204
177
|
// normal attributes
|
|
205
178
|
else {
|
|
179
|
+
// todo 这里也可以绑定ref的
|
|
206
180
|
(handlers[key] || defaultHandler)(element, key, o);
|
|
207
181
|
}
|
|
208
182
|
}
|
|
@@ -219,13 +193,25 @@ function applyAttr(element, attr) {
|
|
|
219
193
|
}
|
|
220
194
|
}
|
|
221
195
|
|
|
196
|
+
const assureNode = (o) => ($isNode(o) ? o : document.createTextNode(o));
|
|
222
197
|
function apdSingle(element, c) {
|
|
223
198
|
// & JSX should ignore false, undefined, and null
|
|
224
199
|
if (c === false || c === undefined || c === null) {
|
|
225
200
|
return;
|
|
226
201
|
}
|
|
227
|
-
if (
|
|
228
|
-
|
|
202
|
+
if (isKT(c)) {
|
|
203
|
+
let node = assureNode(c.value);
|
|
204
|
+
$append.call(element, node);
|
|
205
|
+
c.addOnChange((newValue, oldValue) => {
|
|
206
|
+
if ($isNode(newValue) && $isNode(oldValue)) {
|
|
207
|
+
// & this case is handled automically in `class KTRef`
|
|
208
|
+
// todo 2 cases might be able to merge into 1
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const oldNode = node;
|
|
212
|
+
node = assureNode(newValue);
|
|
213
|
+
oldNode.replaceWith(node);
|
|
214
|
+
});
|
|
229
215
|
}
|
|
230
216
|
else {
|
|
231
217
|
$append.call(element, c);
|
|
@@ -270,8 +256,74 @@ function applyContent(element, content) {
|
|
|
270
256
|
}
|
|
271
257
|
}
|
|
272
258
|
|
|
259
|
+
class KTRef {
|
|
260
|
+
/**
|
|
261
|
+
* Indicates that this is a KTRef instance
|
|
262
|
+
*/
|
|
263
|
+
isKT = true;
|
|
264
|
+
ktType = 1 /* KTReactiveType.REF */;
|
|
265
|
+
/**
|
|
266
|
+
* @internal
|
|
267
|
+
*/
|
|
268
|
+
_value;
|
|
269
|
+
/**
|
|
270
|
+
* @internal
|
|
271
|
+
*/
|
|
272
|
+
_onChanges;
|
|
273
|
+
constructor(_value, _onChanges) {
|
|
274
|
+
this._value = _value;
|
|
275
|
+
this._onChanges = _onChanges;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
279
|
+
*/
|
|
280
|
+
get value() {
|
|
281
|
+
return this._value;
|
|
282
|
+
}
|
|
283
|
+
set value(newValue) {
|
|
284
|
+
if ($is(newValue, this._value)) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const oldValue = this._value;
|
|
288
|
+
$replaceNode(oldValue, newValue);
|
|
289
|
+
this._value = newValue;
|
|
290
|
+
for (let i = 0; i < this._onChanges.length; i++) {
|
|
291
|
+
this._onChanges[i](newValue, oldValue);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Register a callback when the value changes
|
|
296
|
+
* @param callback (newValue, oldValue) => xxx
|
|
297
|
+
*/
|
|
298
|
+
addOnChange(callback) {
|
|
299
|
+
if (typeof callback !== 'function') {
|
|
300
|
+
throw new Error('[kt.js error] KTRef.addOnChange: callback must be a function');
|
|
301
|
+
}
|
|
302
|
+
this._onChanges.push(callback);
|
|
303
|
+
}
|
|
304
|
+
removeOnChange(callback) {
|
|
305
|
+
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
306
|
+
if (this._onChanges[i] === callback) {
|
|
307
|
+
this._onChanges.splice(i, 1);
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Reference to the created HTML element.
|
|
316
|
+
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
317
|
+
* - can alse be used to store normal values, but it is not reactive.
|
|
318
|
+
* - if the value is already a `KTRef`, it will be returned **directly**.
|
|
319
|
+
* @param value mostly an HTMLElement
|
|
320
|
+
*/
|
|
321
|
+
function ref(value, onChange) {
|
|
322
|
+
return new KTRef(value, []);
|
|
323
|
+
}
|
|
324
|
+
|
|
273
325
|
function applyKModel(element, valueRef) {
|
|
274
|
-
if (!
|
|
326
|
+
if (!isKT(valueRef)) {
|
|
275
327
|
console.warn('[kt.js warn] k-model value must be a KTRef.');
|
|
276
328
|
return;
|
|
277
329
|
}
|
|
@@ -298,9 +350,6 @@ const htmlCreator = (tag) => document.createElement(tag);
|
|
|
298
350
|
const svgCreator = (tag) => document.createElementNS('http://www.w3.org/2000/svg', tag);
|
|
299
351
|
const mathMLCreator = (tag) => document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
|
|
300
352
|
let creator = htmlCreator;
|
|
301
|
-
// # consts
|
|
302
|
-
const SVG_ATTR_FLAG = '__kt_svg__';
|
|
303
|
-
const MATHML_ATTR_FLAG = '__kt_mathml__';
|
|
304
353
|
/**
|
|
305
354
|
* Create an enhanced HTMLElement.
|
|
306
355
|
* - Only supports HTMLElements, **NOT** SVGElements or other Elements.
|
|
@@ -311,7 +360,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
|
|
|
311
360
|
* ## About
|
|
312
361
|
* @package @ktjs/core
|
|
313
362
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
314
|
-
* @version 0.
|
|
363
|
+
* @version 0.24.0 (Last Update: 2026.02.05 12:08:54.164)
|
|
315
364
|
* @license MIT
|
|
316
365
|
* @link https://github.com/baendlorel/kt.js
|
|
317
366
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -341,13 +390,7 @@ const h = (tag, attr, content) => {
|
|
|
341
390
|
applyAttr(element, attr);
|
|
342
391
|
applyContent(element, content);
|
|
343
392
|
if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
|
|
344
|
-
|
|
345
|
-
if (isKTRef(kmodel)) {
|
|
346
|
-
applyKModel(element, kmodel);
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
throw new Error('[kt.js error] k-model value must be a KTRef.');
|
|
350
|
-
}
|
|
393
|
+
applyKModel(element, attr['k-model']);
|
|
351
394
|
}
|
|
352
395
|
return element;
|
|
353
396
|
};
|
|
@@ -367,20 +410,23 @@ const placeholder = () => document.createComment('k-if');
|
|
|
367
410
|
* @param props properties/attributes
|
|
368
411
|
*/
|
|
369
412
|
function jsx(tag, props) {
|
|
370
|
-
|
|
413
|
+
if (isComputed(props.ref)) {
|
|
414
|
+
throw new Error('[kt.js error] Cannot assign a computed value to an element.');
|
|
415
|
+
}
|
|
416
|
+
const maybeDummyRef = isRef(props.ref) ? props.ref : dummyRef;
|
|
371
417
|
let el;
|
|
372
418
|
if ('k-if' in props) {
|
|
373
419
|
const kif = props['k-if'];
|
|
374
420
|
let condition = kif; // assume boolean by default
|
|
375
421
|
// Handle reactive k-if
|
|
376
|
-
if (
|
|
422
|
+
if (isKT(kif)) {
|
|
377
423
|
kif.addOnChange((newValue, oldValue) => {
|
|
378
424
|
if (newValue === oldValue) {
|
|
379
425
|
return;
|
|
380
426
|
}
|
|
381
427
|
const oldEl = el;
|
|
382
428
|
el = newValue ? create(tag, props) : placeholder();
|
|
383
|
-
oldEl
|
|
429
|
+
$replaceNode(oldEl, el);
|
|
384
430
|
maybeDummyRef.value = el;
|
|
385
431
|
});
|
|
386
432
|
condition = kif.value;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ktjs/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Core functionality for kt.js - DOM manipulation utilities with JSX/TSX support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"directory": "packages/core"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@ktjs/shared": "0.22.
|
|
47
|
+
"@ktjs/shared": "0.22.6"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "rollup -c rollup.config.mjs",
|