-
Notifications
You must be signed in to change notification settings - Fork 398
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Will Harney <wharney@salesforce.com> Co-authored-by: Eugene Kashida <ekashida@gmail.com>
- Loading branch information
1 parent
e8098e1
commit eb41b26
Showing
29 changed files
with
396 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
packages/@lwc/engine-core/src/framework/sanitized-html-content.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { create as ObjectCreate, isNull, isObject, isUndefined } from '@lwc/shared'; | ||
import { logWarn } from '../shared/logger'; | ||
import type { RendererAPI } from './renderer'; | ||
|
||
const sanitizedHtmlContentSymbol = Symbol('lwc-get-sanitized-html-content'); | ||
|
||
export type SanitizedHtmlContent = { | ||
[sanitizedHtmlContentSymbol]: unknown; | ||
}; | ||
|
||
function isSanitizedHtmlContent(object: any): object is SanitizedHtmlContent { | ||
return isObject(object) && !isNull(object) && sanitizedHtmlContentSymbol in object; | ||
} | ||
|
||
function unwrapIfNecessary(object: any) { | ||
return isSanitizedHtmlContent(object) ? object[sanitizedHtmlContentSymbol] : object; | ||
} | ||
|
||
/** | ||
* Wrap a pre-sanitized string designated for `.innerHTML` via `lwc:inner-html` | ||
* as an object with a Symbol that only we have access to. | ||
* @param sanitizedString | ||
* @returns SanitizedHtmlContent | ||
*/ | ||
export function createSanitizedHtmlContent(sanitizedString: unknown): SanitizedHtmlContent { | ||
return ObjectCreate(null, { | ||
[sanitizedHtmlContentSymbol]: { | ||
value: sanitizedString, | ||
configurable: false, | ||
writable: false, | ||
}, | ||
}); | ||
} | ||
|
||
/** | ||
* Safely call setProperty on an Element while handling any SanitizedHtmlContent objects correctly | ||
* | ||
* @param setProperty - renderer.setProperty | ||
* @param elm - Element | ||
* @param key - key to set | ||
* @param value - value to set | ||
*/ | ||
export function safelySetProperty( | ||
setProperty: RendererAPI['setProperty'], | ||
elm: Element, | ||
key: string, | ||
value: any | ||
) { | ||
// See W-16614337 | ||
// we support setting innerHTML to `undefined` because it's inherently safe | ||
if ((key === 'innerHTML' || key === 'outerHTML') && !isUndefined(value)) { | ||
if (isSanitizedHtmlContent(value)) { | ||
// it's a SanitizedHtmlContent object | ||
setProperty(elm, key, value[sanitizedHtmlContentSymbol]); | ||
} else { | ||
// not a SanitizedHtmlContent object | ||
if (process.env.NODE_ENV !== 'production') { | ||
logWarn( | ||
`Cannot set property "${key}". Instead, use lwc:inner-html or lwc:dom-manual.` | ||
); | ||
} | ||
} | ||
} else { | ||
setProperty(elm, key, value); | ||
} | ||
} | ||
|
||
/** | ||
* Given two objects (likely either a string or a SanitizedHtmlContent object), return true if their | ||
* string values are equivalent. | ||
* @param first | ||
* @param second | ||
*/ | ||
export function isSanitizedHtmlContentEqual(first: any, second: any) { | ||
return unwrapIfNecessary(first) === unwrapIfNecessary(second); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
88 changes: 88 additions & 0 deletions
88
packages/@lwc/engine-server/src/__tests__/fixtures/inner-outer-html/expected.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
<x-inner> | ||
<template shadowrootmode="open"> | ||
<div data-expect-no-warning data-id="div-inner-static" inner-h-t-m-l="replaced"> | ||
original | ||
</div> | ||
<div data-expect-no-warning data-id="div-inner-computed" inner-h-t-m-l="injected"> | ||
original | ||
</div> | ||
<div data-id="div-inner-spread"> | ||
original | ||
</div> | ||
<x-component data-id="cmp-inner-static"> | ||
<template shadowrootmode="open"> | ||
<slot> | ||
</slot> | ||
</template> | ||
original | ||
</x-component> | ||
<x-component data-id="cmp-inner-computed"> | ||
<template shadowrootmode="open"> | ||
<slot> | ||
</slot> | ||
</template> | ||
original | ||
</x-component> | ||
<x-component data-id="cmp-inner-spread"> | ||
<template shadowrootmode="open"> | ||
<slot> | ||
</slot> | ||
</template> | ||
original | ||
</x-component> | ||
<omg-whatever data-id="external-inner-static" inner-h-t-m-l="replaced"> | ||
original | ||
</omg-whatever> | ||
<omg-whatever data-id="external-inner-computed" inner-h-t-m-l="injected"> | ||
original | ||
</omg-whatever> | ||
<omg-whatever data-id="external-inner-spread"> | ||
original | ||
</omg-whatever> | ||
<div data-expect-no-warning data-id="div-outer-static" outer-h-t-m-l="replaced"> | ||
original | ||
</div> | ||
<div data-expect-no-warning data-id="div-outer-computed" outer-h-t-m-l="injected"> | ||
original | ||
</div> | ||
<div data-id="div-outer-spread"> | ||
original | ||
</div> | ||
<x-component data-id="cmp-outer-static"> | ||
<template shadowrootmode="open"> | ||
<slot> | ||
</slot> | ||
</template> | ||
original | ||
</x-component> | ||
<x-component data-id="cmp-outer-computed"> | ||
<template shadowrootmode="open"> | ||
<slot> | ||
</slot> | ||
</template> | ||
original | ||
</x-component> | ||
<x-component data-id="cmp-outer-spread"> | ||
<template shadowrootmode="open"> | ||
<slot> | ||
</slot> | ||
</template> | ||
original | ||
</x-component> | ||
<omg-whatever data-id="external-outer-static"> | ||
original | ||
</omg-whatever> | ||
<omg-whatever data-id="external-outer-computed"> | ||
original | ||
</omg-whatever> | ||
<omg-whatever data-id="external-outer-spread"> | ||
original | ||
</omg-whatever> | ||
<span> | ||
lwc:inner-html | ||
</span> | ||
<p> | ||
injected | ||
</p> | ||
</template> | ||
</x-inner> |
3 changes: 3 additions & 0 deletions
3
packages/@lwc/engine-server/src/__tests__/fixtures/inner-outer-html/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const tagName = 'x-inner'; | ||
export { default } from 'x/inner'; | ||
export * from 'x/inner'; |
3 changes: 3 additions & 0 deletions
3
.../engine-server/src/__tests__/fixtures/inner-outer-html/modules/x/component/component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<template> | ||
<slot></slot> | ||
</template> |
3 changes: 3 additions & 0 deletions
3
...wc/engine-server/src/__tests__/fixtures/inner-outer-html/modules/x/component/component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { LightningElement } from 'lwc'; | ||
|
||
export default class extends LightningElement {} |
28 changes: 28 additions & 0 deletions
28
...ges/@lwc/engine-server/src/__tests__/fixtures/inner-outer-html/modules/x/inner/inner.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<template> | ||
<div data-id="div-inner-static" data-expect-no-warning inner-h-t-m-l="replaced">original</div> | ||
<div data-id="div-inner-computed" data-expect-no-warning inner-h-t-m-l={computed}>original</div> | ||
<div data-id="div-inner-spread" lwc:spread={spread}>original</div> | ||
|
||
<x-component data-id="cmp-inner-static" inner-h-t-m-l="replaced">original</x-component> | ||
<x-component data-id="cmp-inner-computed" inner-h-t-m-l={computed}>original</x-component> | ||
<x-component data-id="cmp-inner-spread" lwc:spread={spread}>original</x-component> | ||
|
||
<omg-whatever lwc:external data-id="external-inner-static" inner-h-t-m-l="replaced">original</omg-whatever> | ||
<omg-whatever lwc:external data-id="external-inner-computed" inner-h-t-m-l={computed}>original</omg-whatever> | ||
<omg-whatever lwc:external data-id="external-inner-spread" lwc:spread={spread}>original</omg-whatever> | ||
|
||
<div data-id="div-outer-static" data-expect-no-warning outer-h-t-m-l="replaced">original</div> | ||
<div data-id="div-outer-computed" data-expect-no-warning outer-h-t-m-l={computed}>original</div> | ||
<div data-id="div-outer-spread" lwc:spread={spread}>original</div> | ||
|
||
<x-component data-id="cmp-outer-static" outer-h-t-m-l="replaced">original</x-component> | ||
<x-component data-id="cmp-outer-computed" outer-h-t-m-l={computed}>original</x-component> | ||
<x-component data-id="cmp-outer-spread" lwc:spread={spread}>original</x-component> | ||
|
||
<omg-whatever lwc:external data-id="external-outer-static" outer-h-t-m-l="replaced">original</omg-whatever> | ||
<omg-whatever lwc:external data-id="external-outer-computed" outer-h-t-m-l={computed}>original</omg-whatever> | ||
<omg-whatever lwc:external data-id="external-outer-spread" lwc:spread={spread}>original</omg-whatever> | ||
|
||
<span lwc:inner-html="lwc:inner-html"></span> | ||
<p lwc:inner-html={computed}></p> | ||
</template> |
6 changes: 6 additions & 0 deletions
6
packages/@lwc/engine-server/src/__tests__/fixtures/inner-outer-html/modules/x/inner/inner.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { LightningElement } from 'lwc'; | ||
|
||
export default class extends LightningElement { | ||
computed = 'injected'; | ||
spread = { innerHTML: 'wheeeeeeeeeeeeeeeeeeeeeeeeeee' }; | ||
} |
16 changes: 16 additions & 0 deletions
16
packages/@lwc/integration-karma/test-hydration/inner-outer-html/index.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
export default { | ||
props: {}, | ||
advancedTest(target, { consoleSpy }) { | ||
const ids = Object.entries(TestUtils.extractDataIds(target)).filter( | ||
([id]) => !id.endsWith('.shadowRoot') | ||
); | ||
for (const [id, node] of ids) { | ||
expect(node.childNodes.length).toBe(1); | ||
expect(node.firstChild.nodeType).toBe(Node.TEXT_NODE); | ||
const expected = id.startsWith('lwc-inner-html-') ? 'injected' : 'original'; | ||
expect(node.firstChild.nodeValue).toBe(expected); | ||
} | ||
expect(consoleSpy.calls.warn).toHaveSize(0); | ||
expect(consoleSpy.calls.error).toHaveSize(0); | ||
}, | ||
}; |
3 changes: 3 additions & 0 deletions
3
packages/@lwc/integration-karma/test-hydration/inner-outer-html/x/component/component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<template> | ||
<slot></slot> | ||
</template> |
3 changes: 3 additions & 0 deletions
3
packages/@lwc/integration-karma/test-hydration/inner-outer-html/x/component/component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { LightningElement } from 'lwc'; | ||
|
||
export default class extends LightningElement {} |
28 changes: 28 additions & 0 deletions
28
packages/@lwc/integration-karma/test-hydration/inner-outer-html/x/main/main.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<template> | ||
<div data-id="div-inner-static" data-expect-no-warning inner-h-t-m-l="replaced">original</div> | ||
<div data-id="div-inner-computed" data-expect-no-warning inner-h-t-m-l={computed}>original</div> | ||
<div data-id="div-inner-spread" lwc:spread={spread}>original</div> | ||
|
||
<x-component data-id="cmp-inner-static" inner-h-t-m-l="replaced">original</x-component> | ||
<x-component data-id="cmp-inner-computed" inner-h-t-m-l={computed}>original</x-component> | ||
<x-component data-id="cmp-inner-spread" lwc:spread={spread}>original</x-component> | ||
|
||
<omg-whatever lwc:external data-id="external-inner-static" inner-h-t-m-l="replaced">original</omg-whatever> | ||
<omg-whatever lwc:external data-id="external-inner-computed" inner-h-t-m-l={computed}>original</omg-whatever> | ||
<omg-whatever lwc:external data-id="external-inner-spread" lwc:spread={spread}>original</omg-whatever> | ||
|
||
<div data-id="div-outer-static" data-expect-no-warning outer-h-t-m-l="replaced">original</div> | ||
<div data-id="div-outer-computed" data-expect-no-warning outer-h-t-m-l={computed}>original</div> | ||
<div data-id="div-outer-spread" lwc:spread={spread}>original</div> | ||
|
||
<x-component data-id="cmp-outer-static" outer-h-t-m-l="replaced">original</x-component> | ||
<x-component data-id="cmp-outer-computed" outer-h-t-m-l={computed}>original</x-component> | ||
<x-component data-id="cmp-outer-spread" lwc:spread={spread}>original</x-component> | ||
|
||
<omg-whatever lwc:external data-id="external-outer-static" outer-h-t-m-l="replaced">original</omg-whatever> | ||
<omg-whatever lwc:external data-id="external-outer-computed" outer-h-t-m-l={computed}>original</omg-whatever> | ||
<omg-whatever lwc:external data-id="external-outer-spread" lwc:spread={spread}>original</omg-whatever> | ||
|
||
<span data-id="lwc-inner-html-static" lwc:inner-html="injected"></span> | ||
<p data-id="lwc-inner-html-computed" lwc:inner-html={computed}></p> | ||
</template> |
6 changes: 6 additions & 0 deletions
6
packages/@lwc/integration-karma/test-hydration/inner-outer-html/x/main/main.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { LightningElement } from 'lwc'; | ||
|
||
export default class extends LightningElement { | ||
computed = 'injected'; | ||
spread = { innerHTML: 'wheeeeeeeeeeeeeeeeeeeeeeeeeee' }; | ||
} |
Oops, something went wrong.