Skip to content

Commit

Permalink
fix(mock-doc): overwrite parentElement in MockHTMLElement to return n…
Browse files Browse the repository at this point in the history
…ull (#5336)

* fix(mock-doc): overwrite parentElement in MockHTMLElement to return null

fixes #5252
STENCIL-1104

* add test

* only return null for html elements

* fix unit tests

* tweak

* another tweak

* revert tests and correct implementation

* update tests

* prettier

* minor comment tweak

* fix assertion
  • Loading branch information
christian-bromann committed Feb 8, 2024
1 parent 8a129ce commit 0d9ed22
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 16 deletions.
17 changes: 16 additions & 1 deletion src/mock-doc/event.ts
Expand Up @@ -39,6 +39,10 @@ export class MockEvent {
this.cancelBubble = true;
}

/**
* @ref https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath
* @returns a composed path of the event
*/
composedPath(): MockElement[] {
const composedPath: MockElement[] = [];

Expand All @@ -54,7 +58,16 @@ export class MockEvent {
break;
}

currentElement = currentElement.parentElement;
/**
* bubble up the parent chain until we arrive to the HTML element. Here we continue
* with the document object instead of the parent element since the parent element
* is `null` for HTML elements.
*/
if (currentElement.parentElement == null && currentElement.tagName === 'HTML') {
currentElement = currentElement.ownerDocument;
} else {
currentElement = currentElement.parentElement;
}
}

return composedPath;
Expand Down Expand Up @@ -202,6 +215,8 @@ function triggerEventListener(elm: any, ev: MockEvent) {

if (elm.nodeName === NODE_NAMES.DOCUMENT_NODE) {
triggerEventListener((elm as MockDocument).defaultView, ev);
} else if (elm.parentElement == null && elm.tagName === 'HTML') {
triggerEventListener(elm.ownerDocument, ev);
} else {
triggerEventListener(elm.parentElement, ev);
}
Expand Down
13 changes: 13 additions & 0 deletions src/mock-doc/node.ts
Expand Up @@ -1101,6 +1101,19 @@ export class MockHTMLElement extends MockElement {
this.nodeName = value;
}

/**
* A node’s parent of type Element is known as its parent element.
* If the node has a parent of a different type, its parent element
* is null.
* @returns MockElement
*/
override get parentElement() {
if (this.nodeName === 'HTML') {
return null;
}
return super.parentElement;
}

override get attributes(): MockAttributeMap {
if (this.__attributeMap == null) {
const attrMap = createAttributeProxy(true);
Expand Down
7 changes: 7 additions & 0 deletions src/mock-doc/test/element.spec.ts
Expand Up @@ -444,6 +444,13 @@ describe('element', () => {
});
});

describe('parentElement', () => {
it('returns `null` for when accessing the parent element of an html node', () => {
const element = new MockHTMLElement(doc, 'myElement');
expect(element.parentElement).toEqual(null);
});
});

describe('input', () => {
it('list is readonly prop', () => {
const input = doc.createElement('input');
Expand Down
14 changes: 11 additions & 3 deletions src/runtime/test/style.spec.tsx
Expand Up @@ -5,7 +5,11 @@ describe('style', () => {
it('get style string', async () => {
@Component({
tag: 'cmp-a',
styles: `div { color: red; }`,
styles: `
div {
color: red;
}
`,
})
class CmpA {
render() {
Expand All @@ -20,13 +24,17 @@ describe('style', () => {
});

expect(root).toHaveClass('hydrated');
expect(styles.get('sc-cmp-a')).toBe(`div { color: red; }`);
expect(styles.get('sc-cmp-a')).toContain(`color: red;`);
});

it('applies the nonce value to the head style tags', async () => {
@Component({
tag: 'cmp-a',
styles: `div { color: red; }`,
styles: `
div {
color: red;
}
`,
})
class CmpA {
render() {
Expand Down
9 changes: 7 additions & 2 deletions test/end-to-end/src/state-cmp/state-cmp.tsx
Expand Up @@ -3,8 +3,13 @@ import { Component, State, h } from '@stencil/core';
@Component({
tag: 'state-cmp',
styles: `
button { color: black; }
.selected { font-weight: bold; color: blue; }
button {
color: black;
}
.selected {
font-weight: bold;
color: blue;
}
`,
shadow: true,
})
Expand Down
6 changes: 3 additions & 3 deletions test/karma/test-app/attribute-host/cmp.tsx
Expand Up @@ -3,19 +3,19 @@ import { Component, State, h } from '@stencil/core';
@Component({
tag: 'attribute-host',
styles: `
[color=lime] {
[color='lime'] {
background: lime;
}
section::before {
content: attr(content);
}
[padding=true] {
[padding='true'] {
padding: 50px;
}
[margin] {
margin: 50px;
}
[bold=true] {
[bold='true'] {
font-weight: bold;
}
`,
Expand Down
15 changes: 8 additions & 7 deletions test/karma/test-app/listen-jsx/cmp.tsx
Expand Up @@ -4,13 +4,14 @@ import { Component, Listen, State, h } from '@stencil/core';
tag: 'listen-jsx',
scoped: true,
styles: `
:host{
background: black;
display: block;
color: white;
width: 100px;
height: 100px;
}`,
:host {
background: black;
display: block;
color: white;
width: 100px;
height: 100px;
}
`,
})
export class AttributeBasic {
@State() wasClicked = '';
Expand Down

0 comments on commit 0d9ed22

Please sign in to comment.