Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/runtime/dom-extras.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,14 +396,14 @@ export const patchChildSlotNodes = (elm: HTMLElement) => {
patchHostOriginalAccessor('firstChild', elm);
Object.defineProperty(elm, 'firstChild', {
get() {
return this.childNodes[0];
return this.childNodes[0] || null;
},
});

patchHostOriginalAccessor('lastChild', elm);
Object.defineProperty(elm, 'lastChild', {
get() {
return this.childNodes[this.childNodes.length - 1];
return this.childNodes[this.childNodes.length - 1] || null;
},
});

Expand Down Expand Up @@ -459,7 +459,7 @@ const patchNextSibling = (node: Node) => {
const parentNodes = this['s-ol']?.parentNode.childNodes;
const index = parentNodes?.indexOf(this);
if (parentNodes && index > -1) {
return parentNodes[index + 1];
return parentNodes[index + 1] || null;
}
return this.__nextSibling;
},
Expand All @@ -480,7 +480,7 @@ const patchNextElementSibling = (element: Element) => {
const parentEles = this['s-ol']?.parentNode.children;
const index = parentEles?.indexOf(this);
if (parentEles && index > -1) {
return parentEles[index + 1];
return parentEles[index + 1] || null;
}
return this.__nextElementSibling;
},
Expand All @@ -501,7 +501,7 @@ const patchPreviousSibling = (node: Node) => {
const parentNodes = this['s-ol']?.parentNode.childNodes;
const index = parentNodes?.indexOf(this);
if (parentNodes && index > -1) {
return parentNodes[index - 1];
return parentNodes[index - 1] || null;
}
return this.__previousSibling;
},
Expand All @@ -523,7 +523,7 @@ const patchPreviousElementSibling = (element: Element) => {
const index = parentNodes?.indexOf(this);

if (parentNodes && index > -1) {
return parentNodes[index - 1];
return parentNodes[index - 1] || null;
}
return this.__previousElementSibling;
},
Expand All @@ -541,7 +541,7 @@ export const patchParentNode = (node: Node) => {
patchHostOriginalAccessor('parentNode', node);
Object.defineProperty(node, 'parentNode', {
get: function () {
return this['s-ol']?.parentNode || this.__parentNode;
return this['s-ol']?.parentNode || this.__parentNode || null;
},
set: function (value) {
// mock-doc sets parentNode?
Expand Down
30 changes: 30 additions & 0 deletions src/runtime/test/dom-extras.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,34 @@ describe('dom-extras - patches for non-shadow dom methods and accessors', () =>
expect(specPage.root.children[0].__parentNode.tagName).toBe('DIV');
expect(specPage.root.childNodes[0].__parentNode.tagName).toBe('DIV');
});

it('returns null (not undefined) for out-of-bounds siblings/children', async () => {
specPage.root.childNodes.forEach((node: Node) => patchSlottedNode(node));

const firstSlottedNode = specPage.root.childNodes[0];
expect(firstSlottedNode.previousSibling).toBeNull();

const lastSlottedNode = specPage.root.childNodes[specPage.root.childNodes.length - 1];
expect(lastSlottedNode.nextSibling).toBeNull();

const firstSlottedElement = specPage.root.children[0];
expect(firstSlottedElement.previousElementSibling).toBeNull();

const lastSlottedElement = specPage.root.children[specPage.root.children.length - 1];
expect(lastSlottedElement.nextElementSibling).toBeNull();
});

it('returns null (not undefined) for firstChild/lastChild on empty patched hosts', async () => {
const emptyPage = await newSpecPage({
components: [],
html: `<div id="empty"></div>`,
});
const emptyElm = emptyPage.root;
(emptyElm as any).__childNodes = [];
patchPseudoShadowDom(emptyElm);

expect(emptyElm.firstChild).toBeNull();
expect(emptyElm.lastChild).toBeNull();
});
});