Skip to content

Commit d8a50dc

Browse files
authored
fix: [#1952] Accept Document nodes as valid boundary points in Selection API (#1954)
1 parent 77a6cd0 commit d8a50dc

2 files changed

Lines changed: 70 additions & 5 deletions

File tree

packages/happy-dom/src/selection/Selection.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,10 @@ export default class Selection {
266266
);
267267
}
268268

269-
if (node[PropertySymbol.ownerDocument] !== this.#ownerDocument) {
269+
if (
270+
node !== this.#ownerDocument &&
271+
node[PropertySymbol.ownerDocument] !== this.#ownerDocument
272+
) {
270273
return;
271274
}
272275

@@ -388,7 +391,10 @@ export default class Selection {
388391
* @param offset Offset.
389392
*/
390393
public extend(node: Node, offset: number): void {
391-
if (node[PropertySymbol.ownerDocument] !== this.#ownerDocument) {
394+
if (
395+
node !== this.#ownerDocument &&
396+
node[PropertySymbol.ownerDocument] !== this.#ownerDocument
397+
) {
392398
return;
393399
}
394400

@@ -451,7 +457,10 @@ export default class Selection {
451457
);
452458
}
453459

454-
if (node[PropertySymbol.ownerDocument] !== this.#ownerDocument) {
460+
if (
461+
node !== this.#ownerDocument &&
462+
node[PropertySymbol.ownerDocument] !== this.#ownerDocument
463+
) {
455464
return;
456465
}
457466

@@ -492,8 +501,10 @@ export default class Selection {
492501
}
493502

494503
if (
495-
anchorNode[PropertySymbol.ownerDocument] !== this.#ownerDocument ||
496-
focusNode[PropertySymbol.ownerDocument] !== this.#ownerDocument
504+
(anchorNode !== this.#ownerDocument &&
505+
anchorNode[PropertySymbol.ownerDocument] !== this.#ownerDocument) ||
506+
(focusNode !== this.#ownerDocument &&
507+
focusNode[PropertySymbol.ownerDocument] !== this.#ownerDocument)
497508
) {
498509
return;
499510
}

packages/happy-dom/test/selection/Selection.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,19 @@ describe('Selection', () => {
419419
expect((<Event>(<unknown>triggeredEvent)).bubbles).toBe(false);
420420
expect((<Event>(<unknown>triggeredEvent)).cancelable).toBe(false);
421421
});
422+
423+
it('Accepts Document node.', () => {
424+
selection[method](document, 0);
425+
426+
expect(selection.rangeCount).toBe(1);
427+
428+
const newRange = selection.getRangeAt(0);
429+
430+
expect(newRange.startContainer).toBe(document);
431+
expect(newRange.startOffset).toBe(0);
432+
expect(newRange.endContainer).toBe(document);
433+
expect(newRange.endOffset).toBe(0);
434+
});
422435
});
423436
}
424437

@@ -659,6 +672,19 @@ describe('Selection', () => {
659672
expect((<Event>(<unknown>triggeredEvent)).bubbles).toBe(false);
660673
expect((<Event>(<unknown>triggeredEvent)).cancelable).toBe(false);
661674
});
675+
676+
it('Accepts Document node.', () => {
677+
const text = document.createTextNode('text');
678+
679+
document.body.appendChild(text);
680+
681+
selection.collapse(text, 0);
682+
selection.extend(document, 0);
683+
684+
expect(selection.rangeCount).toBe(1);
685+
expect(selection.focusNode).toBe(document);
686+
expect(selection.focusOffset).toBe(0);
687+
});
662688
});
663689

664690
describe('selectAllChildren()', () => {
@@ -682,6 +708,19 @@ describe('Selection', () => {
682708
expect(newRange.endOffset).toBe(3);
683709
});
684710

711+
it('Accepts Document node.', () => {
712+
selection.selectAllChildren(document);
713+
714+
expect(selection.rangeCount).toBe(1);
715+
716+
const newRange = selection.getRangeAt(0);
717+
718+
expect(newRange.startContainer).toBe(document);
719+
expect(newRange.startOffset).toBe(0);
720+
expect(newRange.endContainer).toBe(document);
721+
expect(newRange.endOffset).toBe(document.childNodes.length);
722+
});
723+
685724
it(`Throws error if node type is ${NodeTypeEnum.documentTypeNode}.`, () => {
686725
const documentType = document.implementation.createDocumentType('', '', '');
687726

@@ -748,6 +787,21 @@ describe('Selection', () => {
748787
expect(selection.anchorNode).toBe(newRange.endContainer);
749788
});
750789

790+
it('Accepts Document node as boundary point.', () => {
791+
const text = document.createTextNode('text');
792+
793+
document.body.appendChild(text);
794+
795+
selection.setBaseAndExtent(document, 0, text, 2);
796+
797+
expect(selection.rangeCount).toBe(1);
798+
799+
const newRange = selection.getRangeAt(0);
800+
801+
expect(newRange.startContainer).toBe(document);
802+
expect(newRange.endContainer).toBe(text);
803+
});
804+
751805
it('Throws error if wrong offset.', () => {
752806
const start = document.createTextNode('start');
753807
const end = document.createTextNode('end');

0 commit comments

Comments
 (0)