@wsxjs/wsx-core 0.0.17 → 0.0.18
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/LICENSE +2 -2
- package/dist/chunk-7AUYPTR5.mjs +277 -0
- package/dist/chunk-7WRSZQC3.mjs +256 -0
- package/dist/chunk-CBCT3PYF.mjs +250 -0
- package/dist/chunk-G23NXAPQ.mjs +237 -0
- package/dist/chunk-GOIGP2BR.mjs +271 -0
- package/dist/chunk-H6LR3P4O.mjs +256 -0
- package/dist/chunk-JV57DWHH.mjs +265 -0
- package/dist/chunk-UH5BDYGI.mjs +283 -0
- package/dist/index.js +170 -71
- package/dist/index.mjs +113 -69
- package/dist/jsx-runtime.js +56 -2
- package/dist/jsx-runtime.mjs +1 -1
- package/dist/jsx.js +56 -2
- package/dist/jsx.mjs +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +15 -2
- package/src/base-component.ts +60 -11
- package/src/index.ts +3 -2
- package/src/jsx-factory.ts +80 -2
- package/src/light-component.ts +93 -28
- package/src/utils/dom-utils.ts +48 -0
- package/src/utils/logger.ts +2 -2
- package/src/utils/reactive.ts +1 -1
- package/src/web-component.ts +37 -22
- package/types/index.d.ts +6 -3
package/src/web-component.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { h, type JSXChildren } from "./jsx-factory";
|
|
12
12
|
import { StyleManager } from "./styles/style-manager";
|
|
13
13
|
import { BaseComponent, type BaseComponentConfig } from "./base-component";
|
|
14
|
-
import { createLogger } from "
|
|
14
|
+
import { createLogger } from "@wsxjs/wsx-logger";
|
|
15
15
|
|
|
16
16
|
const logger = createLogger("WebComponent");
|
|
17
17
|
|
|
@@ -86,6 +86,8 @@ export abstract class WebComponent extends BaseComponent {
|
|
|
86
86
|
} else {
|
|
87
87
|
// 没有内容,需要渲染
|
|
88
88
|
// 清空 Shadow DOM(包括可能的旧内容)
|
|
89
|
+
// Note: innerHTML is used here for framework-level DOM management
|
|
90
|
+
// This is an exception to the no-inner-html rule for framework code
|
|
89
91
|
this.shadowRoot.innerHTML = "";
|
|
90
92
|
|
|
91
93
|
// 重新应用样式(因为上面清空了)
|
|
@@ -106,6 +108,14 @@ export abstract class WebComponent extends BaseComponent {
|
|
|
106
108
|
|
|
107
109
|
// 调用子类的初始化钩子
|
|
108
110
|
this.onConnected?.();
|
|
111
|
+
|
|
112
|
+
// 如果进行了渲染,调用 onRendered 钩子
|
|
113
|
+
if (hasActualContent === false || hasErrorElement) {
|
|
114
|
+
// 使用 requestAnimationFrame 确保 DOM 已完全更新
|
|
115
|
+
requestAnimationFrame(() => {
|
|
116
|
+
this.onRendered?.();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
109
119
|
} catch (error) {
|
|
110
120
|
logger.error(`Error in connectedCallback:`, error);
|
|
111
121
|
this.renderError(error);
|
|
@@ -142,25 +152,28 @@ export abstract class WebComponent extends BaseComponent {
|
|
|
142
152
|
}
|
|
143
153
|
|
|
144
154
|
/**
|
|
145
|
-
*
|
|
155
|
+
* 内部重渲染实现
|
|
156
|
+
* 包含从 rerender() 方法迁移的实际渲染逻辑
|
|
157
|
+
* WebComponent 使用 Shadow DOM,不存在 JSX children 问题
|
|
158
|
+
*
|
|
159
|
+
* @override
|
|
146
160
|
*/
|
|
147
|
-
protected
|
|
161
|
+
protected _rerender(): void {
|
|
148
162
|
if (!this.connected) {
|
|
149
|
-
|
|
163
|
+
// 如果组件未连接,清除渲染标志
|
|
164
|
+
this._isRendering = false;
|
|
150
165
|
return;
|
|
151
166
|
}
|
|
152
167
|
|
|
153
168
|
// 1. 捕获焦点状态(在 DOM 替换之前)
|
|
154
169
|
const focusState = this.captureFocusState();
|
|
155
|
-
// 保存到实例变量,供 render() 使用(如果需要)
|
|
156
170
|
this._pendingFocusState = focusState;
|
|
157
171
|
|
|
158
|
-
// 保存当前的 adopted stylesheets
|
|
172
|
+
// 2. 保存当前的 adopted stylesheets
|
|
159
173
|
const adoptedStyleSheets = this.shadowRoot.adoptedStyleSheets || [];
|
|
160
174
|
|
|
161
175
|
try {
|
|
162
|
-
// 只有在没有 adopted stylesheets 时才重新应用样式
|
|
163
|
-
// Check both _autoStyles getter and config.styles getter
|
|
176
|
+
// 3. 只有在没有 adopted stylesheets 时才重新应用样式
|
|
164
177
|
if (adoptedStyleSheets.length === 0) {
|
|
165
178
|
const stylesToApply = this._autoStyles || this.config.styles;
|
|
166
179
|
if (stylesToApply) {
|
|
@@ -169,13 +182,11 @@ export abstract class WebComponent extends BaseComponent {
|
|
|
169
182
|
}
|
|
170
183
|
}
|
|
171
184
|
|
|
172
|
-
// 重新渲染JSX
|
|
185
|
+
// 4. 重新渲染JSX
|
|
173
186
|
const content = this.render();
|
|
174
187
|
|
|
175
|
-
// 在添加到 DOM
|
|
176
|
-
// 这样可以确保值在元素添加到 DOM 之前就是正确的
|
|
188
|
+
// 5. 在添加到 DOM 之前恢复值
|
|
177
189
|
if (focusState && focusState.key && focusState.value !== undefined) {
|
|
178
|
-
// 在 content 树中查找目标元素
|
|
179
190
|
const target = content.querySelector(
|
|
180
191
|
`[data-wsx-key="${focusState.key}"]`
|
|
181
192
|
) as HTMLElement;
|
|
@@ -190,35 +201,37 @@ export abstract class WebComponent extends BaseComponent {
|
|
|
190
201
|
}
|
|
191
202
|
}
|
|
192
203
|
|
|
193
|
-
// 恢复 adopted stylesheets
|
|
204
|
+
// 6. 恢复 adopted stylesheets
|
|
194
205
|
if (this.shadowRoot.adoptedStyleSheets) {
|
|
195
206
|
this.shadowRoot.adoptedStyleSheets = adoptedStyleSheets;
|
|
196
207
|
}
|
|
197
208
|
|
|
198
|
-
// 使用 requestAnimationFrame 批量执行 DOM
|
|
199
|
-
// 在同一帧中完成添加和移除,避免中间状态
|
|
209
|
+
// 7. 使用 requestAnimationFrame 批量执行 DOM 操作
|
|
200
210
|
requestAnimationFrame(() => {
|
|
201
|
-
//
|
|
211
|
+
// 添加新内容
|
|
202
212
|
this.shadowRoot.appendChild(content);
|
|
203
213
|
|
|
204
|
-
//
|
|
214
|
+
// 移除旧内容
|
|
205
215
|
const oldChildren = Array.from(this.shadowRoot.children).filter(
|
|
206
216
|
(child) => child !== content
|
|
207
217
|
);
|
|
208
218
|
oldChildren.forEach((child) => child.remove());
|
|
209
219
|
|
|
210
|
-
//
|
|
211
|
-
// 值已经在添加到 DOM 之前恢复了,这里只需要恢复焦点和光标位置
|
|
212
|
-
// 使用另一个 requestAnimationFrame 确保 DOM 已完全更新
|
|
220
|
+
// 恢复焦点状态
|
|
213
221
|
requestAnimationFrame(() => {
|
|
214
222
|
this.restoreFocusState(focusState);
|
|
215
|
-
// 清除待处理的焦点状态
|
|
216
223
|
this._pendingFocusState = null;
|
|
224
|
+
// 调用 onRendered 生命周期钩子
|
|
225
|
+
this.onRendered?.();
|
|
226
|
+
// 在 onRendered() 完成后清除渲染标志,允许后续的 scheduleRerender()
|
|
227
|
+
this._isRendering = false;
|
|
217
228
|
});
|
|
218
229
|
});
|
|
219
230
|
} catch (error) {
|
|
220
|
-
logger.error("Error in
|
|
231
|
+
logger.error("Error in _rerender:", error);
|
|
221
232
|
this.renderError(error);
|
|
233
|
+
// 即使出错也要清除渲染标志,允许后续的 scheduleRerender()
|
|
234
|
+
this._isRendering = false;
|
|
222
235
|
}
|
|
223
236
|
}
|
|
224
237
|
|
|
@@ -229,6 +242,8 @@ export abstract class WebComponent extends BaseComponent {
|
|
|
229
242
|
*/
|
|
230
243
|
private renderError(error: unknown): void {
|
|
231
244
|
// 清空现有内容
|
|
245
|
+
// Note: innerHTML is used here for framework-level error handling
|
|
246
|
+
// This is an exception to the no-inner-html rule for framework code
|
|
232
247
|
this.shadowRoot.innerHTML = "";
|
|
233
248
|
|
|
234
249
|
const errorElement = h(
|
package/types/index.d.ts
CHANGED
|
@@ -28,9 +28,12 @@ export type { AutoRegistrationOptions } from "../src/auto-register";
|
|
|
28
28
|
// 导出 StyleManager
|
|
29
29
|
export { StyleManager } from "../src/styles/style-manager";
|
|
30
30
|
|
|
31
|
-
// 导出 Logger 相关类型和函数
|
|
32
|
-
export {
|
|
33
|
-
export
|
|
31
|
+
// 导出 Logger 相关类型和函数 (re-exported from @wsxjs/wsx-logger for backward compatibility)
|
|
32
|
+
export type { Logger, LogLevel } from "@wsxjs/wsx-logger";
|
|
33
|
+
export { WSXLogger, logger, createLogger, createLoggerWithConfig } from "@wsxjs/wsx-logger";
|
|
34
|
+
|
|
35
|
+
// 导出 DOM 工具函数
|
|
36
|
+
export { parseHTMLToNodes } from "../src/utils/dom-utils";
|
|
34
37
|
|
|
35
38
|
// 重新导出 JSX 运行时
|
|
36
39
|
export { h as jsx, h as jsxs, Fragment as F } from "../src/jsx-factory";
|