defuddle-cli 0.1.1 → 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 +14 -347
- 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 +16 -374
|
@@ -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;
|
|
@@ -377,379 +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
|
-
// Add HTMLAnchorElement to global scope
|
|
739
|
-
try {
|
|
740
|
-
if (!window.HTMLAnchorElement) {
|
|
741
|
-
window.HTMLAnchorElement = (globalThis as any).HTMLAnchorElement as any;
|
|
742
|
-
}
|
|
743
|
-
} catch (error) {
|
|
744
|
-
console.warn('Warning: Could not set HTMLAnchorElement:', error);
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
} catch (error) {
|
|
748
|
-
console.error('Error in setupDOMInterfaces:', error);
|
|
749
|
-
// Don't throw the error, just log it
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
|
|
753
383
|
// Create a virtual DOM
|
|
754
384
|
const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
|
755
385
|
virtualConsole,
|
|
@@ -758,6 +388,9 @@ const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
|
|
758
388
|
pretendToBeVisual: true,
|
|
759
389
|
beforeParse(window: DOMWindow) {
|
|
760
390
|
setupDOMInterfaces(window);
|
|
391
|
+
setupRange(window);
|
|
392
|
+
setupDocumentMethods(window);
|
|
393
|
+
setupWindowMethods(window);
|
|
761
394
|
}
|
|
762
395
|
});
|
|
763
396
|
|
|
@@ -777,7 +410,16 @@ const window = dom.window;
|
|
|
777
410
|
(globalThis as any).Range = window.Range;
|
|
778
411
|
(globalThis as any).DOMParser = window.DOMParser;
|
|
779
412
|
(globalThis as any).XMLSerializer = window.XMLSerializer;
|
|
780
|
-
|
|
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
|
+
|
|
781
423
|
(globalThis as any).HTMLElement = window.HTMLElement;
|
|
782
424
|
|
|
783
425
|
// Define DOMSettableTokenList
|