defuddle-cli 0.2.0 → 0.3.1

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 (36) hide show
  1. package/dist/dom/document.d.ts +3 -0
  2. package/dist/dom/document.js +49 -0
  3. package/dist/dom/elements.d.ts +2 -0
  4. package/dist/dom/elements.js +478 -0
  5. package/dist/dom/interfaces/elements/base.d.ts +14 -0
  6. package/dist/dom/interfaces/elements/base.js +46 -0
  7. package/dist/dom/interfaces/elements/form.d.ts +2 -0
  8. package/dist/dom/interfaces/elements/form.js +123 -0
  9. package/dist/dom/interfaces/elements/index.d.ts +2 -0
  10. package/dist/dom/interfaces/elements/index.js +22 -0
  11. package/dist/dom/interfaces/elements/interactive.d.ts +2 -0
  12. package/dist/dom/interfaces/elements/interactive.js +83 -0
  13. package/dist/dom/interfaces/elements/media.d.ts +2 -0
  14. package/dist/dom/interfaces/elements/media.js +43 -0
  15. package/dist/dom/interfaces/elements/table.d.ts +2 -0
  16. package/dist/dom/interfaces/elements/table.js +155 -0
  17. package/dist/dom/interfaces/elements/text.d.ts +2 -0
  18. package/dist/dom/interfaces/elements/text.js +57 -0
  19. package/dist/dom/interfaces/elements.d.ts +2 -0
  20. package/dist/dom/interfaces/elements.js +478 -0
  21. package/dist/dom/interfaces/range.d.ts +1 -1
  22. package/dist/dom/range.d.ts +2 -0
  23. package/dist/dom/range.js +87 -0
  24. package/dist/dom/setup/document.d.ts +3 -0
  25. package/dist/dom/setup/document.js +49 -0
  26. package/dist/dom/setup.d.ts +12 -9
  27. package/dist/dom/setup.js +148 -533
  28. package/dist/dom/types/setup.d.ts +10 -0
  29. package/dist/dom/types/setup.js +1 -0
  30. package/dist/index.js +9 -684
  31. package/package.json +3 -5
  32. package/src/index.ts +9 -772
  33. package/src/dom/interfaces/document.ts +0 -53
  34. package/src/dom/interfaces/range.ts +0 -120
  35. package/src/dom/interfaces/setup.ts +0 -196
  36. package/src/markdown.ts +0 -592
package/src/index.ts CHANGED
@@ -1,29 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { Command } from 'commander';
4
- import { JSDOM, VirtualConsole, DOMWindow } from 'jsdom';
5
- import Defuddle from 'defuddle';
4
+ import { JSDOM } from 'jsdom';
5
+ import { Defuddle } from 'defuddle/node';
6
6
  import chalk from 'chalk';
7
- import { readFile, writeFile } from 'fs/promises';
7
+ import { writeFile } from 'fs/promises';
8
8
  import { fileURLToPath } from 'url';
9
9
  import { dirname, resolve } from 'path';
10
- import { createMarkdownContent } from './markdown.js';
11
- import { setupDOMInterfaces } from './dom/interfaces/setup.js';
12
- import { setupRange } from './dom/interfaces/range.js';
13
- import { setupDocumentMethods, setupWindowMethods } from './dom/interfaces/document.js';
14
-
15
- interface DOMSettableTokenList {
16
- length: number;
17
- value: string;
18
- add(token: string): void;
19
- contains(token: string): boolean;
20
- item(index: number): string | null;
21
- remove(token: string): void;
22
- replace(oldToken: string, newToken: string): boolean;
23
- supports(token: string): boolean;
24
- toggle(token: string, force?: boolean): boolean;
25
- [Symbol.iterator](): Iterator<string>;
26
- }
27
10
 
28
11
  interface ParseOptions {
29
12
  output?: string;
@@ -37,659 +20,6 @@ interface ParseOptions {
37
20
  const __filename = fileURLToPath(import.meta.url);
38
21
  const __dirname = dirname(__filename);
39
22
 
40
- // Define CSS interfaces globally first
41
- (globalThis as any).CSSRule = class {
42
- readonly type: number = 1;
43
- cssText: string;
44
- parentRule: any;
45
- parentStyleSheet: any;
46
-
47
- constructor(type?: number) {
48
- if (type !== undefined) {
49
- Object.defineProperty(this, 'type', { value: type });
50
- }
51
- this.cssText = '';
52
- this.parentRule = null;
53
- this.parentStyleSheet = null;
54
- }
55
- };
56
-
57
- // Static properties
58
- Object.defineProperties((globalThis as any).CSSRule, {
59
- STYLE_RULE: { value: 1, writable: false },
60
- CHARSET_RULE: { value: 2, writable: false },
61
- IMPORT_RULE: { value: 3, writable: false },
62
- MEDIA_RULE: { value: 4, writable: false },
63
- FONT_FACE_RULE: { value: 5, writable: false },
64
- PAGE_RULE: { value: 6, writable: false },
65
- KEYFRAMES_RULE: { value: 7, writable: false },
66
- KEYFRAME_RULE: { value: 8, writable: false },
67
- NAMESPACE_RULE: { value: 10, writable: false },
68
- COUNTER_STYLE_RULE: { value: 11, writable: false },
69
- SUPPORTS_RULE: { value: 12, writable: false },
70
- DOCUMENT_RULE: { value: 13, writable: false },
71
- FONT_FEATURE_VALUES_RULE: { value: 14, writable: false },
72
- VIEWPORT_RULE: { value: 15, writable: false },
73
- REGION_STYLE_RULE: { value: 16, writable: false }
74
- });
75
-
76
- (globalThis as any).CSSMediaRule = class extends (globalThis as any).CSSRule {
77
- media: MediaList;
78
- cssRules: CSSRuleList;
79
- conditionText: string = '';
80
- deleteRule: (index: number) => void = () => {};
81
- insertRule: (rule: string, index?: number) => number = () => 0;
82
-
83
- constructor() {
84
- super();
85
- Object.defineProperty(this, 'type', { value: 4 }); // CSSRule.MEDIA_RULE
86
- this.media = {
87
- length: 0,
88
- mediaText: '',
89
- item: () => null,
90
- appendMedium: () => {},
91
- deleteMedium: () => {},
92
- toString: () => '',
93
- [Symbol.iterator]: function*() { yield ''; return undefined; }
94
- };
95
- this.cssRules = {
96
- length: 0,
97
- item: () => null,
98
- [Symbol.iterator]: function*() {
99
- yield new (globalThis as any).CSSRule();
100
- return undefined;
101
- }
102
- };
103
- }
104
- };
105
-
106
- (globalThis as any).CSSStyleSheet = class {
107
- type: string = 'text/css';
108
- href: string | null = null;
109
- ownerNode: Element | ProcessingInstruction | null = null;
110
- parentStyleSheet: CSSStyleSheet | null = null;
111
- title: string | null = null;
112
- media: MediaList;
113
- disabled: boolean = false;
114
- cssRules: CSSRuleList;
115
- ownerRule: CSSRule | null = null;
116
- rules: CSSRuleList;
117
- addRule: (selector: string, style: string, index?: number) => number = () => 0;
118
- removeRule: (index?: number) => void = () => {};
119
- replace: (text: string) => Promise<CSSStyleSheet> = async () => this as unknown as CSSStyleSheet;
120
- replaceSync: (text: string) => void = () => {};
121
-
122
- constructor() {
123
- this.media = {
124
- length: 0,
125
- mediaText: '',
126
- item: () => null,
127
- appendMedium: () => {},
128
- deleteMedium: () => {},
129
- toString: () => '',
130
- [Symbol.iterator]: function*() { yield ''; return undefined; }
131
- };
132
- this.cssRules = {
133
- length: 0,
134
- item: () => null,
135
- [Symbol.iterator]: function*() {
136
- yield new (globalThis as any).CSSRule();
137
- return undefined;
138
- }
139
- };
140
- this.rules = this.cssRules;
141
- }
142
-
143
- insertRule(rule: string, index?: number): number {
144
- return 0;
145
- }
146
-
147
- deleteRule(index: number): void {}
148
- };
149
-
150
- // Define SVGElement globally
151
- (globalThis as any).SVGElement = class {
152
- id: string = '';
153
- className: string = '';
154
- style: CSSStyleDeclaration = {
155
- cssText: '',
156
- length: 0,
157
- parentRule: null,
158
- getPropertyPriority: () => '',
159
- getPropertyValue: () => '',
160
- item: () => '',
161
- removeProperty: () => '',
162
- setProperty: () => '',
163
- [Symbol.iterator]: function*() { yield ''; return undefined; }
164
- } as unknown as CSSStyleDeclaration;
165
- ownerSVGElement: SVGElement | null = null;
166
- viewportElement: SVGElement | null = null;
167
- tagName: string = '';
168
- namespaceURI: string | null = null;
169
- prefix: string | null = null;
170
- localName: string = '';
171
- baseURI: string = '';
172
- textContent: string | null = '';
173
- innerHTML: string = '';
174
- outerHTML: string = '';
175
- hidden: boolean = false;
176
- slot: string = '';
177
- attributes: NamedNodeMap = {
178
- length: 0,
179
- getNamedItem: () => null,
180
- getNamedItemNS: () => null,
181
- item: () => null,
182
- removeNamedItem: () => null,
183
- removeNamedItemNS: () => null,
184
- setNamedItem: () => null,
185
- setNamedItemNS: () => null,
186
- [Symbol.iterator]: function*() { yield null; return undefined; }
187
- } as unknown as NamedNodeMap;
188
- childNodes: NodeListOf<ChildNode> = {
189
- length: 0,
190
- item: () => null,
191
- forEach: () => {},
192
- entries: function*() { yield [0, null]; return undefined; },
193
- keys: function*() { yield 0; return undefined; },
194
- values: function*() { yield null; return undefined; },
195
- [Symbol.iterator]: function*() { yield null; return undefined; }
196
- } as unknown as NodeListOf<ChildNode>;
197
- firstChild: ChildNode | null = null;
198
- lastChild: ChildNode | null = null;
199
- nextSibling: ChildNode | null = null;
200
- previousSibling: ChildNode | null = null;
201
- parentNode: Node & ParentNode | null = null;
202
- parentElement: HTMLElement | null = null;
203
- childElementCount: number = 0;
204
- firstElementChild: Element | null = null;
205
- lastElementChild: Element | null = null;
206
- nextElementSibling: Element | null = null;
207
- previousElementSibling: Element | null = null;
208
- children: HTMLCollection = {
209
- length: 0,
210
- item: () => null,
211
- namedItem: () => null,
212
- [Symbol.iterator]: function*() { yield null; return undefined; }
213
- } as unknown as HTMLCollection;
214
-
215
- constructor() {
216
- // Initialize any required properties
217
- }
218
-
219
- getAttribute(name: string): string | null {
220
- return null;
221
- }
222
-
223
- getAttributeNS(namespaceURI: string | null, localName: string): string | null {
224
- return null;
225
- }
226
-
227
- setAttribute(name: string, value: string): void {}
228
-
229
- setAttributeNS(namespaceURI: string | null, qualifiedName: string, value: string): void {}
230
-
231
- removeAttributeNS(namespaceURI: string | null, localName: string): void {}
232
-
233
- hasAttribute(name: string): boolean {
234
- return false;
235
- }
236
-
237
- hasAttributeNS(namespaceURI: string | null, localName: string): boolean {
238
- return false;
239
- }
240
-
241
- getBoundingClientRect(): DOMRect {
242
- return {
243
- top: 0,
244
- left: 0,
245
- bottom: 0,
246
- right: 0,
247
- width: 0,
248
- height: 0,
249
- x: 0,
250
- y: 0,
251
- toJSON: function() { return this; }
252
- };
253
- }
254
-
255
- getClientRects(): DOMRectList {
256
- return {
257
- length: 0,
258
- item: function() { return null; },
259
- [Symbol.iterator]: function*() {}
260
- } as DOMRectList;
261
- }
262
-
263
- getElementsByClassName(classNames: string): HTMLCollectionOf<Element> {
264
- return {
265
- length: 0,
266
- item: () => null,
267
- namedItem: () => null,
268
- [Symbol.iterator]: function*() { yield null; return undefined; }
269
- } as HTMLCollectionOf<Element>;
270
- }
271
-
272
- getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element> {
273
- return {
274
- length: 0,
275
- item: () => null,
276
- namedItem: () => null,
277
- [Symbol.iterator]: function*() { yield null; return undefined; }
278
- } as HTMLCollectionOf<Element>;
279
- }
280
-
281
- getElementsByTagNameNS(namespaceURI: string | null, localName: string): HTMLCollectionOf<Element> {
282
- return {
283
- length: 0,
284
- item: () => null,
285
- namedItem: () => null,
286
- [Symbol.iterator]: function*() { yield null; return undefined; }
287
- } as HTMLCollectionOf<Element>;
288
- }
289
-
290
- querySelector(selectors: string): Element | null {
291
- return null;
292
- }
293
-
294
- querySelectorAll(selectors: string): NodeListOf<Element> {
295
- return {
296
- length: 0,
297
- item: () => null,
298
- forEach: () => {},
299
- entries: function*() { yield [0, null]; return undefined; },
300
- keys: function*() { yield 0; return undefined; },
301
- values: function*() { yield null; return undefined; },
302
- [Symbol.iterator]: function*() { yield null; return undefined; }
303
- } as unknown as NodeListOf<Element>;
304
- }
305
-
306
- matches(selectors: string): boolean {
307
- return false;
308
- }
309
-
310
- closest(selectors: string): Element | null {
311
- return null;
312
- }
313
-
314
- contains(other: Node | null): boolean {
315
- return false;
316
- }
317
-
318
- append(...nodes: (Node | string)[]): void {}
319
-
320
- prepend(...nodes: (Node | string)[]): void {}
321
-
322
- after(...nodes: (Node | string)[]): void {}
323
-
324
- before(...nodes: (Node | string)[]): void {}
325
-
326
- replaceWith(...nodes: (Node | string)[]): void {}
327
-
328
- remove(): void {}
329
-
330
- insertAdjacentElement(where: InsertPosition, element: Element): Element | null {
331
- return null;
332
- }
333
-
334
- insertAdjacentText(where: InsertPosition, data: string): void {}
335
-
336
- insertAdjacentHTML(position: InsertPosition, text: string): void {}
337
-
338
- replaceChildren(...nodes: (Node | string)[]): void {}
339
- };
340
-
341
- // Define HTMLImageElement globally
342
- (globalThis as any).HTMLImageElement = class {
343
- alt: string = '';
344
- src: string = '';
345
- srcset: string = '';
346
- sizes: string = '';
347
- crossOrigin: string | null = null;
348
- useMap: string = '';
349
- isMap: boolean = false;
350
- width: number = 0;
351
- height: number = 0;
352
- naturalWidth: number = 0;
353
- naturalHeight: number = 0;
354
- complete: boolean = false;
355
- name: string = '';
356
- lowsrc: string = '';
357
- align: string = '';
358
- hspace: number = 0;
359
- vspace: number = 0;
360
- longDesc: string = '';
361
- border: string = '';
362
- x: number = 0;
363
- y: number = 0;
364
- currentSrc: string = '';
365
- decoding: 'sync' | 'async' | 'auto' = 'auto';
366
- fetchPriority: 'high' | 'low' | 'auto' = 'auto';
367
- loading: 'eager' | 'lazy' = 'eager';
368
- referrerPolicy: string = '';
369
-
370
- constructor() {
371
- // Initialize any required properties
372
- }
373
-
374
- decode(): Promise<void> {
375
- return Promise.resolve();
376
- }
377
- };
378
-
379
- // Create a virtual console
380
- const virtualConsole = new VirtualConsole();
381
-
382
- // Create a virtual DOM
383
- const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
384
- virtualConsole,
385
- runScripts: 'dangerously',
386
- resources: 'usable',
387
- pretendToBeVisual: true,
388
- beforeParse(window: DOMWindow) {
389
- setupDOMInterfaces(window);
390
- setupRange(window);
391
- setupDocumentMethods(window);
392
- setupWindowMethods(window);
393
- }
394
- });
395
-
396
- // Get the window object
397
- const window = dom.window;
398
-
399
- // Add window to global scope
400
- (globalThis as any).window = window;
401
-
402
- // Add document to global scope
403
- (globalThis as any).document = window.document;
404
-
405
- // Add required DOM interfaces to global scope
406
- (globalThis as any).Element = window.Element;
407
- (globalThis as any).Node = window.Node;
408
- (globalThis as any).NodeFilter = window.NodeFilter;
409
- (globalThis as any).Range = window.Range;
410
- (globalThis as any).DOMParser = window.DOMParser;
411
- (globalThis as any).XMLSerializer = window.XMLSerializer;
412
-
413
- // Handle navigator property
414
- if (!globalThis.navigator || Object.getOwnPropertyDescriptor(globalThis, 'navigator')?.configurable) {
415
- Object.defineProperty(globalThis, 'navigator', {
416
- value: window.navigator,
417
- writable: false,
418
- configurable: true
419
- });
420
- }
421
-
422
- (globalThis as any).HTMLElement = window.HTMLElement;
423
-
424
- // Define DOMSettableTokenList
425
- (globalThis as any).DOMSettableTokenList = class {
426
- length: number = 0;
427
- value: string = '';
428
- add(token: string): void {}
429
- contains(token: string): boolean { return false; }
430
- item(index: number): string | null { return null; }
431
- remove(token: string): void {}
432
- replace(oldToken: string, newToken: string): boolean { return false; }
433
- supports(token: string): boolean { return false; }
434
- toggle(token: string, force?: boolean): boolean { return false; }
435
- [Symbol.iterator](): Iterator<string> {
436
- return function*() { yield ''; return undefined; }();
437
- }
438
- };
439
-
440
- // Define HTML element types
441
- (globalThis as any).HTMLIFrameElement = class extends (globalThis as any).HTMLElement {
442
- constructor() {
443
- super();
444
- }
445
- align: string = '';
446
- allow: string = '';
447
- allowFullscreen: boolean = false;
448
- contentDocument: Document | null = null;
449
- contentWindow: Window | null = null;
450
- frameBorder: string = '';
451
- height: string = '';
452
- longDesc: string = '';
453
- marginHeight: string = '';
454
- marginWidth: string = '';
455
- name: string = '';
456
- referrerPolicy: string = '';
457
- sandbox: DOMSettableTokenList = {
458
- length: 0,
459
- value: '',
460
- add: () => {},
461
- contains: () => false,
462
- item: () => null,
463
- remove: () => {},
464
- replace: () => false,
465
- supports: () => false,
466
- toggle: () => false,
467
- [Symbol.iterator]: function*() { yield ''; return undefined; }
468
- } as unknown as DOMSettableTokenList;
469
- scrolling: string = '';
470
- src: string = '';
471
- srcdoc: string = '';
472
- width: string = '';
473
- };
474
-
475
- (globalThis as any).HTMLOListElement = class extends (globalThis as any).HTMLElement {
476
- constructor() {
477
- super();
478
- }
479
- type: string = '';
480
- compact: boolean = false;
481
- reversed: boolean = false;
482
- start: number = 0;
483
- };
484
-
485
- (globalThis as any).HTMLUListElement = class extends (globalThis as any).HTMLElement {
486
- constructor() {
487
- super();
488
- }
489
- type: string = '';
490
- compact: boolean = false;
491
- };
492
-
493
- (globalThis as any).HTMLTableElement = class extends (globalThis as any).HTMLElement {
494
- constructor() {
495
- super();
496
- }
497
- caption: HTMLTableCaptionElement | null = null;
498
- tHead: HTMLTableSectionElement | null = null;
499
- tFoot: HTMLTableSectionElement | null = null;
500
- tBodies: HTMLCollectionOf<HTMLTableSectionElement> = {
501
- length: 0,
502
- item: () => null,
503
- namedItem: () => null,
504
- [Symbol.iterator]: function*() { yield null; return undefined; }
505
- } as HTMLCollectionOf<HTMLTableSectionElement>;
506
- rows: HTMLCollectionOf<HTMLTableRowElement> = {
507
- length: 0,
508
- item: () => null,
509
- namedItem: () => null,
510
- [Symbol.iterator]: function*() { yield null; return undefined; }
511
- } as HTMLCollectionOf<HTMLTableRowElement>;
512
- align: string = '';
513
- bgColor: string = '';
514
- border: string = '';
515
- cellPadding: string = '';
516
- cellSpacing: string = '';
517
- frame: string = '';
518
- rules: string = '';
519
- summary: string = '';
520
- width: string = '';
521
- createCaption(): HTMLTableCaptionElement {
522
- return new (globalThis as any).HTMLTableCaptionElement();
523
- }
524
- deleteCaption(): void {}
525
- createTHead(): HTMLTableSectionElement {
526
- return new (globalThis as any).HTMLTableSectionElement();
527
- }
528
- deleteTHead(): void {}
529
- createTFoot(): HTMLTableSectionElement {
530
- return new (globalThis as any).HTMLTableSectionElement();
531
- }
532
- deleteTFoot(): void {}
533
- createTBody(): HTMLTableSectionElement {
534
- return new (globalThis as any).HTMLTableSectionElement();
535
- }
536
- insertRow(index?: number): HTMLTableRowElement {
537
- return new (globalThis as any).HTMLTableRowElement();
538
- }
539
- deleteRow(index: number): void {}
540
- };
541
-
542
- (globalThis as any).HTMLTableRowElement = class extends (globalThis as any).HTMLElement {
543
- constructor() {
544
- super();
545
- }
546
- rowIndex: number = 0;
547
- sectionRowIndex: number = 0;
548
- cells: HTMLCollectionOf<HTMLTableCellElement> = {
549
- length: 0,
550
- item: () => null,
551
- namedItem: () => null,
552
- [Symbol.iterator]: function*() { yield null; return undefined; }
553
- } as HTMLCollectionOf<HTMLTableCellElement>;
554
- align: string = '';
555
- bgColor: string = '';
556
- ch: string = '';
557
- chOff: string = '';
558
- vAlign: string = '';
559
- insertCell(index?: number): HTMLTableCellElement {
560
- return new (globalThis as any).HTMLTableCellElement();
561
- }
562
- deleteCell(index: number): void {}
563
- };
564
-
565
- (globalThis as any).HTMLTableCellElement = class extends (globalThis as any).HTMLElement {
566
- constructor() {
567
- super();
568
- }
569
- colSpan: number = 1;
570
- rowSpan: number = 1;
571
- headers: DOMSettableTokenList = {
572
- length: 0,
573
- value: '',
574
- add: () => {},
575
- contains: () => false,
576
- item: () => null,
577
- remove: () => {},
578
- replace: () => false,
579
- supports: () => false,
580
- toggle: () => false,
581
- [Symbol.iterator]: function*() { yield ''; return undefined; }
582
- } as unknown as DOMSettableTokenList;
583
- cellIndex: number = 0;
584
- scope: string = '';
585
- abbr: string = '';
586
- align: string = '';
587
- axis: string = '';
588
- bgColor: string = '';
589
- ch: string = '';
590
- chOff: string = '';
591
- height: string = '';
592
- noWrap: boolean = false;
593
- vAlign: string = '';
594
- width: string = '';
595
- };
596
-
597
- (globalThis as any).HTMLTableSectionElement = class extends (globalThis as any).HTMLElement {
598
- constructor() {
599
- super();
600
- }
601
- rows: HTMLCollectionOf<HTMLTableRowElement> = {
602
- length: 0,
603
- item: () => null,
604
- namedItem: () => null,
605
- [Symbol.iterator]: function*() { yield null; return undefined; }
606
- } as HTMLCollectionOf<HTMLTableRowElement>;
607
- align: string = '';
608
- ch: string = '';
609
- chOff: string = '';
610
- vAlign: string = '';
611
- insertRow(index?: number): HTMLTableRowElement {
612
- return new (globalThis as any).HTMLTableRowElement();
613
- }
614
- deleteRow(index: number): void {}
615
- };
616
-
617
- (globalThis as any).HTMLTableCaptionElement = class extends (globalThis as any).HTMLElement {
618
- constructor() {
619
- super();
620
- }
621
- align: string = '';
622
- };
623
-
624
- (globalThis as any).HTMLButtonElement = class extends (globalThis as any).HTMLElement {
625
- constructor() {
626
- super();
627
- }
628
- disabled: boolean = false;
629
- form: HTMLFormElement | null = null;
630
- formAction: string = '';
631
- formEnctype: string = '';
632
- formMethod: string = '';
633
- formNoValidate: boolean = false;
634
- formTarget: string = '';
635
- name: string = '';
636
- type: string = 'submit';
637
- value: string = '';
638
- menu: HTMLMenuElement | null = null;
639
- };
640
-
641
- // Add HTMLSpanElement interface
642
- (globalThis as any).HTMLSpanElement = class extends (globalThis as any).HTMLElement {
643
- constructor() {
644
- super();
645
- }
646
- };
647
-
648
- // Add HTMLDivElement interface
649
- (globalThis as any).HTMLDivElement = class extends (globalThis as any).HTMLElement {
650
- constructor() {
651
- super();
652
- }
653
- align: string = '';
654
- };
655
-
656
- (globalThis as any).HTMLAnchorElement = class extends (globalThis as any).HTMLElement {
657
- constructor() {
658
- super();
659
- }
660
- href: string = '';
661
- target: string = '';
662
- download: string = '';
663
- ping: string = '';
664
- rel: string = '';
665
- relList: DOMSettableTokenList = {
666
- length: 0,
667
- value: '',
668
- add: () => {},
669
- contains: () => false,
670
- item: () => null,
671
- remove: () => {},
672
- replace: () => false,
673
- supports: () => false,
674
- toggle: () => false,
675
- [Symbol.iterator]: function*() { yield ''; return undefined; }
676
- } as unknown as DOMSettableTokenList;
677
- hreflang: string = '';
678
- type: string = '';
679
- text: string = '';
680
- referrerPolicy: string = '';
681
- origin: string = '';
682
- protocol: string = '';
683
- username: string = '';
684
- password: string = '';
685
- host: string = '';
686
- hostname: string = '';
687
- port: string = '';
688
- pathname: string = '';
689
- search: string = '';
690
- hash: string = '';
691
- };
692
-
693
23
  const program = new Command();
694
24
 
695
25
  program
@@ -713,100 +43,23 @@ program
713
43
  if (options.md) {
714
44
  options.markdown = true;
715
45
  }
716
- let html: string;
46
+ let dom: JSDOM;
717
47
 
718
48
  try {
719
49
  // Determine if source is a URL or file path
720
50
  if (source.startsWith('http://') || source.startsWith('https://')) {
721
- const response = await fetch(source);
722
- html = await response.text();
51
+ dom = await JSDOM.fromURL(source);
723
52
  } else {
724
53
  const filePath = resolve(process.cwd(), source);
725
- html = await readFile(filePath, 'utf-8');
726
- }
727
-
728
- // Create a new JSDOM instance with the HTML content
729
- const contentDom = new JSDOM(html, {
730
- virtualConsole,
731
- runScripts: 'dangerously',
732
- resources: 'usable',
733
- pretendToBeVisual: true,
734
- url: source.startsWith('http') ? source : undefined,
735
- beforeParse(window: DOMWindow) {
736
- try {
737
- setupDOMInterfaces(window);
738
- } catch (error) {
739
- console.error('Error setting up DOM interfaces:', error);
740
- }
741
- }
742
- });
743
-
744
- // Initialize document properties
745
- const doc = contentDom.window.document;
746
-
747
- // Ensure document has required properties
748
- if (!doc.documentElement) {
749
- throw new Error('Document has no root element');
750
- }
751
-
752
- // Set up document properties
753
- try {
754
- doc.documentElement.style.cssText = '';
755
- doc.documentElement.className = '';
756
- } catch (error) {
757
- console.warn('Warning: Could not set document element properties:', error);
758
- }
759
-
760
- // Ensure body exists and is properly set up
761
- if (!doc.body) {
762
- const body = doc.createElement('body');
763
- doc.documentElement.appendChild(body);
764
- }
765
- try {
766
- doc.body.style.cssText = '';
767
- doc.body.className = '';
768
- } catch (error) {
769
- console.warn('Warning: Could not set body properties:', error);
770
- }
771
-
772
- // Set up viewport and ensure head exists
773
- if (!doc.head) {
774
- const head = doc.createElement('head');
775
- doc.documentElement.insertBefore(head, doc.body);
776
- }
777
-
778
- // Add viewport meta tag
779
- try {
780
- const viewport = doc.createElement('meta');
781
- viewport.setAttribute('name', 'viewport');
782
- viewport.setAttribute('content', 'width=device-width, initial-scale=1');
783
- doc.head.appendChild(viewport);
784
- } catch (error) {
785
- console.warn('Warning: Could not add viewport meta tag:', error);
786
- }
787
-
788
- // Add a base style element for mobile styles
789
- try {
790
- const style = doc.createElement('style');
791
- style.textContent = `
792
- @media (max-width: 768px) {
793
- body { width: 100%; }
794
- }
795
- `;
796
- doc.head.appendChild(style);
797
- } catch (error) {
798
- console.warn('Warning: Could not add style element:', error);
54
+ dom = await JSDOM.fromFile(filePath);
799
55
  }
800
56
 
801
57
  // Parse content with debug mode if enabled
802
58
  try {
803
- // @ts-ignore - Module interop issue between ES modules and CommonJS
804
- const defuddle = new Defuddle(doc, {
59
+ const result = await Defuddle(dom, source.startsWith('http') ? source : undefined, {
805
60
  debug: options.debug,
806
- ...(source.startsWith('http') ? { url: source } : {})
61
+ markdown: options.markdown
807
62
  });
808
-
809
- const result = await defuddle.parse();
810
63
 
811
64
  // If in debug mode, don't show content output
812
65
  if (options.debug) {
@@ -815,13 +68,6 @@ program
815
68
 
816
69
  // Format output
817
70
  let output: string;
818
- let content: string;
819
- let contentMarkdown: string | undefined;
820
-
821
- // Convert content to markdown if requested
822
- if (options.markdown || options.json) {
823
- contentMarkdown = createMarkdownContent(result.content, source);
824
- }
825
71
 
826
72
  // Format the response based on options
827
73
  if (options.property) {
@@ -849,18 +95,13 @@ program
849
95
  wordCount: result.wordCount
850
96
  };
851
97
 
852
- // Only include markdown content if markdown flag is set
853
- if (options.markdown) {
854
- jsonObj.contentMarkdown = contentMarkdown;
855
- }
856
-
857
98
  output = JSON.stringify(jsonObj, null, 2)
858
99
  .replace(/"([^"]+)":/g, chalk.cyan('"$1":'))
859
100
  .replace(/: "([^"]+)"/g, chalk.yellow(': "$1"'))
860
101
  .replace(/: (\d+)/g, chalk.yellow(': $1'))
861
102
  .replace(/: (true|false|null)/g, chalk.magenta(': $1'));
862
103
  } else {
863
- output = options.markdown ? contentMarkdown! : result.content;
104
+ output = result.content;
864
105
  }
865
106
 
866
107
  // Handle output
@@ -871,10 +112,6 @@ program
871
112
  } else {
872
113
  console.log(output);
873
114
  }
874
-
875
- // Clean up JSDOM resources
876
- contentDom.window.close();
877
- dom.window.close();
878
115
 
879
116
  process.exit(0);
880
117
  } catch (error) {