@dooboostore/dom-parser 1.0.1 → 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.
Files changed (48) hide show
  1. package/dist/cjs/DomParser.js +33 -12
  2. package/dist/cjs/DomParser.js.map +2 -2
  3. package/dist/cjs/node/DocumentBase.js +4 -0
  4. package/dist/cjs/node/DocumentBase.js.map +2 -2
  5. package/dist/cjs/node/elements/Element.js.map +1 -1
  6. package/dist/cjs/node/elements/ElementBase.js +12 -2
  7. package/dist/cjs/node/elements/ElementBase.js.map +2 -2
  8. package/dist/cjs/node/elements/HTMLElement.js.map +1 -1
  9. package/dist/cjs/node/elements/HTMLElementBase.js +154 -2
  10. package/dist/cjs/node/elements/HTMLElementBase.js.map +2 -2
  11. package/dist/cjs/window/WindowBase.js +128 -7
  12. package/dist/cjs/window/WindowBase.js.map +2 -2
  13. package/dist/esm/DomParser.js +33 -12
  14. package/dist/esm/DomParser.js.map +2 -2
  15. package/dist/esm/node/DocumentBase.js +4 -0
  16. package/dist/esm/node/DocumentBase.js.map +2 -2
  17. package/dist/esm/node/elements/ElementBase.js +12 -2
  18. package/dist/esm/node/elements/ElementBase.js.map +2 -2
  19. package/dist/esm/node/elements/HTMLElementBase.js +154 -2
  20. package/dist/esm/node/elements/HTMLElementBase.js.map +2 -2
  21. package/dist/esm/window/WindowBase.js +128 -7
  22. package/dist/esm/window/WindowBase.js.map +2 -2
  23. package/dist/esm-bundle/dooboostore-dom-parser.esm.js +504 -195
  24. package/dist/esm-bundle/dooboostore-dom-parser.esm.js.map +3 -3
  25. package/dist/types/DomParser.d.ts +4 -0
  26. package/dist/types/DomParser.d.ts.map +1 -1
  27. package/dist/types/node/DocumentBase.d.ts +2 -0
  28. package/dist/types/node/DocumentBase.d.ts.map +1 -1
  29. package/dist/types/node/elements/Element.d.ts +1 -0
  30. package/dist/types/node/elements/Element.d.ts.map +1 -1
  31. package/dist/types/node/elements/ElementBase.d.ts +2 -2
  32. package/dist/types/node/elements/ElementBase.d.ts.map +1 -1
  33. package/dist/types/node/elements/HTMLElement.d.ts +32 -1
  34. package/dist/types/node/elements/HTMLElement.d.ts.map +1 -1
  35. package/dist/types/node/elements/HTMLElementBase.d.ts +11 -2
  36. package/dist/types/node/elements/HTMLElementBase.d.ts.map +1 -1
  37. package/dist/types/window/WindowBase.d.ts +12 -2
  38. package/dist/types/window/WindowBase.d.ts.map +1 -1
  39. package/dist/umd-bundle/dooboostore-dom-parser.umd.js +504 -195
  40. package/dist/umd-bundle/dooboostore-dom-parser.umd.js.map +3 -3
  41. package/package.json +1 -1
  42. package/src/DomParser.ts +457 -436
  43. package/src/node/DocumentBase.ts +7 -2
  44. package/src/node/elements/Element.ts +24 -23
  45. package/src/node/elements/ElementBase.ts +50 -41
  46. package/src/node/elements/HTMLElement.ts +36 -1
  47. package/src/node/elements/HTMLElementBase.ts +191 -5
  48. package/src/window/WindowBase.ts +1128 -919
@@ -185,100 +185,6 @@ var init_NodeListOf = __esm({
185
185
  }
186
186
  });
187
187
 
188
- // src/node/TextBase.ts
189
- var TextBase_exports = {};
190
- __export(TextBase_exports, {
191
- TextBase: () => TextBase
192
- });
193
- var TextBase;
194
- var init_TextBase = __esm({
195
- "src/node/TextBase.ts"() {
196
- init_ChildNodeBase();
197
- init_Node();
198
- TextBase = class _TextBase extends ChildNodeBase {
199
- constructor(data, ownerDocument) {
200
- super(TEXT_NODE, "#text", ownerDocument);
201
- // Override nodeType to match Text interface
202
- this.nodeType = TEXT_NODE;
203
- this.nodeName = "#text";
204
- this._data = data;
205
- this._nodeValue = data;
206
- }
207
- get data() {
208
- return this._data;
209
- }
210
- set data(value) {
211
- this._data = value;
212
- this._nodeValue = value;
213
- }
214
- get length() {
215
- return this._data.length;
216
- }
217
- get textContent() {
218
- return this._data ? this.decodeHTMLEntities(this._data) : this._data;
219
- }
220
- set textContent(value) {
221
- this._data = value || "";
222
- this._nodeValue = this._data;
223
- }
224
- get wholeText() {
225
- return this._data;
226
- }
227
- // CharacterData methods
228
- appendData(data) {
229
- this._data += data;
230
- this._nodeValue = this._data;
231
- }
232
- deleteData(offset, count) {
233
- if (offset < 0 || offset > this._data.length) {
234
- throw new Error("Index out of bounds");
235
- }
236
- const endOffset = Math.min(offset + count, this._data.length);
237
- this._data = this._data.slice(0, offset) + this._data.slice(endOffset);
238
- this._nodeValue = this._data;
239
- }
240
- insertData(offset, data) {
241
- if (offset < 0 || offset > this._data.length) {
242
- throw new Error("Index out of bounds");
243
- }
244
- this._data = this._data.slice(0, offset) + data + this._data.slice(offset);
245
- this._nodeValue = this._data;
246
- }
247
- replaceData(offset, count, data) {
248
- this.deleteData(offset, count);
249
- this.insertData(offset, data);
250
- }
251
- substringData(offset, count) {
252
- if (offset < 0 || offset > this._data.length) {
253
- throw new Error("Index out of bounds");
254
- }
255
- const endOffset = Math.min(offset + count, this._data.length);
256
- return this._data.slice(offset, endOffset);
257
- }
258
- splitText(offset) {
259
- if (offset < 0 || offset > this._data.length) {
260
- throw new Error("Index out of bounds");
261
- }
262
- const newData = this._data.slice(offset);
263
- this._data = this._data.slice(0, offset);
264
- this._nodeValue = this._data;
265
- const newTextNode = new _TextBase(newData, this._ownerDocument);
266
- if (this._parentNodeInternal) {
267
- const nextSibling = this.nextSibling;
268
- this._parentNodeInternal.insertBefore(newTextNode, nextSibling);
269
- }
270
- return newTextNode;
271
- }
272
- cloneNode(deep) {
273
- return new _TextBase(this._data, this._ownerDocument);
274
- }
275
- toString() {
276
- return this._data;
277
- }
278
- };
279
- }
280
- });
281
-
282
188
  // src/node/NodeBase.ts
283
189
  var NodeBase;
284
190
  var init_NodeBase = __esm({
@@ -689,6 +595,174 @@ var init_ChildNodeBase = __esm({
689
595
  }
690
596
  });
691
597
 
598
+ // src/node/TextBase.ts
599
+ var TextBase_exports = {};
600
+ __export(TextBase_exports, {
601
+ TextBase: () => TextBase
602
+ });
603
+ var TextBase;
604
+ var init_TextBase = __esm({
605
+ "src/node/TextBase.ts"() {
606
+ init_ChildNodeBase();
607
+ init_Node();
608
+ TextBase = class _TextBase extends ChildNodeBase {
609
+ constructor(data, ownerDocument) {
610
+ super(TEXT_NODE, "#text", ownerDocument);
611
+ // Override nodeType to match Text interface
612
+ this.nodeType = TEXT_NODE;
613
+ this.nodeName = "#text";
614
+ this._data = data;
615
+ this._nodeValue = data;
616
+ }
617
+ get data() {
618
+ return this._data;
619
+ }
620
+ set data(value) {
621
+ this._data = value;
622
+ this._nodeValue = value;
623
+ }
624
+ get length() {
625
+ return this._data.length;
626
+ }
627
+ get textContent() {
628
+ return this._data ? this.decodeHTMLEntities(this._data) : this._data;
629
+ }
630
+ set textContent(value) {
631
+ this._data = value || "";
632
+ this._nodeValue = this._data;
633
+ }
634
+ get wholeText() {
635
+ return this._data;
636
+ }
637
+ // CharacterData methods
638
+ appendData(data) {
639
+ this._data += data;
640
+ this._nodeValue = this._data;
641
+ }
642
+ deleteData(offset, count) {
643
+ if (offset < 0 || offset > this._data.length) {
644
+ throw new Error("Index out of bounds");
645
+ }
646
+ const endOffset = Math.min(offset + count, this._data.length);
647
+ this._data = this._data.slice(0, offset) + this._data.slice(endOffset);
648
+ this._nodeValue = this._data;
649
+ }
650
+ insertData(offset, data) {
651
+ if (offset < 0 || offset > this._data.length) {
652
+ throw new Error("Index out of bounds");
653
+ }
654
+ this._data = this._data.slice(0, offset) + data + this._data.slice(offset);
655
+ this._nodeValue = this._data;
656
+ }
657
+ replaceData(offset, count, data) {
658
+ this.deleteData(offset, count);
659
+ this.insertData(offset, data);
660
+ }
661
+ substringData(offset, count) {
662
+ if (offset < 0 || offset > this._data.length) {
663
+ throw new Error("Index out of bounds");
664
+ }
665
+ const endOffset = Math.min(offset + count, this._data.length);
666
+ return this._data.slice(offset, endOffset);
667
+ }
668
+ splitText(offset) {
669
+ if (offset < 0 || offset > this._data.length) {
670
+ throw new Error("Index out of bounds");
671
+ }
672
+ const newData = this._data.slice(offset);
673
+ this._data = this._data.slice(0, offset);
674
+ this._nodeValue = this._data;
675
+ const newTextNode = new _TextBase(newData, this._ownerDocument);
676
+ if (this._parentNodeInternal) {
677
+ const nextSibling = this.nextSibling;
678
+ this._parentNodeInternal.insertBefore(newTextNode, nextSibling);
679
+ }
680
+ return newTextNode;
681
+ }
682
+ cloneNode(deep) {
683
+ return new _TextBase(this._data, this._ownerDocument);
684
+ }
685
+ toString() {
686
+ return this._data;
687
+ }
688
+ };
689
+ }
690
+ });
691
+
692
+ // src/node/Comment.ts
693
+ var Comment_exports = {};
694
+ __export(Comment_exports, {
695
+ Comment: () => Comment
696
+ });
697
+ var Comment;
698
+ var init_Comment = __esm({
699
+ "src/node/Comment.ts"() {
700
+ init_ChildNodeBase();
701
+ init_Node();
702
+ Comment = class _Comment extends ChildNodeBase {
703
+ constructor(data, ownerDocument) {
704
+ super(COMMENT_NODE, "#comment", ownerDocument);
705
+ this._data = data;
706
+ this._nodeValue = data;
707
+ }
708
+ get data() {
709
+ return this._data;
710
+ }
711
+ set data(value) {
712
+ this._data = value;
713
+ this._nodeValue = value;
714
+ }
715
+ get length() {
716
+ return this._data.length;
717
+ }
718
+ get textContent() {
719
+ return this._data;
720
+ }
721
+ set textContent(value) {
722
+ this._data = value || "";
723
+ this._nodeValue = this._data;
724
+ }
725
+ // CharacterData methods
726
+ appendData(data) {
727
+ this._data += data;
728
+ this._nodeValue = this._data;
729
+ }
730
+ deleteData(offset, count) {
731
+ if (offset < 0 || offset > this._data.length) {
732
+ throw new Error("Index out of bounds");
733
+ }
734
+ const endOffset = Math.min(offset + count, this._data.length);
735
+ this._data = this._data.slice(0, offset) + this._data.slice(endOffset);
736
+ this._nodeValue = this._data;
737
+ }
738
+ insertData(offset, data) {
739
+ if (offset < 0 || offset > this._data.length) {
740
+ throw new Error("Index out of bounds");
741
+ }
742
+ this._data = this._data.slice(0, offset) + data + this._data.slice(offset);
743
+ this._nodeValue = this._data;
744
+ }
745
+ replaceData(offset, count, data) {
746
+ this.deleteData(offset, count);
747
+ this.insertData(offset, data);
748
+ }
749
+ substringData(offset, count) {
750
+ if (offset < 0 || offset > this._data.length) {
751
+ throw new Error("Index out of bounds");
752
+ }
753
+ const endOffset = Math.min(offset + count, this._data.length);
754
+ return this._data.slice(offset, endOffset);
755
+ }
756
+ cloneNode(deep) {
757
+ return new _Comment(this._data, this._ownerDocument);
758
+ }
759
+ toString() {
760
+ return `<!--${this._data}-->`;
761
+ }
762
+ };
763
+ }
764
+ });
765
+
692
766
  // src/node/collection/HTMLCollection.ts
693
767
  var HTMLCollection;
694
768
  var init_HTMLCollection = __esm({
@@ -1151,80 +1225,6 @@ var init_ParentNodeBase = __esm({
1151
1225
  }
1152
1226
  });
1153
1227
 
1154
- // src/node/Comment.ts
1155
- var Comment_exports = {};
1156
- __export(Comment_exports, {
1157
- Comment: () => Comment
1158
- });
1159
- var Comment;
1160
- var init_Comment = __esm({
1161
- "src/node/Comment.ts"() {
1162
- init_ChildNodeBase();
1163
- init_Node();
1164
- Comment = class _Comment extends ChildNodeBase {
1165
- constructor(data, ownerDocument) {
1166
- super(COMMENT_NODE, "#comment", ownerDocument);
1167
- this._data = data;
1168
- this._nodeValue = data;
1169
- }
1170
- get data() {
1171
- return this._data;
1172
- }
1173
- set data(value) {
1174
- this._data = value;
1175
- this._nodeValue = value;
1176
- }
1177
- get length() {
1178
- return this._data.length;
1179
- }
1180
- get textContent() {
1181
- return this._data;
1182
- }
1183
- set textContent(value) {
1184
- this._data = value || "";
1185
- this._nodeValue = this._data;
1186
- }
1187
- // CharacterData methods
1188
- appendData(data) {
1189
- this._data += data;
1190
- this._nodeValue = this._data;
1191
- }
1192
- deleteData(offset, count) {
1193
- if (offset < 0 || offset > this._data.length) {
1194
- throw new Error("Index out of bounds");
1195
- }
1196
- const endOffset = Math.min(offset + count, this._data.length);
1197
- this._data = this._data.slice(0, offset) + this._data.slice(endOffset);
1198
- this._nodeValue = this._data;
1199
- }
1200
- insertData(offset, data) {
1201
- if (offset < 0 || offset > this._data.length) {
1202
- throw new Error("Index out of bounds");
1203
- }
1204
- this._data = this._data.slice(0, offset) + data + this._data.slice(offset);
1205
- this._nodeValue = this._data;
1206
- }
1207
- replaceData(offset, count, data) {
1208
- this.deleteData(offset, count);
1209
- this.insertData(offset, data);
1210
- }
1211
- substringData(offset, count) {
1212
- if (offset < 0 || offset > this._data.length) {
1213
- throw new Error("Index out of bounds");
1214
- }
1215
- const endOffset = Math.min(offset + count, this._data.length);
1216
- return this._data.slice(offset, endOffset);
1217
- }
1218
- cloneNode(deep) {
1219
- return new _Comment(this._data, this._ownerDocument);
1220
- }
1221
- toString() {
1222
- return `<!--${this._data}-->`;
1223
- }
1224
- };
1225
- }
1226
- });
1227
-
1228
1228
  // src/node/DocumentFragmentBase.ts
1229
1229
  var DocumentFragmentBase;
1230
1230
  var init_DocumentFragmentBase = __esm({
@@ -1423,7 +1423,7 @@ var init_ElementBase = __esm({
1423
1423
  */
1424
1424
  generateChildElementHTML(element) {
1425
1425
  const tagName = element.tagName.toLowerCase();
1426
- const attrs = Array.from(element._attributes?.entries() || []).map(([name, value]) => value === "" ? ` ${name}` : ` ${name}="${value.replace(/"/g, "&quot;")}"`).join("");
1426
+ const attrs = Array.from(element._attributes?.entries() || []).map(([name, value]) => value === "" ? ` ${name}` : ` ${name}="${String(value).replace(/"/g, "&quot;")}"`).join("");
1427
1427
  const selfClosingTags = ["img", "input", "br", "hr", "meta", "link", "area", "base", "col", "embed", "source", "track", "wbr"];
1428
1428
  const isSelfClosing = selfClosingTags.includes(tagName);
1429
1429
  if (isSelfClosing) {
@@ -1855,7 +1855,17 @@ var init_ElementBase = __esm({
1855
1855
  return this.getAttributeNode(localName);
1856
1856
  }
1857
1857
  getBoundingClientRect() {
1858
- throw new Error("Element.getBoundingClientRect() is not implemented yet");
1858
+ return {
1859
+ bottom: 0,
1860
+ height: 0,
1861
+ left: 0,
1862
+ right: 0,
1863
+ top: 0,
1864
+ width: 0,
1865
+ x: 0,
1866
+ y: 0,
1867
+ toJSON: () => ({})
1868
+ };
1859
1869
  }
1860
1870
  getClientRects() {
1861
1871
  throw new Error("Element.getClientRects() is not implemented yet");
@@ -2250,7 +2260,7 @@ var init_ElementBase = __esm({
2250
2260
  });
2251
2261
 
2252
2262
  // src/node/elements/HTMLElementBase.ts
2253
- var HTMLElementBase;
2263
+ var HTMLElementBase, CSSStyleDeclarationImpl, StylePropertyMapImpl;
2254
2264
  var init_HTMLElementBase = __esm({
2255
2265
  "src/node/elements/HTMLElementBase.ts"() {
2256
2266
  init_ElementBase();
@@ -2266,6 +2276,10 @@ var init_HTMLElementBase = __esm({
2266
2276
  this._contentEditable = "inherit";
2267
2277
  this._innerText = "";
2268
2278
  this._outerText = "";
2279
+ // New implementations for style, dataset, nonce
2280
+ this._style = null;
2281
+ this._dataset = null;
2282
+ this._attributeStyleMap = null;
2269
2283
  }
2270
2284
  // HTMLElement interface implementation
2271
2285
  get title() {
@@ -2348,8 +2362,6 @@ var init_HTMLElementBase = __esm({
2348
2362
  console.log(`Clicked on ${this.tagName} element`);
2349
2363
  }
2350
2364
  focus(options) {
2351
- this.setAttribute("data-focused", "true");
2352
- console.log(`Focused on ${this.tagName} element`);
2353
2365
  }
2354
2366
  blur() {
2355
2367
  this.removeAttribute("data-focused");
@@ -2411,6 +2423,156 @@ var init_HTMLElementBase = __esm({
2411
2423
  break;
2412
2424
  }
2413
2425
  }
2426
+ get style() {
2427
+ if (!this._style) {
2428
+ this._style = new Proxy(new CSSStyleDeclarationImpl(this), {
2429
+ get: (target, prop) => {
2430
+ if (typeof prop === "string" && !(prop in target)) {
2431
+ const cssProp = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2432
+ return target.getPropertyValue(cssProp);
2433
+ }
2434
+ return target[prop];
2435
+ },
2436
+ set: (target, prop, value) => {
2437
+ if (typeof prop === "string" && !(prop in target)) {
2438
+ const cssProp = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2439
+ target.setProperty(cssProp, String(value));
2440
+ return true;
2441
+ }
2442
+ target[prop] = value;
2443
+ return true;
2444
+ }
2445
+ });
2446
+ }
2447
+ return this._style;
2448
+ }
2449
+ set style(value) {
2450
+ if (typeof value === "string") {
2451
+ this.style.cssText = value;
2452
+ }
2453
+ }
2454
+ get attributeStyleMap() {
2455
+ if (!this._attributeStyleMap) {
2456
+ this._attributeStyleMap = new StylePropertyMapImpl(this);
2457
+ }
2458
+ return this._attributeStyleMap;
2459
+ }
2460
+ get dataset() {
2461
+ if (!this._dataset) {
2462
+ this._dataset = new Proxy({}, {
2463
+ get: (target, prop) => {
2464
+ if (typeof prop === "string") {
2465
+ const attrName = "data-" + prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2466
+ return this.getAttribute(attrName);
2467
+ }
2468
+ return void 0;
2469
+ },
2470
+ set: (target, prop, value) => {
2471
+ if (typeof prop === "string") {
2472
+ const attrName = "data-" + prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2473
+ this.setAttribute(attrName, String(value));
2474
+ return true;
2475
+ }
2476
+ return false;
2477
+ },
2478
+ deleteProperty: (target, prop) => {
2479
+ if (typeof prop === "string") {
2480
+ const attrName = "data-" + prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2481
+ this.removeAttribute(attrName);
2482
+ return true;
2483
+ }
2484
+ return false;
2485
+ }
2486
+ });
2487
+ }
2488
+ return this._dataset;
2489
+ }
2490
+ get nonce() {
2491
+ return this.getAttribute("nonce") || "";
2492
+ }
2493
+ set nonce(value) {
2494
+ this.setAttribute("nonce", value);
2495
+ }
2496
+ };
2497
+ CSSStyleDeclarationImpl = class {
2498
+ constructor(element) {
2499
+ this.element = element;
2500
+ this.parentRule = null;
2501
+ }
2502
+ getPropertyPriority(property) {
2503
+ return "";
2504
+ }
2505
+ get cssText() {
2506
+ return this.element.getAttribute("style") || "";
2507
+ }
2508
+ set cssText(value) {
2509
+ this.element.setAttribute("style", value);
2510
+ }
2511
+ get length() {
2512
+ return this.parseStyle(this.cssText).size;
2513
+ }
2514
+ getPropertyValue(property) {
2515
+ const style = this.parseStyle(this.cssText);
2516
+ return style.get(property) || "";
2517
+ }
2518
+ setProperty(property, value, priority = "") {
2519
+ const style = this.parseStyle(this.cssText);
2520
+ if (value === null || value === "") {
2521
+ style.delete(property);
2522
+ } else {
2523
+ style.set(property, value);
2524
+ }
2525
+ this.cssText = this.serializeStyle(style);
2526
+ }
2527
+ removeProperty(property) {
2528
+ const style = this.parseStyle(this.cssText);
2529
+ const value = style.get(property) || "";
2530
+ style.delete(property);
2531
+ this.cssText = this.serializeStyle(style);
2532
+ return value;
2533
+ }
2534
+ item(index) {
2535
+ const style = this.parseStyle(this.cssText);
2536
+ return Array.from(style.keys())[index] || "";
2537
+ }
2538
+ parseStyle(cssText) {
2539
+ const style = /* @__PURE__ */ new Map();
2540
+ if (!cssText) return style;
2541
+ cssText.split(";").forEach((declaration) => {
2542
+ const part = declaration.trim();
2543
+ if (!part) return;
2544
+ const colonIndex = part.indexOf(":");
2545
+ if (colonIndex !== -1) {
2546
+ const property = part.substring(0, colonIndex).trim();
2547
+ const value = part.substring(colonIndex + 1).trim();
2548
+ if (property && value) {
2549
+ style.set(property, value);
2550
+ }
2551
+ }
2552
+ });
2553
+ return style;
2554
+ }
2555
+ serializeStyle(style) {
2556
+ return Array.from(style.entries()).map(([property, value]) => `${property}: ${value}`).join("; ");
2557
+ }
2558
+ };
2559
+ StylePropertyMapImpl = class {
2560
+ constructor(element) {
2561
+ this.element = element;
2562
+ }
2563
+ set(property, ...values) {
2564
+ const value = values[0];
2565
+ this.element.style.setProperty(property, String(value));
2566
+ }
2567
+ append(property, ...values) {
2568
+ this.set(property, ...values);
2569
+ }
2570
+ delete(property) {
2571
+ this.element.style.removeProperty(property);
2572
+ }
2573
+ clear() {
2574
+ this.element.style.cssText = "";
2575
+ }
2414
2576
  };
2415
2577
  }
2416
2578
  });
@@ -4494,6 +4656,10 @@ var init_ElementFactory = __esm({
4494
4656
  }
4495
4657
  });
4496
4658
 
4659
+ // src/DomParser.ts
4660
+ init_TextBase();
4661
+ init_Comment();
4662
+
4497
4663
  // src/node/DocumentBase.ts
4498
4664
  init_ParentNodeBase();
4499
4665
  init_Node();
@@ -4709,6 +4875,7 @@ var DocumentBase = class extends ParentNodeBase {
4709
4875
  },
4710
4876
  reload: () => {
4711
4877
  },
4878
+ // @ts-ignore
4712
4879
  toString: () => this._location.href
4713
4880
  };
4714
4881
  // Event handlers
@@ -4738,6 +4905,9 @@ var DocumentBase = class extends ParentNodeBase {
4738
4905
  this.head = head;
4739
4906
  this.body = body;
4740
4907
  }
4908
+ setLocation(location) {
4909
+ this._location = location;
4910
+ }
4741
4911
  get location() {
4742
4912
  return this._location;
4743
4913
  }
@@ -4995,10 +5165,6 @@ var DocumentBase = class extends ParentNodeBase {
4995
5165
  }
4996
5166
  };
4997
5167
 
4998
- // src/DomParser.ts
4999
- init_TextBase();
5000
- init_Comment();
5001
-
5002
5168
  // src/window/WindowBase.ts
5003
5169
  init_NodeBase();
5004
5170
  init_ElementBase();
@@ -5277,10 +5443,14 @@ var NavigatorBase = class {
5277
5443
  }
5278
5444
  };
5279
5445
  var WindowBase = class {
5280
- constructor(document, initialUrl) {
5446
+ constructor(config) {
5281
5447
  // Event system
5282
5448
  this._eventListeners = [];
5283
- this.closed = false;
5449
+ // Timers and intervals tracking
5450
+ this._timers = /* @__PURE__ */ new Set();
5451
+ this._intervals = /* @__PURE__ */ new Set();
5452
+ this._animationFrames = /* @__PURE__ */ new Set();
5453
+ this._closed = false;
5284
5454
  this.cookieStore = {};
5285
5455
  this.customElements = {};
5286
5456
  this.devicePixelRatio = 1;
@@ -5505,11 +5675,13 @@ var WindowBase = class {
5505
5675
  this.performance = {};
5506
5676
  // WindowSessionStorage
5507
5677
  this.sessionStorage = {};
5508
- this.document = document || new DocumentBase();
5678
+ const documentBase = new DocumentBase();
5509
5679
  if (this.document && this.document.setWindow) {
5510
5680
  this.document.setWindow(this);
5511
5681
  }
5512
- this._location = new LocationBase(initialUrl);
5682
+ this._location = new LocationBase(config?.initialUrl);
5683
+ documentBase.setLocation(this._location);
5684
+ this.document = documentBase;
5513
5685
  this.history = new HistoryBase(this);
5514
5686
  this.navigator = new NavigatorBase();
5515
5687
  this.clientInformation = this.navigator;
@@ -5552,6 +5724,9 @@ var WindowBase = class {
5552
5724
  }
5553
5725
  });
5554
5726
  }
5727
+ get closed() {
5728
+ return this._closed;
5729
+ }
5555
5730
  get location() {
5556
5731
  return this._location;
5557
5732
  }
@@ -5572,6 +5747,103 @@ var WindowBase = class {
5572
5747
  captureEvents() {
5573
5748
  }
5574
5749
  close() {
5750
+ if (this._closed) return;
5751
+ this._closed = true;
5752
+ this._timers.forEach((id) => clearTimeout(id));
5753
+ this._timers.clear();
5754
+ this._intervals.forEach((id) => clearInterval(id));
5755
+ this._intervals.clear();
5756
+ this._animationFrames.forEach((id) => clearTimeout(id));
5757
+ this._animationFrames.clear();
5758
+ this._eventListeners.forEach((listener) => {
5759
+ listener.listener = null;
5760
+ });
5761
+ this._eventListeners.length = 0;
5762
+ this.onload = null;
5763
+ this.onunload = null;
5764
+ this.onbeforeunload = null;
5765
+ this.onpopstate = null;
5766
+ this.onerror = null;
5767
+ this.onmessage = null;
5768
+ this.onhashchange = null;
5769
+ if (this.document) {
5770
+ const doc = this.document;
5771
+ if (doc.body) {
5772
+ this.clearNodeRecursively(doc.body);
5773
+ }
5774
+ if (doc.head) {
5775
+ this.clearNodeRecursively(doc.head);
5776
+ }
5777
+ if (doc.documentElement) {
5778
+ this.clearNodeRecursively(doc.documentElement);
5779
+ }
5780
+ if (doc.setWindow) {
5781
+ doc.setWindow(null);
5782
+ }
5783
+ if (doc._eventListeners) {
5784
+ doc._eventListeners.forEach((listener) => {
5785
+ listener.listener = null;
5786
+ });
5787
+ doc._eventListeners.length = 0;
5788
+ }
5789
+ }
5790
+ if (this.history) {
5791
+ const hist = this.history;
5792
+ if (hist.historyStack) {
5793
+ hist.historyStack.forEach((entry) => {
5794
+ entry.state = null;
5795
+ });
5796
+ hist.historyStack.length = 0;
5797
+ }
5798
+ hist.state = null;
5799
+ hist.window = null;
5800
+ }
5801
+ if (this._location) {
5802
+ this._location.urlChangeCallback = null;
5803
+ }
5804
+ }
5805
+ /**
5806
+ * Recursively clear a node and its children to prevent memory leaks
5807
+ */
5808
+ clearNodeRecursively(node) {
5809
+ if (!node) return;
5810
+ while (node.firstChild) {
5811
+ const child = node.firstChild;
5812
+ node.removeChild(child);
5813
+ this.clearNodeRecursively(child);
5814
+ }
5815
+ if (node._eventListeners) {
5816
+ node._eventListeners.forEach((listener) => {
5817
+ listener.listener = null;
5818
+ });
5819
+ node._eventListeners.length = 0;
5820
+ }
5821
+ try {
5822
+ if (node.parentNode) {
5823
+ node.parentNode = null;
5824
+ }
5825
+ } catch (e) {
5826
+ }
5827
+ try {
5828
+ if (node.ownerDocument) {
5829
+ node.ownerDocument = null;
5830
+ }
5831
+ } catch (e) {
5832
+ }
5833
+ if (node._childNodes) {
5834
+ if (Array.isArray(node._childNodes)) {
5835
+ node._childNodes = [];
5836
+ } else if (node._childNodes instanceof Map) {
5837
+ node._childNodes.clear();
5838
+ }
5839
+ }
5840
+ if (node._attributes) {
5841
+ if (Array.isArray(node._attributes)) {
5842
+ node._attributes = [];
5843
+ } else if (node._attributes instanceof Map) {
5844
+ node._attributes.clear();
5845
+ }
5846
+ }
5575
5847
  }
5576
5848
  confirm(message) {
5577
5849
  return false;
@@ -5620,23 +5892,38 @@ var WindowBase = class {
5620
5892
  }
5621
5893
  // Timer methods
5622
5894
  setTimeout(callback, delay, ...args) {
5623
- return setTimeout(callback, delay, ...args);
5895
+ if (this._closed) return 0;
5896
+ const id = setTimeout(() => {
5897
+ this._timers.delete(id);
5898
+ callback(...args);
5899
+ }, delay);
5900
+ this._timers.add(id);
5901
+ return id;
5624
5902
  }
5625
5903
  clearTimeout(id) {
5626
5904
  clearTimeout(id);
5905
+ this._timers.delete(id);
5627
5906
  }
5628
5907
  setInterval(callback, delay, ...args) {
5629
- return setInterval(callback, delay, ...args);
5908
+ if (this._closed) return 0;
5909
+ const id = setInterval(callback, delay, ...args);
5910
+ this._intervals.add(id);
5911
+ return id;
5630
5912
  }
5631
5913
  clearInterval(id) {
5632
5914
  clearInterval(id);
5915
+ this._intervals.delete(id);
5633
5916
  }
5634
5917
  // Animation methods
5635
5918
  requestAnimationFrame(callback) {
5636
- return this.setTimeout(callback, 16);
5919
+ if (this._closed) return 0;
5920
+ const id = this.setTimeout(callback, 16);
5921
+ this._animationFrames.add(id);
5922
+ return id;
5637
5923
  }
5638
5924
  cancelAnimationFrame(id) {
5639
5925
  this.clearTimeout(id);
5926
+ this._animationFrames.delete(id);
5640
5927
  }
5641
5928
  addEventListener(type, listener, options) {
5642
5929
  if (type === "popstate" || type === "load" || type === "unload" || type === "beforeunload") {
@@ -5827,43 +6114,65 @@ var WindowBase = class {
5827
6114
  // src/DomParser.ts
5828
6115
  var DomParser = class {
5829
6116
  constructor(html, option) {
5830
- const document = new DocumentBase();
5831
- const windowBase = new WindowBase(document, option?.href);
6117
+ const windowBase = new WindowBase({ initialUrl: option?.href });
5832
6118
  this._window = windowBase;
5833
- this._document = document;
6119
+ this._document = windowBase.document;
5834
6120
  this.parseHTML(html);
5835
6121
  this.setupDocumentReferences();
5836
- if (document && document.simulateLoading) {
5837
- document.simulateLoading();
6122
+ if (this._document && this._document.simulateLoading) {
6123
+ this._document.simulateLoading();
5838
6124
  }
5839
6125
  }
5840
6126
  get window() {
6127
+ if (!this._window) {
6128
+ throw new Error("DomParser has been destroyed");
6129
+ }
5841
6130
  return this._window;
5842
6131
  }
5843
6132
  get document() {
6133
+ if (!this._document) {
6134
+ throw new Error("DomParser has been destroyed");
6135
+ }
5844
6136
  return this._document;
5845
6137
  }
6138
+ /**
6139
+ * Destroy the DomParser instance and free memory
6140
+ */
6141
+ destroy() {
6142
+ if (this._window) {
6143
+ this._window.close();
6144
+ this._window = null;
6145
+ }
6146
+ this._document = null;
6147
+ }
5846
6148
  /**
5847
6149
  * Load new HTML content and replace the current document
5848
6150
  */
5849
6151
  loadHTML(html) {
6152
+ if (!this._document) {
6153
+ throw new Error("DomParser has been destroyed");
6154
+ }
5850
6155
  this.clearDocument();
5851
6156
  this.parseHTML(html);
5852
6157
  this.setupDocumentReferences();
5853
6158
  }
5854
6159
  clearDocument() {
5855
- if (this.document.head) {
5856
- while (this.document.head.firstChild) {
5857
- this.document.head.removeChild(this.document.head.firstChild);
6160
+ if (!this._document) return;
6161
+ if (this._document.head) {
6162
+ while (this._document.head.firstChild) {
6163
+ this._document.head.removeChild(this._document.head.firstChild);
5858
6164
  }
5859
6165
  }
5860
- if (this.document.body) {
5861
- while (this.document.body.firstChild) {
5862
- this.document.body.removeChild(this.document.body.firstChild);
6166
+ if (this._document.body) {
6167
+ while (this._document.body.firstChild) {
6168
+ this._document.body.removeChild(this._document.body.firstChild);
5863
6169
  }
5864
6170
  }
5865
6171
  }
5866
6172
  parseHTML(html) {
6173
+ if (!this._document) {
6174
+ throw new Error("DomParser has been destroyed");
6175
+ }
5867
6176
  if (!html.trim()) {
5868
6177
  return;
5869
6178
  }