@ktjs/core 0.21.1 → 0.22.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 +6 -3
- package/dist/index.iife.js +123 -94
- package/dist/index.legacy.js +120 -91
- package/dist/index.mjs +123 -94
- package/dist/jsx/index.d.ts +6 -3
- package/dist/jsx/index.mjs +123 -94
- package/dist/jsx/jsx-runtime.d.ts +6 -3
- package/dist/jsx/jsx-runtime.mjs +99 -70
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -72,12 +72,15 @@ interface KTBaseAttribute {
|
|
|
72
72
|
// # kt-specific attributes
|
|
73
73
|
ref?: KTRef<JSX.Element>;
|
|
74
74
|
|
|
75
|
-
// todo 是否要让k-if是KTRef的时候具备响应能力?
|
|
76
75
|
/**
|
|
77
76
|
* If a `KTRef` is bound, it will be reactive; otherwise, it will be static.
|
|
78
77
|
*/
|
|
79
78
|
'k-if'?: any;
|
|
80
|
-
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Register two-way data binding between an input element and a KTRef.
|
|
82
|
+
* - Default to regist `input` event and `value` property(`checked` for checkboxes and radios).
|
|
83
|
+
*/
|
|
81
84
|
'k-model'?: KTRef<any>;
|
|
82
85
|
|
|
83
86
|
// # normal HTML attributes
|
|
@@ -157,7 +160,7 @@ type KTComponent = (
|
|
|
157
160
|
* ## About
|
|
158
161
|
* @package @ktjs/core
|
|
159
162
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
160
|
-
* @version 0.
|
|
163
|
+
* @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
|
|
161
164
|
* @license MIT
|
|
162
165
|
* @link https://github.com/baendlorel/kt.js
|
|
163
166
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
package/dist/index.iife.js
CHANGED
|
@@ -10,10 +10,6 @@ var __ktjs_core__ = (function (exports) {
|
|
|
10
10
|
const $throw = (message) => {
|
|
11
11
|
throw new Error('@ktjs/shared: ' + message);
|
|
12
12
|
};
|
|
13
|
-
|
|
14
|
-
// DOM manipulation utilities
|
|
15
|
-
// # dom natives
|
|
16
|
-
const $replaceWith = Element.prototype.replaceWith;
|
|
17
13
|
/**
|
|
18
14
|
* & Remove `bind` because it is shockingly slower than wrapper
|
|
19
15
|
* & `window.document` is safe because it is not configurable and its setter is undefined
|
|
@@ -55,6 +51,96 @@ var __ktjs_core__ = (function (exports) {
|
|
|
55
51
|
// Re-export all utilities
|
|
56
52
|
Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
|
|
57
53
|
|
|
54
|
+
class KTRef {
|
|
55
|
+
/**
|
|
56
|
+
* Indicates that this is a KTRef instance
|
|
57
|
+
*/
|
|
58
|
+
isKT = true;
|
|
59
|
+
/**
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
_value;
|
|
63
|
+
/**
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
_onChanges;
|
|
67
|
+
constructor(_value, _onChanges) {
|
|
68
|
+
this._value = _value;
|
|
69
|
+
this._onChanges = _onChanges;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
73
|
+
*/
|
|
74
|
+
get value() {
|
|
75
|
+
return this._value;
|
|
76
|
+
}
|
|
77
|
+
set value(newValue) {
|
|
78
|
+
if (newValue === this._value) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// replace the old node with the new one in the DOM if both are nodes
|
|
82
|
+
if (this._value instanceof Node && newValue instanceof Node) {
|
|
83
|
+
if (newValue.contains(this._value)) {
|
|
84
|
+
this._value.remove();
|
|
85
|
+
}
|
|
86
|
+
this._value.replaceWith(newValue);
|
|
87
|
+
}
|
|
88
|
+
const oldValue = this._value;
|
|
89
|
+
this._value = newValue;
|
|
90
|
+
for (let i = 0; i < this._onChanges.length; i++) {
|
|
91
|
+
this._onChanges[i](newValue, oldValue);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
addOnChange(callback) {
|
|
95
|
+
this._onChanges.push(callback);
|
|
96
|
+
}
|
|
97
|
+
removeOnChange(callback) {
|
|
98
|
+
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
99
|
+
if (this._onChanges[i] === callback) {
|
|
100
|
+
this._onChanges.splice(i, 1);
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const isKTRef = (obj) => {
|
|
108
|
+
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Reference to the created HTML element.
|
|
112
|
+
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
113
|
+
* - can alse be used to store normal values, but it is not reactive.
|
|
114
|
+
* @param value mostly an HTMLElement
|
|
115
|
+
*/
|
|
116
|
+
function ref(value, onChange) {
|
|
117
|
+
return new KTRef(value, onChange ? [onChange] : []);
|
|
118
|
+
}
|
|
119
|
+
function kcollect() {
|
|
120
|
+
const newObj = {};
|
|
121
|
+
const entries = $entries(this);
|
|
122
|
+
for (let i = 0; i < entries.length; i++) {
|
|
123
|
+
const key = entries[i][0];
|
|
124
|
+
if (key === 'kcollect') {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
newObj[key] = entries[i][1].value;
|
|
128
|
+
}
|
|
129
|
+
return newObj;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Make all first-level properties of the object a `KTRef`.
|
|
133
|
+
* - `obj.a.b` is not reactive
|
|
134
|
+
*/
|
|
135
|
+
const surfaceRef = (obj) => {
|
|
136
|
+
const entries = $entries(obj);
|
|
137
|
+
const newObj = { kcollect };
|
|
138
|
+
for (let i = 0; i < entries.length; i++) {
|
|
139
|
+
newObj[entries[i][0]] = ref(entries[i][1]);
|
|
140
|
+
}
|
|
141
|
+
return newObj;
|
|
142
|
+
};
|
|
143
|
+
|
|
58
144
|
const booleanHandler = (element, key, value) => {
|
|
59
145
|
if (key in element) {
|
|
60
146
|
element[key] = !!value;
|
|
@@ -119,6 +205,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
119
205
|
key === 'style' ||
|
|
120
206
|
key === 'children' ||
|
|
121
207
|
key === 'k-if' ||
|
|
208
|
+
key.startsWith('k-model') ||
|
|
122
209
|
key === 'ref') {
|
|
123
210
|
continue;
|
|
124
211
|
}
|
|
@@ -196,6 +283,29 @@ var __ktjs_core__ = (function (exports) {
|
|
|
196
283
|
}
|
|
197
284
|
}
|
|
198
285
|
|
|
286
|
+
function register(element, valueRef, propName, eventName) {
|
|
287
|
+
element[propName] = valueRef.value; // initialize
|
|
288
|
+
valueRef.addOnChange((newValue) => (element[propName] = newValue));
|
|
289
|
+
element.addEventListener(eventName, () => (valueRef.value = element[propName]));
|
|
290
|
+
}
|
|
291
|
+
function applyModel(element, valueRef) {
|
|
292
|
+
if (element instanceof HTMLInputElement) {
|
|
293
|
+
if (element.type === 'radio' || element.type === 'checkbox') {
|
|
294
|
+
register(element, valueRef, 'checked', 'change');
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
register(element, valueRef, 'value', 'input');
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else if (element instanceof HTMLSelectElement) {
|
|
301
|
+
register(element, valueRef, 'value', 'change');
|
|
302
|
+
}
|
|
303
|
+
else if (element instanceof HTMLTextAreaElement) {
|
|
304
|
+
register(element, valueRef, 'value', 'input');
|
|
305
|
+
}
|
|
306
|
+
console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
|
|
307
|
+
}
|
|
308
|
+
|
|
199
309
|
const htmlCreator = (tag) => document.createElement(tag);
|
|
200
310
|
const svgCreator = (tag) => document.createElementNS('http://www.w3.org/2000/svg', tag);
|
|
201
311
|
const mathMLCreator = (tag) => document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
|
|
@@ -213,7 +323,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
213
323
|
* ## About
|
|
214
324
|
* @package @ktjs/core
|
|
215
325
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
216
|
-
* @version 0.
|
|
326
|
+
* @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
|
|
217
327
|
* @license MIT
|
|
218
328
|
* @link https://github.com/baendlorel/kt.js
|
|
219
329
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -242,97 +352,16 @@ var __ktjs_core__ = (function (exports) {
|
|
|
242
352
|
// * Handle content
|
|
243
353
|
applyAttr(element, attr);
|
|
244
354
|
applyContent(element, content);
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Indicates that this is a KTRef instance
|
|
251
|
-
*/
|
|
252
|
-
isKT = true;
|
|
253
|
-
/**
|
|
254
|
-
* @internal
|
|
255
|
-
*/
|
|
256
|
-
_value;
|
|
257
|
-
/**
|
|
258
|
-
* @internal
|
|
259
|
-
*/
|
|
260
|
-
_onChanges;
|
|
261
|
-
constructor(_value, _onChanges) {
|
|
262
|
-
this._value = _value;
|
|
263
|
-
this._onChanges = _onChanges;
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
267
|
-
*/
|
|
268
|
-
get value() {
|
|
269
|
-
return this._value;
|
|
270
|
-
}
|
|
271
|
-
set value(newValue) {
|
|
272
|
-
if (newValue === this._value) {
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
// replace the old node with the new one in the DOM if both are nodes
|
|
276
|
-
if (this._value instanceof Node && newValue instanceof Node) {
|
|
277
|
-
if (newValue.contains(this._value)) {
|
|
278
|
-
this._value.remove();
|
|
279
|
-
}
|
|
280
|
-
this._value.replaceWith(newValue);
|
|
281
|
-
}
|
|
282
|
-
const oldValue = this._value;
|
|
283
|
-
this._value = newValue;
|
|
284
|
-
for (let i = 0; i < this._onChanges.length; i++) {
|
|
285
|
-
this._onChanges[i](newValue, oldValue);
|
|
355
|
+
if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
|
|
356
|
+
const kmodel = attr['k-model'];
|
|
357
|
+
if (isKTRef(kmodel)) {
|
|
358
|
+
applyModel(element, kmodel);
|
|
286
359
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
this._onChanges.push(callback);
|
|
290
|
-
}
|
|
291
|
-
removeOnChange(callback) {
|
|
292
|
-
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
293
|
-
if (this._onChanges[i] === callback) {
|
|
294
|
-
this._onChanges.splice(i, 1);
|
|
295
|
-
return true;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return false;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
const isKTRef = (obj) => {
|
|
302
|
-
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
303
|
-
};
|
|
304
|
-
/**
|
|
305
|
-
* Reference to the created HTML element.
|
|
306
|
-
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
307
|
-
* - can alse be used to store normal values, but it is not reactive.
|
|
308
|
-
* @param value mostly an HTMLElement
|
|
309
|
-
*/
|
|
310
|
-
function ref(value, onChange) {
|
|
311
|
-
return new KTRef(value, onChange ? [onChange] : []);
|
|
312
|
-
}
|
|
313
|
-
function kcollect() {
|
|
314
|
-
const newObj = {};
|
|
315
|
-
const entries = $entries(this);
|
|
316
|
-
for (let i = 0; i < entries.length; i++) {
|
|
317
|
-
const key = entries[i][0];
|
|
318
|
-
if (key === 'kcollect') {
|
|
319
|
-
continue;
|
|
360
|
+
else {
|
|
361
|
+
$throw('k-model value must be a KTRef.');
|
|
320
362
|
}
|
|
321
|
-
newObj[key] = entries[i][1].value;
|
|
322
363
|
}
|
|
323
|
-
return
|
|
324
|
-
}
|
|
325
|
-
/**
|
|
326
|
-
* Make all first-level properties of the object a `KTRef`.
|
|
327
|
-
* - `obj.a.b` is not reactive
|
|
328
|
-
*/
|
|
329
|
-
const surfaceRef = (obj) => {
|
|
330
|
-
const entries = $entries(obj);
|
|
331
|
-
const newObj = { kcollect };
|
|
332
|
-
for (let i = 0; i < entries.length; i++) {
|
|
333
|
-
newObj[entries[i][0]] = ref(entries[i][1]);
|
|
334
|
-
}
|
|
335
|
-
return newObj;
|
|
364
|
+
return element;
|
|
336
365
|
};
|
|
337
366
|
|
|
338
367
|
const dummyRef = { value: null };
|
|
@@ -363,7 +392,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
363
392
|
}
|
|
364
393
|
const oldEl = el;
|
|
365
394
|
el = newValue ? create(tag, props) : placeholder();
|
|
366
|
-
|
|
395
|
+
oldEl.replaceWith(el);
|
|
367
396
|
maybeDummyRef.value = el;
|
|
368
397
|
});
|
|
369
398
|
condition = kif.value;
|
package/dist/index.legacy.js
CHANGED
|
@@ -10,10 +10,6 @@ var __ktjs_core__ = (function (exports) {
|
|
|
10
10
|
const $throw = (message) => {
|
|
11
11
|
throw new Error('@ktjs/shared: ' + message);
|
|
12
12
|
};
|
|
13
|
-
|
|
14
|
-
// DOM manipulation utilities
|
|
15
|
-
// # dom natives
|
|
16
|
-
const $replaceWith = Element.prototype.replaceWith;
|
|
17
13
|
/**
|
|
18
14
|
* & Remove `bind` because it is shockingly slower than wrapper
|
|
19
15
|
* & `window.document` is safe because it is not configurable and its setter is undefined
|
|
@@ -55,6 +51,93 @@ var __ktjs_core__ = (function (exports) {
|
|
|
55
51
|
// Re-export all utilities
|
|
56
52
|
Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
|
|
57
53
|
|
|
54
|
+
var KTRef = /** @class */ (function () {
|
|
55
|
+
function KTRef(_value, _onChanges) {
|
|
56
|
+
/**
|
|
57
|
+
* Indicates that this is a KTRef instance
|
|
58
|
+
*/
|
|
59
|
+
this.isKT = true;
|
|
60
|
+
this._value = _value;
|
|
61
|
+
this._onChanges = _onChanges;
|
|
62
|
+
}
|
|
63
|
+
Object.defineProperty(KTRef.prototype, "value", {
|
|
64
|
+
/**
|
|
65
|
+
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
66
|
+
*/
|
|
67
|
+
get: function () {
|
|
68
|
+
return this._value;
|
|
69
|
+
},
|
|
70
|
+
set: function (newValue) {
|
|
71
|
+
if (newValue === this._value) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// replace the old node with the new one in the DOM if both are nodes
|
|
75
|
+
if (this._value instanceof Node && newValue instanceof Node) {
|
|
76
|
+
if (newValue.contains(this._value)) {
|
|
77
|
+
this._value.remove();
|
|
78
|
+
}
|
|
79
|
+
this._value.replaceWith(newValue);
|
|
80
|
+
}
|
|
81
|
+
var oldValue = this._value;
|
|
82
|
+
this._value = newValue;
|
|
83
|
+
for (var i = 0; i < this._onChanges.length; i++) {
|
|
84
|
+
this._onChanges[i](newValue, oldValue);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
enumerable: false,
|
|
88
|
+
configurable: true
|
|
89
|
+
});
|
|
90
|
+
KTRef.prototype.addOnChange = function (callback) {
|
|
91
|
+
this._onChanges.push(callback);
|
|
92
|
+
};
|
|
93
|
+
KTRef.prototype.removeOnChange = function (callback) {
|
|
94
|
+
for (var i = this._onChanges.length - 1; i >= 0; i--) {
|
|
95
|
+
if (this._onChanges[i] === callback) {
|
|
96
|
+
this._onChanges.splice(i, 1);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
};
|
|
102
|
+
return KTRef;
|
|
103
|
+
}());
|
|
104
|
+
var isKTRef = function (obj) {
|
|
105
|
+
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Reference to the created HTML element.
|
|
109
|
+
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
110
|
+
* - can alse be used to store normal values, but it is not reactive.
|
|
111
|
+
* @param value mostly an HTMLElement
|
|
112
|
+
*/
|
|
113
|
+
function ref(value, onChange) {
|
|
114
|
+
return new KTRef(value, onChange ? [onChange] : []);
|
|
115
|
+
}
|
|
116
|
+
function kcollect() {
|
|
117
|
+
var newObj = {};
|
|
118
|
+
var entries = $entries(this);
|
|
119
|
+
for (var i = 0; i < entries.length; i++) {
|
|
120
|
+
var key = entries[i][0];
|
|
121
|
+
if (key === 'kcollect') {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
newObj[key] = entries[i][1].value;
|
|
125
|
+
}
|
|
126
|
+
return newObj;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Make all first-level properties of the object a `KTRef`.
|
|
130
|
+
* - `obj.a.b` is not reactive
|
|
131
|
+
*/
|
|
132
|
+
var surfaceRef = function (obj) {
|
|
133
|
+
var entries = $entries(obj);
|
|
134
|
+
var newObj = { kcollect: kcollect };
|
|
135
|
+
for (var i = 0; i < entries.length; i++) {
|
|
136
|
+
newObj[entries[i][0]] = ref(entries[i][1]);
|
|
137
|
+
}
|
|
138
|
+
return newObj;
|
|
139
|
+
};
|
|
140
|
+
|
|
58
141
|
var booleanHandler = function (element, key, value) {
|
|
59
142
|
if (key in element) {
|
|
60
143
|
element[key] = !!value;
|
|
@@ -121,6 +204,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
121
204
|
key === 'style' ||
|
|
122
205
|
key === 'children' ||
|
|
123
206
|
key === 'k-if' ||
|
|
207
|
+
key.startsWith('k-model') ||
|
|
124
208
|
key === 'ref') {
|
|
125
209
|
continue;
|
|
126
210
|
}
|
|
@@ -201,6 +285,29 @@ var __ktjs_core__ = (function (exports) {
|
|
|
201
285
|
}
|
|
202
286
|
}
|
|
203
287
|
|
|
288
|
+
function register(element, valueRef, propName, eventName) {
|
|
289
|
+
element[propName] = valueRef.value; // initialize
|
|
290
|
+
valueRef.addOnChange(function (newValue) { return (element[propName] = newValue); });
|
|
291
|
+
element.addEventListener(eventName, function () { return (valueRef.value = element[propName]); });
|
|
292
|
+
}
|
|
293
|
+
function applyModel(element, valueRef) {
|
|
294
|
+
if (element instanceof HTMLInputElement) {
|
|
295
|
+
if (element.type === 'radio' || element.type === 'checkbox') {
|
|
296
|
+
register(element, valueRef, 'checked', 'change');
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
register(element, valueRef, 'value', 'input');
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
else if (element instanceof HTMLSelectElement) {
|
|
303
|
+
register(element, valueRef, 'value', 'change');
|
|
304
|
+
}
|
|
305
|
+
else if (element instanceof HTMLTextAreaElement) {
|
|
306
|
+
register(element, valueRef, 'value', 'input');
|
|
307
|
+
}
|
|
308
|
+
console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
|
|
309
|
+
}
|
|
310
|
+
|
|
204
311
|
var htmlCreator = function (tag) { return document.createElement(tag); };
|
|
205
312
|
var svgCreator = function (tag) { return document.createElementNS('http://www.w3.org/2000/svg', tag); };
|
|
206
313
|
var mathMLCreator = function (tag) { return document.createElementNS('http://www.w3.org/1998/Math/MathML', tag); };
|
|
@@ -218,7 +325,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
218
325
|
* ## About
|
|
219
326
|
* @package @ktjs/core
|
|
220
327
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
221
|
-
* @version 0.
|
|
328
|
+
* @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
|
|
222
329
|
* @license MIT
|
|
223
330
|
* @link https://github.com/baendlorel/kt.js
|
|
224
331
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -247,94 +354,16 @@ var __ktjs_core__ = (function (exports) {
|
|
|
247
354
|
// * Handle content
|
|
248
355
|
applyAttr(element, attr);
|
|
249
356
|
applyContent(element, content);
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
function KTRef(_value, _onChanges) {
|
|
255
|
-
/**
|
|
256
|
-
* Indicates that this is a KTRef instance
|
|
257
|
-
*/
|
|
258
|
-
this.isKT = true;
|
|
259
|
-
this._value = _value;
|
|
260
|
-
this._onChanges = _onChanges;
|
|
261
|
-
}
|
|
262
|
-
Object.defineProperty(KTRef.prototype, "value", {
|
|
263
|
-
/**
|
|
264
|
-
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
265
|
-
*/
|
|
266
|
-
get: function () {
|
|
267
|
-
return this._value;
|
|
268
|
-
},
|
|
269
|
-
set: function (newValue) {
|
|
270
|
-
if (newValue === this._value) {
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
// replace the old node with the new one in the DOM if both are nodes
|
|
274
|
-
if (this._value instanceof Node && newValue instanceof Node) {
|
|
275
|
-
if (newValue.contains(this._value)) {
|
|
276
|
-
this._value.remove();
|
|
277
|
-
}
|
|
278
|
-
this._value.replaceWith(newValue);
|
|
279
|
-
}
|
|
280
|
-
var oldValue = this._value;
|
|
281
|
-
this._value = newValue;
|
|
282
|
-
for (var i = 0; i < this._onChanges.length; i++) {
|
|
283
|
-
this._onChanges[i](newValue, oldValue);
|
|
284
|
-
}
|
|
285
|
-
},
|
|
286
|
-
enumerable: false,
|
|
287
|
-
configurable: true
|
|
288
|
-
});
|
|
289
|
-
KTRef.prototype.addOnChange = function (callback) {
|
|
290
|
-
this._onChanges.push(callback);
|
|
291
|
-
};
|
|
292
|
-
KTRef.prototype.removeOnChange = function (callback) {
|
|
293
|
-
for (var i = this._onChanges.length - 1; i >= 0; i--) {
|
|
294
|
-
if (this._onChanges[i] === callback) {
|
|
295
|
-
this._onChanges.splice(i, 1);
|
|
296
|
-
return true;
|
|
297
|
-
}
|
|
357
|
+
if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
|
|
358
|
+
var kmodel = attr['k-model'];
|
|
359
|
+
if (isKTRef(kmodel)) {
|
|
360
|
+
applyModel(element, kmodel);
|
|
298
361
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
return KTRef;
|
|
302
|
-
}());
|
|
303
|
-
var isKTRef = function (obj) {
|
|
304
|
-
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
305
|
-
};
|
|
306
|
-
/**
|
|
307
|
-
* Reference to the created HTML element.
|
|
308
|
-
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
309
|
-
* - can alse be used to store normal values, but it is not reactive.
|
|
310
|
-
* @param value mostly an HTMLElement
|
|
311
|
-
*/
|
|
312
|
-
function ref(value, onChange) {
|
|
313
|
-
return new KTRef(value, onChange ? [onChange] : []);
|
|
314
|
-
}
|
|
315
|
-
function kcollect() {
|
|
316
|
-
var newObj = {};
|
|
317
|
-
var entries = $entries(this);
|
|
318
|
-
for (var i = 0; i < entries.length; i++) {
|
|
319
|
-
var key = entries[i][0];
|
|
320
|
-
if (key === 'kcollect') {
|
|
321
|
-
continue;
|
|
362
|
+
else {
|
|
363
|
+
$throw('k-model value must be a KTRef.');
|
|
322
364
|
}
|
|
323
|
-
newObj[key] = entries[i][1].value;
|
|
324
365
|
}
|
|
325
|
-
return
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Make all first-level properties of the object a `KTRef`.
|
|
329
|
-
* - `obj.a.b` is not reactive
|
|
330
|
-
*/
|
|
331
|
-
var surfaceRef = function (obj) {
|
|
332
|
-
var entries = $entries(obj);
|
|
333
|
-
var newObj = { kcollect: kcollect };
|
|
334
|
-
for (var i = 0; i < entries.length; i++) {
|
|
335
|
-
newObj[entries[i][0]] = ref(entries[i][1]);
|
|
336
|
-
}
|
|
337
|
-
return newObj;
|
|
366
|
+
return element;
|
|
338
367
|
};
|
|
339
368
|
|
|
340
369
|
var dummyRef = { value: null };
|
|
@@ -365,7 +394,7 @@ var __ktjs_core__ = (function (exports) {
|
|
|
365
394
|
}
|
|
366
395
|
var oldEl = el;
|
|
367
396
|
el = newValue ? create(tag, props) : placeholder();
|
|
368
|
-
|
|
397
|
+
oldEl.replaceWith(el);
|
|
369
398
|
maybeDummyRef.value = el;
|
|
370
399
|
});
|
|
371
400
|
condition = kif.value;
|
package/dist/index.mjs
CHANGED
|
@@ -7,10 +7,6 @@ const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then
|
|
|
7
7
|
const $throw = (message) => {
|
|
8
8
|
throw new Error('@ktjs/shared: ' + message);
|
|
9
9
|
};
|
|
10
|
-
|
|
11
|
-
// DOM manipulation utilities
|
|
12
|
-
// # dom natives
|
|
13
|
-
const $replaceWith = Element.prototype.replaceWith;
|
|
14
10
|
/**
|
|
15
11
|
* & Remove `bind` because it is shockingly slower than wrapper
|
|
16
12
|
* & `window.document` is safe because it is not configurable and its setter is undefined
|
|
@@ -52,6 +48,96 @@ const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwn
|
|
|
52
48
|
// Re-export all utilities
|
|
53
49
|
Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
|
|
54
50
|
|
|
51
|
+
class KTRef {
|
|
52
|
+
/**
|
|
53
|
+
* Indicates that this is a KTRef instance
|
|
54
|
+
*/
|
|
55
|
+
isKT = true;
|
|
56
|
+
/**
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
_value;
|
|
60
|
+
/**
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
_onChanges;
|
|
64
|
+
constructor(_value, _onChanges) {
|
|
65
|
+
this._value = _value;
|
|
66
|
+
this._onChanges = _onChanges;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
70
|
+
*/
|
|
71
|
+
get value() {
|
|
72
|
+
return this._value;
|
|
73
|
+
}
|
|
74
|
+
set value(newValue) {
|
|
75
|
+
if (newValue === this._value) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// replace the old node with the new one in the DOM if both are nodes
|
|
79
|
+
if (this._value instanceof Node && newValue instanceof Node) {
|
|
80
|
+
if (newValue.contains(this._value)) {
|
|
81
|
+
this._value.remove();
|
|
82
|
+
}
|
|
83
|
+
this._value.replaceWith(newValue);
|
|
84
|
+
}
|
|
85
|
+
const oldValue = this._value;
|
|
86
|
+
this._value = newValue;
|
|
87
|
+
for (let i = 0; i < this._onChanges.length; i++) {
|
|
88
|
+
this._onChanges[i](newValue, oldValue);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
addOnChange(callback) {
|
|
92
|
+
this._onChanges.push(callback);
|
|
93
|
+
}
|
|
94
|
+
removeOnChange(callback) {
|
|
95
|
+
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
96
|
+
if (this._onChanges[i] === callback) {
|
|
97
|
+
this._onChanges.splice(i, 1);
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const isKTRef = (obj) => {
|
|
105
|
+
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Reference to the created HTML element.
|
|
109
|
+
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
110
|
+
* - can alse be used to store normal values, but it is not reactive.
|
|
111
|
+
* @param value mostly an HTMLElement
|
|
112
|
+
*/
|
|
113
|
+
function ref(value, onChange) {
|
|
114
|
+
return new KTRef(value, onChange ? [onChange] : []);
|
|
115
|
+
}
|
|
116
|
+
function kcollect() {
|
|
117
|
+
const newObj = {};
|
|
118
|
+
const entries = $entries(this);
|
|
119
|
+
for (let i = 0; i < entries.length; i++) {
|
|
120
|
+
const key = entries[i][0];
|
|
121
|
+
if (key === 'kcollect') {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
newObj[key] = entries[i][1].value;
|
|
125
|
+
}
|
|
126
|
+
return newObj;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Make all first-level properties of the object a `KTRef`.
|
|
130
|
+
* - `obj.a.b` is not reactive
|
|
131
|
+
*/
|
|
132
|
+
const surfaceRef = (obj) => {
|
|
133
|
+
const entries = $entries(obj);
|
|
134
|
+
const newObj = { kcollect };
|
|
135
|
+
for (let i = 0; i < entries.length; i++) {
|
|
136
|
+
newObj[entries[i][0]] = ref(entries[i][1]);
|
|
137
|
+
}
|
|
138
|
+
return newObj;
|
|
139
|
+
};
|
|
140
|
+
|
|
55
141
|
const booleanHandler = (element, key, value) => {
|
|
56
142
|
if (key in element) {
|
|
57
143
|
element[key] = !!value;
|
|
@@ -116,6 +202,7 @@ function attrIsObject(element, attr) {
|
|
|
116
202
|
key === 'style' ||
|
|
117
203
|
key === 'children' ||
|
|
118
204
|
key === 'k-if' ||
|
|
205
|
+
key.startsWith('k-model') ||
|
|
119
206
|
key === 'ref') {
|
|
120
207
|
continue;
|
|
121
208
|
}
|
|
@@ -193,6 +280,29 @@ function applyContent(element, content) {
|
|
|
193
280
|
}
|
|
194
281
|
}
|
|
195
282
|
|
|
283
|
+
function register(element, valueRef, propName, eventName) {
|
|
284
|
+
element[propName] = valueRef.value; // initialize
|
|
285
|
+
valueRef.addOnChange((newValue) => (element[propName] = newValue));
|
|
286
|
+
element.addEventListener(eventName, () => (valueRef.value = element[propName]));
|
|
287
|
+
}
|
|
288
|
+
function applyModel(element, valueRef) {
|
|
289
|
+
if (element instanceof HTMLInputElement) {
|
|
290
|
+
if (element.type === 'radio' || element.type === 'checkbox') {
|
|
291
|
+
register(element, valueRef, 'checked', 'change');
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
register(element, valueRef, 'value', 'input');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else if (element instanceof HTMLSelectElement) {
|
|
298
|
+
register(element, valueRef, 'value', 'change');
|
|
299
|
+
}
|
|
300
|
+
else if (element instanceof HTMLTextAreaElement) {
|
|
301
|
+
register(element, valueRef, 'value', 'input');
|
|
302
|
+
}
|
|
303
|
+
console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
|
|
304
|
+
}
|
|
305
|
+
|
|
196
306
|
const htmlCreator = (tag) => document.createElement(tag);
|
|
197
307
|
const svgCreator = (tag) => document.createElementNS('http://www.w3.org/2000/svg', tag);
|
|
198
308
|
const mathMLCreator = (tag) => document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
|
|
@@ -210,7 +320,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
|
|
|
210
320
|
* ## About
|
|
211
321
|
* @package @ktjs/core
|
|
212
322
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
213
|
-
* @version 0.
|
|
323
|
+
* @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
|
|
214
324
|
* @license MIT
|
|
215
325
|
* @link https://github.com/baendlorel/kt.js
|
|
216
326
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -239,97 +349,16 @@ const h = (tag, attr, content) => {
|
|
|
239
349
|
// * Handle content
|
|
240
350
|
applyAttr(element, attr);
|
|
241
351
|
applyContent(element, content);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Indicates that this is a KTRef instance
|
|
248
|
-
*/
|
|
249
|
-
isKT = true;
|
|
250
|
-
/**
|
|
251
|
-
* @internal
|
|
252
|
-
*/
|
|
253
|
-
_value;
|
|
254
|
-
/**
|
|
255
|
-
* @internal
|
|
256
|
-
*/
|
|
257
|
-
_onChanges;
|
|
258
|
-
constructor(_value, _onChanges) {
|
|
259
|
-
this._value = _value;
|
|
260
|
-
this._onChanges = _onChanges;
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
264
|
-
*/
|
|
265
|
-
get value() {
|
|
266
|
-
return this._value;
|
|
267
|
-
}
|
|
268
|
-
set value(newValue) {
|
|
269
|
-
if (newValue === this._value) {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
// replace the old node with the new one in the DOM if both are nodes
|
|
273
|
-
if (this._value instanceof Node && newValue instanceof Node) {
|
|
274
|
-
if (newValue.contains(this._value)) {
|
|
275
|
-
this._value.remove();
|
|
276
|
-
}
|
|
277
|
-
this._value.replaceWith(newValue);
|
|
278
|
-
}
|
|
279
|
-
const oldValue = this._value;
|
|
280
|
-
this._value = newValue;
|
|
281
|
-
for (let i = 0; i < this._onChanges.length; i++) {
|
|
282
|
-
this._onChanges[i](newValue, oldValue);
|
|
352
|
+
if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
|
|
353
|
+
const kmodel = attr['k-model'];
|
|
354
|
+
if (isKTRef(kmodel)) {
|
|
355
|
+
applyModel(element, kmodel);
|
|
283
356
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
this._onChanges.push(callback);
|
|
287
|
-
}
|
|
288
|
-
removeOnChange(callback) {
|
|
289
|
-
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
290
|
-
if (this._onChanges[i] === callback) {
|
|
291
|
-
this._onChanges.splice(i, 1);
|
|
292
|
-
return true;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
return false;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
const isKTRef = (obj) => {
|
|
299
|
-
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
300
|
-
};
|
|
301
|
-
/**
|
|
302
|
-
* Reference to the created HTML element.
|
|
303
|
-
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
304
|
-
* - can alse be used to store normal values, but it is not reactive.
|
|
305
|
-
* @param value mostly an HTMLElement
|
|
306
|
-
*/
|
|
307
|
-
function ref(value, onChange) {
|
|
308
|
-
return new KTRef(value, onChange ? [onChange] : []);
|
|
309
|
-
}
|
|
310
|
-
function kcollect() {
|
|
311
|
-
const newObj = {};
|
|
312
|
-
const entries = $entries(this);
|
|
313
|
-
for (let i = 0; i < entries.length; i++) {
|
|
314
|
-
const key = entries[i][0];
|
|
315
|
-
if (key === 'kcollect') {
|
|
316
|
-
continue;
|
|
357
|
+
else {
|
|
358
|
+
$throw('k-model value must be a KTRef.');
|
|
317
359
|
}
|
|
318
|
-
newObj[key] = entries[i][1].value;
|
|
319
360
|
}
|
|
320
|
-
return
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Make all first-level properties of the object a `KTRef`.
|
|
324
|
-
* - `obj.a.b` is not reactive
|
|
325
|
-
*/
|
|
326
|
-
const surfaceRef = (obj) => {
|
|
327
|
-
const entries = $entries(obj);
|
|
328
|
-
const newObj = { kcollect };
|
|
329
|
-
for (let i = 0; i < entries.length; i++) {
|
|
330
|
-
newObj[entries[i][0]] = ref(entries[i][1]);
|
|
331
|
-
}
|
|
332
|
-
return newObj;
|
|
361
|
+
return element;
|
|
333
362
|
};
|
|
334
363
|
|
|
335
364
|
const dummyRef = { value: null };
|
|
@@ -360,7 +389,7 @@ function jsx(tag, props) {
|
|
|
360
389
|
}
|
|
361
390
|
const oldEl = el;
|
|
362
391
|
el = newValue ? create(tag, props) : placeholder();
|
|
363
|
-
|
|
392
|
+
oldEl.replaceWith(el);
|
|
364
393
|
maybeDummyRef.value = el;
|
|
365
394
|
});
|
|
366
395
|
condition = kif.value;
|
package/dist/jsx/index.d.ts
CHANGED
|
@@ -66,12 +66,15 @@ interface KTBaseAttribute {
|
|
|
66
66
|
// # kt-specific attributes
|
|
67
67
|
ref?: KTRef<JSX.Element>;
|
|
68
68
|
|
|
69
|
-
// todo 是否要让k-if是KTRef的时候具备响应能力?
|
|
70
69
|
/**
|
|
71
70
|
* If a `KTRef` is bound, it will be reactive; otherwise, it will be static.
|
|
72
71
|
*/
|
|
73
72
|
'k-if'?: any;
|
|
74
|
-
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Register two-way data binding between an input element and a KTRef.
|
|
76
|
+
* - Default to regist `input` event and `value` property(`checked` for checkboxes and radios).
|
|
77
|
+
*/
|
|
75
78
|
'k-model'?: KTRef<any>;
|
|
76
79
|
|
|
77
80
|
// # normal HTML attributes
|
|
@@ -143,7 +146,7 @@ type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers;
|
|
|
143
146
|
* ## About
|
|
144
147
|
* @package @ktjs/core
|
|
145
148
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
146
|
-
* @version 0.
|
|
149
|
+
* @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
|
|
147
150
|
* @license MIT
|
|
148
151
|
* @link https://github.com/baendlorel/kt.js
|
|
149
152
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
package/dist/jsx/index.mjs
CHANGED
|
@@ -7,10 +7,6 @@ const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then
|
|
|
7
7
|
const $throw = (message) => {
|
|
8
8
|
throw new Error('@ktjs/shared: ' + message);
|
|
9
9
|
};
|
|
10
|
-
|
|
11
|
-
// DOM manipulation utilities
|
|
12
|
-
// # dom natives
|
|
13
|
-
const $replaceWith = Element.prototype.replaceWith;
|
|
14
10
|
/**
|
|
15
11
|
* & Remove `bind` because it is shockingly slower than wrapper
|
|
16
12
|
* & `window.document` is safe because it is not configurable and its setter is undefined
|
|
@@ -52,6 +48,96 @@ const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwn
|
|
|
52
48
|
// Re-export all utilities
|
|
53
49
|
Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
|
|
54
50
|
|
|
51
|
+
class KTRef {
|
|
52
|
+
/**
|
|
53
|
+
* Indicates that this is a KTRef instance
|
|
54
|
+
*/
|
|
55
|
+
isKT = true;
|
|
56
|
+
/**
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
_value;
|
|
60
|
+
/**
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
_onChanges;
|
|
64
|
+
constructor(_value, _onChanges) {
|
|
65
|
+
this._value = _value;
|
|
66
|
+
this._onChanges = _onChanges;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
70
|
+
*/
|
|
71
|
+
get value() {
|
|
72
|
+
return this._value;
|
|
73
|
+
}
|
|
74
|
+
set value(newValue) {
|
|
75
|
+
if (newValue === this._value) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// replace the old node with the new one in the DOM if both are nodes
|
|
79
|
+
if (this._value instanceof Node && newValue instanceof Node) {
|
|
80
|
+
if (newValue.contains(this._value)) {
|
|
81
|
+
this._value.remove();
|
|
82
|
+
}
|
|
83
|
+
this._value.replaceWith(newValue);
|
|
84
|
+
}
|
|
85
|
+
const oldValue = this._value;
|
|
86
|
+
this._value = newValue;
|
|
87
|
+
for (let i = 0; i < this._onChanges.length; i++) {
|
|
88
|
+
this._onChanges[i](newValue, oldValue);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
addOnChange(callback) {
|
|
92
|
+
this._onChanges.push(callback);
|
|
93
|
+
}
|
|
94
|
+
removeOnChange(callback) {
|
|
95
|
+
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
96
|
+
if (this._onChanges[i] === callback) {
|
|
97
|
+
this._onChanges.splice(i, 1);
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const isKTRef = (obj) => {
|
|
105
|
+
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Reference to the created HTML element.
|
|
109
|
+
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
110
|
+
* - can alse be used to store normal values, but it is not reactive.
|
|
111
|
+
* @param value mostly an HTMLElement
|
|
112
|
+
*/
|
|
113
|
+
function ref(value, onChange) {
|
|
114
|
+
return new KTRef(value, onChange ? [onChange] : []);
|
|
115
|
+
}
|
|
116
|
+
function kcollect() {
|
|
117
|
+
const newObj = {};
|
|
118
|
+
const entries = $entries(this);
|
|
119
|
+
for (let i = 0; i < entries.length; i++) {
|
|
120
|
+
const key = entries[i][0];
|
|
121
|
+
if (key === 'kcollect') {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
newObj[key] = entries[i][1].value;
|
|
125
|
+
}
|
|
126
|
+
return newObj;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Make all first-level properties of the object a `KTRef`.
|
|
130
|
+
* - `obj.a.b` is not reactive
|
|
131
|
+
*/
|
|
132
|
+
const surfaceRef = (obj) => {
|
|
133
|
+
const entries = $entries(obj);
|
|
134
|
+
const newObj = { kcollect };
|
|
135
|
+
for (let i = 0; i < entries.length; i++) {
|
|
136
|
+
newObj[entries[i][0]] = ref(entries[i][1]);
|
|
137
|
+
}
|
|
138
|
+
return newObj;
|
|
139
|
+
};
|
|
140
|
+
|
|
55
141
|
const booleanHandler = (element, key, value) => {
|
|
56
142
|
if (key in element) {
|
|
57
143
|
element[key] = !!value;
|
|
@@ -116,6 +202,7 @@ function attrIsObject(element, attr) {
|
|
|
116
202
|
key === 'style' ||
|
|
117
203
|
key === 'children' ||
|
|
118
204
|
key === 'k-if' ||
|
|
205
|
+
key.startsWith('k-model') ||
|
|
119
206
|
key === 'ref') {
|
|
120
207
|
continue;
|
|
121
208
|
}
|
|
@@ -193,6 +280,29 @@ function applyContent(element, content) {
|
|
|
193
280
|
}
|
|
194
281
|
}
|
|
195
282
|
|
|
283
|
+
function register(element, valueRef, propName, eventName) {
|
|
284
|
+
element[propName] = valueRef.value; // initialize
|
|
285
|
+
valueRef.addOnChange((newValue) => (element[propName] = newValue));
|
|
286
|
+
element.addEventListener(eventName, () => (valueRef.value = element[propName]));
|
|
287
|
+
}
|
|
288
|
+
function applyModel(element, valueRef) {
|
|
289
|
+
if (element instanceof HTMLInputElement) {
|
|
290
|
+
if (element.type === 'radio' || element.type === 'checkbox') {
|
|
291
|
+
register(element, valueRef, 'checked', 'change');
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
register(element, valueRef, 'value', 'input');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else if (element instanceof HTMLSelectElement) {
|
|
298
|
+
register(element, valueRef, 'value', 'change');
|
|
299
|
+
}
|
|
300
|
+
else if (element instanceof HTMLTextAreaElement) {
|
|
301
|
+
register(element, valueRef, 'value', 'input');
|
|
302
|
+
}
|
|
303
|
+
console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
|
|
304
|
+
}
|
|
305
|
+
|
|
196
306
|
const htmlCreator = (tag) => document.createElement(tag);
|
|
197
307
|
const svgCreator = (tag) => document.createElementNS('http://www.w3.org/2000/svg', tag);
|
|
198
308
|
const mathMLCreator = (tag) => document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
|
|
@@ -210,7 +320,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
|
|
|
210
320
|
* ## About
|
|
211
321
|
* @package @ktjs/core
|
|
212
322
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
213
|
-
* @version 0.
|
|
323
|
+
* @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
|
|
214
324
|
* @license MIT
|
|
215
325
|
* @link https://github.com/baendlorel/kt.js
|
|
216
326
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -239,97 +349,16 @@ const h = (tag, attr, content) => {
|
|
|
239
349
|
// * Handle content
|
|
240
350
|
applyAttr(element, attr);
|
|
241
351
|
applyContent(element, content);
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Indicates that this is a KTRef instance
|
|
248
|
-
*/
|
|
249
|
-
isKT = true;
|
|
250
|
-
/**
|
|
251
|
-
* @internal
|
|
252
|
-
*/
|
|
253
|
-
_value;
|
|
254
|
-
/**
|
|
255
|
-
* @internal
|
|
256
|
-
*/
|
|
257
|
-
_onChanges;
|
|
258
|
-
constructor(_value, _onChanges) {
|
|
259
|
-
this._value = _value;
|
|
260
|
-
this._onChanges = _onChanges;
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
264
|
-
*/
|
|
265
|
-
get value() {
|
|
266
|
-
return this._value;
|
|
267
|
-
}
|
|
268
|
-
set value(newValue) {
|
|
269
|
-
if (newValue === this._value) {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
// replace the old node with the new one in the DOM if both are nodes
|
|
273
|
-
if (this._value instanceof Node && newValue instanceof Node) {
|
|
274
|
-
if (newValue.contains(this._value)) {
|
|
275
|
-
this._value.remove();
|
|
276
|
-
}
|
|
277
|
-
this._value.replaceWith(newValue);
|
|
278
|
-
}
|
|
279
|
-
const oldValue = this._value;
|
|
280
|
-
this._value = newValue;
|
|
281
|
-
for (let i = 0; i < this._onChanges.length; i++) {
|
|
282
|
-
this._onChanges[i](newValue, oldValue);
|
|
352
|
+
if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
|
|
353
|
+
const kmodel = attr['k-model'];
|
|
354
|
+
if (isKTRef(kmodel)) {
|
|
355
|
+
applyModel(element, kmodel);
|
|
283
356
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
this._onChanges.push(callback);
|
|
287
|
-
}
|
|
288
|
-
removeOnChange(callback) {
|
|
289
|
-
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
290
|
-
if (this._onChanges[i] === callback) {
|
|
291
|
-
this._onChanges.splice(i, 1);
|
|
292
|
-
return true;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
return false;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
const isKTRef = (obj) => {
|
|
299
|
-
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
300
|
-
};
|
|
301
|
-
/**
|
|
302
|
-
* Reference to the created HTML element.
|
|
303
|
-
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
304
|
-
* - can alse be used to store normal values, but it is not reactive.
|
|
305
|
-
* @param value mostly an HTMLElement
|
|
306
|
-
*/
|
|
307
|
-
function ref(value, onChange) {
|
|
308
|
-
return new KTRef(value, onChange ? [onChange] : []);
|
|
309
|
-
}
|
|
310
|
-
function kcollect() {
|
|
311
|
-
const newObj = {};
|
|
312
|
-
const entries = $entries(this);
|
|
313
|
-
for (let i = 0; i < entries.length; i++) {
|
|
314
|
-
const key = entries[i][0];
|
|
315
|
-
if (key === 'kcollect') {
|
|
316
|
-
continue;
|
|
357
|
+
else {
|
|
358
|
+
$throw('k-model value must be a KTRef.');
|
|
317
359
|
}
|
|
318
|
-
newObj[key] = entries[i][1].value;
|
|
319
360
|
}
|
|
320
|
-
return
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Make all first-level properties of the object a `KTRef`.
|
|
324
|
-
* - `obj.a.b` is not reactive
|
|
325
|
-
*/
|
|
326
|
-
const surfaceRef = (obj) => {
|
|
327
|
-
const entries = $entries(obj);
|
|
328
|
-
const newObj = { kcollect };
|
|
329
|
-
for (let i = 0; i < entries.length; i++) {
|
|
330
|
-
newObj[entries[i][0]] = ref(entries[i][1]);
|
|
331
|
-
}
|
|
332
|
-
return newObj;
|
|
361
|
+
return element;
|
|
333
362
|
};
|
|
334
363
|
|
|
335
364
|
const dummyRef = { value: null };
|
|
@@ -360,7 +389,7 @@ function jsx(tag, props) {
|
|
|
360
389
|
}
|
|
361
390
|
const oldEl = el;
|
|
362
391
|
el = newValue ? create(tag, props) : placeholder();
|
|
363
|
-
|
|
392
|
+
oldEl.replaceWith(el);
|
|
364
393
|
maybeDummyRef.value = el;
|
|
365
394
|
});
|
|
366
395
|
condition = kif.value;
|
|
@@ -45,12 +45,15 @@ interface KTBaseAttribute {
|
|
|
45
45
|
// # kt-specific attributes
|
|
46
46
|
ref?: KTRef<JSX.Element>;
|
|
47
47
|
|
|
48
|
-
// todo 是否要让k-if是KTRef的时候具备响应能力?
|
|
49
48
|
/**
|
|
50
49
|
* If a `KTRef` is bound, it will be reactive; otherwise, it will be static.
|
|
51
50
|
*/
|
|
52
51
|
'k-if'?: any;
|
|
53
|
-
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Register two-way data binding between an input element and a KTRef.
|
|
55
|
+
* - Default to regist `input` event and `value` property(`checked` for checkboxes and radios).
|
|
56
|
+
*/
|
|
54
57
|
'k-model'?: KTRef<any>;
|
|
55
58
|
|
|
56
59
|
// # normal HTML attributes
|
|
@@ -122,7 +125,7 @@ type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers;
|
|
|
122
125
|
* ## About
|
|
123
126
|
* @package @ktjs/core
|
|
124
127
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
125
|
-
* @version 0.
|
|
128
|
+
* @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
|
|
126
129
|
* @license MIT
|
|
127
130
|
* @link https://github.com/baendlorel/kt.js
|
|
128
131
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
package/dist/jsx/jsx-runtime.mjs
CHANGED
|
@@ -6,10 +6,6 @@ const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then
|
|
|
6
6
|
const $throw = (message) => {
|
|
7
7
|
throw new Error('@ktjs/shared: ' + message);
|
|
8
8
|
};
|
|
9
|
-
|
|
10
|
-
// DOM manipulation utilities
|
|
11
|
-
// # dom natives
|
|
12
|
-
const $replaceWith = Element.prototype.replaceWith;
|
|
13
9
|
/**
|
|
14
10
|
* & Remove `bind` because it is shockingly slower than wrapper
|
|
15
11
|
* & `window.document` is safe because it is not configurable and its setter is undefined
|
|
@@ -51,6 +47,72 @@ const { get: $buttonDisabledGetter, set: $buttonDisabledSetter } = Object.getOwn
|
|
|
51
47
|
// Re-export all utilities
|
|
52
48
|
Object.defineProperty(window, '@ktjs/shared', { value: '0.20.2' });
|
|
53
49
|
|
|
50
|
+
class KTRef {
|
|
51
|
+
/**
|
|
52
|
+
* Indicates that this is a KTRef instance
|
|
53
|
+
*/
|
|
54
|
+
isKT = true;
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
_value;
|
|
59
|
+
/**
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
_onChanges;
|
|
63
|
+
constructor(_value, _onChanges) {
|
|
64
|
+
this._value = _value;
|
|
65
|
+
this._onChanges = _onChanges;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
69
|
+
*/
|
|
70
|
+
get value() {
|
|
71
|
+
return this._value;
|
|
72
|
+
}
|
|
73
|
+
set value(newValue) {
|
|
74
|
+
if (newValue === this._value) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
// replace the old node with the new one in the DOM if both are nodes
|
|
78
|
+
if (this._value instanceof Node && newValue instanceof Node) {
|
|
79
|
+
if (newValue.contains(this._value)) {
|
|
80
|
+
this._value.remove();
|
|
81
|
+
}
|
|
82
|
+
this._value.replaceWith(newValue);
|
|
83
|
+
}
|
|
84
|
+
const oldValue = this._value;
|
|
85
|
+
this._value = newValue;
|
|
86
|
+
for (let i = 0; i < this._onChanges.length; i++) {
|
|
87
|
+
this._onChanges[i](newValue, oldValue);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
addOnChange(callback) {
|
|
91
|
+
this._onChanges.push(callback);
|
|
92
|
+
}
|
|
93
|
+
removeOnChange(callback) {
|
|
94
|
+
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
95
|
+
if (this._onChanges[i] === callback) {
|
|
96
|
+
this._onChanges.splice(i, 1);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const isKTRef = (obj) => {
|
|
104
|
+
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* Reference to the created HTML element.
|
|
108
|
+
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
109
|
+
* - can alse be used to store normal values, but it is not reactive.
|
|
110
|
+
* @param value mostly an HTMLElement
|
|
111
|
+
*/
|
|
112
|
+
function ref(value, onChange) {
|
|
113
|
+
return new KTRef(value, []);
|
|
114
|
+
}
|
|
115
|
+
|
|
54
116
|
const booleanHandler = (element, key, value) => {
|
|
55
117
|
if (key in element) {
|
|
56
118
|
element[key] = !!value;
|
|
@@ -115,6 +177,7 @@ function attrIsObject(element, attr) {
|
|
|
115
177
|
key === 'style' ||
|
|
116
178
|
key === 'children' ||
|
|
117
179
|
key === 'k-if' ||
|
|
180
|
+
key.startsWith('k-model') ||
|
|
118
181
|
key === 'ref') {
|
|
119
182
|
continue;
|
|
120
183
|
}
|
|
@@ -192,6 +255,29 @@ function applyContent(element, content) {
|
|
|
192
255
|
}
|
|
193
256
|
}
|
|
194
257
|
|
|
258
|
+
function register(element, valueRef, propName, eventName) {
|
|
259
|
+
element[propName] = valueRef.value; // initialize
|
|
260
|
+
valueRef.addOnChange((newValue) => (element[propName] = newValue));
|
|
261
|
+
element.addEventListener(eventName, () => (valueRef.value = element[propName]));
|
|
262
|
+
}
|
|
263
|
+
function applyModel(element, valueRef) {
|
|
264
|
+
if (element instanceof HTMLInputElement) {
|
|
265
|
+
if (element.type === 'radio' || element.type === 'checkbox') {
|
|
266
|
+
register(element, valueRef, 'checked', 'change');
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
register(element, valueRef, 'value', 'input');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else if (element instanceof HTMLSelectElement) {
|
|
273
|
+
register(element, valueRef, 'value', 'change');
|
|
274
|
+
}
|
|
275
|
+
else if (element instanceof HTMLTextAreaElement) {
|
|
276
|
+
register(element, valueRef, 'value', 'input');
|
|
277
|
+
}
|
|
278
|
+
console.warn('[kt.js warn] not supported element for k-model:', element.tagName);
|
|
279
|
+
}
|
|
280
|
+
|
|
195
281
|
const htmlCreator = (tag) => document.createElement(tag);
|
|
196
282
|
const svgCreator = (tag) => document.createElementNS('http://www.w3.org/2000/svg', tag);
|
|
197
283
|
const mathMLCreator = (tag) => document.createElementNS('http://www.w3.org/1998/Math/MathML', tag);
|
|
@@ -209,7 +295,7 @@ const MATHML_ATTR_FLAG = '__kt_mathml__';
|
|
|
209
295
|
* ## About
|
|
210
296
|
* @package @ktjs/core
|
|
211
297
|
* @author Kasukabe Tsumugi <futami16237@gmail.com>
|
|
212
|
-
* @version 0.
|
|
298
|
+
* @version 0.22.0 (Last Update: 2026.02.02 17:11:04.703)
|
|
213
299
|
* @license MIT
|
|
214
300
|
* @link https://github.com/baendlorel/kt.js
|
|
215
301
|
* @link https://baendlorel.github.io/ Welcome to my site!
|
|
@@ -238,74 +324,17 @@ const h = (tag, attr, content) => {
|
|
|
238
324
|
// * Handle content
|
|
239
325
|
applyAttr(element, attr);
|
|
240
326
|
applyContent(element, content);
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Indicates that this is a KTRef instance
|
|
247
|
-
*/
|
|
248
|
-
isKT = true;
|
|
249
|
-
/**
|
|
250
|
-
* @internal
|
|
251
|
-
*/
|
|
252
|
-
_value;
|
|
253
|
-
/**
|
|
254
|
-
* @internal
|
|
255
|
-
*/
|
|
256
|
-
_onChanges;
|
|
257
|
-
constructor(_value, _onChanges) {
|
|
258
|
-
this._value = _value;
|
|
259
|
-
this._onChanges = _onChanges;
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* If new value and old value are both nodes, the old one will be replaced in the DOM
|
|
263
|
-
*/
|
|
264
|
-
get value() {
|
|
265
|
-
return this._value;
|
|
266
|
-
}
|
|
267
|
-
set value(newValue) {
|
|
268
|
-
if (newValue === this._value) {
|
|
269
|
-
return;
|
|
327
|
+
if (typeof attr === 'object' && attr !== null && 'k-model' in attr) {
|
|
328
|
+
const kmodel = attr['k-model'];
|
|
329
|
+
if (isKTRef(kmodel)) {
|
|
330
|
+
applyModel(element, kmodel);
|
|
270
331
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (newValue.contains(this._value)) {
|
|
274
|
-
this._value.remove();
|
|
275
|
-
}
|
|
276
|
-
this._value.replaceWith(newValue);
|
|
277
|
-
}
|
|
278
|
-
const oldValue = this._value;
|
|
279
|
-
this._value = newValue;
|
|
280
|
-
for (let i = 0; i < this._onChanges.length; i++) {
|
|
281
|
-
this._onChanges[i](newValue, oldValue);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
addOnChange(callback) {
|
|
285
|
-
this._onChanges.push(callback);
|
|
286
|
-
}
|
|
287
|
-
removeOnChange(callback) {
|
|
288
|
-
for (let i = this._onChanges.length - 1; i >= 0; i--) {
|
|
289
|
-
if (this._onChanges[i] === callback) {
|
|
290
|
-
this._onChanges.splice(i, 1);
|
|
291
|
-
return true;
|
|
292
|
-
}
|
|
332
|
+
else {
|
|
333
|
+
$throw('k-model value must be a KTRef.');
|
|
293
334
|
}
|
|
294
|
-
return false;
|
|
295
335
|
}
|
|
296
|
-
|
|
297
|
-
const isKTRef = (obj) => {
|
|
298
|
-
return typeof obj === 'object' && obj !== null && obj.isKT === true;
|
|
336
|
+
return element;
|
|
299
337
|
};
|
|
300
|
-
/**
|
|
301
|
-
* Reference to the created HTML element.
|
|
302
|
-
* - **Only** respond to `ref.value` changes, not reactive to internal changes of the element.
|
|
303
|
-
* - can alse be used to store normal values, but it is not reactive.
|
|
304
|
-
* @param value mostly an HTMLElement
|
|
305
|
-
*/
|
|
306
|
-
function ref(value, onChange) {
|
|
307
|
-
return new KTRef(value, []);
|
|
308
|
-
}
|
|
309
338
|
|
|
310
339
|
const dummyRef = { value: null };
|
|
311
340
|
const create = (tag, props) => {
|
|
@@ -335,7 +364,7 @@ function jsx(tag, props) {
|
|
|
335
364
|
}
|
|
336
365
|
const oldEl = el;
|
|
337
366
|
el = newValue ? create(tag, props) : placeholder();
|
|
338
|
-
|
|
367
|
+
oldEl.replaceWith(el);
|
|
339
368
|
maybeDummyRef.value = el;
|
|
340
369
|
});
|
|
341
370
|
condition = kif.value;
|