@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
@@ -186,100 +186,6 @@ var dooboostoreDomParser = (() => {
186
186
  }
187
187
  });
188
188
 
189
- // src/node/TextBase.ts
190
- var TextBase_exports = {};
191
- __export(TextBase_exports, {
192
- TextBase: () => TextBase
193
- });
194
- var TextBase;
195
- var init_TextBase = __esm({
196
- "src/node/TextBase.ts"() {
197
- init_ChildNodeBase();
198
- init_Node();
199
- TextBase = class _TextBase extends ChildNodeBase {
200
- constructor(data, ownerDocument) {
201
- super(TEXT_NODE, "#text", ownerDocument);
202
- // Override nodeType to match Text interface
203
- this.nodeType = TEXT_NODE;
204
- this.nodeName = "#text";
205
- this._data = data;
206
- this._nodeValue = data;
207
- }
208
- get data() {
209
- return this._data;
210
- }
211
- set data(value) {
212
- this._data = value;
213
- this._nodeValue = value;
214
- }
215
- get length() {
216
- return this._data.length;
217
- }
218
- get textContent() {
219
- return this._data ? this.decodeHTMLEntities(this._data) : this._data;
220
- }
221
- set textContent(value) {
222
- this._data = value || "";
223
- this._nodeValue = this._data;
224
- }
225
- get wholeText() {
226
- return this._data;
227
- }
228
- // CharacterData methods
229
- appendData(data) {
230
- this._data += data;
231
- this._nodeValue = this._data;
232
- }
233
- deleteData(offset, count) {
234
- if (offset < 0 || offset > this._data.length) {
235
- throw new Error("Index out of bounds");
236
- }
237
- const endOffset = Math.min(offset + count, this._data.length);
238
- this._data = this._data.slice(0, offset) + this._data.slice(endOffset);
239
- this._nodeValue = this._data;
240
- }
241
- insertData(offset, data) {
242
- if (offset < 0 || offset > this._data.length) {
243
- throw new Error("Index out of bounds");
244
- }
245
- this._data = this._data.slice(0, offset) + data + this._data.slice(offset);
246
- this._nodeValue = this._data;
247
- }
248
- replaceData(offset, count, data) {
249
- this.deleteData(offset, count);
250
- this.insertData(offset, data);
251
- }
252
- substringData(offset, count) {
253
- if (offset < 0 || offset > this._data.length) {
254
- throw new Error("Index out of bounds");
255
- }
256
- const endOffset = Math.min(offset + count, this._data.length);
257
- return this._data.slice(offset, endOffset);
258
- }
259
- splitText(offset) {
260
- if (offset < 0 || offset > this._data.length) {
261
- throw new Error("Index out of bounds");
262
- }
263
- const newData = this._data.slice(offset);
264
- this._data = this._data.slice(0, offset);
265
- this._nodeValue = this._data;
266
- const newTextNode = new _TextBase(newData, this._ownerDocument);
267
- if (this._parentNodeInternal) {
268
- const nextSibling = this.nextSibling;
269
- this._parentNodeInternal.insertBefore(newTextNode, nextSibling);
270
- }
271
- return newTextNode;
272
- }
273
- cloneNode(deep) {
274
- return new _TextBase(this._data, this._ownerDocument);
275
- }
276
- toString() {
277
- return this._data;
278
- }
279
- };
280
- }
281
- });
282
-
283
189
  // src/node/NodeBase.ts
284
190
  var NodeBase;
285
191
  var init_NodeBase = __esm({
@@ -690,6 +596,174 @@ var dooboostoreDomParser = (() => {
690
596
  }
691
597
  });
692
598
 
599
+ // src/node/TextBase.ts
600
+ var TextBase_exports = {};
601
+ __export(TextBase_exports, {
602
+ TextBase: () => TextBase
603
+ });
604
+ var TextBase;
605
+ var init_TextBase = __esm({
606
+ "src/node/TextBase.ts"() {
607
+ init_ChildNodeBase();
608
+ init_Node();
609
+ TextBase = class _TextBase extends ChildNodeBase {
610
+ constructor(data, ownerDocument) {
611
+ super(TEXT_NODE, "#text", ownerDocument);
612
+ // Override nodeType to match Text interface
613
+ this.nodeType = TEXT_NODE;
614
+ this.nodeName = "#text";
615
+ this._data = data;
616
+ this._nodeValue = data;
617
+ }
618
+ get data() {
619
+ return this._data;
620
+ }
621
+ set data(value) {
622
+ this._data = value;
623
+ this._nodeValue = value;
624
+ }
625
+ get length() {
626
+ return this._data.length;
627
+ }
628
+ get textContent() {
629
+ return this._data ? this.decodeHTMLEntities(this._data) : this._data;
630
+ }
631
+ set textContent(value) {
632
+ this._data = value || "";
633
+ this._nodeValue = this._data;
634
+ }
635
+ get wholeText() {
636
+ return this._data;
637
+ }
638
+ // CharacterData methods
639
+ appendData(data) {
640
+ this._data += data;
641
+ this._nodeValue = this._data;
642
+ }
643
+ deleteData(offset, count) {
644
+ if (offset < 0 || offset > this._data.length) {
645
+ throw new Error("Index out of bounds");
646
+ }
647
+ const endOffset = Math.min(offset + count, this._data.length);
648
+ this._data = this._data.slice(0, offset) + this._data.slice(endOffset);
649
+ this._nodeValue = this._data;
650
+ }
651
+ insertData(offset, data) {
652
+ if (offset < 0 || offset > this._data.length) {
653
+ throw new Error("Index out of bounds");
654
+ }
655
+ this._data = this._data.slice(0, offset) + data + this._data.slice(offset);
656
+ this._nodeValue = this._data;
657
+ }
658
+ replaceData(offset, count, data) {
659
+ this.deleteData(offset, count);
660
+ this.insertData(offset, data);
661
+ }
662
+ substringData(offset, count) {
663
+ if (offset < 0 || offset > this._data.length) {
664
+ throw new Error("Index out of bounds");
665
+ }
666
+ const endOffset = Math.min(offset + count, this._data.length);
667
+ return this._data.slice(offset, endOffset);
668
+ }
669
+ splitText(offset) {
670
+ if (offset < 0 || offset > this._data.length) {
671
+ throw new Error("Index out of bounds");
672
+ }
673
+ const newData = this._data.slice(offset);
674
+ this._data = this._data.slice(0, offset);
675
+ this._nodeValue = this._data;
676
+ const newTextNode = new _TextBase(newData, this._ownerDocument);
677
+ if (this._parentNodeInternal) {
678
+ const nextSibling = this.nextSibling;
679
+ this._parentNodeInternal.insertBefore(newTextNode, nextSibling);
680
+ }
681
+ return newTextNode;
682
+ }
683
+ cloneNode(deep) {
684
+ return new _TextBase(this._data, this._ownerDocument);
685
+ }
686
+ toString() {
687
+ return this._data;
688
+ }
689
+ };
690
+ }
691
+ });
692
+
693
+ // src/node/Comment.ts
694
+ var Comment_exports = {};
695
+ __export(Comment_exports, {
696
+ Comment: () => Comment
697
+ });
698
+ var Comment;
699
+ var init_Comment = __esm({
700
+ "src/node/Comment.ts"() {
701
+ init_ChildNodeBase();
702
+ init_Node();
703
+ Comment = class _Comment extends ChildNodeBase {
704
+ constructor(data, ownerDocument) {
705
+ super(COMMENT_NODE, "#comment", ownerDocument);
706
+ this._data = data;
707
+ this._nodeValue = data;
708
+ }
709
+ get data() {
710
+ return this._data;
711
+ }
712
+ set data(value) {
713
+ this._data = value;
714
+ this._nodeValue = value;
715
+ }
716
+ get length() {
717
+ return this._data.length;
718
+ }
719
+ get textContent() {
720
+ return this._data;
721
+ }
722
+ set textContent(value) {
723
+ this._data = value || "";
724
+ this._nodeValue = this._data;
725
+ }
726
+ // CharacterData methods
727
+ appendData(data) {
728
+ this._data += data;
729
+ this._nodeValue = this._data;
730
+ }
731
+ deleteData(offset, count) {
732
+ if (offset < 0 || offset > this._data.length) {
733
+ throw new Error("Index out of bounds");
734
+ }
735
+ const endOffset = Math.min(offset + count, this._data.length);
736
+ this._data = this._data.slice(0, offset) + this._data.slice(endOffset);
737
+ this._nodeValue = this._data;
738
+ }
739
+ insertData(offset, data) {
740
+ if (offset < 0 || offset > this._data.length) {
741
+ throw new Error("Index out of bounds");
742
+ }
743
+ this._data = this._data.slice(0, offset) + data + this._data.slice(offset);
744
+ this._nodeValue = this._data;
745
+ }
746
+ replaceData(offset, count, data) {
747
+ this.deleteData(offset, count);
748
+ this.insertData(offset, data);
749
+ }
750
+ substringData(offset, count) {
751
+ if (offset < 0 || offset > this._data.length) {
752
+ throw new Error("Index out of bounds");
753
+ }
754
+ const endOffset = Math.min(offset + count, this._data.length);
755
+ return this._data.slice(offset, endOffset);
756
+ }
757
+ cloneNode(deep) {
758
+ return new _Comment(this._data, this._ownerDocument);
759
+ }
760
+ toString() {
761
+ return `<!--${this._data}-->`;
762
+ }
763
+ };
764
+ }
765
+ });
766
+
693
767
  // src/node/collection/HTMLCollection.ts
694
768
  var HTMLCollection;
695
769
  var init_HTMLCollection = __esm({
@@ -1152,80 +1226,6 @@ var dooboostoreDomParser = (() => {
1152
1226
  }
1153
1227
  });
1154
1228
 
1155
- // src/node/Comment.ts
1156
- var Comment_exports = {};
1157
- __export(Comment_exports, {
1158
- Comment: () => Comment
1159
- });
1160
- var Comment;
1161
- var init_Comment = __esm({
1162
- "src/node/Comment.ts"() {
1163
- init_ChildNodeBase();
1164
- init_Node();
1165
- Comment = class _Comment extends ChildNodeBase {
1166
- constructor(data, ownerDocument) {
1167
- super(COMMENT_NODE, "#comment", ownerDocument);
1168
- this._data = data;
1169
- this._nodeValue = data;
1170
- }
1171
- get data() {
1172
- return this._data;
1173
- }
1174
- set data(value) {
1175
- this._data = value;
1176
- this._nodeValue = value;
1177
- }
1178
- get length() {
1179
- return this._data.length;
1180
- }
1181
- get textContent() {
1182
- return this._data;
1183
- }
1184
- set textContent(value) {
1185
- this._data = value || "";
1186
- this._nodeValue = this._data;
1187
- }
1188
- // CharacterData methods
1189
- appendData(data) {
1190
- this._data += data;
1191
- this._nodeValue = this._data;
1192
- }
1193
- deleteData(offset, count) {
1194
- if (offset < 0 || offset > this._data.length) {
1195
- throw new Error("Index out of bounds");
1196
- }
1197
- const endOffset = Math.min(offset + count, this._data.length);
1198
- this._data = this._data.slice(0, offset) + this._data.slice(endOffset);
1199
- this._nodeValue = this._data;
1200
- }
1201
- insertData(offset, data) {
1202
- if (offset < 0 || offset > this._data.length) {
1203
- throw new Error("Index out of bounds");
1204
- }
1205
- this._data = this._data.slice(0, offset) + data + this._data.slice(offset);
1206
- this._nodeValue = this._data;
1207
- }
1208
- replaceData(offset, count, data) {
1209
- this.deleteData(offset, count);
1210
- this.insertData(offset, data);
1211
- }
1212
- substringData(offset, count) {
1213
- if (offset < 0 || offset > this._data.length) {
1214
- throw new Error("Index out of bounds");
1215
- }
1216
- const endOffset = Math.min(offset + count, this._data.length);
1217
- return this._data.slice(offset, endOffset);
1218
- }
1219
- cloneNode(deep) {
1220
- return new _Comment(this._data, this._ownerDocument);
1221
- }
1222
- toString() {
1223
- return `<!--${this._data}-->`;
1224
- }
1225
- };
1226
- }
1227
- });
1228
-
1229
1229
  // src/node/DocumentFragmentBase.ts
1230
1230
  var DocumentFragmentBase;
1231
1231
  var init_DocumentFragmentBase = __esm({
@@ -1424,7 +1424,7 @@ var dooboostoreDomParser = (() => {
1424
1424
  */
1425
1425
  generateChildElementHTML(element) {
1426
1426
  const tagName = element.tagName.toLowerCase();
1427
- const attrs = Array.from(element._attributes?.entries() || []).map(([name, value]) => value === "" ? ` ${name}` : ` ${name}="${value.replace(/"/g, "&quot;")}"`).join("");
1427
+ const attrs = Array.from(element._attributes?.entries() || []).map(([name, value]) => value === "" ? ` ${name}` : ` ${name}="${String(value).replace(/"/g, "&quot;")}"`).join("");
1428
1428
  const selfClosingTags = ["img", "input", "br", "hr", "meta", "link", "area", "base", "col", "embed", "source", "track", "wbr"];
1429
1429
  const isSelfClosing = selfClosingTags.includes(tagName);
1430
1430
  if (isSelfClosing) {
@@ -1856,7 +1856,17 @@ var dooboostoreDomParser = (() => {
1856
1856
  return this.getAttributeNode(localName);
1857
1857
  }
1858
1858
  getBoundingClientRect() {
1859
- throw new Error("Element.getBoundingClientRect() is not implemented yet");
1859
+ return {
1860
+ bottom: 0,
1861
+ height: 0,
1862
+ left: 0,
1863
+ right: 0,
1864
+ top: 0,
1865
+ width: 0,
1866
+ x: 0,
1867
+ y: 0,
1868
+ toJSON: () => ({})
1869
+ };
1860
1870
  }
1861
1871
  getClientRects() {
1862
1872
  throw new Error("Element.getClientRects() is not implemented yet");
@@ -2251,7 +2261,7 @@ var dooboostoreDomParser = (() => {
2251
2261
  });
2252
2262
 
2253
2263
  // src/node/elements/HTMLElementBase.ts
2254
- var HTMLElementBase;
2264
+ var HTMLElementBase, CSSStyleDeclarationImpl, StylePropertyMapImpl;
2255
2265
  var init_HTMLElementBase = __esm({
2256
2266
  "src/node/elements/HTMLElementBase.ts"() {
2257
2267
  init_ElementBase();
@@ -2267,6 +2277,10 @@ var dooboostoreDomParser = (() => {
2267
2277
  this._contentEditable = "inherit";
2268
2278
  this._innerText = "";
2269
2279
  this._outerText = "";
2280
+ // New implementations for style, dataset, nonce
2281
+ this._style = null;
2282
+ this._dataset = null;
2283
+ this._attributeStyleMap = null;
2270
2284
  }
2271
2285
  // HTMLElement interface implementation
2272
2286
  get title() {
@@ -2349,8 +2363,6 @@ var dooboostoreDomParser = (() => {
2349
2363
  console.log(`Clicked on ${this.tagName} element`);
2350
2364
  }
2351
2365
  focus(options) {
2352
- this.setAttribute("data-focused", "true");
2353
- console.log(`Focused on ${this.tagName} element`);
2354
2366
  }
2355
2367
  blur() {
2356
2368
  this.removeAttribute("data-focused");
@@ -2412,6 +2424,156 @@ var dooboostoreDomParser = (() => {
2412
2424
  break;
2413
2425
  }
2414
2426
  }
2427
+ get style() {
2428
+ if (!this._style) {
2429
+ this._style = new Proxy(new CSSStyleDeclarationImpl(this), {
2430
+ get: (target, prop) => {
2431
+ if (typeof prop === "string" && !(prop in target)) {
2432
+ const cssProp = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2433
+ return target.getPropertyValue(cssProp);
2434
+ }
2435
+ return target[prop];
2436
+ },
2437
+ set: (target, prop, value) => {
2438
+ if (typeof prop === "string" && !(prop in target)) {
2439
+ const cssProp = prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2440
+ target.setProperty(cssProp, String(value));
2441
+ return true;
2442
+ }
2443
+ target[prop] = value;
2444
+ return true;
2445
+ }
2446
+ });
2447
+ }
2448
+ return this._style;
2449
+ }
2450
+ set style(value) {
2451
+ if (typeof value === "string") {
2452
+ this.style.cssText = value;
2453
+ }
2454
+ }
2455
+ get attributeStyleMap() {
2456
+ if (!this._attributeStyleMap) {
2457
+ this._attributeStyleMap = new StylePropertyMapImpl(this);
2458
+ }
2459
+ return this._attributeStyleMap;
2460
+ }
2461
+ get dataset() {
2462
+ if (!this._dataset) {
2463
+ this._dataset = new Proxy({}, {
2464
+ get: (target, prop) => {
2465
+ if (typeof prop === "string") {
2466
+ const attrName = "data-" + prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2467
+ return this.getAttribute(attrName);
2468
+ }
2469
+ return void 0;
2470
+ },
2471
+ set: (target, prop, value) => {
2472
+ if (typeof prop === "string") {
2473
+ const attrName = "data-" + prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2474
+ this.setAttribute(attrName, String(value));
2475
+ return true;
2476
+ }
2477
+ return false;
2478
+ },
2479
+ deleteProperty: (target, prop) => {
2480
+ if (typeof prop === "string") {
2481
+ const attrName = "data-" + prop.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
2482
+ this.removeAttribute(attrName);
2483
+ return true;
2484
+ }
2485
+ return false;
2486
+ }
2487
+ });
2488
+ }
2489
+ return this._dataset;
2490
+ }
2491
+ get nonce() {
2492
+ return this.getAttribute("nonce") || "";
2493
+ }
2494
+ set nonce(value) {
2495
+ this.setAttribute("nonce", value);
2496
+ }
2497
+ };
2498
+ CSSStyleDeclarationImpl = class {
2499
+ constructor(element) {
2500
+ this.element = element;
2501
+ this.parentRule = null;
2502
+ }
2503
+ getPropertyPriority(property) {
2504
+ return "";
2505
+ }
2506
+ get cssText() {
2507
+ return this.element.getAttribute("style") || "";
2508
+ }
2509
+ set cssText(value) {
2510
+ this.element.setAttribute("style", value);
2511
+ }
2512
+ get length() {
2513
+ return this.parseStyle(this.cssText).size;
2514
+ }
2515
+ getPropertyValue(property) {
2516
+ const style = this.parseStyle(this.cssText);
2517
+ return style.get(property) || "";
2518
+ }
2519
+ setProperty(property, value, priority = "") {
2520
+ const style = this.parseStyle(this.cssText);
2521
+ if (value === null || value === "") {
2522
+ style.delete(property);
2523
+ } else {
2524
+ style.set(property, value);
2525
+ }
2526
+ this.cssText = this.serializeStyle(style);
2527
+ }
2528
+ removeProperty(property) {
2529
+ const style = this.parseStyle(this.cssText);
2530
+ const value = style.get(property) || "";
2531
+ style.delete(property);
2532
+ this.cssText = this.serializeStyle(style);
2533
+ return value;
2534
+ }
2535
+ item(index) {
2536
+ const style = this.parseStyle(this.cssText);
2537
+ return Array.from(style.keys())[index] || "";
2538
+ }
2539
+ parseStyle(cssText) {
2540
+ const style = /* @__PURE__ */ new Map();
2541
+ if (!cssText) return style;
2542
+ cssText.split(";").forEach((declaration) => {
2543
+ const part = declaration.trim();
2544
+ if (!part) return;
2545
+ const colonIndex = part.indexOf(":");
2546
+ if (colonIndex !== -1) {
2547
+ const property = part.substring(0, colonIndex).trim();
2548
+ const value = part.substring(colonIndex + 1).trim();
2549
+ if (property && value) {
2550
+ style.set(property, value);
2551
+ }
2552
+ }
2553
+ });
2554
+ return style;
2555
+ }
2556
+ serializeStyle(style) {
2557
+ return Array.from(style.entries()).map(([property, value]) => `${property}: ${value}`).join("; ");
2558
+ }
2559
+ };
2560
+ StylePropertyMapImpl = class {
2561
+ constructor(element) {
2562
+ this.element = element;
2563
+ }
2564
+ set(property, ...values) {
2565
+ const value = values[0];
2566
+ this.element.style.setProperty(property, String(value));
2567
+ }
2568
+ append(property, ...values) {
2569
+ this.set(property, ...values);
2570
+ }
2571
+ delete(property) {
2572
+ this.element.style.removeProperty(property);
2573
+ }
2574
+ clear() {
2575
+ this.element.style.cssText = "";
2576
+ }
2415
2577
  };
2416
2578
  }
2417
2579
  });
@@ -4503,6 +4665,10 @@ var dooboostoreDomParser = (() => {
4503
4665
  parseHTML: () => parseHTML
4504
4666
  });
4505
4667
 
4668
+ // src/DomParser.ts
4669
+ init_TextBase();
4670
+ init_Comment();
4671
+
4506
4672
  // src/node/DocumentBase.ts
4507
4673
  init_ParentNodeBase();
4508
4674
  init_Node();
@@ -4718,6 +4884,7 @@ var dooboostoreDomParser = (() => {
4718
4884
  },
4719
4885
  reload: () => {
4720
4886
  },
4887
+ // @ts-ignore
4721
4888
  toString: () => this._location.href
4722
4889
  };
4723
4890
  // Event handlers
@@ -4747,6 +4914,9 @@ var dooboostoreDomParser = (() => {
4747
4914
  this.head = head;
4748
4915
  this.body = body;
4749
4916
  }
4917
+ setLocation(location) {
4918
+ this._location = location;
4919
+ }
4750
4920
  get location() {
4751
4921
  return this._location;
4752
4922
  }
@@ -5004,10 +5174,6 @@ var dooboostoreDomParser = (() => {
5004
5174
  }
5005
5175
  };
5006
5176
 
5007
- // src/DomParser.ts
5008
- init_TextBase();
5009
- init_Comment();
5010
-
5011
5177
  // src/window/WindowBase.ts
5012
5178
  init_NodeBase();
5013
5179
  init_ElementBase();
@@ -5286,10 +5452,14 @@ var dooboostoreDomParser = (() => {
5286
5452
  }
5287
5453
  };
5288
5454
  var WindowBase = class {
5289
- constructor(document, initialUrl) {
5455
+ constructor(config) {
5290
5456
  // Event system
5291
5457
  this._eventListeners = [];
5292
- this.closed = false;
5458
+ // Timers and intervals tracking
5459
+ this._timers = /* @__PURE__ */ new Set();
5460
+ this._intervals = /* @__PURE__ */ new Set();
5461
+ this._animationFrames = /* @__PURE__ */ new Set();
5462
+ this._closed = false;
5293
5463
  this.cookieStore = {};
5294
5464
  this.customElements = {};
5295
5465
  this.devicePixelRatio = 1;
@@ -5514,11 +5684,13 @@ var dooboostoreDomParser = (() => {
5514
5684
  this.performance = {};
5515
5685
  // WindowSessionStorage
5516
5686
  this.sessionStorage = {};
5517
- this.document = document || new DocumentBase();
5687
+ const documentBase = new DocumentBase();
5518
5688
  if (this.document && this.document.setWindow) {
5519
5689
  this.document.setWindow(this);
5520
5690
  }
5521
- this._location = new LocationBase(initialUrl);
5691
+ this._location = new LocationBase(config?.initialUrl);
5692
+ documentBase.setLocation(this._location);
5693
+ this.document = documentBase;
5522
5694
  this.history = new HistoryBase(this);
5523
5695
  this.navigator = new NavigatorBase();
5524
5696
  this.clientInformation = this.navigator;
@@ -5561,6 +5733,9 @@ var dooboostoreDomParser = (() => {
5561
5733
  }
5562
5734
  });
5563
5735
  }
5736
+ get closed() {
5737
+ return this._closed;
5738
+ }
5564
5739
  get location() {
5565
5740
  return this._location;
5566
5741
  }
@@ -5581,6 +5756,103 @@ var dooboostoreDomParser = (() => {
5581
5756
  captureEvents() {
5582
5757
  }
5583
5758
  close() {
5759
+ if (this._closed) return;
5760
+ this._closed = true;
5761
+ this._timers.forEach((id) => clearTimeout(id));
5762
+ this._timers.clear();
5763
+ this._intervals.forEach((id) => clearInterval(id));
5764
+ this._intervals.clear();
5765
+ this._animationFrames.forEach((id) => clearTimeout(id));
5766
+ this._animationFrames.clear();
5767
+ this._eventListeners.forEach((listener) => {
5768
+ listener.listener = null;
5769
+ });
5770
+ this._eventListeners.length = 0;
5771
+ this.onload = null;
5772
+ this.onunload = null;
5773
+ this.onbeforeunload = null;
5774
+ this.onpopstate = null;
5775
+ this.onerror = null;
5776
+ this.onmessage = null;
5777
+ this.onhashchange = null;
5778
+ if (this.document) {
5779
+ const doc = this.document;
5780
+ if (doc.body) {
5781
+ this.clearNodeRecursively(doc.body);
5782
+ }
5783
+ if (doc.head) {
5784
+ this.clearNodeRecursively(doc.head);
5785
+ }
5786
+ if (doc.documentElement) {
5787
+ this.clearNodeRecursively(doc.documentElement);
5788
+ }
5789
+ if (doc.setWindow) {
5790
+ doc.setWindow(null);
5791
+ }
5792
+ if (doc._eventListeners) {
5793
+ doc._eventListeners.forEach((listener) => {
5794
+ listener.listener = null;
5795
+ });
5796
+ doc._eventListeners.length = 0;
5797
+ }
5798
+ }
5799
+ if (this.history) {
5800
+ const hist = this.history;
5801
+ if (hist.historyStack) {
5802
+ hist.historyStack.forEach((entry) => {
5803
+ entry.state = null;
5804
+ });
5805
+ hist.historyStack.length = 0;
5806
+ }
5807
+ hist.state = null;
5808
+ hist.window = null;
5809
+ }
5810
+ if (this._location) {
5811
+ this._location.urlChangeCallback = null;
5812
+ }
5813
+ }
5814
+ /**
5815
+ * Recursively clear a node and its children to prevent memory leaks
5816
+ */
5817
+ clearNodeRecursively(node) {
5818
+ if (!node) return;
5819
+ while (node.firstChild) {
5820
+ const child = node.firstChild;
5821
+ node.removeChild(child);
5822
+ this.clearNodeRecursively(child);
5823
+ }
5824
+ if (node._eventListeners) {
5825
+ node._eventListeners.forEach((listener) => {
5826
+ listener.listener = null;
5827
+ });
5828
+ node._eventListeners.length = 0;
5829
+ }
5830
+ try {
5831
+ if (node.parentNode) {
5832
+ node.parentNode = null;
5833
+ }
5834
+ } catch (e) {
5835
+ }
5836
+ try {
5837
+ if (node.ownerDocument) {
5838
+ node.ownerDocument = null;
5839
+ }
5840
+ } catch (e) {
5841
+ }
5842
+ if (node._childNodes) {
5843
+ if (Array.isArray(node._childNodes)) {
5844
+ node._childNodes = [];
5845
+ } else if (node._childNodes instanceof Map) {
5846
+ node._childNodes.clear();
5847
+ }
5848
+ }
5849
+ if (node._attributes) {
5850
+ if (Array.isArray(node._attributes)) {
5851
+ node._attributes = [];
5852
+ } else if (node._attributes instanceof Map) {
5853
+ node._attributes.clear();
5854
+ }
5855
+ }
5584
5856
  }
5585
5857
  confirm(message) {
5586
5858
  return false;
@@ -5629,23 +5901,38 @@ var dooboostoreDomParser = (() => {
5629
5901
  }
5630
5902
  // Timer methods
5631
5903
  setTimeout(callback, delay, ...args) {
5632
- return setTimeout(callback, delay, ...args);
5904
+ if (this._closed) return 0;
5905
+ const id = setTimeout(() => {
5906
+ this._timers.delete(id);
5907
+ callback(...args);
5908
+ }, delay);
5909
+ this._timers.add(id);
5910
+ return id;
5633
5911
  }
5634
5912
  clearTimeout(id) {
5635
5913
  clearTimeout(id);
5914
+ this._timers.delete(id);
5636
5915
  }
5637
5916
  setInterval(callback, delay, ...args) {
5638
- return setInterval(callback, delay, ...args);
5917
+ if (this._closed) return 0;
5918
+ const id = setInterval(callback, delay, ...args);
5919
+ this._intervals.add(id);
5920
+ return id;
5639
5921
  }
5640
5922
  clearInterval(id) {
5641
5923
  clearInterval(id);
5924
+ this._intervals.delete(id);
5642
5925
  }
5643
5926
  // Animation methods
5644
5927
  requestAnimationFrame(callback) {
5645
- return this.setTimeout(callback, 16);
5928
+ if (this._closed) return 0;
5929
+ const id = this.setTimeout(callback, 16);
5930
+ this._animationFrames.add(id);
5931
+ return id;
5646
5932
  }
5647
5933
  cancelAnimationFrame(id) {
5648
5934
  this.clearTimeout(id);
5935
+ this._animationFrames.delete(id);
5649
5936
  }
5650
5937
  addEventListener(type, listener, options) {
5651
5938
  if (type === "popstate" || type === "load" || type === "unload" || type === "beforeunload") {
@@ -5836,43 +6123,65 @@ var dooboostoreDomParser = (() => {
5836
6123
  // src/DomParser.ts
5837
6124
  var DomParser = class {
5838
6125
  constructor(html, option) {
5839
- const document = new DocumentBase();
5840
- const windowBase = new WindowBase(document, option?.href);
6126
+ const windowBase = new WindowBase({ initialUrl: option?.href });
5841
6127
  this._window = windowBase;
5842
- this._document = document;
6128
+ this._document = windowBase.document;
5843
6129
  this.parseHTML(html);
5844
6130
  this.setupDocumentReferences();
5845
- if (document && document.simulateLoading) {
5846
- document.simulateLoading();
6131
+ if (this._document && this._document.simulateLoading) {
6132
+ this._document.simulateLoading();
5847
6133
  }
5848
6134
  }
5849
6135
  get window() {
6136
+ if (!this._window) {
6137
+ throw new Error("DomParser has been destroyed");
6138
+ }
5850
6139
  return this._window;
5851
6140
  }
5852
6141
  get document() {
6142
+ if (!this._document) {
6143
+ throw new Error("DomParser has been destroyed");
6144
+ }
5853
6145
  return this._document;
5854
6146
  }
6147
+ /**
6148
+ * Destroy the DomParser instance and free memory
6149
+ */
6150
+ destroy() {
6151
+ if (this._window) {
6152
+ this._window.close();
6153
+ this._window = null;
6154
+ }
6155
+ this._document = null;
6156
+ }
5855
6157
  /**
5856
6158
  * Load new HTML content and replace the current document
5857
6159
  */
5858
6160
  loadHTML(html) {
6161
+ if (!this._document) {
6162
+ throw new Error("DomParser has been destroyed");
6163
+ }
5859
6164
  this.clearDocument();
5860
6165
  this.parseHTML(html);
5861
6166
  this.setupDocumentReferences();
5862
6167
  }
5863
6168
  clearDocument() {
5864
- if (this.document.head) {
5865
- while (this.document.head.firstChild) {
5866
- this.document.head.removeChild(this.document.head.firstChild);
6169
+ if (!this._document) return;
6170
+ if (this._document.head) {
6171
+ while (this._document.head.firstChild) {
6172
+ this._document.head.removeChild(this._document.head.firstChild);
5867
6173
  }
5868
6174
  }
5869
- if (this.document.body) {
5870
- while (this.document.body.firstChild) {
5871
- this.document.body.removeChild(this.document.body.firstChild);
6175
+ if (this._document.body) {
6176
+ while (this._document.body.firstChild) {
6177
+ this._document.body.removeChild(this._document.body.firstChild);
5872
6178
  }
5873
6179
  }
5874
6180
  }
5875
6181
  parseHTML(html) {
6182
+ if (!this._document) {
6183
+ throw new Error("DomParser has been destroyed");
6184
+ }
5876
6185
  if (!html.trim()) {
5877
6186
  return;
5878
6187
  }