@dooboostore/dom-parser 1.0.0

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 (519) hide show
  1. package/README.MD +280 -0
  2. package/dist/cjs/DomParser.js +360 -0
  3. package/dist/cjs/DomParser.js.map +7 -0
  4. package/dist/cjs/factory/ElementFactory.js +76 -0
  5. package/dist/cjs/factory/ElementFactory.js.map +7 -0
  6. package/dist/cjs/factory/index.js +24 -0
  7. package/dist/cjs/factory/index.js.map +7 -0
  8. package/dist/cjs/index.js +34 -0
  9. package/dist/cjs/index.js.map +7 -0
  10. package/dist/cjs/node/CharacterData.js +16 -0
  11. package/dist/cjs/node/CharacterData.js.map +7 -0
  12. package/dist/cjs/node/ChildNode.js +16 -0
  13. package/dist/cjs/node/ChildNode.js.map +7 -0
  14. package/dist/cjs/node/ChildNodeBase.js +62 -0
  15. package/dist/cjs/node/ChildNodeBase.js.map +7 -0
  16. package/dist/cjs/node/Comment.js +86 -0
  17. package/dist/cjs/node/Comment.js.map +7 -0
  18. package/dist/cjs/node/Document.js +28 -0
  19. package/dist/cjs/node/Document.js.map +7 -0
  20. package/dist/cjs/node/DocumentBase.js +378 -0
  21. package/dist/cjs/node/DocumentBase.js.map +7 -0
  22. package/dist/cjs/node/DocumentFragment.js +16 -0
  23. package/dist/cjs/node/DocumentFragment.js.map +7 -0
  24. package/dist/cjs/node/DocumentFragmentBase.js +88 -0
  25. package/dist/cjs/node/DocumentFragmentBase.js.map +7 -0
  26. package/dist/cjs/node/GetRootNodeOptions.js +16 -0
  27. package/dist/cjs/node/GetRootNodeOptions.js.map +7 -0
  28. package/dist/cjs/node/Node.js +58 -0
  29. package/dist/cjs/node/Node.js.map +7 -0
  30. package/dist/cjs/node/NodeBase.js +380 -0
  31. package/dist/cjs/node/NodeBase.js.map +7 -0
  32. package/dist/cjs/node/NodeIterator.js +163 -0
  33. package/dist/cjs/node/NodeIterator.js.map +7 -0
  34. package/dist/cjs/node/ParentNode.js +16 -0
  35. package/dist/cjs/node/ParentNode.js.map +7 -0
  36. package/dist/cjs/node/ParentNodeBase.js +134 -0
  37. package/dist/cjs/node/ParentNodeBase.js.map +7 -0
  38. package/dist/cjs/node/Text.js +16 -0
  39. package/dist/cjs/node/Text.js.map +7 -0
  40. package/dist/cjs/node/TextBase.js +106 -0
  41. package/dist/cjs/node/TextBase.js.map +7 -0
  42. package/dist/cjs/node/collection/HTMLCollection.js +105 -0
  43. package/dist/cjs/node/collection/HTMLCollection.js.map +7 -0
  44. package/dist/cjs/node/collection/HTMLCollectionOf.js +36 -0
  45. package/dist/cjs/node/collection/HTMLCollectionOf.js.map +7 -0
  46. package/dist/cjs/node/collection/NodeList.js +135 -0
  47. package/dist/cjs/node/collection/NodeList.js.map +7 -0
  48. package/dist/cjs/node/collection/NodeListOf.js +38 -0
  49. package/dist/cjs/node/collection/NodeListOf.js.map +7 -0
  50. package/dist/cjs/node/collection/index.js +30 -0
  51. package/dist/cjs/node/collection/index.js.map +7 -0
  52. package/dist/cjs/node/elements/Element.js +16 -0
  53. package/dist/cjs/node/elements/Element.js.map +7 -0
  54. package/dist/cjs/node/elements/ElementBase.js +936 -0
  55. package/dist/cjs/node/elements/ElementBase.js.map +7 -0
  56. package/dist/cjs/node/elements/HTMLAnchorElement.js +71 -0
  57. package/dist/cjs/node/elements/HTMLAnchorElement.js.map +7 -0
  58. package/dist/cjs/node/elements/HTMLAreaElement.js +77 -0
  59. package/dist/cjs/node/elements/HTMLAreaElement.js.map +7 -0
  60. package/dist/cjs/node/elements/HTMLBaseElement.js +77 -0
  61. package/dist/cjs/node/elements/HTMLBaseElement.js.map +7 -0
  62. package/dist/cjs/node/elements/HTMLBodyElement.js +29 -0
  63. package/dist/cjs/node/elements/HTMLBodyElement.js.map +7 -0
  64. package/dist/cjs/node/elements/HTMLButtonElement.js +89 -0
  65. package/dist/cjs/node/elements/HTMLButtonElement.js.map +7 -0
  66. package/dist/cjs/node/elements/HTMLCanvasElement.js +79 -0
  67. package/dist/cjs/node/elements/HTMLCanvasElement.js.map +7 -0
  68. package/dist/cjs/node/elements/HTMLCaptionElement.js +41 -0
  69. package/dist/cjs/node/elements/HTMLCaptionElement.js.map +7 -0
  70. package/dist/cjs/node/elements/HTMLDivElement.js +29 -0
  71. package/dist/cjs/node/elements/HTMLDivElement.js.map +7 -0
  72. package/dist/cjs/node/elements/HTMLElement.js +16 -0
  73. package/dist/cjs/node/elements/HTMLElement.js.map +7 -0
  74. package/dist/cjs/node/elements/HTMLElementBase.js +182 -0
  75. package/dist/cjs/node/elements/HTMLElementBase.js.map +7 -0
  76. package/dist/cjs/node/elements/HTMLEmbedElement.js +45 -0
  77. package/dist/cjs/node/elements/HTMLEmbedElement.js.map +7 -0
  78. package/dist/cjs/node/elements/HTMLFormElement.js +127 -0
  79. package/dist/cjs/node/elements/HTMLFormElement.js.map +7 -0
  80. package/dist/cjs/node/elements/HTMLGenericElement.js +32 -0
  81. package/dist/cjs/node/elements/HTMLGenericElement.js.map +7 -0
  82. package/dist/cjs/node/elements/HTMLH1Element.js +29 -0
  83. package/dist/cjs/node/elements/HTMLH1Element.js.map +7 -0
  84. package/dist/cjs/node/elements/HTMLHeadElement.js +29 -0
  85. package/dist/cjs/node/elements/HTMLHeadElement.js.map +7 -0
  86. package/dist/cjs/node/elements/HTMLHtmlElement.js +92 -0
  87. package/dist/cjs/node/elements/HTMLHtmlElement.js.map +7 -0
  88. package/dist/cjs/node/elements/HTMLImgElement.js +99 -0
  89. package/dist/cjs/node/elements/HTMLImgElement.js.map +7 -0
  90. package/dist/cjs/node/elements/HTMLInputElement.js +157 -0
  91. package/dist/cjs/node/elements/HTMLInputElement.js.map +7 -0
  92. package/dist/cjs/node/elements/HTMLLIElement.js +57 -0
  93. package/dist/cjs/node/elements/HTMLLIElement.js.map +7 -0
  94. package/dist/cjs/node/elements/HTMLLinkElement.js +99 -0
  95. package/dist/cjs/node/elements/HTMLLinkElement.js.map +7 -0
  96. package/dist/cjs/node/elements/HTMLMetaElement.js +29 -0
  97. package/dist/cjs/node/elements/HTMLMetaElement.js.map +7 -0
  98. package/dist/cjs/node/elements/HTMLOListElement.js +89 -0
  99. package/dist/cjs/node/elements/HTMLOListElement.js.map +7 -0
  100. package/dist/cjs/node/elements/HTMLPElement.js +29 -0
  101. package/dist/cjs/node/elements/HTMLPElement.js.map +7 -0
  102. package/dist/cjs/node/elements/HTMLScriptElement.js +127 -0
  103. package/dist/cjs/node/elements/HTMLScriptElement.js.map +7 -0
  104. package/dist/cjs/node/elements/HTMLSpanElement.js +29 -0
  105. package/dist/cjs/node/elements/HTMLSpanElement.js.map +7 -0
  106. package/dist/cjs/node/elements/HTMLStyleElement.js +71 -0
  107. package/dist/cjs/node/elements/HTMLStyleElement.js.map +7 -0
  108. package/dist/cjs/node/elements/HTMLTableElement.js +112 -0
  109. package/dist/cjs/node/elements/HTMLTableElement.js.map +7 -0
  110. package/dist/cjs/node/elements/HTMLTbodyElement.js +54 -0
  111. package/dist/cjs/node/elements/HTMLTbodyElement.js.map +7 -0
  112. package/dist/cjs/node/elements/HTMLTdElement.js +72 -0
  113. package/dist/cjs/node/elements/HTMLTdElement.js.map +7 -0
  114. package/dist/cjs/node/elements/HTMLTemplateElement.js +97 -0
  115. package/dist/cjs/node/elements/HTMLTemplateElement.js.map +7 -0
  116. package/dist/cjs/node/elements/HTMLTfootElement.js +56 -0
  117. package/dist/cjs/node/elements/HTMLTfootElement.js.map +7 -0
  118. package/dist/cjs/node/elements/HTMLThElement.js +72 -0
  119. package/dist/cjs/node/elements/HTMLThElement.js.map +7 -0
  120. package/dist/cjs/node/elements/HTMLTheadElement.js +54 -0
  121. package/dist/cjs/node/elements/HTMLTheadElement.js.map +7 -0
  122. package/dist/cjs/node/elements/HTMLTitleElement.js +38 -0
  123. package/dist/cjs/node/elements/HTMLTitleElement.js.map +7 -0
  124. package/dist/cjs/node/elements/HTMLTrElement.js +77 -0
  125. package/dist/cjs/node/elements/HTMLTrElement.js.map +7 -0
  126. package/dist/cjs/node/elements/HTMLUListElement.js +29 -0
  127. package/dist/cjs/node/elements/HTMLUListElement.js.map +7 -0
  128. package/dist/cjs/node/elements/MathMLElement.js +32 -0
  129. package/dist/cjs/node/elements/MathMLElement.js.map +7 -0
  130. package/dist/cjs/node/elements/SVGCircleElement.js +69 -0
  131. package/dist/cjs/node/elements/SVGCircleElement.js.map +7 -0
  132. package/dist/cjs/node/elements/SVGElement.js +32 -0
  133. package/dist/cjs/node/elements/SVGElement.js.map +7 -0
  134. package/dist/cjs/node/elements/SVGRectElement.js +80 -0
  135. package/dist/cjs/node/elements/SVGRectElement.js.map +7 -0
  136. package/dist/cjs/node/elements/index.js +183 -0
  137. package/dist/cjs/node/elements/index.js.map +7 -0
  138. package/dist/cjs/node/index.js +73 -0
  139. package/dist/cjs/node/index.js.map +7 -0
  140. package/dist/cjs/package.json +5 -0
  141. package/dist/cjs/utils/CSSSelector.js +271 -0
  142. package/dist/cjs/utils/CSSSelector.js.map +7 -0
  143. package/dist/cjs/window/Window.js +16 -0
  144. package/dist/cjs/window/Window.js.map +7 -0
  145. package/dist/cjs/window/WindowBase.js +847 -0
  146. package/dist/cjs/window/WindowBase.js.map +7 -0
  147. package/dist/cjs/window/index.js +29 -0
  148. package/dist/cjs/window/index.js.map +7 -0
  149. package/dist/esm/DomParser.js +341 -0
  150. package/dist/esm/DomParser.js.map +7 -0
  151. package/dist/esm/factory/ElementFactory.js +57 -0
  152. package/dist/esm/factory/ElementFactory.js.map +7 -0
  153. package/dist/esm/factory/index.js +5 -0
  154. package/dist/esm/factory/index.js.map +7 -0
  155. package/dist/esm/index.js +15 -0
  156. package/dist/esm/index.js.map +7 -0
  157. package/dist/esm/node/CharacterData.js +1 -0
  158. package/dist/esm/node/CharacterData.js.map +7 -0
  159. package/dist/esm/node/ChildNode.js +1 -0
  160. package/dist/esm/node/ChildNode.js.map +7 -0
  161. package/dist/esm/node/ChildNodeBase.js +43 -0
  162. package/dist/esm/node/ChildNodeBase.js.map +7 -0
  163. package/dist/esm/node/Comment.js +67 -0
  164. package/dist/esm/node/Comment.js.map +7 -0
  165. package/dist/esm/node/Document.js +9 -0
  166. package/dist/esm/node/Document.js.map +7 -0
  167. package/dist/esm/node/DocumentBase.js +359 -0
  168. package/dist/esm/node/DocumentBase.js.map +7 -0
  169. package/dist/esm/node/DocumentFragment.js +1 -0
  170. package/dist/esm/node/DocumentFragment.js.map +7 -0
  171. package/dist/esm/node/DocumentFragmentBase.js +69 -0
  172. package/dist/esm/node/DocumentFragmentBase.js.map +7 -0
  173. package/dist/esm/node/GetRootNodeOptions.js +1 -0
  174. package/dist/esm/node/GetRootNodeOptions.js.map +7 -0
  175. package/dist/esm/node/Node.js +39 -0
  176. package/dist/esm/node/Node.js.map +7 -0
  177. package/dist/esm/node/NodeBase.js +380 -0
  178. package/dist/esm/node/NodeBase.js.map +7 -0
  179. package/dist/esm/node/NodeIterator.js +144 -0
  180. package/dist/esm/node/NodeIterator.js.map +7 -0
  181. package/dist/esm/node/ParentNode.js +1 -0
  182. package/dist/esm/node/ParentNode.js.map +7 -0
  183. package/dist/esm/node/ParentNodeBase.js +115 -0
  184. package/dist/esm/node/ParentNodeBase.js.map +7 -0
  185. package/dist/esm/node/Text.js +1 -0
  186. package/dist/esm/node/Text.js.map +7 -0
  187. package/dist/esm/node/TextBase.js +87 -0
  188. package/dist/esm/node/TextBase.js.map +7 -0
  189. package/dist/esm/node/collection/HTMLCollection.js +86 -0
  190. package/dist/esm/node/collection/HTMLCollection.js.map +7 -0
  191. package/dist/esm/node/collection/HTMLCollectionOf.js +17 -0
  192. package/dist/esm/node/collection/HTMLCollectionOf.js.map +7 -0
  193. package/dist/esm/node/collection/NodeList.js +116 -0
  194. package/dist/esm/node/collection/NodeList.js.map +7 -0
  195. package/dist/esm/node/collection/NodeListOf.js +19 -0
  196. package/dist/esm/node/collection/NodeListOf.js.map +7 -0
  197. package/dist/esm/node/collection/index.js +11 -0
  198. package/dist/esm/node/collection/index.js.map +7 -0
  199. package/dist/esm/node/elements/Element.js +1 -0
  200. package/dist/esm/node/elements/Element.js.map +7 -0
  201. package/dist/esm/node/elements/ElementBase.js +917 -0
  202. package/dist/esm/node/elements/ElementBase.js.map +7 -0
  203. package/dist/esm/node/elements/HTMLAnchorElement.js +52 -0
  204. package/dist/esm/node/elements/HTMLAnchorElement.js.map +7 -0
  205. package/dist/esm/node/elements/HTMLAreaElement.js +58 -0
  206. package/dist/esm/node/elements/HTMLAreaElement.js.map +7 -0
  207. package/dist/esm/node/elements/HTMLBaseElement.js +58 -0
  208. package/dist/esm/node/elements/HTMLBaseElement.js.map +7 -0
  209. package/dist/esm/node/elements/HTMLBodyElement.js +10 -0
  210. package/dist/esm/node/elements/HTMLBodyElement.js.map +7 -0
  211. package/dist/esm/node/elements/HTMLButtonElement.js +70 -0
  212. package/dist/esm/node/elements/HTMLButtonElement.js.map +7 -0
  213. package/dist/esm/node/elements/HTMLCanvasElement.js +60 -0
  214. package/dist/esm/node/elements/HTMLCanvasElement.js.map +7 -0
  215. package/dist/esm/node/elements/HTMLCaptionElement.js +22 -0
  216. package/dist/esm/node/elements/HTMLCaptionElement.js.map +7 -0
  217. package/dist/esm/node/elements/HTMLDivElement.js +10 -0
  218. package/dist/esm/node/elements/HTMLDivElement.js.map +7 -0
  219. package/dist/esm/node/elements/HTMLElement.js +1 -0
  220. package/dist/esm/node/elements/HTMLElement.js.map +7 -0
  221. package/dist/esm/node/elements/HTMLElementBase.js +163 -0
  222. package/dist/esm/node/elements/HTMLElementBase.js.map +7 -0
  223. package/dist/esm/node/elements/HTMLEmbedElement.js +26 -0
  224. package/dist/esm/node/elements/HTMLEmbedElement.js.map +7 -0
  225. package/dist/esm/node/elements/HTMLFormElement.js +108 -0
  226. package/dist/esm/node/elements/HTMLFormElement.js.map +7 -0
  227. package/dist/esm/node/elements/HTMLGenericElement.js +13 -0
  228. package/dist/esm/node/elements/HTMLGenericElement.js.map +7 -0
  229. package/dist/esm/node/elements/HTMLH1Element.js +10 -0
  230. package/dist/esm/node/elements/HTMLH1Element.js.map +7 -0
  231. package/dist/esm/node/elements/HTMLHeadElement.js +10 -0
  232. package/dist/esm/node/elements/HTMLHeadElement.js.map +7 -0
  233. package/dist/esm/node/elements/HTMLHtmlElement.js +73 -0
  234. package/dist/esm/node/elements/HTMLHtmlElement.js.map +7 -0
  235. package/dist/esm/node/elements/HTMLImgElement.js +80 -0
  236. package/dist/esm/node/elements/HTMLImgElement.js.map +7 -0
  237. package/dist/esm/node/elements/HTMLInputElement.js +138 -0
  238. package/dist/esm/node/elements/HTMLInputElement.js.map +7 -0
  239. package/dist/esm/node/elements/HTMLLIElement.js +38 -0
  240. package/dist/esm/node/elements/HTMLLIElement.js.map +7 -0
  241. package/dist/esm/node/elements/HTMLLinkElement.js +80 -0
  242. package/dist/esm/node/elements/HTMLLinkElement.js.map +7 -0
  243. package/dist/esm/node/elements/HTMLMetaElement.js +10 -0
  244. package/dist/esm/node/elements/HTMLMetaElement.js.map +7 -0
  245. package/dist/esm/node/elements/HTMLOListElement.js +70 -0
  246. package/dist/esm/node/elements/HTMLOListElement.js.map +7 -0
  247. package/dist/esm/node/elements/HTMLPElement.js +10 -0
  248. package/dist/esm/node/elements/HTMLPElement.js.map +7 -0
  249. package/dist/esm/node/elements/HTMLScriptElement.js +108 -0
  250. package/dist/esm/node/elements/HTMLScriptElement.js.map +7 -0
  251. package/dist/esm/node/elements/HTMLSpanElement.js +10 -0
  252. package/dist/esm/node/elements/HTMLSpanElement.js.map +7 -0
  253. package/dist/esm/node/elements/HTMLStyleElement.js +52 -0
  254. package/dist/esm/node/elements/HTMLStyleElement.js.map +7 -0
  255. package/dist/esm/node/elements/HTMLTableElement.js +93 -0
  256. package/dist/esm/node/elements/HTMLTableElement.js.map +7 -0
  257. package/dist/esm/node/elements/HTMLTbodyElement.js +35 -0
  258. package/dist/esm/node/elements/HTMLTbodyElement.js.map +7 -0
  259. package/dist/esm/node/elements/HTMLTdElement.js +53 -0
  260. package/dist/esm/node/elements/HTMLTdElement.js.map +7 -0
  261. package/dist/esm/node/elements/HTMLTemplateElement.js +78 -0
  262. package/dist/esm/node/elements/HTMLTemplateElement.js.map +7 -0
  263. package/dist/esm/node/elements/HTMLTfootElement.js +37 -0
  264. package/dist/esm/node/elements/HTMLTfootElement.js.map +7 -0
  265. package/dist/esm/node/elements/HTMLThElement.js +53 -0
  266. package/dist/esm/node/elements/HTMLThElement.js.map +7 -0
  267. package/dist/esm/node/elements/HTMLTheadElement.js +35 -0
  268. package/dist/esm/node/elements/HTMLTheadElement.js.map +7 -0
  269. package/dist/esm/node/elements/HTMLTitleElement.js +19 -0
  270. package/dist/esm/node/elements/HTMLTitleElement.js.map +7 -0
  271. package/dist/esm/node/elements/HTMLTrElement.js +58 -0
  272. package/dist/esm/node/elements/HTMLTrElement.js.map +7 -0
  273. package/dist/esm/node/elements/HTMLUListElement.js +10 -0
  274. package/dist/esm/node/elements/HTMLUListElement.js.map +7 -0
  275. package/dist/esm/node/elements/MathMLElement.js +13 -0
  276. package/dist/esm/node/elements/MathMLElement.js.map +7 -0
  277. package/dist/esm/node/elements/SVGCircleElement.js +50 -0
  278. package/dist/esm/node/elements/SVGCircleElement.js.map +7 -0
  279. package/dist/esm/node/elements/SVGElement.js +13 -0
  280. package/dist/esm/node/elements/SVGElement.js.map +7 -0
  281. package/dist/esm/node/elements/SVGRectElement.js +61 -0
  282. package/dist/esm/node/elements/SVGRectElement.js.map +7 -0
  283. package/dist/esm/node/elements/index.js +164 -0
  284. package/dist/esm/node/elements/index.js.map +7 -0
  285. package/dist/esm/node/index.js +53 -0
  286. package/dist/esm/node/index.js.map +7 -0
  287. package/dist/esm/utils/CSSSelector.js +252 -0
  288. package/dist/esm/utils/CSSSelector.js.map +7 -0
  289. package/dist/esm/window/Window.js +1 -0
  290. package/dist/esm/window/Window.js.map +7 -0
  291. package/dist/esm/window/WindowBase.js +828 -0
  292. package/dist/esm/window/WindowBase.js.map +7 -0
  293. package/dist/esm/window/index.js +10 -0
  294. package/dist/esm/window/index.js.map +7 -0
  295. package/dist/esm-bundle/dooboostore-dom-parser.esm.js +6176 -0
  296. package/dist/esm-bundle/dooboostore-dom-parser.esm.js.map +7 -0
  297. package/dist/types/DomParser.d.ts +30 -0
  298. package/dist/types/DomParser.d.ts.map +1 -0
  299. package/dist/types/factory/ElementFactory.d.ts +27 -0
  300. package/dist/types/factory/ElementFactory.d.ts.map +1 -0
  301. package/dist/types/factory/index.d.ts +2 -0
  302. package/dist/types/factory/index.d.ts.map +1 -0
  303. package/dist/types/index.d.ts +9 -0
  304. package/dist/types/index.d.ts.map +1 -0
  305. package/dist/types/node/CharacterData.d.ts +52 -0
  306. package/dist/types/node/CharacterData.d.ts.map +1 -0
  307. package/dist/types/node/ChildNode.d.ts +39 -0
  308. package/dist/types/node/ChildNode.d.ts.map +1 -0
  309. package/dist/types/node/ChildNodeBase.d.ts +12 -0
  310. package/dist/types/node/ChildNodeBase.d.ts.map +1 -0
  311. package/dist/types/node/Comment.d.ts +26 -0
  312. package/dist/types/node/Comment.d.ts.map +1 -0
  313. package/dist/types/node/Document.d.ts +857 -0
  314. package/dist/types/node/Document.d.ts.map +1 -0
  315. package/dist/types/node/DocumentBase.d.ts +153 -0
  316. package/dist/types/node/DocumentBase.d.ts.map +1 -0
  317. package/dist/types/node/DocumentFragment.d.ts +39 -0
  318. package/dist/types/node/DocumentFragment.d.ts.map +1 -0
  319. package/dist/types/node/DocumentFragmentBase.d.ts +51 -0
  320. package/dist/types/node/DocumentFragmentBase.d.ts.map +1 -0
  321. package/dist/types/node/GetRootNodeOptions.d.ts +14 -0
  322. package/dist/types/node/GetRootNodeOptions.d.ts.map +1 -0
  323. package/dist/types/node/Node.d.ts +232 -0
  324. package/dist/types/node/Node.d.ts.map +1 -0
  325. package/dist/types/node/NodeBase.d.ts +98 -0
  326. package/dist/types/node/NodeBase.d.ts.map +1 -0
  327. package/dist/types/node/NodeIterator.d.ts +61 -0
  328. package/dist/types/node/NodeIterator.d.ts.map +1 -0
  329. package/dist/types/node/ParentNode.d.ts +85 -0
  330. package/dist/types/node/ParentNode.d.ts.map +1 -0
  331. package/dist/types/node/ParentNodeBase.d.ts +22 -0
  332. package/dist/types/node/ParentNodeBase.d.ts.map +1 -0
  333. package/dist/types/node/Text.d.ts +25 -0
  334. package/dist/types/node/Text.d.ts.map +1 -0
  335. package/dist/types/node/TextBase.d.ts +26 -0
  336. package/dist/types/node/TextBase.d.ts.map +1 -0
  337. package/dist/types/node/collection/HTMLCollection.d.ts +37 -0
  338. package/dist/types/node/collection/HTMLCollection.d.ts.map +1 -0
  339. package/dist/types/node/collection/HTMLCollectionOf.d.ts +14 -0
  340. package/dist/types/node/collection/HTMLCollectionOf.d.ts.map +1 -0
  341. package/dist/types/node/collection/NodeList.d.ts +55 -0
  342. package/dist/types/node/collection/NodeList.d.ts.map +1 -0
  343. package/dist/types/node/collection/NodeListOf.d.ts +14 -0
  344. package/dist/types/node/collection/NodeListOf.d.ts.map +1 -0
  345. package/dist/types/node/collection/index.d.ts +5 -0
  346. package/dist/types/node/collection/index.d.ts.map +1 -0
  347. package/dist/types/node/elements/Element.d.ts +687 -0
  348. package/dist/types/node/elements/Element.d.ts.map +1 -0
  349. package/dist/types/node/elements/ElementBase.d.ts +143 -0
  350. package/dist/types/node/elements/ElementBase.d.ts.map +1 -0
  351. package/dist/types/node/elements/HTMLAnchorElement.d.ts +18 -0
  352. package/dist/types/node/elements/HTMLAnchorElement.d.ts.map +1 -0
  353. package/dist/types/node/elements/HTMLAreaElement.d.ts +59 -0
  354. package/dist/types/node/elements/HTMLAreaElement.d.ts.map +1 -0
  355. package/dist/types/node/elements/HTMLBaseElement.d.ts +25 -0
  356. package/dist/types/node/elements/HTMLBaseElement.d.ts.map +1 -0
  357. package/dist/types/node/elements/HTMLBodyElement.d.ts +10 -0
  358. package/dist/types/node/elements/HTMLBodyElement.d.ts.map +1 -0
  359. package/dist/types/node/elements/HTMLButtonElement.d.ts +21 -0
  360. package/dist/types/node/elements/HTMLButtonElement.d.ts.map +1 -0
  361. package/dist/types/node/elements/HTMLCanvasElement.d.ts +15 -0
  362. package/dist/types/node/elements/HTMLCanvasElement.d.ts.map +1 -0
  363. package/dist/types/node/elements/HTMLCaptionElement.d.ts +18 -0
  364. package/dist/types/node/elements/HTMLCaptionElement.d.ts.map +1 -0
  365. package/dist/types/node/elements/HTMLDivElement.d.ts +10 -0
  366. package/dist/types/node/elements/HTMLDivElement.d.ts.map +1 -0
  367. package/dist/types/node/elements/HTMLElement.d.ts +90 -0
  368. package/dist/types/node/elements/HTMLElement.d.ts.map +1 -0
  369. package/dist/types/node/elements/HTMLElementBase.d.ts +42 -0
  370. package/dist/types/node/elements/HTMLElementBase.d.ts.map +1 -0
  371. package/dist/types/node/elements/HTMLEmbedElement.d.ts +27 -0
  372. package/dist/types/node/elements/HTMLEmbedElement.d.ts.map +1 -0
  373. package/dist/types/node/elements/HTMLFormElement.d.ts +30 -0
  374. package/dist/types/node/elements/HTMLFormElement.d.ts.map +1 -0
  375. package/dist/types/node/elements/HTMLGenericElement.d.ts +6 -0
  376. package/dist/types/node/elements/HTMLGenericElement.d.ts.map +1 -0
  377. package/dist/types/node/elements/HTMLH1Element.d.ts +10 -0
  378. package/dist/types/node/elements/HTMLH1Element.d.ts.map +1 -0
  379. package/dist/types/node/elements/HTMLHeadElement.d.ts +10 -0
  380. package/dist/types/node/elements/HTMLHeadElement.d.ts.map +1 -0
  381. package/dist/types/node/elements/HTMLHtmlElement.d.ts +17 -0
  382. package/dist/types/node/elements/HTMLHtmlElement.d.ts.map +1 -0
  383. package/dist/types/node/elements/HTMLImgElement.d.ts +24 -0
  384. package/dist/types/node/elements/HTMLImgElement.d.ts.map +1 -0
  385. package/dist/types/node/elements/HTMLInputElement.d.ts +33 -0
  386. package/dist/types/node/elements/HTMLInputElement.d.ts.map +1 -0
  387. package/dist/types/node/elements/HTMLLIElement.d.ts +15 -0
  388. package/dist/types/node/elements/HTMLLIElement.d.ts.map +1 -0
  389. package/dist/types/node/elements/HTMLLinkElement.d.ts +24 -0
  390. package/dist/types/node/elements/HTMLLinkElement.d.ts.map +1 -0
  391. package/dist/types/node/elements/HTMLMetaElement.d.ts +10 -0
  392. package/dist/types/node/elements/HTMLMetaElement.d.ts.map +1 -0
  393. package/dist/types/node/elements/HTMLOListElement.d.ts +21 -0
  394. package/dist/types/node/elements/HTMLOListElement.d.ts.map +1 -0
  395. package/dist/types/node/elements/HTMLPElement.d.ts +10 -0
  396. package/dist/types/node/elements/HTMLPElement.d.ts.map +1 -0
  397. package/dist/types/node/elements/HTMLScriptElement.d.ts +29 -0
  398. package/dist/types/node/elements/HTMLScriptElement.d.ts.map +1 -0
  399. package/dist/types/node/elements/HTMLSpanElement.d.ts +10 -0
  400. package/dist/types/node/elements/HTMLSpanElement.d.ts.map +1 -0
  401. package/dist/types/node/elements/HTMLStyleElement.d.ts +18 -0
  402. package/dist/types/node/elements/HTMLStyleElement.d.ts.map +1 -0
  403. package/dist/types/node/elements/HTMLTableElement.d.ts +25 -0
  404. package/dist/types/node/elements/HTMLTableElement.d.ts.map +1 -0
  405. package/dist/types/node/elements/HTMLTbodyElement.d.ts +15 -0
  406. package/dist/types/node/elements/HTMLTbodyElement.d.ts.map +1 -0
  407. package/dist/types/node/elements/HTMLTdElement.d.ts +21 -0
  408. package/dist/types/node/elements/HTMLTdElement.d.ts.map +1 -0
  409. package/dist/types/node/elements/HTMLTemplateElement.d.ts +32 -0
  410. package/dist/types/node/elements/HTMLTemplateElement.d.ts.map +1 -0
  411. package/dist/types/node/elements/HTMLTfootElement.d.ts +16 -0
  412. package/dist/types/node/elements/HTMLTfootElement.d.ts.map +1 -0
  413. package/dist/types/node/elements/HTMLThElement.d.ts +21 -0
  414. package/dist/types/node/elements/HTMLThElement.d.ts.map +1 -0
  415. package/dist/types/node/elements/HTMLTheadElement.d.ts +15 -0
  416. package/dist/types/node/elements/HTMLTheadElement.d.ts.map +1 -0
  417. package/dist/types/node/elements/HTMLTitleElement.d.ts +15 -0
  418. package/dist/types/node/elements/HTMLTitleElement.d.ts.map +1 -0
  419. package/dist/types/node/elements/HTMLTrElement.d.ts +17 -0
  420. package/dist/types/node/elements/HTMLTrElement.d.ts.map +1 -0
  421. package/dist/types/node/elements/HTMLUListElement.d.ts +10 -0
  422. package/dist/types/node/elements/HTMLUListElement.d.ts.map +1 -0
  423. package/dist/types/node/elements/MathMLElement.d.ts +11 -0
  424. package/dist/types/node/elements/MathMLElement.d.ts.map +1 -0
  425. package/dist/types/node/elements/SVGCircleElement.d.ts +20 -0
  426. package/dist/types/node/elements/SVGCircleElement.d.ts.map +1 -0
  427. package/dist/types/node/elements/SVGElement.d.ts +11 -0
  428. package/dist/types/node/elements/SVGElement.d.ts.map +1 -0
  429. package/dist/types/node/elements/SVGRectElement.d.ts +23 -0
  430. package/dist/types/node/elements/SVGRectElement.d.ts.map +1 -0
  431. package/dist/types/node/elements/index.d.ts +128 -0
  432. package/dist/types/node/elements/index.d.ts.map +1 -0
  433. package/dist/types/node/index.d.ts +16 -0
  434. package/dist/types/node/index.d.ts.map +1 -0
  435. package/dist/types/utils/CSSSelector.d.ts +36 -0
  436. package/dist/types/utils/CSSSelector.d.ts.map +1 -0
  437. package/dist/types/window/Window.d.ts +620 -0
  438. package/dist/types/window/Window.d.ts.map +1 -0
  439. package/dist/types/window/WindowBase.d.ts +342 -0
  440. package/dist/types/window/WindowBase.d.ts.map +1 -0
  441. package/dist/types/window/index.d.ts +3 -0
  442. package/dist/types/window/index.d.ts.map +1 -0
  443. package/dist/umd-bundle/dooboostore-dom-parser.umd.js +6182 -0
  444. package/dist/umd-bundle/dooboostore-dom-parser.umd.js.map +7 -0
  445. package/package.json +120 -0
  446. package/src/DomParser.ts +491 -0
  447. package/src/factory/ElementFactory.ts +69 -0
  448. package/src/factory/index.ts +1 -0
  449. package/src/index.ts +28 -0
  450. package/src/node/CharacterData.ts +58 -0
  451. package/src/node/ChildNode.ts +42 -0
  452. package/src/node/ChildNodeBase.ts +54 -0
  453. package/src/node/Comment.ts +98 -0
  454. package/src/node/Document.ts +882 -0
  455. package/src/node/DocumentBase.ts +465 -0
  456. package/src/node/DocumentFragment.ts +44 -0
  457. package/src/node/DocumentFragmentBase.ts +109 -0
  458. package/src/node/GetRootNodeOptions.ts +13 -0
  459. package/src/node/Node.ts +245 -0
  460. package/src/node/NodeBase.ts +506 -0
  461. package/src/node/NodeIterator.ts +200 -0
  462. package/src/node/ParentNode.ts +93 -0
  463. package/src/node/ParentNodeBase.ts +145 -0
  464. package/src/node/Text.ts +30 -0
  465. package/src/node/TextBase.ts +113 -0
  466. package/src/node/collection/HTMLCollection.ts +107 -0
  467. package/src/node/collection/HTMLCollectionOf.ts +26 -0
  468. package/src/node/collection/NodeList.ts +140 -0
  469. package/src/node/collection/NodeListOf.ts +28 -0
  470. package/src/node/collection/index.ts +4 -0
  471. package/src/node/elements/Element.ts +771 -0
  472. package/src/node/elements/ElementBase.ts +1239 -0
  473. package/src/node/elements/HTMLAnchorElement.ts +63 -0
  474. package/src/node/elements/HTMLAreaElement.ts +73 -0
  475. package/src/node/elements/HTMLBaseElement.ts +70 -0
  476. package/src/node/elements/HTMLBodyElement.ts +12 -0
  477. package/src/node/elements/HTMLButtonElement.ts +83 -0
  478. package/src/node/elements/HTMLCanvasElement.ts +71 -0
  479. package/src/node/elements/HTMLCaptionElement.ts +26 -0
  480. package/src/node/elements/HTMLDivElement.ts +12 -0
  481. package/src/node/elements/HTMLElement.ts +105 -0
  482. package/src/node/elements/HTMLElementBase.ts +198 -0
  483. package/src/node/elements/HTMLEmbedElement.ts +33 -0
  484. package/src/node/elements/HTMLFormElement.ts +131 -0
  485. package/src/node/elements/HTMLGenericElement.ts +13 -0
  486. package/src/node/elements/HTMLH1Element.ts +12 -0
  487. package/src/node/elements/HTMLHeadElement.ts +12 -0
  488. package/src/node/elements/HTMLHtmlElement.ts +82 -0
  489. package/src/node/elements/HTMLImgElement.ts +96 -0
  490. package/src/node/elements/HTMLInputElement.ts +160 -0
  491. package/src/node/elements/HTMLLIElement.ts +47 -0
  492. package/src/node/elements/HTMLLinkElement.ts +95 -0
  493. package/src/node/elements/HTMLMetaElement.ts +12 -0
  494. package/src/node/elements/HTMLOListElement.ts +83 -0
  495. package/src/node/elements/HTMLPElement.ts +12 -0
  496. package/src/node/elements/HTMLScriptElement.ts +127 -0
  497. package/src/node/elements/HTMLSpanElement.ts +12 -0
  498. package/src/node/elements/HTMLStyleElement.ts +63 -0
  499. package/src/node/elements/HTMLTableElement.ts +117 -0
  500. package/src/node/elements/HTMLTbodyElement.ts +46 -0
  501. package/src/node/elements/HTMLTdElement.ts +67 -0
  502. package/src/node/elements/HTMLTemplateElement.ts +112 -0
  503. package/src/node/elements/HTMLTfootElement.ts +47 -0
  504. package/src/node/elements/HTMLThElement.ts +67 -0
  505. package/src/node/elements/HTMLTheadElement.ts +46 -0
  506. package/src/node/elements/HTMLTitleElement.ts +23 -0
  507. package/src/node/elements/HTMLTrElement.ts +72 -0
  508. package/src/node/elements/HTMLUListElement.ts +12 -0
  509. package/src/node/elements/MathMLElement.ts +16 -0
  510. package/src/node/elements/SVGCircleElement.ts +61 -0
  511. package/src/node/elements/SVGElement.ts +16 -0
  512. package/src/node/elements/SVGRectElement.ts +74 -0
  513. package/src/node/elements/index.ts +186 -0
  514. package/src/node/index.ts +28 -0
  515. package/src/utils/CSSSelector.ts +360 -0
  516. package/src/window/Window.ts +715 -0
  517. package/src/window/WindowBase.ts +1018 -0
  518. package/src/window/index.ts +2 -0
  519. package/tsconfig.json +24 -0
@@ -0,0 +1,1239 @@
1
+ import { ParentNodeBase } from '../ParentNodeBase';
2
+ import { ChildNodeBase } from '../ChildNodeBase';
3
+ import { HTMLCollection } from "../collection";
4
+ import { Text } from "../Text";
5
+ import { ElementFactory } from "../../factory/ElementFactory";
6
+ import { Element, DOMTokenList, Attr, NamedNodeMap } from './Element';
7
+ import { ELEMENT_NODE, TEXT_NODE, ATTRIBUTE_NODE } from '../Node';
8
+ import { CSSSelector } from '../../utils/CSSSelector';
9
+ import { HTMLElementTagNameMap } from "./index";
10
+ import { NodeBase } from '../NodeBase';
11
+
12
+ // InsertPosition type for insertAdjacent methods
13
+ type InsertPosition = 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend';
14
+
15
+ // Simple DOMException class for error handling
16
+ class DOMException extends Error {
17
+ constructor(message: string, public name: string = 'DOMException') {
18
+ super(message);
19
+ this.name = name;
20
+ }
21
+ }
22
+ /**
23
+ * Base implementation of the Element interface
24
+ */
25
+ export abstract class ElementBase extends ParentNodeBase implements Element {
26
+ private _id: string = '';
27
+ private _className: string = '';
28
+ private _attributes: Map<string, string> = new Map();
29
+
30
+ constructor(
31
+ public _tagName: string,
32
+ ownerDocument?: any
33
+ ) {
34
+ super(ELEMENT_NODE, _tagName.toUpperCase(), ownerDocument);
35
+ }
36
+
37
+ get tagName(): string {
38
+ return this._tagName.toUpperCase();
39
+ }
40
+
41
+ get localName(): string {
42
+ return this._tagName.toLowerCase();
43
+ }
44
+
45
+ // Element interface implementation
46
+ get id(): string {
47
+ return this._id;
48
+ }
49
+
50
+ set id(value: string) {
51
+ this._id = value;
52
+ this._attributes.set('id', value);
53
+ }
54
+
55
+ get className(): string {
56
+ return this._className;
57
+ }
58
+
59
+ set className(value: string) {
60
+ this._className = value;
61
+ this._attributes.set('class', value);
62
+ }
63
+
64
+ get classList(): DOMTokenList {
65
+ return new DOMTokenListImpl(this);
66
+ }
67
+
68
+ get innerHTML(): string {
69
+ // Generate innerHTML from actual child nodes
70
+ let html = '';
71
+ for (const child of this._childNodesInternal) {
72
+ if (child.nodeType === TEXT_NODE) {
73
+ // For text nodes, use the escaped content stored in _nodeValue
74
+ html += (child as any)._nodeValue || '';
75
+ } else if (child.nodeType === ELEMENT_NODE) {
76
+ // Generate outerHTML directly to avoid circular dependency
77
+ html += this.generateChildElementHTML(child as any);
78
+ } else if (child.nodeType === 8) { // COMMENT_NODE
79
+ html += `<!--${(child as any).textContent || ''}-->`;
80
+ }
81
+ }
82
+ return html;
83
+ }
84
+
85
+ get innerText(): string {
86
+ // innerText should return the decoded text content
87
+ return this.textContent || '';
88
+ }
89
+
90
+ set innerText(value: string | null) {
91
+ // Clear all children and add escaped text content
92
+ this._childNodesInternal = [];
93
+ if (value !== null && value !== undefined) {
94
+ const stringValue = String(value);
95
+ const escapedValue = this.escapeHTMLEntities(stringValue);
96
+ // Create text node with escaped content
97
+ const { TextBase } = require('../TextBase');
98
+ const textNode = new TextBase(escapedValue, this._ownerDocument);
99
+ this._childNodesInternal.push(textNode);
100
+ textNode._parentNodeInternal = this;
101
+ }
102
+ }
103
+
104
+ set innerHTML(value: string) {
105
+ // Clear existing children
106
+ while (this._childNodesInternal.length > 0) {
107
+ const child = this._childNodesInternal[0];
108
+ if (child) {
109
+ this.removeChild(child);
110
+ }
111
+ }
112
+
113
+ // Parse HTML and create child nodes
114
+ if (value.trim()) {
115
+ this.parseAndAppendHTML(value);
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Generate HTML for a child element without using outerHTML to avoid circular dependency
121
+ */
122
+ private generateChildElementHTML(element: any): string {
123
+ const tagName = element.tagName.toLowerCase();
124
+
125
+ // Get attributes
126
+ const attrs = Array.from(element._attributes?.entries() || [])
127
+ .map(([name, value]: [string, string]) => value === '' ? ` ${name}` : ` ${name}="${value.replace(/"/g, '&quot;')}"`)
128
+ .join('');
129
+
130
+ // Check if it's a self-closing tag
131
+ const selfClosingTags = ['img', 'input', 'br', 'hr', 'meta', 'link', 'area', 'base', 'col', 'embed', 'source', 'track', 'wbr'];
132
+ const isSelfClosing = selfClosingTags.includes(tagName);
133
+
134
+ if (isSelfClosing) {
135
+ return `<${tagName}${attrs} />`;
136
+ } else {
137
+ // Generate innerHTML directly without calling element.innerHTML to avoid recursion
138
+ let childHTML = '';
139
+ for (const child of element._childNodesInternal || []) {
140
+ if (child.nodeType === TEXT_NODE) {
141
+ childHTML += (child as any)._nodeValue || '';
142
+ } else if (child.nodeType === ELEMENT_NODE) {
143
+ childHTML += this.generateChildElementHTML(child as any);
144
+ } else if (child.nodeType === 8) { // COMMENT_NODE
145
+ childHTML += `<!--${(child as any).textContent || ''}-->`;
146
+ }
147
+ }
148
+ return `<${tagName}${attrs}>${childHTML}</${tagName}>`;
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Improved HTML parser for innerHTML using a stack-based approach
154
+ */
155
+ private parseAndAppendHTML(html: string): void {
156
+ const ElementFactory = require('../../factory/ElementFactory').ElementFactory;
157
+
158
+ let i = 0;
159
+ const length = html.length;
160
+
161
+ while (i < length) {
162
+ const nextTagStart = html.indexOf('<', i);
163
+
164
+ // Handle text content before next tag
165
+ if (nextTagStart === -1) {
166
+ // No more tags, rest is text
167
+ let text = html.substring(i).trim();
168
+ if (text) {
169
+ // Fix broken closing tags (e.g., "/div>" -> "</div>")
170
+ text = this.fixBrokenClosingTags(text);
171
+ const { TextBase } = require('../TextBase');
172
+ const textNode = new TextBase(text, this._ownerDocument);
173
+ this.appendChild(textNode);
174
+ }
175
+ break;
176
+ } else if (nextTagStart > i) {
177
+ // Text content before the tag
178
+ let text = html.substring(i, nextTagStart).trim();
179
+ if (text) {
180
+ // Fix broken closing tags (e.g., "/div>" -> "</div>")
181
+ text = this.fixBrokenClosingTags(text);
182
+ const { TextBase } = require('../TextBase');
183
+ const textNode = new TextBase(text, this._ownerDocument);
184
+ this.appendChild(textNode);
185
+ }
186
+ }
187
+
188
+ i = nextTagStart;
189
+
190
+ // Parse the tag - find the real tag end, considering quoted attributes
191
+ const tagEnd = this.findTagEnd(html, i);
192
+ if (tagEnd === -1) break;
193
+
194
+ const tagContent = html.substring(i + 1, tagEnd);
195
+
196
+ // Handle comments
197
+ if (tagContent.startsWith('!--')) {
198
+ const commentEnd = html.indexOf('-->', i);
199
+ if (commentEnd !== -1) {
200
+ const commentContent = html.substring(i + 4, commentEnd);
201
+ const { Comment } = require('../Comment');
202
+ const commentNode = new Comment(commentContent, this._ownerDocument);
203
+ this.appendChild(commentNode);
204
+ i = commentEnd + 3;
205
+ continue;
206
+ }
207
+ }
208
+
209
+ // Handle self-closing tags
210
+ if (tagContent.endsWith('/')) {
211
+ const parts = tagContent.slice(0, -1).trim().split(/\s+/);
212
+ const tagName = parts[0];
213
+ const attributeString = tagContent.slice(tagName.length, -1).trim();
214
+
215
+ const element = ElementFactory.createElement(tagName, this._ownerDocument);
216
+ this.parseAttributes(element, attributeString);
217
+ this.appendChild(element);
218
+ i = tagEnd + 1;
219
+ continue;
220
+ }
221
+
222
+ // Handle closing tags - if they don't have matching opening tags, treat as text
223
+ if (tagContent.startsWith('/')) {
224
+ // For now, treat unmatched closing tags as text content
225
+ const closingTagText = `<${tagContent}>`;
226
+ const { TextBase } = require('../TextBase');
227
+ const textNode = new TextBase(closingTagText, this._ownerDocument);
228
+ this.appendChild(textNode);
229
+ i = tagEnd + 1;
230
+ continue;
231
+ }
232
+
233
+ // Handle opening tags
234
+ const parts = tagContent.split(/\s+/);
235
+ const tagName = parts[0];
236
+ const attributeString = tagContent.slice(tagName.length).trim();
237
+
238
+ // Special handling for style and script tags
239
+ if (tagName === 'style' || tagName === 'script') {
240
+ const closingTag = `</${tagName}>`;
241
+ const closingTagIndex = html.indexOf(closingTag, tagEnd + 1);
242
+
243
+ if (closingTagIndex !== -1) {
244
+ const element = ElementFactory.createElement(tagName, this._ownerDocument);
245
+ this.parseAttributes(element, attributeString);
246
+
247
+ const content = html.substring(tagEnd + 1, closingTagIndex);
248
+ if (content) {
249
+ const { TextBase } = require('../TextBase');
250
+ const textNode = new TextBase(content, this._ownerDocument);
251
+ element.appendChild(textNode);
252
+ }
253
+
254
+ this.appendChild(element);
255
+ i = closingTagIndex + closingTag.length;
256
+ continue;
257
+ }
258
+ }
259
+
260
+ // Handle regular opening tags with content
261
+ const closingTag = `</${tagName}>`;
262
+ const closingTagIndex = this.findMatchingClosingTag(html, tagName, tagEnd + 1);
263
+
264
+ if (closingTagIndex !== -1) {
265
+ const element = ElementFactory.createElement(tagName, this._ownerDocument);
266
+ this.parseAttributes(element, attributeString);
267
+
268
+ const content = html.substring(tagEnd + 1, closingTagIndex);
269
+ if (content.trim()) {
270
+ element.innerHTML = content;
271
+ }
272
+
273
+ this.appendChild(element);
274
+ i = closingTagIndex + closingTag.length;
275
+ } else {
276
+ // No matching closing tag found, treat as self-closing
277
+ const element = ElementFactory.createElement(tagName, this._ownerDocument);
278
+ this.parseAttributes(element, attributeString);
279
+ this.appendChild(element);
280
+ i = tagEnd + 1;
281
+ }
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Find the real end of a tag, considering quoted attributes
287
+ */
288
+ private findTagEnd(html: string, startIndex: number): number {
289
+ let i = startIndex + 1; // Skip the '<'
290
+ let inQuotes = false;
291
+ let quoteChar = '';
292
+
293
+ while (i < html.length) {
294
+ const char = html[i];
295
+
296
+ if (!inQuotes) {
297
+ if (char === '"' || char === "'") {
298
+ inQuotes = true;
299
+ quoteChar = char;
300
+ } else if (char === '>') {
301
+ return i;
302
+ }
303
+ } else {
304
+ if (char === quoteChar) {
305
+ inQuotes = false;
306
+ quoteChar = '';
307
+ }
308
+ }
309
+
310
+ i++;
311
+ }
312
+
313
+ return -1; // No closing '>' found
314
+ }
315
+
316
+ /**
317
+ * Fix broken closing tags in text content
318
+ * Converts patterns like "/div>" to "</div>"
319
+ */
320
+ private fixBrokenClosingTags(text: string): string {
321
+ // Pattern to match broken closing tags: /tagname>
322
+ return text.replace(/\/(\w+)>/g, '</$1>');
323
+ }
324
+
325
+ /**
326
+ * Find the matching closing tag, accounting for nested tags of the same type
327
+ */
328
+ private findMatchingClosingTag(html: string, tagName: string, startIndex: number): number {
329
+ const openTag = `<${tagName}`;
330
+ const closeTag = `</${tagName}>`;
331
+ let depth = 1;
332
+ let i = startIndex;
333
+
334
+ while (i < html.length && depth > 0) {
335
+ const nextOpen = html.indexOf(openTag, i);
336
+ const nextClose = html.indexOf(closeTag, i);
337
+
338
+ if (nextClose === -1) {
339
+ return -1; // No closing tag found
340
+ }
341
+
342
+ if (nextOpen !== -1 && nextOpen < nextClose) {
343
+ // Found another opening tag before the closing tag
344
+ // Make sure it's a complete tag (not just a substring)
345
+ const afterTag = html.charAt(nextOpen + openTag.length);
346
+ if (afterTag === ' ' || afterTag === '>' || afterTag === '/') {
347
+ depth++;
348
+ }
349
+ i = nextOpen + openTag.length;
350
+ } else {
351
+ // Found a closing tag
352
+ depth--;
353
+ if (depth === 0) {
354
+ return nextClose;
355
+ }
356
+ i = nextClose + closeTag.length;
357
+ }
358
+ }
359
+
360
+ return -1;
361
+ }
362
+
363
+ /**
364
+ * Parse attributes from attribute string
365
+ */
366
+ private parseAttributes(element: any, attributeString: string): void {
367
+ // Improved attribute parsing that handles complex JavaScript expressions
368
+ let position = 0;
369
+ const length = attributeString.length;
370
+
371
+ while (position < length) {
372
+ // Skip whitespace
373
+ while (position < length && /\s/.test(attributeString[position])) {
374
+ position++;
375
+ }
376
+
377
+ if (position >= length) break;
378
+
379
+ // Find attribute name
380
+ const nameStart = position;
381
+ while (position < length && /[\w:-]/.test(attributeString[position])) {
382
+ position++;
383
+ }
384
+
385
+ if (position === nameStart) {
386
+ // Invalid character, skip it
387
+ position++;
388
+ continue;
389
+ }
390
+
391
+ const name = attributeString.substring(nameStart, position);
392
+
393
+ // Skip whitespace
394
+ while (position < length && /\s/.test(attributeString[position])) {
395
+ position++;
396
+ }
397
+
398
+ let value = '';
399
+
400
+ // Check if there's an equals sign
401
+ if (position < length && attributeString[position] === '=') {
402
+ position++; // Skip '='
403
+
404
+ // Skip whitespace
405
+ while (position < length && /\s/.test(attributeString[position])) {
406
+ position++;
407
+ }
408
+
409
+ if (position < length) {
410
+ const quote = attributeString[position];
411
+
412
+ if (quote === '"' || quote === "'") {
413
+ // Quoted value - find matching closing quote
414
+ position++; // Skip opening quote
415
+ const valueStart = position;
416
+
417
+ while (position < length && attributeString[position] !== quote) {
418
+ position++;
419
+ }
420
+
421
+ value = attributeString.substring(valueStart, position);
422
+
423
+ if (position < length && attributeString[position] === quote) {
424
+ position++; // Skip closing quote
425
+ }
426
+ } else {
427
+ // Unquoted value - read until whitespace or end
428
+ const valueStart = position;
429
+ while (position < length && !/\s/.test(attributeString[position])) {
430
+ position++;
431
+ }
432
+ value = attributeString.substring(valueStart, position);
433
+ }
434
+ }
435
+ }
436
+
437
+ // Decode HTML entities in attribute values
438
+ value = this.decodeHTMLEntities(value);
439
+
440
+ element.setAttribute(name, value);
441
+ }
442
+ }
443
+
444
+ /**
445
+ * Escape HTML entities in a string to prevent XSS
446
+ */
447
+ protected escapeHTMLEntities(str: string): string {
448
+ const entityMap: { [key: string]: string } = {
449
+ '&': '&amp;',
450
+ '<': '&lt;',
451
+ '>': '&gt;',
452
+ '"': '&quot;',
453
+ "'": '&#39;'
454
+ };
455
+
456
+ return str.replace(/[&<>"']/g, (char) => {
457
+ return entityMap[char] || char;
458
+ });
459
+ }
460
+
461
+ /**
462
+ * Decode HTML entities in a string
463
+ */
464
+ protected decodeHTMLEntities(str: string): string {
465
+ const entityMap: { [key: string]: string } = {
466
+ '&amp;': '&',
467
+ '&lt;': '<',
468
+ '&gt;': '>',
469
+ '&quot;': '"',
470
+ '&#39;': "'",
471
+ '&#34;': '"',
472
+ '&apos;': "'",
473
+ '&copy;': '©',
474
+ '&reg;': '®',
475
+ '&trade;': '™',
476
+ '&nbsp;': ' ',
477
+ '&hellip;': '…',
478
+ '&mdash;': '—',
479
+ '&ndash;': '–',
480
+ '&lsquo;': '\u2018',
481
+ '&rsquo;': '\u2019',
482
+ '&ldquo;': '"',
483
+ '&rdquo;': '"'
484
+ };
485
+
486
+ return str.replace(/&[a-zA-Z0-9#]+;/g, (entity) => {
487
+ // Handle named entities
488
+ if (entityMap[entity]) {
489
+ return entityMap[entity];
490
+ }
491
+
492
+ // Handle numeric entities like &#39; &#34;
493
+ if (entity.startsWith('&#') && entity.endsWith(';')) {
494
+ const numStr = entity.slice(2, -1);
495
+ const num = parseInt(numStr, 10);
496
+ if (!isNaN(num)) {
497
+ return String.fromCharCode(num);
498
+ }
499
+ }
500
+
501
+ // Handle hex entities like &#x27;
502
+ if (entity.startsWith('&#x') && entity.endsWith(';')) {
503
+ const hexStr = entity.slice(3, -1);
504
+ const num = parseInt(hexStr, 16);
505
+ if (!isNaN(num)) {
506
+ return String.fromCharCode(num);
507
+ }
508
+ }
509
+
510
+ // Return original if not recognized
511
+ return entity;
512
+ });
513
+ }
514
+
515
+ get outerHTML(): string {
516
+ const attrs = Array.from(this._attributes.entries())
517
+ .map(([name, value]) => value === '' ? ` ${name}` : ` ${name}="${value.replace(/"/g, '&quot;')}"`)
518
+ .join('');
519
+
520
+ // Check if it's a self-closing tag
521
+ const selfClosingTags = ['img', 'input', 'br', 'hr', 'meta', 'link', 'area', 'base', 'col', 'embed', 'source', 'track', 'wbr'];
522
+ const isSelfClosing = selfClosingTags.includes(this.tagName.toLowerCase());
523
+
524
+ if (isSelfClosing) {
525
+ return `<${this.tagName.toLowerCase()}${attrs} />`;
526
+ } else {
527
+ return `<${this.tagName.toLowerCase()}${attrs}>${this.innerHTML}</${this.tagName.toLowerCase()}>`;
528
+ }
529
+ }
530
+
531
+ get namespaceURI(): string | null {
532
+ return 'http://www.w3.org/1999/xhtml';
533
+ }
534
+
535
+ get prefix(): string | null {
536
+ return null;
537
+ }
538
+
539
+ // Attribute methods
540
+ getAttribute(qualifiedName: string): string | null {
541
+ const value = this._attributes.get(qualifiedName.toLowerCase());
542
+ return value !== undefined ? value : null;
543
+ }
544
+
545
+ setAttribute(qualifiedName: string, value: string): void {
546
+ const name = qualifiedName.toLowerCase();
547
+ this._attributes.set(name, value);
548
+
549
+ // Update special properties
550
+ if (name === 'id') {
551
+ this._id = value;
552
+ } else if (name === 'class') {
553
+ this._className = value;
554
+ }
555
+ }
556
+
557
+ removeAttribute(qualifiedName: string): void {
558
+ const name = qualifiedName.toLowerCase();
559
+ this._attributes.delete(name);
560
+
561
+ // Update special properties
562
+ if (name === 'id') {
563
+ this._id = '';
564
+ } else if (name === 'class') {
565
+ this._className = '';
566
+ }
567
+ }
568
+
569
+ hasAttribute(qualifiedName: string): boolean {
570
+ return this._attributes.has(qualifiedName.toLowerCase());
571
+ }
572
+
573
+ /**
574
+ * Returns the closest ancestor element (including the element itself) that matches the specified CSS selector.
575
+ *
576
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/closest)
577
+ */
578
+ closest<K extends keyof HTMLElementTagNameMap>(selector: K): HTMLElementTagNameMap[K] | null;
579
+ closest<K extends keyof SVGElementTagNameMap>(selector: K): SVGElementTagNameMap[K] | null;
580
+ closest<K extends keyof MathMLElementTagNameMap>(selector: K): MathMLElementTagNameMap[K] | null;
581
+ closest<E extends Element = Element>(selectors: string): E | null;
582
+ closest(selectors: string): Element | null {
583
+ let element: Element | null = this as any;
584
+
585
+ while (element) {
586
+ if (element.matches && element.matches(selectors)) {
587
+ return element;
588
+ }
589
+ element = element.parentElement;
590
+ }
591
+
592
+ return null;
593
+ }
594
+
595
+ /**
596
+ * Returns true if the element would be selected by the specified CSS selector; otherwise, returns false.
597
+ *
598
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/matches)
599
+ */
600
+ matches(selectors: string): boolean {
601
+ return CSSSelector.matches(this as any, selectors);
602
+ }
603
+
604
+ // ChildNode methods are inherited from ParentNodeBase -> ChildNodeBase
605
+
606
+ // Additional Element properties and methods - Not implemented yet
607
+
608
+ get attributes(): NamedNodeMap {
609
+ return new NamedNodeMapImpl(this._attributes);
610
+ }
611
+
612
+ get clientHeight(): number {
613
+ throw new Error('Element.clientHeight is not implemented yet');
614
+ }
615
+
616
+ get clientLeft(): number {
617
+ throw new Error('Element.clientLeft is not implemented yet');
618
+ }
619
+
620
+ get clientTop(): number {
621
+ throw new Error('Element.clientTop is not implemented yet');
622
+ }
623
+
624
+ get clientWidth(): number {
625
+ throw new Error('Element.clientWidth is not implemented yet');
626
+ }
627
+
628
+ get currentCSSZoom(): number {
629
+ throw new Error('Element.currentCSSZoom is not implemented yet');
630
+ }
631
+
632
+ onfullscreenchange: ((this: Element, ev: Event) => any) | null = null;
633
+ onfullscreenerror: ((this: Element, ev: Event) => any) | null = null;
634
+
635
+ get part(): any {
636
+ throw new Error('Element.part is not implemented yet');
637
+ }
638
+
639
+ get scrollHeight(): number {
640
+ throw new Error('Element.scrollHeight is not implemented yet');
641
+ }
642
+
643
+ get scrollLeft(): number {
644
+ throw new Error('Element.scrollLeft is not implemented yet');
645
+ }
646
+
647
+ set scrollLeft(value: number) {
648
+ throw new Error('Element.scrollLeft setter is not implemented yet');
649
+ }
650
+
651
+ get scrollTop(): number {
652
+ throw new Error('Element.scrollTop is not implemented yet');
653
+ }
654
+
655
+ set scrollTop(value: number) {
656
+ throw new Error('Element.scrollTop setter is not implemented yet');
657
+ }
658
+
659
+ get scrollWidth(): number {
660
+ throw new Error('Element.scrollWidth is not implemented yet');
661
+ }
662
+
663
+ get shadowRoot(): any {
664
+ throw new Error('Element.shadowRoot is not implemented yet');
665
+ }
666
+
667
+ get slot(): string {
668
+ throw new Error('Element.slot is not implemented yet');
669
+ }
670
+
671
+ set slot(value: string) {
672
+ throw new Error('Element.slot setter is not implemented yet');
673
+ }
674
+
675
+ // Methods - Not implemented yet
676
+
677
+ attachShadow(init: any): any {
678
+ throw new Error('Element.attachShadow() is not implemented yet');
679
+ }
680
+
681
+ checkVisibility(options?: any): boolean {
682
+ throw new Error('Element.checkVisibility() is not implemented yet');
683
+ }
684
+
685
+ computedStyleMap(): any {
686
+ throw new Error('Element.computedStyleMap() is not implemented yet');
687
+ }
688
+
689
+ getAttributeNS(namespace: string | null, localName: string): string | null {
690
+ // For simplicity, we'll ignore namespace and use localName
691
+ return this.getAttribute(localName);
692
+ }
693
+
694
+ getAttributeNames(): string[] {
695
+ return Array.from(this._attributes.keys());
696
+ }
697
+
698
+ getAttributeNode(qualifiedName: string): Attr | null {
699
+ const value = this.getAttribute(qualifiedName);
700
+ if (value !== null) {
701
+ return new AttrImpl(qualifiedName, value);
702
+ }
703
+ return null;
704
+ }
705
+
706
+ getAttributeNodeNS(namespace: string | null, localName: string): Attr | null {
707
+ // For simplicity, we'll ignore namespace and use localName
708
+ return this.getAttributeNode(localName);
709
+ }
710
+
711
+ getBoundingClientRect(): any {
712
+ throw new Error('Element.getBoundingClientRect() is not implemented yet');
713
+ }
714
+
715
+ getClientRects(): any {
716
+ throw new Error('Element.getClientRects() is not implemented yet');
717
+ }
718
+
719
+ getElementsByClassName(classNames: string): HTMLCollection {
720
+ const result: Element[] = [];
721
+ const classNameList = classNames.trim().split(/\s+/);
722
+
723
+ // Helper function to check if element has all specified classes
724
+ const hasAllClasses = (element: Element, classes: string[]): boolean => {
725
+ const elementClasses = element.className.trim().split(/\s+/);
726
+ return classes.every(cls => elementClasses.includes(cls));
727
+ };
728
+
729
+ // Recursive function to traverse all descendants
730
+ const traverse = (node: any) => {
731
+ if (node.nodeType === ELEMENT_NODE) {
732
+ const element = node as Element;
733
+ if (hasAllClasses(element, classNameList)) {
734
+ result.push(element);
735
+ }
736
+ }
737
+
738
+ // Traverse children
739
+ for (let i = 0; i < node.childNodes.length; i++) {
740
+ traverse(node.childNodes[i]);
741
+ }
742
+ };
743
+
744
+ // Start traversal from this element's children
745
+ for (let i = 0; i < this.childNodes.length; i++) {
746
+ traverse(this.childNodes[i]);
747
+ }
748
+
749
+ return new HTMLCollection(result);
750
+ }
751
+
752
+ getElementsByTagName(qualifiedName: string): HTMLCollection {
753
+ const result: Element[] = [];
754
+ const tagName = qualifiedName.toLowerCase();
755
+ const isWildcard = tagName === '*';
756
+
757
+ // Recursive function to traverse all descendants
758
+ const traverse = (node: any) => {
759
+ if (node.nodeType === ELEMENT_NODE) {
760
+ const element = node as Element;
761
+ if (isWildcard || element.localName === tagName) {
762
+ result.push(element);
763
+ }
764
+ }
765
+
766
+ // Traverse children
767
+ for (let i = 0; i < node.childNodes.length; i++) {
768
+ traverse(node.childNodes[i]);
769
+ }
770
+ };
771
+
772
+ // Start traversal from this element's children
773
+ for (let i = 0; i < this.childNodes.length; i++) {
774
+ traverse(this.childNodes[i]);
775
+ }
776
+
777
+ return new HTMLCollection(result);
778
+ }
779
+
780
+ getElementsByTagNameNS(namespace: string | null, localName: string): any {
781
+ // For simplicity, we'll implement this similar to getElementsByTagName
782
+ // In a full implementation, namespace handling would be more complex
783
+ return this.getElementsByTagName(localName);
784
+ }
785
+
786
+ getHTML(options?: any): string {
787
+ throw new Error('Element.getHTML() is not implemented yet');
788
+ }
789
+
790
+ hasAttributeNS(namespace: string | null, localName: string): boolean {
791
+ // For simplicity, we'll ignore namespace and use localName
792
+ return this.hasAttribute(localName);
793
+ }
794
+
795
+ hasAttributes(): boolean {
796
+ return this._attributes.size > 0;
797
+ }
798
+
799
+ hasPointerCapture(pointerId: number): boolean {
800
+ throw new Error('Element.hasPointerCapture() is not implemented yet');
801
+ }
802
+
803
+ insertAdjacentElement(where: InsertPosition, element: Element): Element | null {
804
+ const position = where.toLowerCase();
805
+
806
+ switch (position) {
807
+ case 'beforebegin':
808
+ // Insert before this element
809
+ if (this.parentNode) {
810
+ this.parentNode.insertBefore(element as any, this as any);
811
+ return element;
812
+ }
813
+ return null;
814
+
815
+ case 'afterbegin':
816
+ // Insert as first child of this element
817
+ if (this.firstChild) {
818
+ this.insertBefore(element as any, this.firstChild);
819
+ } else {
820
+ this.appendChild(element as any);
821
+ }
822
+ return element;
823
+
824
+ case 'beforeend':
825
+ // Insert as last child of this element
826
+ this.appendChild(element as any);
827
+ return element;
828
+
829
+ case 'afterend':
830
+ // Insert after this element
831
+ if (this.parentNode) {
832
+ if (this.nextSibling) {
833
+ this.parentNode.insertBefore(element as any, this.nextSibling);
834
+ } else {
835
+ this.parentNode.appendChild(element as any);
836
+ }
837
+ return element;
838
+ }
839
+ return null;
840
+
841
+ default:
842
+ throw new DOMException(`Invalid position: ${where}`, 'SyntaxError');
843
+ }
844
+ }
845
+
846
+ insertAdjacentHTML(position: InsertPosition, html: string): void {
847
+ const pos = position.toLowerCase();
848
+
849
+ // Parse HTML string into elements
850
+ const tempDiv = this._ownerDocument.createElement('div');
851
+ tempDiv.innerHTML = html;
852
+
853
+ // Move all parsed nodes to the target position
854
+ const fragment = this._ownerDocument.createDocumentFragment();
855
+ while (tempDiv.firstChild) {
856
+ fragment.appendChild(tempDiv.firstChild);
857
+ }
858
+
859
+ switch (pos) {
860
+ case 'beforebegin':
861
+ if (this.parentNode) {
862
+ this.parentNode.insertBefore(fragment, this as any);
863
+ }
864
+ break;
865
+
866
+ case 'afterbegin':
867
+ if (this.firstChild) {
868
+ this.insertBefore(fragment, this.firstChild);
869
+ } else {
870
+ this.appendChild(fragment);
871
+ }
872
+ break;
873
+
874
+ case 'beforeend':
875
+ this.appendChild(fragment);
876
+ break;
877
+
878
+ case 'afterend':
879
+ if (this.parentNode) {
880
+ if (this.nextSibling) {
881
+ this.parentNode.insertBefore(fragment, this.nextSibling);
882
+ } else {
883
+ this.parentNode.appendChild(fragment);
884
+ }
885
+ }
886
+ break;
887
+
888
+ default:
889
+ throw new DOMException(`Invalid position: ${position}`, 'SyntaxError');
890
+ }
891
+ }
892
+
893
+ insertAdjacentText(where: InsertPosition, data: string): void {
894
+ const position = where.toLowerCase();
895
+
896
+ // Create text node
897
+ const textNode = this._ownerDocument.createTextNode(data);
898
+
899
+ switch (position) {
900
+ case 'beforebegin':
901
+ if (this.parentNode) {
902
+ this.parentNode.insertBefore(textNode, this as any);
903
+ }
904
+ break;
905
+
906
+ case 'afterbegin':
907
+ if (this.firstChild) {
908
+ this.insertBefore(textNode, this.firstChild);
909
+ } else {
910
+ this.appendChild(textNode);
911
+ }
912
+ break;
913
+
914
+ case 'beforeend':
915
+ this.appendChild(textNode);
916
+ break;
917
+
918
+ case 'afterend':
919
+ if (this.parentNode) {
920
+ if (this.nextSibling) {
921
+ this.parentNode.insertBefore(textNode, this.nextSibling);
922
+ } else {
923
+ this.parentNode.appendChild(textNode);
924
+ }
925
+ }
926
+ break;
927
+
928
+ default:
929
+ throw new DOMException(`Invalid position: ${where}`, 'SyntaxError');
930
+ }
931
+ }
932
+
933
+ releasePointerCapture(pointerId: number): void {
934
+ // throw new Error('Element.releasePointerCapture() is not implemented yet');
935
+ }
936
+
937
+ removeAttributeNS(namespace: string | null, localName: string): void {
938
+ // For simplicity, we'll ignore namespace and use localName
939
+ this.removeAttribute(localName);
940
+ }
941
+
942
+ removeAttributeNode(attr: Attr): Attr {
943
+ const oldValue = this.getAttribute(attr.name);
944
+ if (oldValue !== null) {
945
+ this.removeAttribute(attr.name);
946
+ return new AttrImpl(attr.name, oldValue);
947
+ }
948
+ throw new DOMException('The attribute node is not an attribute of this element', 'NotFoundError');
949
+ }
950
+
951
+ requestFullscreen(options?: any): Promise<void> {
952
+ throw new Error('Element.requestFullscreen() is not implemented yet');
953
+ }
954
+
955
+ requestPointerLock(options?: any): Promise<void> {
956
+ throw new Error('Element.requestPointerLock() is not implemented yet');
957
+ }
958
+
959
+ scroll(options?: any): void;
960
+ scroll(x: number, y: number): void;
961
+ scroll(optionsOrX?: any, y?: number): void {
962
+ // throw new Error('Element.scroll() is not implemented yet');
963
+ }
964
+
965
+ scrollBy(options?: any): void;
966
+ scrollBy(x: number, y: number): void;
967
+ scrollBy(optionsOrX?: any, y?: number): void {
968
+ // throw new Error('Element.scrollBy() is not implemented yet');
969
+ }
970
+
971
+ scrollIntoView(arg?: boolean | any): void {
972
+ // throw new Error('Element.scrollIntoView() is not implemented yet');
973
+ }
974
+
975
+ scrollTo(options?: any): void;
976
+ scrollTo(x: number, y: number): void;
977
+ scrollTo(optionsOrX?: any, y?: number): void {
978
+ // throw new Error('Element.scrollTo() is not implemented yet');
979
+ }
980
+
981
+ setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void {
982
+ // For simplicity, we'll ignore namespace and use qualifiedName
983
+ this.setAttribute(qualifiedName, value);
984
+ }
985
+
986
+ setAttributeNode(attr: Attr): Attr | null {
987
+ const oldAttr = this.getAttributeNode(attr.name);
988
+ this.setAttribute(attr.name, attr.value);
989
+ return oldAttr;
990
+ }
991
+
992
+ setAttributeNodeNS(attr: Attr): Attr | null {
993
+ // For simplicity, we'll ignore namespace
994
+ return this.setAttributeNode(attr);
995
+ }
996
+
997
+ setHTMLUnsafe(html: string): void {
998
+ // throw new Error('Element.setHTMLUnsafe() is not implemented yet');
999
+ }
1000
+
1001
+ setPointerCapture(pointerId: number): void {
1002
+ // throw new Error('Element.setPointerCapture() is not implemented yet');
1003
+ }
1004
+
1005
+ toggleAttribute(qualifiedName: string, force?: boolean): boolean {
1006
+ const hasAttr = this.hasAttribute(qualifiedName);
1007
+
1008
+ if (force === true || (force === undefined && !hasAttr)) {
1009
+ this.setAttribute(qualifiedName, '');
1010
+ return true;
1011
+ } else if (force === false || (force === undefined && hasAttr)) {
1012
+ this.removeAttribute(qualifiedName);
1013
+ return false;
1014
+ }
1015
+
1016
+ return hasAttr;
1017
+ }
1018
+
1019
+ webkitMatchesSelector(selectors: string): boolean {
1020
+ // throw new Error('Element.webkitMatchesSelector() is not implemented yet');
1021
+ return false;
1022
+ }
1023
+
1024
+ // EventTarget methods - Not implemented yet
1025
+ addEventListener(type: string, listener: any, options?: any): void {
1026
+ // throw new Error('Element.addEventListener() is not implemented yet');
1027
+ }
1028
+
1029
+ removeEventListener(type: string, listener: any, options?: any): void {
1030
+ // throw new Error('Element.removeEventListener() is not implemented yet');
1031
+ }
1032
+
1033
+ dispatchEvent(event: any): boolean {
1034
+ // throw new Error('Element.dispatchEvent() is not implemented yet');
1035
+ return true;
1036
+ }
1037
+
1038
+ cloneNode(deep?: boolean): ElementBase {
1039
+ // Use ElementFactory to create the correct element type
1040
+ const clone = ElementFactory.createElement(this.tagName, this._ownerDocument);
1041
+
1042
+ // Copy attributes
1043
+ for (const [name, value] of this._attributes) {
1044
+ clone.setAttribute(name, value);
1045
+ }
1046
+
1047
+ // Copy children if deep clone
1048
+ if (deep) {
1049
+ for (const child of this._childNodesInternal) {
1050
+ if (child && 'cloneNode' in child) {
1051
+ clone.appendChild((child as any).cloneNode(true));
1052
+ }
1053
+ }
1054
+ }
1055
+
1056
+ return clone;
1057
+ }
1058
+ }
1059
+
1060
+ // DOMTokenList implementation
1061
+ class DOMTokenListImpl implements DOMTokenList {
1062
+ constructor(private element: ElementBase) { }
1063
+
1064
+ get length(): number {
1065
+ return this.element.className.split(/\s+/).filter(c => c.length > 0).length;
1066
+ }
1067
+
1068
+ get value(): string {
1069
+ return this.element.className;
1070
+ }
1071
+
1072
+ set value(value: string) {
1073
+ this.element.className = value;
1074
+ }
1075
+
1076
+ add(...tokens: string[]): void {
1077
+ const classes = new Set(this.element.className.split(/\s+/).filter(c => c.length > 0));
1078
+ for (const token of tokens) {
1079
+ classes.add(token);
1080
+ }
1081
+ this.element.className = Array.from(classes).join(' ');
1082
+ }
1083
+
1084
+ remove(...tokens: string[]): void {
1085
+ const classes = new Set(this.element.className.split(/\s+/).filter(c => c.length > 0));
1086
+ for (const token of tokens) {
1087
+ classes.delete(token);
1088
+ }
1089
+ this.element.className = Array.from(classes).join(' ');
1090
+ }
1091
+
1092
+ contains(token: string): boolean {
1093
+ return this.element.className.split(/\s+/).includes(token);
1094
+ }
1095
+
1096
+ toggle(token: string, force?: boolean): boolean {
1097
+ const hasToken = this.contains(token);
1098
+
1099
+ if (force === true || (force === undefined && !hasToken)) {
1100
+ this.add(token);
1101
+ return true;
1102
+ } else {
1103
+ this.remove(token);
1104
+ return false;
1105
+ }
1106
+ }
1107
+
1108
+ replace(oldToken: string, newToken: string): boolean {
1109
+ if (this.contains(oldToken)) {
1110
+ this.remove(oldToken);
1111
+ this.add(newToken);
1112
+ return true;
1113
+ }
1114
+ return false;
1115
+ }
1116
+
1117
+ item(index: number): string | null {
1118
+ const classes = this.element.className.split(/\s+/).filter(c => c.length > 0);
1119
+ return index >= 0 && index < classes.length ? classes[index] : null;
1120
+ }
1121
+
1122
+ [index: number]: string;
1123
+ }
1124
+
1125
+
1126
+
1127
+ // Attr implementation
1128
+ class AttrImpl extends NodeBase implements Attr {
1129
+ public ownerElement: Element | null = null;
1130
+ public namespaceURI: string | null = null;
1131
+ public prefix: string | null = null;
1132
+ public specified: boolean = true;
1133
+
1134
+ constructor(public name: string, public value: string) {
1135
+ super(ATTRIBUTE_NODE, name);
1136
+ }
1137
+
1138
+ get localName(): string {
1139
+ return this.name;
1140
+ }
1141
+ }
1142
+
1143
+ // NamedNodeMap implementation
1144
+ class NamedNodeMapImpl implements NamedNodeMap {
1145
+ constructor(private attributes: Map<string, string>) { }
1146
+
1147
+ get length(): number {
1148
+ return this.attributes.size;
1149
+ }
1150
+
1151
+ getNamedItem(qualifiedName: string): Attr | null {
1152
+ const value = this.attributes.get(qualifiedName.toLowerCase());
1153
+ return value !== undefined ? new AttrImpl(qualifiedName, value) : null;
1154
+ }
1155
+
1156
+ getNamedItemNS(namespace: string | null, localName: string): Attr | null {
1157
+ // For simplicity, ignore namespace
1158
+ return this.getNamedItem(localName);
1159
+ }
1160
+
1161
+ item(index: number): Attr | null {
1162
+ const keys = Array.from(this.attributes.keys());
1163
+ if (index >= 0 && index < keys.length) {
1164
+ const key = keys[index];
1165
+ const value = this.attributes.get(key)!;
1166
+ return new AttrImpl(key, value);
1167
+ }
1168
+ return null;
1169
+ }
1170
+
1171
+ removeNamedItem(qualifiedName: string): Attr {
1172
+ const value = this.attributes.get(qualifiedName.toLowerCase());
1173
+ if (value !== undefined) {
1174
+ this.attributes.delete(qualifiedName.toLowerCase());
1175
+ return new AttrImpl(qualifiedName, value);
1176
+ }
1177
+ throw new DOMException('The attribute is not found', 'NotFoundError');
1178
+ }
1179
+
1180
+ removeNamedItemNS(namespace: string | null, localName: string): Attr {
1181
+ // For simplicity, ignore namespace
1182
+ return this.removeNamedItem(localName);
1183
+ }
1184
+
1185
+ setNamedItem(attr: Attr): Attr | null {
1186
+ const oldValue = this.attributes.get(attr.name.toLowerCase());
1187
+ this.attributes.set(attr.name.toLowerCase(), attr.value);
1188
+ return oldValue !== undefined ? new AttrImpl(attr.name, oldValue) : null;
1189
+ }
1190
+
1191
+ setNamedItemNS(attr: Attr): Attr | null {
1192
+ // For simplicity, ignore namespace
1193
+ return this.setNamedItem(attr);
1194
+ }
1195
+
1196
+ // Iterator implementation
1197
+ *[Symbol.iterator](): IterableIterator<Attr> {
1198
+ const keys = Array.from(this.attributes.keys());
1199
+ for (const key of keys) {
1200
+ const value = this.attributes.get(key)!;
1201
+ yield new AttrImpl(key, value);
1202
+ }
1203
+ }
1204
+
1205
+ // Additional iterator methods for compatibility
1206
+ keys(): IterableIterator<string> {
1207
+ return this.attributes.keys();
1208
+ }
1209
+
1210
+ values(): IterableIterator<Attr> {
1211
+ const self = this;
1212
+ return (function* () {
1213
+ for (const [key, value] of self.attributes) {
1214
+ yield new AttrImpl(key, value);
1215
+ }
1216
+ })();
1217
+ }
1218
+
1219
+ entries(): IterableIterator<[string, Attr]> {
1220
+ const self = this;
1221
+ return (function* () {
1222
+ for (const [key, value] of self.attributes) {
1223
+ yield [key, new AttrImpl(key, value)] as [string, Attr];
1224
+ }
1225
+ })();
1226
+ }
1227
+
1228
+ // forEach method for compatibility
1229
+ forEach(callback: (attr: Attr, index: number, map: NamedNodeMap) => void, thisArg?: any): void {
1230
+ const keys = Array.from(this.attributes.keys());
1231
+ keys.forEach((key, index) => {
1232
+ const value = this.attributes.get(key)!;
1233
+ const attr = new AttrImpl(key, value);
1234
+ callback.call(thisArg, attr, index, this);
1235
+ });
1236
+ }
1237
+
1238
+ [index: number]: Attr;
1239
+ }