@lwc/engine-core 8.1.0 → 8.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/dist/framework/api.d.ts +2 -1
- package/dist/framework/sanitized-html-content.d.ts +29 -0
- package/dist/index.cjs.js +67 -5
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.js +67 -5
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/framework/api.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SlotSet } from './vm';
|
|
2
2
|
import { LightningElementConstructor } from './base-lightning-element';
|
|
3
3
|
import { Key, VComment, VCustomElement, VElement, VElementData, VFragment, VNode, VNodes, VScopedSlotFragment, VStatic, VStaticPart, VStaticPartData, VText } from './vnodes';
|
|
4
|
+
import { SanitizedHtmlContent } from './sanitized-html-content';
|
|
4
5
|
declare function sp(partId: number, data: VStaticPartData | null, text: string | null): VStaticPart;
|
|
5
6
|
declare function ssf(slotName: unknown, factory: (value: any, key: any) => VFragment): VScopedSlotFragment;
|
|
6
7
|
declare function st(fragmentFactory: (parts?: VStaticPart[]) => Element, key: Key, parts?: VStaticPart[]): VStatic;
|
|
@@ -45,7 +46,7 @@ export type SanitizeHtmlContentHook = (content: unknown) => string;
|
|
|
45
46
|
* @param newHookImpl
|
|
46
47
|
*/
|
|
47
48
|
export declare function setSanitizeHtmlContentHook(newHookImpl: SanitizeHtmlContentHook): void;
|
|
48
|
-
declare function shc(content: unknown):
|
|
49
|
+
declare function shc(content: unknown): SanitizedHtmlContent;
|
|
49
50
|
/**
|
|
50
51
|
* [ncls] - Normalize class name attribute.
|
|
51
52
|
*
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { RendererAPI } from './renderer';
|
|
2
|
+
declare const sanitizedHtmlContentSymbol: unique symbol;
|
|
3
|
+
export type SanitizedHtmlContent = {
|
|
4
|
+
[sanitizedHtmlContentSymbol]: unknown;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Wrap a pre-sanitized string designated for `.innerHTML` via `lwc:inner-html`
|
|
8
|
+
* as an object with a Symbol that only we have access to.
|
|
9
|
+
* @param sanitizedString
|
|
10
|
+
* @returns SanitizedHtmlContent
|
|
11
|
+
*/
|
|
12
|
+
export declare function createSanitizedHtmlContent(sanitizedString: unknown): SanitizedHtmlContent;
|
|
13
|
+
/**
|
|
14
|
+
* Safely call setProperty on an Element while handling any SanitizedHtmlContent objects correctly
|
|
15
|
+
*
|
|
16
|
+
* @param setProperty - renderer.setProperty
|
|
17
|
+
* @param elm - Element
|
|
18
|
+
* @param key - key to set
|
|
19
|
+
* @param value - value to set
|
|
20
|
+
*/
|
|
21
|
+
export declare function safelySetProperty(setProperty: RendererAPI['setProperty'], elm: Element, key: string, value: any): void;
|
|
22
|
+
/**
|
|
23
|
+
* Given two objects (likely either a string or a SanitizedHtmlContent object), return true if their
|
|
24
|
+
* string values are equivalent.
|
|
25
|
+
* @param first
|
|
26
|
+
* @param second
|
|
27
|
+
*/
|
|
28
|
+
export declare function isSanitizedHtmlContentEqual(first: any, second: any): boolean;
|
|
29
|
+
export {};
|
package/dist/index.cjs.js
CHANGED
|
@@ -3937,6 +3937,65 @@ function isVStaticPartText(vnode) {
|
|
|
3937
3937
|
return vnode.type === 0 /* VStaticPartType.Text */;
|
|
3938
3938
|
}
|
|
3939
3939
|
|
|
3940
|
+
const sanitizedHtmlContentSymbol = Symbol('lwc-get-sanitized-html-content');
|
|
3941
|
+
function isSanitizedHtmlContent(object) {
|
|
3942
|
+
return shared.isObject(object) && !shared.isNull(object) && sanitizedHtmlContentSymbol in object;
|
|
3943
|
+
}
|
|
3944
|
+
function unwrapIfNecessary(object) {
|
|
3945
|
+
return isSanitizedHtmlContent(object) ? object[sanitizedHtmlContentSymbol] : object;
|
|
3946
|
+
}
|
|
3947
|
+
/**
|
|
3948
|
+
* Wrap a pre-sanitized string designated for `.innerHTML` via `lwc:inner-html`
|
|
3949
|
+
* as an object with a Symbol that only we have access to.
|
|
3950
|
+
* @param sanitizedString
|
|
3951
|
+
* @returns SanitizedHtmlContent
|
|
3952
|
+
*/
|
|
3953
|
+
function createSanitizedHtmlContent(sanitizedString) {
|
|
3954
|
+
return shared.create(null, {
|
|
3955
|
+
[sanitizedHtmlContentSymbol]: {
|
|
3956
|
+
value: sanitizedString,
|
|
3957
|
+
configurable: false,
|
|
3958
|
+
writable: false,
|
|
3959
|
+
},
|
|
3960
|
+
});
|
|
3961
|
+
}
|
|
3962
|
+
/**
|
|
3963
|
+
* Safely call setProperty on an Element while handling any SanitizedHtmlContent objects correctly
|
|
3964
|
+
*
|
|
3965
|
+
* @param setProperty - renderer.setProperty
|
|
3966
|
+
* @param elm - Element
|
|
3967
|
+
* @param key - key to set
|
|
3968
|
+
* @param value - value to set
|
|
3969
|
+
*/
|
|
3970
|
+
function safelySetProperty(setProperty, elm, key, value) {
|
|
3971
|
+
// See W-16614337
|
|
3972
|
+
// we support setting innerHTML to `undefined` because it's inherently safe
|
|
3973
|
+
if ((key === 'innerHTML' || key === 'outerHTML') && !shared.isUndefined(value)) {
|
|
3974
|
+
if (isSanitizedHtmlContent(value)) {
|
|
3975
|
+
// it's a SanitizedHtmlContent object
|
|
3976
|
+
setProperty(elm, key, value[sanitizedHtmlContentSymbol]);
|
|
3977
|
+
}
|
|
3978
|
+
else {
|
|
3979
|
+
// not a SanitizedHtmlContent object
|
|
3980
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
3981
|
+
logWarn(`Cannot set property "${key}". Instead, use lwc:inner-html or lwc:dom-manual.`);
|
|
3982
|
+
}
|
|
3983
|
+
}
|
|
3984
|
+
}
|
|
3985
|
+
else {
|
|
3986
|
+
setProperty(elm, key, value);
|
|
3987
|
+
}
|
|
3988
|
+
}
|
|
3989
|
+
/**
|
|
3990
|
+
* Given two objects (likely either a string or a SanitizedHtmlContent object), return true if their
|
|
3991
|
+
* string values are equivalent.
|
|
3992
|
+
* @param first
|
|
3993
|
+
* @param second
|
|
3994
|
+
*/
|
|
3995
|
+
function isSanitizedHtmlContentEqual(first, second) {
|
|
3996
|
+
return unwrapIfNecessary(first) === unwrapIfNecessary(second);
|
|
3997
|
+
}
|
|
3998
|
+
|
|
3940
3999
|
/*
|
|
3941
4000
|
* Copyright (c) 2018, salesforce.com, inc.
|
|
3942
4001
|
* All rights reserved.
|
|
@@ -3967,7 +4026,7 @@ function patchAttributes(oldVnode, vnode, renderer) {
|
|
|
3967
4026
|
// Use kebabCaseToCamelCase directly because we don't want to set props like `ariaLabel` or `tabIndex`
|
|
3968
4027
|
// on a custom element versus just using the more reliable attribute format.
|
|
3969
4028
|
if (external && (propName = shared.kebabCaseToCamelCase(key)) in elm) {
|
|
3970
|
-
setProperty
|
|
4029
|
+
safelySetProperty(setProperty, elm, propName, cur);
|
|
3971
4030
|
}
|
|
3972
4031
|
else if (shared.StringCharCodeAt.call(key, 3) === ColonCharCode) {
|
|
3973
4032
|
// Assume xml namespace
|
|
@@ -4047,7 +4106,7 @@ function patchProps(oldVnode, vnode, renderer) {
|
|
|
4047
4106
|
logWarn(`Unknown public property "${key}" of element <${elm.tagName.toLowerCase()}>. This is either a typo on the corresponding attribute "${shared.htmlPropertyToAttribute(key)}", or the attribute does not exist in this browser or DOM implementation.`);
|
|
4048
4107
|
}
|
|
4049
4108
|
}
|
|
4050
|
-
setProperty
|
|
4109
|
+
safelySetProperty(setProperty, elm, key, cur);
|
|
4051
4110
|
}
|
|
4052
4111
|
}
|
|
4053
4112
|
}
|
|
@@ -5755,7 +5814,8 @@ function setSanitizeHtmlContentHook(newHookImpl) {
|
|
|
5755
5814
|
}
|
|
5756
5815
|
// [s]anitize [h]tml [c]ontent
|
|
5757
5816
|
function shc(content) {
|
|
5758
|
-
|
|
5817
|
+
const sanitizedString = sanitizeHtmlContentHook(content);
|
|
5818
|
+
return createSanitizedHtmlContent(sanitizedString);
|
|
5759
5819
|
}
|
|
5760
5820
|
/**
|
|
5761
5821
|
* [ncls] - Normalize class name attribute.
|
|
@@ -7653,6 +7713,8 @@ function hydrateComment(node, vnode, renderer) {
|
|
|
7653
7713
|
}
|
|
7654
7714
|
}
|
|
7655
7715
|
const { setProperty } = renderer;
|
|
7716
|
+
// We only set the `nodeValue` property here (on a comment), so we don't need
|
|
7717
|
+
// to sanitize the content as HTML using `safelySetProperty`
|
|
7656
7718
|
setProperty(node, NODE_VALUE_PROP, vnode.text ?? null);
|
|
7657
7719
|
vnode.elm = node;
|
|
7658
7720
|
return node;
|
|
@@ -7699,7 +7761,7 @@ function hydrateElement(elm, vnode, renderer) {
|
|
|
7699
7761
|
const { data: { props }, } = vnode;
|
|
7700
7762
|
const { getProperty } = renderer;
|
|
7701
7763
|
if (!shared.isUndefined(props) && !shared.isUndefined(props.innerHTML)) {
|
|
7702
|
-
if (getProperty(elm, 'innerHTML')
|
|
7764
|
+
if (isSanitizedHtmlContentEqual(getProperty(elm, 'innerHTML'), props.innerHTML)) {
|
|
7703
7765
|
// Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
|
|
7704
7766
|
vnode.data = {
|
|
7705
7767
|
...vnode.data,
|
|
@@ -8416,5 +8478,5 @@ exports.swapTemplate = swapTemplate;
|
|
|
8416
8478
|
exports.track = track;
|
|
8417
8479
|
exports.unwrap = unwrap;
|
|
8418
8480
|
exports.wire = wire;
|
|
8419
|
-
/** version: 8.1.
|
|
8481
|
+
/** version: 8.1.2 */
|
|
8420
8482
|
//# sourceMappingURL=index.cjs.js.map
|