@dooboostore/dom-parser 1.0.0 → 1.0.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.
- package/README.MD +47 -94
- package/dist/cjs/DomParser.js +33 -12
- package/dist/cjs/DomParser.js.map +2 -2
- package/dist/cjs/node/DocumentBase.js +4 -0
- package/dist/cjs/node/DocumentBase.js.map +2 -2
- package/dist/cjs/node/elements/Element.js.map +1 -1
- package/dist/cjs/node/elements/ElementBase.js +12 -2
- package/dist/cjs/node/elements/ElementBase.js.map +2 -2
- package/dist/cjs/node/elements/HTMLElement.js.map +1 -1
- package/dist/cjs/node/elements/HTMLElementBase.js +154 -2
- package/dist/cjs/node/elements/HTMLElementBase.js.map +2 -2
- package/dist/cjs/window/WindowBase.js +128 -7
- package/dist/cjs/window/WindowBase.js.map +2 -2
- package/dist/esm/DomParser.js +33 -12
- package/dist/esm/DomParser.js.map +2 -2
- package/dist/esm/node/DocumentBase.js +4 -0
- package/dist/esm/node/DocumentBase.js.map +2 -2
- package/dist/esm/node/elements/ElementBase.js +12 -2
- package/dist/esm/node/elements/ElementBase.js.map +2 -2
- package/dist/esm/node/elements/HTMLElementBase.js +154 -2
- package/dist/esm/node/elements/HTMLElementBase.js.map +2 -2
- package/dist/esm/window/WindowBase.js +128 -7
- package/dist/esm/window/WindowBase.js.map +2 -2
- package/dist/esm-bundle/dooboostore-dom-parser.esm.js +504 -195
- package/dist/esm-bundle/dooboostore-dom-parser.esm.js.map +3 -3
- package/dist/types/DomParser.d.ts +4 -0
- package/dist/types/DomParser.d.ts.map +1 -1
- package/dist/types/node/DocumentBase.d.ts +2 -0
- package/dist/types/node/DocumentBase.d.ts.map +1 -1
- package/dist/types/node/elements/Element.d.ts +1 -0
- package/dist/types/node/elements/Element.d.ts.map +1 -1
- package/dist/types/node/elements/ElementBase.d.ts +2 -2
- package/dist/types/node/elements/ElementBase.d.ts.map +1 -1
- package/dist/types/node/elements/HTMLElement.d.ts +32 -1
- package/dist/types/node/elements/HTMLElement.d.ts.map +1 -1
- package/dist/types/node/elements/HTMLElementBase.d.ts +11 -2
- package/dist/types/node/elements/HTMLElementBase.d.ts.map +1 -1
- package/dist/types/window/WindowBase.d.ts +12 -2
- package/dist/types/window/WindowBase.d.ts.map +1 -1
- package/dist/umd-bundle/dooboostore-dom-parser.umd.js +504 -195
- package/dist/umd-bundle/dooboostore-dom-parser.umd.js.map +3 -3
- package/package.json +3 -10
- package/src/DomParser.ts +457 -436
- package/src/node/DocumentBase.ts +7 -2
- package/src/node/elements/Element.ts +24 -23
- package/src/node/elements/ElementBase.ts +50 -41
- package/src/node/elements/HTMLElement.ts +36 -1
- package/src/node/elements/HTMLElementBase.ts +191 -5
- package/src/window/WindowBase.ts +1128 -919
|
@@ -11,6 +11,10 @@ class HTMLElementBase extends ElementBase {
|
|
|
11
11
|
this._contentEditable = "inherit";
|
|
12
12
|
this._innerText = "";
|
|
13
13
|
this._outerText = "";
|
|
14
|
+
// New implementations for style, dataset, nonce
|
|
15
|
+
this._style = null;
|
|
16
|
+
this._dataset = null;
|
|
17
|
+
this._attributeStyleMap = null;
|
|
14
18
|
}
|
|
15
19
|
// HTMLElement interface implementation
|
|
16
20
|
get title() {
|
|
@@ -93,8 +97,6 @@ class HTMLElementBase extends ElementBase {
|
|
|
93
97
|
console.log(`Clicked on ${this.tagName} element`);
|
|
94
98
|
}
|
|
95
99
|
focus(options) {
|
|
96
|
-
this.setAttribute("data-focused", "true");
|
|
97
|
-
console.log(`Focused on ${this.tagName} element`);
|
|
98
100
|
}
|
|
99
101
|
blur() {
|
|
100
102
|
this.removeAttribute("data-focused");
|
|
@@ -156,6 +158,156 @@ class HTMLElementBase extends ElementBase {
|
|
|
156
158
|
break;
|
|
157
159
|
}
|
|
158
160
|
}
|
|
161
|
+
get style() {
|
|
162
|
+
if (!this._style) {
|
|
163
|
+
this._style = new Proxy(new CSSStyleDeclarationImpl(this), {
|
|
164
|
+
get: (target, prop) => {
|
|
165
|
+
if (typeof prop === "string" && !(prop in target)) {
|
|
166
|
+
const cssProp = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
167
|
+
return target.getPropertyValue(cssProp);
|
|
168
|
+
}
|
|
169
|
+
return target[prop];
|
|
170
|
+
},
|
|
171
|
+
set: (target, prop, value) => {
|
|
172
|
+
if (typeof prop === "string" && !(prop in target)) {
|
|
173
|
+
const cssProp = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
174
|
+
target.setProperty(cssProp, String(value));
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
target[prop] = value;
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return this._style;
|
|
183
|
+
}
|
|
184
|
+
set style(value) {
|
|
185
|
+
if (typeof value === "string") {
|
|
186
|
+
this.style.cssText = value;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
get attributeStyleMap() {
|
|
190
|
+
if (!this._attributeStyleMap) {
|
|
191
|
+
this._attributeStyleMap = new StylePropertyMapImpl(this);
|
|
192
|
+
}
|
|
193
|
+
return this._attributeStyleMap;
|
|
194
|
+
}
|
|
195
|
+
get dataset() {
|
|
196
|
+
if (!this._dataset) {
|
|
197
|
+
this._dataset = new Proxy({}, {
|
|
198
|
+
get: (target, prop) => {
|
|
199
|
+
if (typeof prop === "string") {
|
|
200
|
+
const attrName = "data-" + prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
201
|
+
return this.getAttribute(attrName);
|
|
202
|
+
}
|
|
203
|
+
return void 0;
|
|
204
|
+
},
|
|
205
|
+
set: (target, prop, value) => {
|
|
206
|
+
if (typeof prop === "string") {
|
|
207
|
+
const attrName = "data-" + prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
208
|
+
this.setAttribute(attrName, String(value));
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
return false;
|
|
212
|
+
},
|
|
213
|
+
deleteProperty: (target, prop) => {
|
|
214
|
+
if (typeof prop === "string") {
|
|
215
|
+
const attrName = "data-" + prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
|
|
216
|
+
this.removeAttribute(attrName);
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return this._dataset;
|
|
224
|
+
}
|
|
225
|
+
get nonce() {
|
|
226
|
+
return this.getAttribute("nonce") || "";
|
|
227
|
+
}
|
|
228
|
+
set nonce(value) {
|
|
229
|
+
this.setAttribute("nonce", value);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
class CSSStyleDeclarationImpl {
|
|
233
|
+
constructor(element) {
|
|
234
|
+
this.element = element;
|
|
235
|
+
this.parentRule = null;
|
|
236
|
+
}
|
|
237
|
+
getPropertyPriority(property) {
|
|
238
|
+
return "";
|
|
239
|
+
}
|
|
240
|
+
get cssText() {
|
|
241
|
+
return this.element.getAttribute("style") || "";
|
|
242
|
+
}
|
|
243
|
+
set cssText(value) {
|
|
244
|
+
this.element.setAttribute("style", value);
|
|
245
|
+
}
|
|
246
|
+
get length() {
|
|
247
|
+
return this.parseStyle(this.cssText).size;
|
|
248
|
+
}
|
|
249
|
+
getPropertyValue(property) {
|
|
250
|
+
const style = this.parseStyle(this.cssText);
|
|
251
|
+
return style.get(property) || "";
|
|
252
|
+
}
|
|
253
|
+
setProperty(property, value, priority = "") {
|
|
254
|
+
const style = this.parseStyle(this.cssText);
|
|
255
|
+
if (value === null || value === "") {
|
|
256
|
+
style.delete(property);
|
|
257
|
+
} else {
|
|
258
|
+
style.set(property, value);
|
|
259
|
+
}
|
|
260
|
+
this.cssText = this.serializeStyle(style);
|
|
261
|
+
}
|
|
262
|
+
removeProperty(property) {
|
|
263
|
+
const style = this.parseStyle(this.cssText);
|
|
264
|
+
const value = style.get(property) || "";
|
|
265
|
+
style.delete(property);
|
|
266
|
+
this.cssText = this.serializeStyle(style);
|
|
267
|
+
return value;
|
|
268
|
+
}
|
|
269
|
+
item(index) {
|
|
270
|
+
const style = this.parseStyle(this.cssText);
|
|
271
|
+
return Array.from(style.keys())[index] || "";
|
|
272
|
+
}
|
|
273
|
+
parseStyle(cssText) {
|
|
274
|
+
const style = /* @__PURE__ */ new Map();
|
|
275
|
+
if (!cssText) return style;
|
|
276
|
+
cssText.split(";").forEach((declaration) => {
|
|
277
|
+
const part = declaration.trim();
|
|
278
|
+
if (!part) return;
|
|
279
|
+
const colonIndex = part.indexOf(":");
|
|
280
|
+
if (colonIndex !== -1) {
|
|
281
|
+
const property = part.substring(0, colonIndex).trim();
|
|
282
|
+
const value = part.substring(colonIndex + 1).trim();
|
|
283
|
+
if (property && value) {
|
|
284
|
+
style.set(property, value);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
return style;
|
|
289
|
+
}
|
|
290
|
+
serializeStyle(style) {
|
|
291
|
+
return Array.from(style.entries()).map(([property, value]) => `${property}: ${value}`).join("; ");
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
class StylePropertyMapImpl {
|
|
295
|
+
constructor(element) {
|
|
296
|
+
this.element = element;
|
|
297
|
+
}
|
|
298
|
+
set(property, ...values) {
|
|
299
|
+
const value = values[0];
|
|
300
|
+
this.element.style.setProperty(property, String(value));
|
|
301
|
+
}
|
|
302
|
+
append(property, ...values) {
|
|
303
|
+
this.set(property, ...values);
|
|
304
|
+
}
|
|
305
|
+
delete(property) {
|
|
306
|
+
this.element.style.removeProperty(property);
|
|
307
|
+
}
|
|
308
|
+
clear() {
|
|
309
|
+
this.element.style.cssText = "";
|
|
310
|
+
}
|
|
159
311
|
}
|
|
160
312
|
export {
|
|
161
313
|
HTMLElementBase
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/node/elements/HTMLElementBase.ts"],
|
|
4
|
-
"sourcesContent": ["import { ElementBase } from './ElementBase';\nimport { HTMLElement, FocusOptions } from './HTMLElement';\nimport { Text } from '../Text';\nimport { ElementFactory } from '../../factory';\n\n/**\n * Base implementation for all HTML elements\n */\nexport abstract class HTMLElementBase extends ElementBase implements HTMLElement {\n private _title: string = '';\n private _lang: string = '';\n private _dir: string = '';\n private _hidden: boolean = false;\n private _tabIndex: number = -1;\n private _accessKey: string = '';\n private _contentEditable: string = 'inherit';\n private _innerText: string = '';\n private _outerText: string = '';\n\n constructor(tagName: string, ownerDocument?: any) {\n super(tagName, ownerDocument);\n }\n\n // HTMLElement interface implementation\n get title(): string {\n return this._title;\n }\n\n set title(value: string) {\n this._title = value;\n this.setAttribute('title', value);\n }\n\n get lang(): string {\n return this._lang;\n }\n\n set lang(value: string) {\n this._lang = value;\n this.setAttribute('lang', value);\n }\n\n get dir(): string {\n return this._dir;\n }\n\n set dir(value: string) {\n this._dir = value;\n this.setAttribute('dir', value);\n }\n\n get hidden(): boolean {\n return this._hidden;\n }\n\n set hidden(value: boolean) {\n this._hidden = value;\n if (value) {\n this.setAttribute('hidden', '');\n } else {\n this.removeAttribute('hidden');\n }\n }\n\n get tabIndex(): number {\n return this._tabIndex;\n }\n\n set tabIndex(value: number) {\n this._tabIndex = value;\n this.setAttribute('tabindex', value.toString());\n }\n\n get accessKey(): string {\n return this._accessKey;\n }\n\n set accessKey(value: string) {\n this._accessKey = value;\n this.setAttribute('accesskey', value);\n }\n\n get contentEditable(): string {\n return this._contentEditable;\n }\n\n set contentEditable(value: string) {\n this._contentEditable = value;\n this.setAttribute('contenteditable', value);\n }\n\n get isContentEditable(): boolean {\n return this._contentEditable === 'true';\n }\n\n get innerText(): string {\n return this._innerText || this.textContent || '';\n }\n\n set innerText(value: string) {\n this._innerText = value;\n this.textContent = value;\n }\n\n get outerText(): string {\n return this._outerText || this.innerText;\n }\n\n set outerText(value: string) {\n this._outerText = value;\n if (this.parentNode) {\n const { TextBase } = require('../TextBase');\n const textNode = new TextBase(value, this._ownerDocument);\n this.parentNode.replaceChild(textNode, this);\n }\n }\n\n // innerHTML functionality is inherited from ElementBase\n\n // HTMLElement methods\n click(): void {\n // Simulate click event - in a real implementation, this would dispatch events\n console.log(`Clicked on ${this.tagName} element`);\n }\n\n focus(options?: FocusOptions): void {\n // Set focus state using data attribute\n this.setAttribute('data-focused', 'true');\n console.log(`Focused on ${this.tagName} element`);\n }\n\n blur(): void {\n // Remove focus state\n this.removeAttribute('data-focused');\n console.log(`Blurred ${this.tagName} element`);\n }\n\n // Override setAttribute to sync with properties\n setAttribute(qualifiedName: string, value: string): void {\n super.setAttribute(qualifiedName, value);\n\n // Sync with properties\n const name = qualifiedName.toLowerCase();\n switch (name) {\n case 'title':\n this._title = value;\n break;\n case 'lang':\n this._lang = value;\n break;\n case 'dir':\n this._dir = value;\n break;\n case 'hidden':\n this._hidden = true;\n break;\n case 'tabindex':\n this._tabIndex = parseInt(value, 10) || -1;\n break;\n case 'accesskey':\n this._accessKey = value;\n break;\n case 'contenteditable':\n this._contentEditable = value;\n break;\n }\n }\n\n // Override removeAttribute to sync with properties\n removeAttribute(qualifiedName: string): void {\n super.removeAttribute(qualifiedName);\n\n const name = qualifiedName.toLowerCase();\n switch (name) {\n case 'title':\n this._title = '';\n break;\n case 'lang':\n this._lang = '';\n break;\n case 'dir':\n this._dir = '';\n break;\n case 'hidden':\n this._hidden = false;\n break;\n case 'tabindex':\n this._tabIndex = -1;\n break;\n case 'accesskey':\n this._accessKey = '';\n break;\n case 'contenteditable':\n this._contentEditable = 'inherit';\n break;\n }\n }\n}"],
|
|
5
|
-
"mappings": "AAAA,SAAS,mBAAmB;AAQrB,MAAe,wBAAwB,
|
|
4
|
+
"sourcesContent": ["import { ElementBase } from './ElementBase';\nimport { HTMLElement, FocusOptions, CSSStyleDeclaration, DOMStringMap, ElementCSSInlineStyle, StylePropertyMap } from './HTMLElement';\nimport { Text } from '../Text';\nimport { ElementFactory } from '../../factory';\n\n/**\n * Base implementation for all HTML elements\n */\nexport abstract class HTMLElementBase extends ElementBase implements HTMLElement, ElementCSSInlineStyle {\n private _title: string = '';\n private _lang: string = '';\n private _dir: string = '';\n private _hidden: boolean = false;\n private _tabIndex: number = -1;\n private _accessKey: string = '';\n private _contentEditable: string = 'inherit';\n private _innerText: string = '';\n private _outerText: string = '';\n\n constructor(tagName: string, ownerDocument?: any) {\n super(tagName, ownerDocument);\n }\n\n // HTMLElement interface implementation\n get title(): string {\n return this._title;\n }\n\n set title(value: string) {\n this._title = value;\n this.setAttribute('title', value);\n }\n\n get lang(): string {\n return this._lang;\n }\n\n set lang(value: string) {\n this._lang = value;\n this.setAttribute('lang', value);\n }\n\n get dir(): string {\n return this._dir;\n }\n\n set dir(value: string) {\n this._dir = value;\n this.setAttribute('dir', value);\n }\n\n get hidden(): boolean {\n return this._hidden;\n }\n\n set hidden(value: boolean) {\n this._hidden = value;\n if (value) {\n this.setAttribute('hidden', '');\n } else {\n this.removeAttribute('hidden');\n }\n }\n\n get tabIndex(): number {\n return this._tabIndex;\n }\n\n set tabIndex(value: number) {\n this._tabIndex = value;\n this.setAttribute('tabindex', value.toString());\n }\n\n get accessKey(): string {\n return this._accessKey;\n }\n\n set accessKey(value: string) {\n this._accessKey = value;\n this.setAttribute('accesskey', value);\n }\n\n get contentEditable(): string {\n return this._contentEditable;\n }\n\n set contentEditable(value: string) {\n this._contentEditable = value;\n this.setAttribute('contenteditable', value);\n }\n\n get isContentEditable(): boolean {\n return this._contentEditable === 'true';\n }\n\n get innerText(): string {\n return this._innerText || this.textContent || '';\n }\n\n set innerText(value: string) {\n this._innerText = value;\n this.textContent = value;\n }\n\n get outerText(): string {\n return this._outerText || this.innerText;\n }\n\n set outerText(value: string) {\n this._outerText = value;\n if (this.parentNode) {\n const { TextBase } = require('../TextBase');\n const textNode = new TextBase(value, this._ownerDocument);\n this.parentNode.replaceChild(textNode, this);\n }\n }\n\n // innerHTML functionality is inherited from ElementBase\n\n // HTMLElement methods\n click(): void {\n // Simulate click event - in a real implementation, this would dispatch events\n console.log(`Clicked on ${this.tagName} element`);\n }\n\n focus(options?: FocusOptions): void {\n }\n\n blur(): void {\n // Remove focus state\n this.removeAttribute('data-focused');\n console.log(`Blurred ${this.tagName} element`);\n }\n\n // Override setAttribute to sync with properties\n setAttribute(qualifiedName: string, value: string): void {\n super.setAttribute(qualifiedName, value);\n\n // Sync with properties\n const name = qualifiedName.toLowerCase();\n switch (name) {\n case 'title':\n this._title = value;\n break;\n case 'lang':\n this._lang = value;\n break;\n case 'dir':\n this._dir = value;\n break;\n case 'hidden':\n this._hidden = true;\n break;\n case 'tabindex':\n this._tabIndex = parseInt(value, 10) || -1;\n break;\n case 'accesskey':\n this._accessKey = value;\n break;\n case 'contenteditable':\n this._contentEditable = value;\n break;\n }\n }\n\n // Override removeAttribute to sync with properties\n removeAttribute(qualifiedName: string): void {\n super.removeAttribute(qualifiedName);\n\n const name = qualifiedName.toLowerCase();\n switch (name) {\n case 'title':\n this._title = '';\n break;\n case 'lang':\n this._lang = '';\n break;\n case 'dir':\n this._dir = '';\n break;\n case 'hidden':\n this._hidden = false;\n break;\n case 'tabindex':\n this._tabIndex = -1;\n break;\n case 'accesskey':\n this._accessKey = '';\n break;\n case 'contenteditable':\n this._contentEditable = 'inherit';\n break;\n }\n }\n\n // New implementations for style, dataset, nonce\n private _style: CSSStyleDeclaration | null = null;\n private _dataset: DOMStringMap | null = null;\n\n get style(): CSSStyleDeclaration {\n if (!this._style) {\n this._style = new Proxy(new CSSStyleDeclarationImpl(this), {\n get: (target, prop: string | symbol) => {\n if (typeof prop === 'string' && !(prop in target)) {\n // Convert camelCase to kebab-case for CSS properties\n const cssProp = prop.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`);\n return target.getPropertyValue(cssProp);\n }\n return (target as any)[prop];\n },\n set: (target, prop: string | symbol, value: any) => {\n if (typeof prop === 'string' && !(prop in target)) {\n // Convert camelCase to kebab-case for CSS properties\n const cssProp = prop.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`);\n target.setProperty(cssProp, String(value));\n return true;\n }\n (target as any)[prop] = value;\n return true;\n }\n }) as unknown as CSSStyleDeclaration;\n }\n return this._style;\n }\n\n set style(value: string | CSSStyleDeclaration) {\n if (typeof value === 'string') {\n this.style.cssText = value;\n }\n }\n\n private _attributeStyleMap: StylePropertyMap | null = null;\n\n get attributeStyleMap(): StylePropertyMap {\n if (!this._attributeStyleMap) {\n this._attributeStyleMap = new StylePropertyMapImpl(this);\n }\n return this._attributeStyleMap;\n }\n\n get dataset(): DOMStringMap {\n if (!this._dataset) {\n this._dataset = new Proxy({}, {\n get: (target, prop: string | symbol) => {\n if (typeof prop === 'string') {\n // Convert camelCase to kebab-case: fooBar -> data-foo-bar\n const attrName = 'data-' + prop.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`);\n return this.getAttribute(attrName);\n }\n return undefined;\n },\n set: (target, prop: string | symbol, value: any) => {\n if (typeof prop === 'string') {\n // Convert camelCase to kebab-case: fooBar -> data-foo-bar\n const attrName = 'data-' + prop.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`);\n this.setAttribute(attrName, String(value));\n return true;\n }\n return false;\n },\n deleteProperty: (target, prop: string | symbol) => {\n if (typeof prop === 'string') {\n const attrName = 'data-' + prop.replace(/[A-Z]/g, m => `-${m.toLowerCase()}`);\n this.removeAttribute(attrName);\n return true;\n }\n return false;\n }\n });\n }\n return this._dataset;\n }\n\n get nonce(): string {\n return this.getAttribute('nonce') || '';\n }\n\n set nonce(value: string) {\n this.setAttribute('nonce', value);\n }\n}\n\n// CSSStyleDeclaration implementation\nclass CSSStyleDeclarationImpl {\n [key: string]: any;\n\n constructor(private element: HTMLElementBase) { }\n\n parentRule: any = null;\n\n getPropertyPriority(property: string): string {\n return '';\n }\n\n get cssText(): string {\n return this.element.getAttribute('style') || '';\n }\n\n set cssText(value: string) {\n this.element.setAttribute('style', value);\n }\n\n get length(): number {\n return this.parseStyle(this.cssText).size;\n }\n\n getPropertyValue(property: string): string {\n const style = this.parseStyle(this.cssText);\n return style.get(property) || '';\n }\n\n setProperty(property: string, value: string | null, priority: string = ''): void {\n const style = this.parseStyle(this.cssText);\n if (value === null || value === '') {\n style.delete(property);\n } else {\n style.set(property, value); // TODO: handle priority\n }\n this.cssText = this.serializeStyle(style);\n }\n\n removeProperty(property: string): string {\n const style = this.parseStyle(this.cssText);\n const value = style.get(property) || '';\n style.delete(property);\n this.cssText = this.serializeStyle(style);\n return value;\n }\n\n item(index: number): string {\n const style = this.parseStyle(this.cssText);\n return Array.from(style.keys())[index] || '';\n }\n\n private parseStyle(cssText: string): Map<string, string> {\n const style = new Map<string, string>();\n if (!cssText) return style;\n\n cssText.split(';').forEach(declaration => {\n const part = declaration.trim();\n if (!part) return;\n\n const colonIndex = part.indexOf(':');\n if (colonIndex !== -1) {\n const property = part.substring(0, colonIndex).trim();\n const value = part.substring(colonIndex + 1).trim();\n if (property && value) {\n style.set(property, value);\n }\n }\n });\n return style;\n }\n\n private serializeStyle(style: Map<string, string>): string {\n return Array.from(style.entries())\n .map(([property, value]) => `${property}: ${value}`)\n .join('; ');\n }\n}\n\n// StylePropertyMap implementation\nclass StylePropertyMapImpl implements StylePropertyMap {\n [key: string]: any;\n\n constructor(private element: HTMLElementBase) { }\n\n set(property: string, ...values: (string | any)[]): void {\n const value = values[0];\n this.element.style.setProperty(property, String(value));\n }\n\n append(property: string, ...values: (string | any)[]): void {\n this.set(property, ...values);\n }\n\n delete(property: string): void {\n this.element.style.removeProperty(property);\n }\n\n clear(): void {\n this.element.style.cssText = '';\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -276,10 +276,14 @@ class NavigatorBase {
|
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
278
|
class WindowBase {
|
|
279
|
-
constructor(
|
|
279
|
+
constructor(config) {
|
|
280
280
|
// Event system
|
|
281
281
|
this._eventListeners = [];
|
|
282
|
-
|
|
282
|
+
// Timers and intervals tracking
|
|
283
|
+
this._timers = /* @__PURE__ */ new Set();
|
|
284
|
+
this._intervals = /* @__PURE__ */ new Set();
|
|
285
|
+
this._animationFrames = /* @__PURE__ */ new Set();
|
|
286
|
+
this._closed = false;
|
|
283
287
|
this.cookieStore = {};
|
|
284
288
|
this.customElements = {};
|
|
285
289
|
this.devicePixelRatio = 1;
|
|
@@ -504,11 +508,13 @@ class WindowBase {
|
|
|
504
508
|
this.performance = {};
|
|
505
509
|
// WindowSessionStorage
|
|
506
510
|
this.sessionStorage = {};
|
|
507
|
-
|
|
511
|
+
const documentBase = new DocumentBase();
|
|
508
512
|
if (this.document && this.document.setWindow) {
|
|
509
513
|
this.document.setWindow(this);
|
|
510
514
|
}
|
|
511
|
-
this._location = new LocationBase(initialUrl);
|
|
515
|
+
this._location = new LocationBase(config?.initialUrl);
|
|
516
|
+
documentBase.setLocation(this._location);
|
|
517
|
+
this.document = documentBase;
|
|
512
518
|
this.history = new HistoryBase(this);
|
|
513
519
|
this.navigator = new NavigatorBase();
|
|
514
520
|
this.clientInformation = this.navigator;
|
|
@@ -551,6 +557,9 @@ class WindowBase {
|
|
|
551
557
|
}
|
|
552
558
|
});
|
|
553
559
|
}
|
|
560
|
+
get closed() {
|
|
561
|
+
return this._closed;
|
|
562
|
+
}
|
|
554
563
|
get location() {
|
|
555
564
|
return this._location;
|
|
556
565
|
}
|
|
@@ -571,6 +580,103 @@ class WindowBase {
|
|
|
571
580
|
captureEvents() {
|
|
572
581
|
}
|
|
573
582
|
close() {
|
|
583
|
+
if (this._closed) return;
|
|
584
|
+
this._closed = true;
|
|
585
|
+
this._timers.forEach((id) => clearTimeout(id));
|
|
586
|
+
this._timers.clear();
|
|
587
|
+
this._intervals.forEach((id) => clearInterval(id));
|
|
588
|
+
this._intervals.clear();
|
|
589
|
+
this._animationFrames.forEach((id) => clearTimeout(id));
|
|
590
|
+
this._animationFrames.clear();
|
|
591
|
+
this._eventListeners.forEach((listener) => {
|
|
592
|
+
listener.listener = null;
|
|
593
|
+
});
|
|
594
|
+
this._eventListeners.length = 0;
|
|
595
|
+
this.onload = null;
|
|
596
|
+
this.onunload = null;
|
|
597
|
+
this.onbeforeunload = null;
|
|
598
|
+
this.onpopstate = null;
|
|
599
|
+
this.onerror = null;
|
|
600
|
+
this.onmessage = null;
|
|
601
|
+
this.onhashchange = null;
|
|
602
|
+
if (this.document) {
|
|
603
|
+
const doc = this.document;
|
|
604
|
+
if (doc.body) {
|
|
605
|
+
this.clearNodeRecursively(doc.body);
|
|
606
|
+
}
|
|
607
|
+
if (doc.head) {
|
|
608
|
+
this.clearNodeRecursively(doc.head);
|
|
609
|
+
}
|
|
610
|
+
if (doc.documentElement) {
|
|
611
|
+
this.clearNodeRecursively(doc.documentElement);
|
|
612
|
+
}
|
|
613
|
+
if (doc.setWindow) {
|
|
614
|
+
doc.setWindow(null);
|
|
615
|
+
}
|
|
616
|
+
if (doc._eventListeners) {
|
|
617
|
+
doc._eventListeners.forEach((listener) => {
|
|
618
|
+
listener.listener = null;
|
|
619
|
+
});
|
|
620
|
+
doc._eventListeners.length = 0;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
if (this.history) {
|
|
624
|
+
const hist = this.history;
|
|
625
|
+
if (hist.historyStack) {
|
|
626
|
+
hist.historyStack.forEach((entry) => {
|
|
627
|
+
entry.state = null;
|
|
628
|
+
});
|
|
629
|
+
hist.historyStack.length = 0;
|
|
630
|
+
}
|
|
631
|
+
hist.state = null;
|
|
632
|
+
hist.window = null;
|
|
633
|
+
}
|
|
634
|
+
if (this._location) {
|
|
635
|
+
this._location.urlChangeCallback = null;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Recursively clear a node and its children to prevent memory leaks
|
|
640
|
+
*/
|
|
641
|
+
clearNodeRecursively(node) {
|
|
642
|
+
if (!node) return;
|
|
643
|
+
while (node.firstChild) {
|
|
644
|
+
const child = node.firstChild;
|
|
645
|
+
node.removeChild(child);
|
|
646
|
+
this.clearNodeRecursively(child);
|
|
647
|
+
}
|
|
648
|
+
if (node._eventListeners) {
|
|
649
|
+
node._eventListeners.forEach((listener) => {
|
|
650
|
+
listener.listener = null;
|
|
651
|
+
});
|
|
652
|
+
node._eventListeners.length = 0;
|
|
653
|
+
}
|
|
654
|
+
try {
|
|
655
|
+
if (node.parentNode) {
|
|
656
|
+
node.parentNode = null;
|
|
657
|
+
}
|
|
658
|
+
} catch (e) {
|
|
659
|
+
}
|
|
660
|
+
try {
|
|
661
|
+
if (node.ownerDocument) {
|
|
662
|
+
node.ownerDocument = null;
|
|
663
|
+
}
|
|
664
|
+
} catch (e) {
|
|
665
|
+
}
|
|
666
|
+
if (node._childNodes) {
|
|
667
|
+
if (Array.isArray(node._childNodes)) {
|
|
668
|
+
node._childNodes = [];
|
|
669
|
+
} else if (node._childNodes instanceof Map) {
|
|
670
|
+
node._childNodes.clear();
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (node._attributes) {
|
|
674
|
+
if (Array.isArray(node._attributes)) {
|
|
675
|
+
node._attributes = [];
|
|
676
|
+
} else if (node._attributes instanceof Map) {
|
|
677
|
+
node._attributes.clear();
|
|
678
|
+
}
|
|
679
|
+
}
|
|
574
680
|
}
|
|
575
681
|
confirm(message) {
|
|
576
682
|
return false;
|
|
@@ -619,23 +725,38 @@ class WindowBase {
|
|
|
619
725
|
}
|
|
620
726
|
// Timer methods
|
|
621
727
|
setTimeout(callback, delay, ...args) {
|
|
622
|
-
|
|
728
|
+
if (this._closed) return 0;
|
|
729
|
+
const id = setTimeout(() => {
|
|
730
|
+
this._timers.delete(id);
|
|
731
|
+
callback(...args);
|
|
732
|
+
}, delay);
|
|
733
|
+
this._timers.add(id);
|
|
734
|
+
return id;
|
|
623
735
|
}
|
|
624
736
|
clearTimeout(id) {
|
|
625
737
|
clearTimeout(id);
|
|
738
|
+
this._timers.delete(id);
|
|
626
739
|
}
|
|
627
740
|
setInterval(callback, delay, ...args) {
|
|
628
|
-
|
|
741
|
+
if (this._closed) return 0;
|
|
742
|
+
const id = setInterval(callback, delay, ...args);
|
|
743
|
+
this._intervals.add(id);
|
|
744
|
+
return id;
|
|
629
745
|
}
|
|
630
746
|
clearInterval(id) {
|
|
631
747
|
clearInterval(id);
|
|
748
|
+
this._intervals.delete(id);
|
|
632
749
|
}
|
|
633
750
|
// Animation methods
|
|
634
751
|
requestAnimationFrame(callback) {
|
|
635
|
-
|
|
752
|
+
if (this._closed) return 0;
|
|
753
|
+
const id = this.setTimeout(callback, 16);
|
|
754
|
+
this._animationFrames.add(id);
|
|
755
|
+
return id;
|
|
636
756
|
}
|
|
637
757
|
cancelAnimationFrame(id) {
|
|
638
758
|
this.clearTimeout(id);
|
|
759
|
+
this._animationFrames.delete(id);
|
|
639
760
|
}
|
|
640
761
|
addEventListener(type, listener, options) {
|
|
641
762
|
if (type === "popstate" || type === "load" || type === "unload" || type === "beforeunload") {
|