@ktjs/core 0.12.0 → 0.13.2

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.
@@ -5,38 +5,6 @@ var __ktjs_core__ = (function (exports) {
5
5
  throw new Error('kt.js: ' + message);
6
6
  };
7
7
 
8
- var $isArray = Array.isArray;
9
- var $keys = Object.keys;
10
- var $defines = Object.defineProperties;
11
- var $mark = function (func, tag) {
12
- return $defines(func, { __ktjs_h__: { value: tag, configurable: true } });
13
- };
14
- var emptyPromiseHandler = function () { return ({}); };
15
- if (typeof Promise === 'undefined') {
16
- window.Promise = { resolve: emptyPromiseHandler, reject: emptyPromiseHandler };
17
- }
18
- var $isThenable = function (o) {
19
- return typeof o === 'object' && o !== null && 'then' in o && typeof o.then === 'function';
20
- };
21
-
22
- ((function () {
23
- var _a;
24
- var runtimeKey = '__ktjs__';
25
- if (runtimeKey in window) {
26
- return;
27
- }
28
- var __ktjs__ = Object.create(null);
29
- // & We can add new functions when we need more
30
- var descriptor = {
31
- throws: { value: $throw, enumerable: true },
32
- defines: { value: $defines, enumerable: true },
33
- mark: { value: $mark, enumerable: true },
34
- };
35
- $defines(__ktjs__, descriptor);
36
- $defines(window, (_a = {}, _a[runtimeKey] = { value: __ktjs__, enumerable: true }, _a));
37
- return {};
38
- }))();
39
-
40
8
  /**
41
9
  * & Remove `bind` because it is shockingly slower than wrapper
42
10
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -83,22 +51,32 @@ var __ktjs_core__ = (function (exports) {
83
51
  }
84
52
  };
85
53
 
86
- function booleanHandler(element, key, value) {
54
+ var $isArray = Array.isArray;
55
+ var $keys = Object.keys;
56
+ var emptyPromiseHandler = function () { return ({}); };
57
+ if (typeof Promise === 'undefined') {
58
+ window.Promise = { resolve: emptyPromiseHandler, reject: emptyPromiseHandler };
59
+ }
60
+ var $isThenable = function (o) {
61
+ return typeof o === 'object' && o !== null && typeof o.then === 'function';
62
+ };
63
+
64
+ var booleanHandler = function (element, key, value) {
87
65
  if (key in element) {
88
66
  element[key] = !!value;
89
67
  }
90
68
  else {
91
69
  element.setAttribute(key, value);
92
70
  }
93
- }
94
- function valueHandler(element, key, value) {
71
+ };
72
+ var valueHandler = function (element, key, value) {
95
73
  if (key in element) {
96
74
  element[key] = value;
97
75
  }
98
76
  else {
99
77
  element.setAttribute(key, value);
100
78
  }
101
- }
79
+ };
102
80
  // Attribute handlers map for optimized lookup
103
81
  var handlers = {
104
82
  checked: booleanHandler,
@@ -121,13 +99,30 @@ var __ktjs_core__ = (function (exports) {
121
99
  muted: booleanHandler,
122
100
  defer: booleanHandler,
123
101
  async: booleanHandler,
124
- hidden: function (element, _key, value) {
125
- element.hidden = !!value;
126
- },
102
+ hidden: function (element, _key, value) { return (element.hidden = !!value); },
127
103
  };
128
- var defaultHandler = function (element, key, value) {
129
- return element.setAttribute(key, value);
104
+ var ktEventHandlers = {
105
+ 'on:ktchange': function (element, handler) {
106
+ return element.addEventListener('change', function () { return handler(element.value); });
107
+ },
108
+ 'ontrim:ktchange': function (element, handler) {
109
+ return element.addEventListener('change', function () { return handler(element.value.trim()); });
110
+ },
111
+ 'on:ktchangenumber': function (element, handler) {
112
+ return element.addEventListener('change', function () { return handler(Number(element.value)); });
113
+ },
114
+ 'on:ktinput': function (element, handler) {
115
+ return element.addEventListener('input', function () { return handler(element.value); });
116
+ },
117
+ 'ontrim:ktinput': function (element, handler) {
118
+ return element.addEventListener('input', function () { return handler(element.value.trim()); });
119
+ },
120
+ 'on:ktinputnumber': function (element, handler) {
121
+ return element.addEventListener('input', function () { return handler(Number(element.value)); });
122
+ },
130
123
  };
124
+
125
+ var defaultHandler = function (element, key, value) { return element.setAttribute(key, value); };
131
126
  function attrIsObject(element, attr) {
132
127
  var classValue = attr.class;
133
128
  var style = attr.style;
@@ -147,11 +142,19 @@ var __ktjs_core__ = (function (exports) {
147
142
  delete attr.style;
148
143
  }
149
144
  var keys = $keys(attr);
145
+ // todo 这里的处理每次遍历都要if所有的情况,能否用map或者对象来优化?
150
146
  for (var i = keys.length - 1; i >= 0; i--) {
151
147
  var key = keys[i];
152
148
  var o = attr[key];
153
149
  // force register on:xxx as an event handler
154
150
  // !if o is not valid, the throwing job will be done by `on`, not kt.js
151
+ // # special handling for kt.js specific events
152
+ var ktEvent = ktEventHandlers[key];
153
+ if (ktEvent) {
154
+ ktEvent(element, o);
155
+ continue;
156
+ }
157
+ // # normal event handler
155
158
  if (key.startsWith('on:')) {
156
159
  element.addEventListener(key.slice(3), o); // chop off the `@`
157
160
  continue;
@@ -241,7 +244,7 @@ var __ktjs_core__ = (function (exports) {
241
244
  * ## About
242
245
  * @package @ktjs/core
243
246
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
244
- * @version 0.12.0 (Last Update: 2026.01.14 15:48:26.320)
247
+ * @version 0.13.2 (Last Update: 2026.01.16 19:38:40.621)
245
248
  * @license MIT
246
249
  * @link https://github.com/baendlorel/kt.js
247
250
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -261,7 +264,6 @@ var __ktjs_core__ = (function (exports) {
261
264
  applyContent(element, content);
262
265
  return element;
263
266
  });
264
- $mark(h, 'h');
265
267
 
266
268
  /******************************************************************************
267
269
  Copyright (c) Microsoft Corporation.
@@ -299,41 +301,65 @@ var __ktjs_core__ = (function (exports) {
299
301
  /**
300
302
  * @param tag html tag or function component
301
303
  * @param props properties/attributes
302
- * @param _metadata metadata is ignored
303
304
  */
304
305
  function jsx(tag, props) {
305
306
  var _a;
307
+ if (props === void 0) { props = {}; }
308
+ var ref = ((_a = props.ref) === null || _a === void 0 ? void 0 : _a.isKT) ? props.ref : null;
309
+ if (ref) {
310
+ delete props.ref;
311
+ }
306
312
  // Handle function components
307
313
  if (typeof tag === 'function') {
308
- var propObj_1 = typeof props === 'string' ? { class: props } : props || {};
309
- var children_1 = propObj_1.children;
310
- return tag(__assign(__assign({}, propObj_1), { children: children_1 }));
311
- }
312
- // Handle regular HTML tags
313
- var propObj = typeof props === 'string' ? { class: props } : props;
314
- if (propObj === undefined || propObj === null) {
315
- return h(tag);
316
- }
317
- var children = propObj.children;
318
- delete propObj.children;
319
- // deal with ref attribute
320
- var ref = ((_a = propObj.ref) === null || _a === void 0 ? void 0 : _a.isKT) ? propObj.ref : null;
321
- if (ref) {
322
- delete propObj.ref;
314
+ var el_1 = tag(props);
315
+ if (!el_1.redraw) {
316
+ el_1.redraw = function (newProps) {
317
+ props = newProps ? __assign(__assign({}, props), newProps) : props;
318
+ // $ same as below
319
+ var old = el_1;
320
+ el_1 = tag(props);
321
+ el_1.redraw = old.redraw; // inherit redraw
322
+ if (ref) {
323
+ ref.value = el_1;
324
+ }
325
+ old.replaceWith(el_1);
326
+ };
327
+ }
328
+ if (ref) {
329
+ ref.value = el_1;
330
+ }
331
+ return el_1;
323
332
  }
324
- var el = h(tag, propObj, children);
325
- if (ref) {
326
- ref.value = el;
333
+ else {
334
+ // & deal children here
335
+ var children_1 = props.children;
336
+ delete props.children;
337
+ var el_2 = h(tag, props, children_1);
338
+ if (ref) {
339
+ ref.value = el_2;
340
+ }
341
+ el_2.redraw = function (newProps, newChildren) {
342
+ props = newProps ? __assign(__assign({}, props), newProps) : props;
343
+ children_1 = (newChildren !== null && newChildren !== void 0 ? newChildren : children_1);
344
+ // $ same as above
345
+ var old = el_2;
346
+ el_2 = h(tag, props, children_1);
347
+ el_2.redraw = old.redraw; // inherit redraw
348
+ if (ref) {
349
+ ref.value = el_2;
350
+ }
351
+ old.replaceWith(el_2);
352
+ };
353
+ return el_2;
327
354
  }
328
- return el;
329
355
  }
330
356
  /**
331
357
  * Fragment support - returns an array of children
332
358
  * Note: kt.js doesn't have a real Fragment concept,
333
359
  */
334
360
  function Fragment(props) {
335
- window.__ktjs__.throws("kt.js doesn't have a Fragment concept");
336
- // const { children } = props || {};
361
+ throw new Error("kt.js doesn't have a Fragment concept");
362
+ // const { children } = props ?? {};
337
363
  // if (!children) {
338
364
  // return ;
339
365
  // }
package/dist/index.mjs CHANGED
@@ -2,33 +2,6 @@ const $throw = (message) => {
2
2
  throw new Error('kt.js: ' + message);
3
3
  };
4
4
 
5
- const $isArray = Array.isArray;
6
- const $keys = Object.keys;
7
- const $defines = Object.defineProperties;
8
- const $mark = (func, tag) => $defines(func, { __ktjs_h__: { value: tag, configurable: true } });
9
- const emptyPromiseHandler = () => ({});
10
- if (typeof Promise === 'undefined') {
11
- window.Promise = { resolve: emptyPromiseHandler, reject: emptyPromiseHandler };
12
- }
13
- const $isThenable = (o) => typeof o === 'object' && o !== null && 'then' in o && typeof o.then === 'function';
14
-
15
- (() => {
16
- const runtimeKey = '__ktjs__';
17
- if (runtimeKey in window) {
18
- return;
19
- }
20
- const __ktjs__ = Object.create(null);
21
- // & We can add new functions when we need more
22
- const descriptor = {
23
- throws: { value: $throw, enumerable: true },
24
- defines: { value: $defines, enumerable: true },
25
- mark: { value: $mark, enumerable: true },
26
- };
27
- $defines(__ktjs__, descriptor);
28
- $defines(window, { [runtimeKey]: { value: __ktjs__, enumerable: true } });
29
- return {};
30
- })();
31
-
32
5
  /**
33
6
  * & Remove `bind` because it is shockingly slower than wrapper
34
7
  * & `window.document` is safe because it is not configurable and its setter is undefined
@@ -67,22 +40,30 @@ const $append = // for ie 9/10/11
67
40
  }
68
41
  };
69
42
 
70
- function booleanHandler(element, key, value) {
43
+ const $isArray = Array.isArray;
44
+ const $keys = Object.keys;
45
+ const emptyPromiseHandler = () => ({});
46
+ if (typeof Promise === 'undefined') {
47
+ window.Promise = { resolve: emptyPromiseHandler, reject: emptyPromiseHandler };
48
+ }
49
+ const $isThenable = (o) => typeof o === 'object' && o !== null && typeof o.then === 'function';
50
+
51
+ const booleanHandler = (element, key, value) => {
71
52
  if (key in element) {
72
53
  element[key] = !!value;
73
54
  }
74
55
  else {
75
56
  element.setAttribute(key, value);
76
57
  }
77
- }
78
- function valueHandler(element, key, value) {
58
+ };
59
+ const valueHandler = (element, key, value) => {
79
60
  if (key in element) {
80
61
  element[key] = value;
81
62
  }
82
63
  else {
83
64
  element.setAttribute(key, value);
84
65
  }
85
- }
66
+ };
86
67
  // Attribute handlers map for optimized lookup
87
68
  const handlers = {
88
69
  checked: booleanHandler,
@@ -105,13 +86,18 @@ const handlers = {
105
86
  muted: booleanHandler,
106
87
  defer: booleanHandler,
107
88
  async: booleanHandler,
108
- hidden: function (element, _key, value) {
109
- element.hidden = !!value;
110
- },
89
+ hidden: (element, _key, value) => (element.hidden = !!value),
111
90
  };
112
- const defaultHandler = function (element, key, value) {
113
- return element.setAttribute(key, value);
91
+ const ktEventHandlers = {
92
+ 'on:ktchange': (element, handler) => element.addEventListener('change', () => handler(element.value)),
93
+ 'ontrim:ktchange': (element, handler) => element.addEventListener('change', () => handler(element.value.trim())),
94
+ 'on:ktchangenumber': (element, handler) => element.addEventListener('change', () => handler(Number(element.value))),
95
+ 'on:ktinput': (element, handler) => element.addEventListener('input', () => handler(element.value)),
96
+ 'ontrim:ktinput': (element, handler) => element.addEventListener('input', () => handler(element.value.trim())),
97
+ 'on:ktinputnumber': (element, handler) => element.addEventListener('input', () => handler(Number(element.value))),
114
98
  };
99
+
100
+ const defaultHandler = (element, key, value) => element.setAttribute(key, value);
115
101
  function attrIsObject(element, attr) {
116
102
  const classValue = attr.class;
117
103
  const style = attr.style;
@@ -131,11 +117,19 @@ function attrIsObject(element, attr) {
131
117
  delete attr.style;
132
118
  }
133
119
  const keys = $keys(attr);
120
+ // todo 这里的处理每次遍历都要if所有的情况,能否用map或者对象来优化?
134
121
  for (let i = keys.length - 1; i >= 0; i--) {
135
122
  const key = keys[i];
136
123
  const o = attr[key];
137
124
  // force register on:xxx as an event handler
138
125
  // !if o is not valid, the throwing job will be done by `on`, not kt.js
126
+ // # special handling for kt.js specific events
127
+ const ktEvent = ktEventHandlers[key];
128
+ if (ktEvent) {
129
+ ktEvent(element, o);
130
+ continue;
131
+ }
132
+ // # normal event handler
139
133
  if (key.startsWith('on:')) {
140
134
  element.addEventListener(key.slice(3), o); // chop off the `@`
141
135
  continue;
@@ -222,7 +216,7 @@ function applyContent(element, content) {
222
216
  * ## About
223
217
  * @package @ktjs/core
224
218
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
225
- * @version 0.12.0 (Last Update: 2026.01.14 15:48:26.320)
219
+ * @version 0.13.2 (Last Update: 2026.01.16 19:38:40.621)
226
220
  * @license MIT
227
221
  * @link https://github.com/baendlorel/kt.js
228
222
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -240,45 +234,67 @@ const h = ((tag, attr = '', content = '') => {
240
234
  applyContent(element, content);
241
235
  return element;
242
236
  });
243
- $mark(h, 'h');
244
237
 
245
238
  /**
246
239
  * @param tag html tag or function component
247
240
  * @param props properties/attributes
248
- * @param _metadata metadata is ignored
249
241
  */
250
- function jsx(tag, props, ..._metadata) {
242
+ function jsx(tag, props = {}) {
243
+ const ref = props.ref?.isKT ? props.ref : null;
244
+ if (ref) {
245
+ delete props.ref;
246
+ }
251
247
  // Handle function components
252
248
  if (typeof tag === 'function') {
253
- const propObj = typeof props === 'string' ? { class: props } : props || {};
254
- const children = propObj.children;
255
- return tag({ ...propObj, children });
256
- }
257
- // Handle regular HTML tags
258
- const propObj = typeof props === 'string' ? { class: props } : props;
259
- if (propObj === undefined || propObj === null) {
260
- return h(tag);
261
- }
262
- const children = propObj.children;
263
- delete propObj.children;
264
- // deal with ref attribute
265
- const ref = propObj.ref?.isKT ? propObj.ref : null;
266
- if (ref) {
267
- delete propObj.ref;
249
+ let el = tag(props);
250
+ if (!el.redraw) {
251
+ el.redraw = (newProps) => {
252
+ props = newProps ? { ...props, ...newProps } : props;
253
+ // $ same as below
254
+ const old = el;
255
+ el = tag(props);
256
+ el.redraw = old.redraw; // inherit redraw
257
+ if (ref) {
258
+ ref.value = el;
259
+ }
260
+ old.replaceWith(el);
261
+ };
262
+ }
263
+ if (ref) {
264
+ ref.value = el;
265
+ }
266
+ return el;
268
267
  }
269
- const el = h(tag, propObj, children);
270
- if (ref) {
271
- ref.value = el;
268
+ else {
269
+ // & deal children here
270
+ let children = props.children;
271
+ delete props.children;
272
+ let el = h(tag, props, children);
273
+ if (ref) {
274
+ ref.value = el;
275
+ }
276
+ el.redraw = (newProps, newChildren) => {
277
+ props = newProps ? { ...props, ...newProps } : props;
278
+ children = (newChildren ?? children);
279
+ // $ same as above
280
+ const old = el;
281
+ el = h(tag, props, children);
282
+ el.redraw = old.redraw; // inherit redraw
283
+ if (ref) {
284
+ ref.value = el;
285
+ }
286
+ old.replaceWith(el);
287
+ };
288
+ return el;
272
289
  }
273
- return el;
274
290
  }
275
291
  /**
276
292
  * Fragment support - returns an array of children
277
293
  * Note: kt.js doesn't have a real Fragment concept,
278
294
  */
279
295
  function Fragment(props) {
280
- window.__ktjs__.throws("kt.js doesn't have a Fragment concept");
281
- // const { children } = props || {};
296
+ throw new Error("kt.js doesn't have a Fragment concept");
297
+ // const { children } = props ?? {};
282
298
  // if (!children) {
283
299
  // return ;
284
300
  // }
@@ -16,6 +16,33 @@ interface KTRef<T> {
16
16
  */
17
17
  declare function ref<T = HTMLElement>(value?: T): KTRef<T>;
18
18
 
19
+ type KTHTMLElement = HTMLElement & {
20
+ /**
21
+ * Automically generate a redraw function if it is not provided
22
+ * @param props
23
+ */
24
+ redraw: (props?: KTAttribute, children?: KTRawContent) => void;
25
+ };
26
+
27
+ declare global {
28
+ namespace JSX {
29
+ type Element = KTHTMLElement;
30
+
31
+ interface IntrinsicElements {
32
+ [tag: string]: KTAttribute & { children?: KTRawContent };
33
+ }
34
+
35
+ // interface IntrinsicAttributes {
36
+ // key?: string | number;
37
+ // }
38
+ type IntrinsicAttributes = KTAttribute;
39
+
40
+ interface ElementChildrenAttribute {
41
+ children: {};
42
+ }
43
+ }
44
+ }
45
+
19
46
  type KTAvailableContent =
20
47
  | KTRef<any>
21
48
  | HTMLElement
@@ -92,7 +119,17 @@ type KTPrefixedEventHandlers = {
92
119
  [EventName in keyof HTMLElementEventMap as `on:${EventName}`]?: (ev: HTMLElementEventMap[EventName]) => void;
93
120
  };
94
121
 
95
- type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers;
122
+ type KTSpecialEventHandlers = {
123
+ 'on:ktchange'?: (value: string) => void;
124
+ 'ontrim:ktchange'?: (value: string) => void;
125
+ 'on:ktchangenumber'?: (value: number) => void;
126
+
127
+ 'on:ktinput'?: (value: string) => void;
128
+ 'ontrim:ktinput'?: (value: string) => void;
129
+ 'on:ktinputnumber'?: (value: number) => void;
130
+ };
131
+
132
+ type KTAttribute = KTBaseAttribute & KTPrefixedEventHandlers & KTSpecialEventHandlers;
96
133
 
97
134
  type HTML<T extends HTMLTag & otherstring> = T extends HTMLTag ? HTMLElementTagNameMap[T] : HTMLElement;
98
135
  type H = (<T extends HTMLTag>(tag: T, attr?: KTRawAttr, content?: KTRawContent) => HTML<T>) & {
@@ -109,7 +146,7 @@ type H = (<T extends HTMLTag>(tag: T, attr?: KTRawAttr, content?: KTRawContent)
109
146
  * ## About
110
147
  * @package @ktjs/core
111
148
  * @author Kasukabe Tsumugi <futami16237@gmail.com>
112
- * @version 0.12.0 (Last Update: 2026.01.14 15:48:26.320)
149
+ * @version 0.13.2 (Last Update: 2026.01.16 19:38:40.621)
113
150
  * @license MIT
114
151
  * @link https://github.com/baendlorel/kt.js
115
152
  * @link https://baendlorel.github.io/ Welcome to my site!
@@ -118,12 +155,12 @@ type H = (<T extends HTMLTag>(tag: T, attr?: KTRawAttr, content?: KTRawContent)
118
155
  */
119
156
  declare const h: H;
120
157
 
158
+ type JSXTag = HTMLTag | ((props?: any) => HTMLElement) | ((props?: any) => Promise<HTMLElement>) | ((props?: any) => KTHTMLElement) | ((props?: any) => Promise<KTHTMLElement>);
121
159
  /**
122
160
  * @param tag html tag or function component
123
161
  * @param props properties/attributes
124
- * @param _metadata metadata is ignored
125
162
  */
126
- declare function jsx<T extends HTMLTag>(tag: T | Function, props: KTRawAttr, ..._metadata: any[]): HTMLElementTagNameMap[T] | HTMLElement;
163
+ declare function jsx(tag: JSXTag, props?: KTAttribute): KTHTMLElement;
127
164
  /**
128
165
  * Fragment support - returns an array of children
129
166
  * Note: kt.js doesn't have a real Fragment concept,
@@ -141,24 +178,5 @@ declare const jsxDEV: typeof jsx;
141
178
  */
142
179
  declare const jsxs: typeof jsx;
143
180
 
144
- declare global {
145
- namespace JSX {
146
- type Element = HTMLElementTagNameMap[keyof HTMLElementTagNameMap];
147
-
148
- interface IntrinsicElements {
149
- [tag: string]: KTAttribute & { children?: KTRawContent };
150
- }
151
-
152
- // interface IntrinsicAttributes {
153
- // key?: string | number;
154
- // }
155
- type IntrinsicAttributes = KTAttribute;
156
-
157
- interface ElementChildrenAttribute {
158
- children: {};
159
- }
160
- }
161
- }
162
-
163
181
  export { Fragment, h as createElement, jsx, jsxDEV, jsxs, ref };
164
- export type { KTRef };
182
+ export type { KTHTMLElement, KTRef };