defuddle-cli 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +77 -0
- package/dist/commands/parse.d.ts +8 -0
- package/dist/commands/parse.js +66 -0
- package/dist/dom/interfaces/css.d.ts +38 -0
- package/dist/dom/interfaces/css.js +20 -0
- package/dist/dom/interfaces/document.d.ts +3 -0
- package/dist/dom/interfaces/document.js +49 -0
- package/dist/dom/interfaces/global.d.ts +21 -0
- package/dist/dom/interfaces/global.js +182 -0
- package/dist/dom/interfaces/html.d.ts +57 -0
- package/dist/dom/interfaces/html.js +3 -0
- package/dist/dom/interfaces/range.d.ts +2 -0
- package/dist/dom/interfaces/range.js +87 -0
- package/dist/dom/interfaces/setup.d.ts +12 -0
- package/dist/dom/interfaces/setup.js +182 -0
- package/dist/dom/interfaces/svg.d.ts +59 -0
- package/dist/dom/interfaces/svg.js +161 -0
- package/dist/dom/setup.d.ts +9 -0
- package/dist/dom/setup.js +660 -0
- package/dist/dom.d.ts +1 -0
- package/dist/dom.js +586 -0
- package/dist/index.js +84 -339
- package/dist/markdown.js +0 -8
- package/package.json +1 -1
- package/src/dom/interfaces/document.ts +53 -0
- package/src/dom/interfaces/range.ts +120 -0
- package/src/dom/interfaces/setup.ts +196 -0
- package/src/index.ts +91 -366
- package/src/markdown.ts +0 -11
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { DOMWindow } from 'jsdom';
|
|
2
|
+
import { setupDocumentMethods, setupWindowMethods } from './document.js';
|
|
3
|
+
|
|
4
|
+
// Type for DOM interface setup functions
|
|
5
|
+
export type SetupFunction = (window: DOMWindow) => void;
|
|
6
|
+
|
|
7
|
+
// Setup basic window properties
|
|
8
|
+
export const setupBasicWindow: SetupFunction = (window) => {
|
|
9
|
+
if (!window.innerWidth) {
|
|
10
|
+
Object.defineProperty(window, 'innerWidth', { value: 1024 });
|
|
11
|
+
}
|
|
12
|
+
if (!window.innerHeight) {
|
|
13
|
+
Object.defineProperty(window, 'innerHeight', { value: 768 });
|
|
14
|
+
}
|
|
15
|
+
if (!window.devicePixelRatio) {
|
|
16
|
+
Object.defineProperty(window, 'devicePixelRatio', { value: 1 });
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// Setup CSS interfaces
|
|
21
|
+
export const setupCSSInterfaces: SetupFunction = (window) => {
|
|
22
|
+
if (!window.CSSRule) {
|
|
23
|
+
window.CSSRule = (globalThis as any).CSSRule as any;
|
|
24
|
+
}
|
|
25
|
+
if (!window.CSSMediaRule) {
|
|
26
|
+
window.CSSMediaRule = (globalThis as any).CSSMediaRule as any;
|
|
27
|
+
}
|
|
28
|
+
if (!window.CSSStyleSheet) {
|
|
29
|
+
window.CSSStyleSheet = (globalThis as any).CSSStyleSheet as any;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Setup HTML and SVG interfaces
|
|
34
|
+
export const setupHTMLAndSVG: SetupFunction = (window) => {
|
|
35
|
+
if (!window.HTMLImageElement) {
|
|
36
|
+
window.HTMLImageElement = (globalThis as any).HTMLImageElement as any;
|
|
37
|
+
}
|
|
38
|
+
if (!window.SVGElement) {
|
|
39
|
+
window.SVGElement = (globalThis as any).SVGElement as any;
|
|
40
|
+
}
|
|
41
|
+
if (!window.HTMLAnchorElement) {
|
|
42
|
+
window.HTMLAnchorElement = (globalThis as any).HTMLAnchorElement as any;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Setup screen object
|
|
47
|
+
export const setupScreen: SetupFunction = (window) => {
|
|
48
|
+
if (!window.screen) {
|
|
49
|
+
Object.defineProperty(window, 'screen', {
|
|
50
|
+
value: {
|
|
51
|
+
width: 1024,
|
|
52
|
+
height: 768,
|
|
53
|
+
availWidth: 1024,
|
|
54
|
+
availHeight: 768,
|
|
55
|
+
colorDepth: 24,
|
|
56
|
+
pixelDepth: 24,
|
|
57
|
+
orientation: {
|
|
58
|
+
type: 'landscape-primary',
|
|
59
|
+
angle: 0
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Setup storage objects
|
|
67
|
+
export const setupStorage: SetupFunction = (window) => {
|
|
68
|
+
const createStorage = () => {
|
|
69
|
+
const storage = {
|
|
70
|
+
length: 0,
|
|
71
|
+
getItem: () => null,
|
|
72
|
+
setItem: () => {},
|
|
73
|
+
removeItem: () => {},
|
|
74
|
+
clear: () => {},
|
|
75
|
+
key: () => null
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Make the storage object non-extensible
|
|
79
|
+
Object.preventExtensions(storage);
|
|
80
|
+
return storage;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
// Create storage objects
|
|
85
|
+
const localStorage = createStorage();
|
|
86
|
+
const sessionStorage = createStorage();
|
|
87
|
+
|
|
88
|
+
// Define properties with more permissive attributes
|
|
89
|
+
Object.defineProperties(window, {
|
|
90
|
+
localStorage: {
|
|
91
|
+
value: localStorage,
|
|
92
|
+
writable: true,
|
|
93
|
+
configurable: true
|
|
94
|
+
},
|
|
95
|
+
sessionStorage: {
|
|
96
|
+
value: sessionStorage,
|
|
97
|
+
writable: true,
|
|
98
|
+
configurable: true
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
} catch (error) {
|
|
102
|
+
// Log the error but don't throw
|
|
103
|
+
console.warn('Warning: Could not set up storage objects:', error instanceof Error ? error.message : 'Unknown error');
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Setup animation frame methods
|
|
108
|
+
export const setupAnimationFrame: SetupFunction = (window) => {
|
|
109
|
+
if (!window.requestAnimationFrame) {
|
|
110
|
+
window.requestAnimationFrame = (callback: FrameRequestCallback): number => {
|
|
111
|
+
return setTimeout(callback, 0) as unknown as number;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (!window.cancelAnimationFrame) {
|
|
115
|
+
window.cancelAnimationFrame = (handle: number): void => {
|
|
116
|
+
clearTimeout(handle as unknown as number);
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// Setup DOM methods
|
|
122
|
+
export const setupDOMMethods: SetupFunction = (window) => {
|
|
123
|
+
if (!window.Document.prototype.getElementsByClassName) {
|
|
124
|
+
window.Document.prototype.getElementsByClassName = function(classNames: string): HTMLCollectionOf<Element> {
|
|
125
|
+
const elements = this.querySelectorAll('.' + classNames);
|
|
126
|
+
const collection = new HTMLCollection();
|
|
127
|
+
elements.forEach((el, i) => {
|
|
128
|
+
collection[i] = el;
|
|
129
|
+
});
|
|
130
|
+
return collection;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// Setup Node methods
|
|
136
|
+
export const setupNodeMethods: SetupFunction = (window) => {
|
|
137
|
+
if (!window.Node.prototype.contains) {
|
|
138
|
+
window.Node.prototype.contains = function(node: Node): boolean {
|
|
139
|
+
let current: Node | null = node;
|
|
140
|
+
while (current) {
|
|
141
|
+
if (current === this) return true;
|
|
142
|
+
current = current.parentNode;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
// Setup Element methods
|
|
150
|
+
export const setupElementMethods: SetupFunction = (window) => {
|
|
151
|
+
if (!window.Element.prototype.getBoundingClientRect) {
|
|
152
|
+
window.Element.prototype.getBoundingClientRect = function(): DOMRect {
|
|
153
|
+
return {
|
|
154
|
+
top: 0,
|
|
155
|
+
left: 0,
|
|
156
|
+
bottom: 0,
|
|
157
|
+
right: 0,
|
|
158
|
+
width: 0,
|
|
159
|
+
height: 0,
|
|
160
|
+
x: 0,
|
|
161
|
+
y: 0,
|
|
162
|
+
toJSON: function() { return this; }
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Main setup function that orchestrates all the individual setups
|
|
169
|
+
export const setupDOMInterfaces = (window: DOMWindow): void => {
|
|
170
|
+
const setupFunctions: [string, SetupFunction][] = [
|
|
171
|
+
['basic window', setupBasicWindow],
|
|
172
|
+
['CSS interfaces', setupCSSInterfaces],
|
|
173
|
+
['HTML and SVG interfaces', setupHTMLAndSVG],
|
|
174
|
+
['screen object', setupScreen],
|
|
175
|
+
['storage objects', setupStorage],
|
|
176
|
+
['animation frame methods', setupAnimationFrame],
|
|
177
|
+
['DOM methods', setupDOMMethods],
|
|
178
|
+
['Node methods', setupNodeMethods],
|
|
179
|
+
['Element methods', setupElementMethods],
|
|
180
|
+
['Document methods', setupDocumentMethods],
|
|
181
|
+
['Window methods', setupWindowMethods]
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
for (const [name, setup] of setupFunctions) {
|
|
186
|
+
try {
|
|
187
|
+
setup(window);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
console.warn(`Warning: Could not set up ${name}:`, error instanceof Error ? error.message : 'Unknown error');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.error('Error in setupDOMInterfaces:', error instanceof Error ? error.message : 'Unknown error');
|
|
194
|
+
// Don't throw the error, just log it
|
|
195
|
+
}
|
|
196
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,9 @@ import { readFile, writeFile } from 'fs/promises';
|
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
import { dirname, resolve } from 'path';
|
|
11
11
|
import { createMarkdownContent } from './markdown.js';
|
|
12
|
+
import { setupDOMInterfaces } from './dom/interfaces/setup.js';
|
|
13
|
+
import { setupRange } from './dom/interfaces/range.js';
|
|
14
|
+
import { setupDocumentMethods, setupWindowMethods } from './dom/interfaces/document.js';
|
|
12
15
|
|
|
13
16
|
interface DOMSettableTokenList {
|
|
14
17
|
length: number;
|
|
@@ -52,7 +55,7 @@ const __dirname = dirname(__filename);
|
|
|
52
55
|
}
|
|
53
56
|
};
|
|
54
57
|
|
|
55
|
-
//
|
|
58
|
+
// Static properties
|
|
56
59
|
Object.defineProperties((globalThis as any).CSSRule, {
|
|
57
60
|
STYLE_RULE: { value: 1, writable: false },
|
|
58
61
|
CHARSET_RULE: { value: 2, writable: false },
|
|
@@ -377,370 +380,6 @@ Object.defineProperties((globalThis as any).CSSRule, {
|
|
|
377
380
|
// Create a virtual console
|
|
378
381
|
const virtualConsole = new VirtualConsole();
|
|
379
382
|
|
|
380
|
-
// Function to set up DOM interfaces
|
|
381
|
-
function setupDOMInterfaces(window: DOMWindow) {
|
|
382
|
-
try {
|
|
383
|
-
// First, set up basic window properties
|
|
384
|
-
try {
|
|
385
|
-
if (!window.innerWidth) {
|
|
386
|
-
Object.defineProperty(window, 'innerWidth', { value: 1024 });
|
|
387
|
-
}
|
|
388
|
-
if (!window.innerHeight) {
|
|
389
|
-
Object.defineProperty(window, 'innerHeight', { value: 768 });
|
|
390
|
-
}
|
|
391
|
-
if (!window.devicePixelRatio) {
|
|
392
|
-
Object.defineProperty(window, 'devicePixelRatio', { value: 1 });
|
|
393
|
-
}
|
|
394
|
-
} catch (error) {
|
|
395
|
-
console.warn('Warning: Could not set basic window properties:', error);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
// Set up CSS interfaces
|
|
399
|
-
try {
|
|
400
|
-
if (!window.CSSRule) {
|
|
401
|
-
window.CSSRule = (globalThis as any).CSSRule as any;
|
|
402
|
-
}
|
|
403
|
-
if (!window.CSSMediaRule) {
|
|
404
|
-
window.CSSMediaRule = (globalThis as any).CSSMediaRule as any;
|
|
405
|
-
}
|
|
406
|
-
if (!window.CSSStyleSheet) {
|
|
407
|
-
window.CSSStyleSheet = (globalThis as any).CSSStyleSheet as any;
|
|
408
|
-
}
|
|
409
|
-
} catch (error) {
|
|
410
|
-
console.warn('Warning: Could not set CSS interfaces:', error);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// Set up HTML and SVG interfaces
|
|
414
|
-
try {
|
|
415
|
-
if (!window.HTMLImageElement) {
|
|
416
|
-
window.HTMLImageElement = (globalThis as any).HTMLImageElement as any;
|
|
417
|
-
}
|
|
418
|
-
if (!window.SVGElement) {
|
|
419
|
-
window.SVGElement = (globalThis as any).SVGElement as any;
|
|
420
|
-
}
|
|
421
|
-
} catch (error) {
|
|
422
|
-
console.warn('Warning: Could not set HTML/SVG interfaces:', error);
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// Set up screen object
|
|
426
|
-
try {
|
|
427
|
-
if (!window.screen) {
|
|
428
|
-
Object.defineProperty(window, 'screen', {
|
|
429
|
-
value: {
|
|
430
|
-
width: 1024,
|
|
431
|
-
height: 768,
|
|
432
|
-
availWidth: 1024,
|
|
433
|
-
availHeight: 768,
|
|
434
|
-
colorDepth: 24,
|
|
435
|
-
pixelDepth: 24,
|
|
436
|
-
orientation: {
|
|
437
|
-
type: 'landscape-primary',
|
|
438
|
-
angle: 0
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
} catch (error) {
|
|
444
|
-
console.warn('Warning: Could not set screen object:', error);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Set up storage objects
|
|
448
|
-
try {
|
|
449
|
-
if (!window.localStorage) {
|
|
450
|
-
const storage = {
|
|
451
|
-
length: 0,
|
|
452
|
-
getItem: () => null,
|
|
453
|
-
setItem: () => {},
|
|
454
|
-
removeItem: () => {},
|
|
455
|
-
clear: () => {},
|
|
456
|
-
key: () => null
|
|
457
|
-
};
|
|
458
|
-
try {
|
|
459
|
-
Object.defineProperty(window, 'localStorage', {
|
|
460
|
-
value: storage,
|
|
461
|
-
writable: false,
|
|
462
|
-
configurable: false
|
|
463
|
-
});
|
|
464
|
-
} catch (error) {
|
|
465
|
-
// Silently ignore storage setup failures
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
if (!window.sessionStorage) {
|
|
469
|
-
const storage = {
|
|
470
|
-
length: 0,
|
|
471
|
-
getItem: () => null,
|
|
472
|
-
setItem: () => {},
|
|
473
|
-
removeItem: () => {},
|
|
474
|
-
clear: () => {},
|
|
475
|
-
key: () => null
|
|
476
|
-
};
|
|
477
|
-
try {
|
|
478
|
-
Object.defineProperty(window, 'sessionStorage', {
|
|
479
|
-
value: storage,
|
|
480
|
-
writable: false,
|
|
481
|
-
configurable: false
|
|
482
|
-
});
|
|
483
|
-
} catch (error) {
|
|
484
|
-
// Silently ignore storage setup failures
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
} catch (error) {
|
|
488
|
-
// Silently ignore storage setup failures
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// Set up animation frame methods
|
|
492
|
-
try {
|
|
493
|
-
if (!window.requestAnimationFrame) {
|
|
494
|
-
window.requestAnimationFrame = (callback: FrameRequestCallback): number => {
|
|
495
|
-
return setTimeout(callback, 0) as unknown as number;
|
|
496
|
-
};
|
|
497
|
-
}
|
|
498
|
-
if (!window.cancelAnimationFrame) {
|
|
499
|
-
window.cancelAnimationFrame = (handle: number): void => {
|
|
500
|
-
clearTimeout(handle as unknown as number);
|
|
501
|
-
};
|
|
502
|
-
}
|
|
503
|
-
} catch (error) {
|
|
504
|
-
console.warn('Warning: Could not set animation frame methods:', error);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
// Set up DOM methods
|
|
508
|
-
try {
|
|
509
|
-
if (!window.Document.prototype.getElementsByClassName) {
|
|
510
|
-
window.Document.prototype.getElementsByClassName = function(classNames: string): HTMLCollectionOf<Element> {
|
|
511
|
-
const elements = this.querySelectorAll('.' + classNames);
|
|
512
|
-
const collection = new HTMLCollection();
|
|
513
|
-
elements.forEach((el, i) => {
|
|
514
|
-
collection[i] = el;
|
|
515
|
-
});
|
|
516
|
-
return collection;
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
} catch (error) {
|
|
520
|
-
console.warn('Warning: Could not set getElementsByClassName:', error);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// Set up Node methods
|
|
524
|
-
try {
|
|
525
|
-
if (!window.Node.prototype.contains) {
|
|
526
|
-
window.Node.prototype.contains = function(node: Node): boolean {
|
|
527
|
-
let current: Node | null = node;
|
|
528
|
-
while (current) {
|
|
529
|
-
if (current === this) return true;
|
|
530
|
-
current = current.parentNode;
|
|
531
|
-
}
|
|
532
|
-
return false;
|
|
533
|
-
};
|
|
534
|
-
}
|
|
535
|
-
} catch (error) {
|
|
536
|
-
console.warn('Warning: Could not set Node.contains:', error);
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
// Set up Element methods
|
|
540
|
-
try {
|
|
541
|
-
if (!window.Element.prototype.getBoundingClientRect) {
|
|
542
|
-
window.Element.prototype.getBoundingClientRect = function(): DOMRect {
|
|
543
|
-
return {
|
|
544
|
-
top: 0,
|
|
545
|
-
left: 0,
|
|
546
|
-
bottom: 0,
|
|
547
|
-
right: 0,
|
|
548
|
-
width: 0,
|
|
549
|
-
height: 0,
|
|
550
|
-
x: 0,
|
|
551
|
-
y: 0,
|
|
552
|
-
toJSON: function() { return this; }
|
|
553
|
-
};
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
} catch (error) {
|
|
557
|
-
console.warn('Warning: Could not set getBoundingClientRect:', error);
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
// Set up Document methods
|
|
561
|
-
try {
|
|
562
|
-
if (!window.Document.prototype.getSelection) {
|
|
563
|
-
window.Document.prototype.getSelection = function(): Selection | null {
|
|
564
|
-
const selection = {
|
|
565
|
-
anchorNode: null,
|
|
566
|
-
anchorOffset: 0,
|
|
567
|
-
direction: 'forward',
|
|
568
|
-
focusNode: null,
|
|
569
|
-
focusOffset: 0,
|
|
570
|
-
isCollapsed: true,
|
|
571
|
-
rangeCount: 0,
|
|
572
|
-
type: 'None',
|
|
573
|
-
getRangeAt: function() { return new window.Range(); },
|
|
574
|
-
removeAllRanges: function() {},
|
|
575
|
-
addRange: function() {},
|
|
576
|
-
collapse: function() {},
|
|
577
|
-
collapseToEnd: function() {},
|
|
578
|
-
collapseToStart: function() {},
|
|
579
|
-
deleteFromDocument: function() {},
|
|
580
|
-
empty: function() {},
|
|
581
|
-
extend: function() {},
|
|
582
|
-
modify: function() {},
|
|
583
|
-
selectAllChildren: function() {},
|
|
584
|
-
setBaseAndExtent: function() {},
|
|
585
|
-
setPosition: function() {},
|
|
586
|
-
toString: function() { return ''; },
|
|
587
|
-
containsNode: function(node: Node, allowPartialContainment: boolean = false): boolean {
|
|
588
|
-
return false;
|
|
589
|
-
},
|
|
590
|
-
removeRange: function(range: Range): void {}
|
|
591
|
-
} as unknown as Selection;
|
|
592
|
-
return selection;
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
} catch (error) {
|
|
596
|
-
console.warn('Warning: Could not set getSelection:', error);
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
// Set up Window methods
|
|
600
|
-
try {
|
|
601
|
-
if (!window.Window.prototype.getComputedStyle) {
|
|
602
|
-
window.Window.prototype.getComputedStyle = function(elt: Element, pseudoElt?: string | null): CSSStyleDeclaration {
|
|
603
|
-
const style = {
|
|
604
|
-
accentColor: '',
|
|
605
|
-
alignContent: '',
|
|
606
|
-
alignItems: '',
|
|
607
|
-
alignSelf: '',
|
|
608
|
-
getPropertyValue: function(prop: string): string { return ''; }
|
|
609
|
-
} as CSSStyleDeclaration;
|
|
610
|
-
return style;
|
|
611
|
-
};
|
|
612
|
-
}
|
|
613
|
-
} catch (error) {
|
|
614
|
-
console.warn('Warning: Could not set getComputedStyle:', error);
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// Set up Range constructor last
|
|
618
|
-
try {
|
|
619
|
-
if (!window.Range) {
|
|
620
|
-
window.Range = class Range {
|
|
621
|
-
static readonly START_TO_START = 0;
|
|
622
|
-
static readonly START_TO_END = 1;
|
|
623
|
-
static readonly END_TO_END = 2;
|
|
624
|
-
static readonly END_TO_START = 3;
|
|
625
|
-
|
|
626
|
-
readonly START_TO_START = 0;
|
|
627
|
-
readonly START_TO_END = 1;
|
|
628
|
-
readonly END_TO_END = 2;
|
|
629
|
-
readonly END_TO_START = 3;
|
|
630
|
-
|
|
631
|
-
startContainer: Node;
|
|
632
|
-
startOffset: number;
|
|
633
|
-
endContainer: Node;
|
|
634
|
-
endOffset: number;
|
|
635
|
-
collapsed: boolean;
|
|
636
|
-
commonAncestorContainer: Node;
|
|
637
|
-
|
|
638
|
-
constructor() {
|
|
639
|
-
this.startContainer = document.documentElement;
|
|
640
|
-
this.startOffset = 0;
|
|
641
|
-
this.endContainer = document.documentElement;
|
|
642
|
-
this.endOffset = 0;
|
|
643
|
-
this.collapsed = true;
|
|
644
|
-
this.commonAncestorContainer = document.documentElement;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
createContextualFragment(fragment: string): DocumentFragment {
|
|
648
|
-
return document.createDocumentFragment();
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
detach(): void {}
|
|
652
|
-
|
|
653
|
-
cloneContents(): DocumentFragment {
|
|
654
|
-
return document.createDocumentFragment();
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
cloneRange(): Range {
|
|
658
|
-
return new Range();
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
collapse(toStart: boolean = false): void {}
|
|
662
|
-
|
|
663
|
-
compareBoundaryPoints(how: number, sourceRange: Range): number {
|
|
664
|
-
return 0;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
comparePoint(node: Node, offset: number): number {
|
|
668
|
-
return 0;
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
deleteContents(): void {}
|
|
672
|
-
|
|
673
|
-
extractContents(): DocumentFragment {
|
|
674
|
-
return document.createDocumentFragment();
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
getBoundingClientRect(): DOMRect {
|
|
678
|
-
return {
|
|
679
|
-
top: 0,
|
|
680
|
-
left: 0,
|
|
681
|
-
bottom: 0,
|
|
682
|
-
right: 0,
|
|
683
|
-
width: 0,
|
|
684
|
-
height: 0,
|
|
685
|
-
x: 0,
|
|
686
|
-
y: 0,
|
|
687
|
-
toJSON: function() { return this; }
|
|
688
|
-
};
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
getClientRects(): DOMRectList {
|
|
692
|
-
return {
|
|
693
|
-
length: 0,
|
|
694
|
-
item: function() { return null; },
|
|
695
|
-
[Symbol.iterator]: function*() {}
|
|
696
|
-
} as DOMRectList;
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
insertNode(node: Node): void {}
|
|
700
|
-
|
|
701
|
-
intersectsNode(node: Node): boolean {
|
|
702
|
-
return false;
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
isPointInRange(node: Node, offset: number): boolean {
|
|
706
|
-
return false;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
selectNode(node: Node): void {}
|
|
710
|
-
|
|
711
|
-
selectNodeContents(node: Node): void {
|
|
712
|
-
this.startContainer = node;
|
|
713
|
-
this.startOffset = 0;
|
|
714
|
-
this.endContainer = node;
|
|
715
|
-
this.endOffset = node.childNodes.length;
|
|
716
|
-
this.collapsed = false;
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
setEnd(node: Node, offset: number): void {}
|
|
720
|
-
|
|
721
|
-
setEndAfter(node: Node): void {}
|
|
722
|
-
|
|
723
|
-
setEndBefore(node: Node): void {}
|
|
724
|
-
|
|
725
|
-
setStart(node: Node, offset: number): void {}
|
|
726
|
-
|
|
727
|
-
setStartAfter(node: Node): void {}
|
|
728
|
-
|
|
729
|
-
setStartBefore(node: Node): void {}
|
|
730
|
-
|
|
731
|
-
surroundContents(newParent: Node): void {}
|
|
732
|
-
};
|
|
733
|
-
}
|
|
734
|
-
} catch (error) {
|
|
735
|
-
console.warn('Warning: Could not set Range constructor:', error);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
} catch (error) {
|
|
739
|
-
console.error('Error in setupDOMInterfaces:', error);
|
|
740
|
-
// Don't throw the error, just log it
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
383
|
// Create a virtual DOM
|
|
745
384
|
const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
|
746
385
|
virtualConsole,
|
|
@@ -749,6 +388,9 @@ const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
|
|
749
388
|
pretendToBeVisual: true,
|
|
750
389
|
beforeParse(window: DOMWindow) {
|
|
751
390
|
setupDOMInterfaces(window);
|
|
391
|
+
setupRange(window);
|
|
392
|
+
setupDocumentMethods(window);
|
|
393
|
+
setupWindowMethods(window);
|
|
752
394
|
}
|
|
753
395
|
});
|
|
754
396
|
|
|
@@ -768,7 +410,16 @@ const window = dom.window;
|
|
|
768
410
|
(globalThis as any).Range = window.Range;
|
|
769
411
|
(globalThis as any).DOMParser = window.DOMParser;
|
|
770
412
|
(globalThis as any).XMLSerializer = window.XMLSerializer;
|
|
771
|
-
|
|
413
|
+
|
|
414
|
+
// Handle navigator property
|
|
415
|
+
if (!globalThis.navigator || Object.getOwnPropertyDescriptor(globalThis, 'navigator')?.configurable) {
|
|
416
|
+
Object.defineProperty(globalThis, 'navigator', {
|
|
417
|
+
value: window.navigator,
|
|
418
|
+
writable: false,
|
|
419
|
+
configurable: true
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
772
423
|
(globalThis as any).HTMLElement = window.HTMLElement;
|
|
773
424
|
|
|
774
425
|
// Define DOMSettableTokenList
|
|
@@ -971,6 +622,75 @@ const window = dom.window;
|
|
|
971
622
|
align: string = '';
|
|
972
623
|
};
|
|
973
624
|
|
|
625
|
+
(globalThis as any).HTMLButtonElement = class extends (globalThis as any).HTMLElement {
|
|
626
|
+
constructor() {
|
|
627
|
+
super();
|
|
628
|
+
}
|
|
629
|
+
disabled: boolean = false;
|
|
630
|
+
form: HTMLFormElement | null = null;
|
|
631
|
+
formAction: string = '';
|
|
632
|
+
formEnctype: string = '';
|
|
633
|
+
formMethod: string = '';
|
|
634
|
+
formNoValidate: boolean = false;
|
|
635
|
+
formTarget: string = '';
|
|
636
|
+
name: string = '';
|
|
637
|
+
type: string = 'submit';
|
|
638
|
+
value: string = '';
|
|
639
|
+
menu: HTMLMenuElement | null = null;
|
|
640
|
+
};
|
|
641
|
+
|
|
642
|
+
// Add HTMLSpanElement interface
|
|
643
|
+
(globalThis as any).HTMLSpanElement = class extends (globalThis as any).HTMLElement {
|
|
644
|
+
constructor() {
|
|
645
|
+
super();
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
// Add HTMLDivElement interface
|
|
650
|
+
(globalThis as any).HTMLDivElement = class extends (globalThis as any).HTMLElement {
|
|
651
|
+
constructor() {
|
|
652
|
+
super();
|
|
653
|
+
}
|
|
654
|
+
align: string = '';
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
(globalThis as any).HTMLAnchorElement = class extends (globalThis as any).HTMLElement {
|
|
658
|
+
constructor() {
|
|
659
|
+
super();
|
|
660
|
+
}
|
|
661
|
+
href: string = '';
|
|
662
|
+
target: string = '';
|
|
663
|
+
download: string = '';
|
|
664
|
+
ping: string = '';
|
|
665
|
+
rel: string = '';
|
|
666
|
+
relList: DOMSettableTokenList = {
|
|
667
|
+
length: 0,
|
|
668
|
+
value: '',
|
|
669
|
+
add: () => {},
|
|
670
|
+
contains: () => false,
|
|
671
|
+
item: () => null,
|
|
672
|
+
remove: () => {},
|
|
673
|
+
replace: () => false,
|
|
674
|
+
supports: () => false,
|
|
675
|
+
toggle: () => false,
|
|
676
|
+
[Symbol.iterator]: function*() { yield ''; return undefined; }
|
|
677
|
+
} as unknown as DOMSettableTokenList;
|
|
678
|
+
hreflang: string = '';
|
|
679
|
+
type: string = '';
|
|
680
|
+
text: string = '';
|
|
681
|
+
referrerPolicy: string = '';
|
|
682
|
+
origin: string = '';
|
|
683
|
+
protocol: string = '';
|
|
684
|
+
username: string = '';
|
|
685
|
+
password: string = '';
|
|
686
|
+
host: string = '';
|
|
687
|
+
hostname: string = '';
|
|
688
|
+
port: string = '';
|
|
689
|
+
pathname: string = '';
|
|
690
|
+
search: string = '';
|
|
691
|
+
hash: string = '';
|
|
692
|
+
};
|
|
693
|
+
|
|
974
694
|
const program = new Command();
|
|
975
695
|
|
|
976
696
|
program
|
|
@@ -1087,6 +807,11 @@ program
|
|
|
1087
807
|
|
|
1088
808
|
const result = await defuddle.parse();
|
|
1089
809
|
|
|
810
|
+
// If in debug mode, don't show content output
|
|
811
|
+
if (options.debug) {
|
|
812
|
+
process.exit(0);
|
|
813
|
+
}
|
|
814
|
+
|
|
1090
815
|
// Format output
|
|
1091
816
|
let output: string;
|
|
1092
817
|
let content: string;
|
package/src/markdown.ts
CHANGED
|
@@ -283,17 +283,6 @@ export function createMarkdownContent(content: string, url: string) {
|
|
|
283
283
|
}
|
|
284
284
|
});
|
|
285
285
|
|
|
286
|
-
turndownService.addRule('removeHiddenElements', {
|
|
287
|
-
filter: function (node) {
|
|
288
|
-
return (
|
|
289
|
-
node.style.display === 'none'
|
|
290
|
-
);
|
|
291
|
-
},
|
|
292
|
-
replacement: function () {
|
|
293
|
-
return '';
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
|
|
297
286
|
turndownService.addRule('citations', {
|
|
298
287
|
filter: (node: Node): boolean => {
|
|
299
288
|
if (node instanceof Element) {
|