feat(ivy): provide sanitization methods which can be tree shaken (#22540)

By providing a top level sanitization methods (rather than service) the
compiler can generate calls into the methods only when needed. This makes
the methods tree shakable.

PR Close #22540
This commit is contained in:
Miško Hevery
2018-03-01 17:14:01 -08:00
committed by Kara Erickson
parent 538f1d980f
commit 6d1367d297
15 changed files with 592 additions and 77 deletions

View File

@ -38,6 +38,11 @@ export const NG_HOST_SYMBOL = '__ngHostLNode__';
*/
const _CLEAN_PROMISE = Promise.resolve(null);
/**
* Function used to sanitize the value before writing it into the renderer.
*/
export type Sanitizer = (value: any) => string;
/**
* This property gets set before entering a template.
@ -689,20 +694,22 @@ export function elementEnd() {
* Updates the value of removes an attribute on an Element.
*
* @param number index The index of the element in the data array
* @param string name The name of the attribute.
* @param any value The attribute is removed when value is `null` or `undefined`.
* @param name name The name of the attribute.
* @param value value The attribute is removed when value is `null` or `undefined`.
* Otherwise the attribute value is set to the stringified value.
* @param sanitizer An optional function used to sanitize the value.
*/
export function elementAttribute(index: number, name: string, value: any): void {
export function elementAttribute(
index: number, name: string, value: any, sanitizer?: Sanitizer): void {
if (value !== NO_CHANGE) {
const element: LElementNode = data[index];
if (value == null) {
isProceduralRenderer(renderer) ? renderer.removeAttribute(element.native, name) :
element.native.removeAttribute(name);
} else {
isProceduralRenderer(renderer) ?
renderer.setAttribute(element.native, name, stringify(value)) :
element.native.setAttribute(name, stringify(value));
const strValue = sanitizer == null ? stringify(value) : sanitizer(value);
isProceduralRenderer(renderer) ? renderer.setAttribute(element.native, name, strValue) :
element.native.setAttribute(name, strValue);
}
}
}
@ -718,9 +725,11 @@ export function elementAttribute(index: number, name: string, value: any): void
* @param propName Name of property. Because it is going to DOM, this is not subject to
* renaming as part of minification.
* @param value New value to write.
* @param sanitizer An optional function used to sanitize the value.
*/
export function elementProperty<T>(index: number, propName: string, value: T | NO_CHANGE): void {
export function elementProperty<T>(
index: number, propName: string, value: T | NO_CHANGE, sanitizer?: Sanitizer): void {
if (value === NO_CHANGE) return;
const node = data[index] as LElementNode;
const tNode = node.tNode !;
@ -737,6 +746,7 @@ export function elementProperty<T>(index: number, propName: string, value: T | N
setInputsForProperty(dataValue, value);
markDirtyIfOnPush(node);
} else {
value = (sanitizer != null ? sanitizer(value) : stringify(value)) as any;
const native = node.native;
isProceduralRenderer(renderer) ? renderer.setProperty(native, propName, value) :
(native.setProperty ? native.setProperty(propName, value) :
@ -842,10 +852,17 @@ export function elementClass<T>(index: number, className: string, value: T | NO_
* @param styleName Name of property. Because it is going to DOM this is not subject to
* renaming as part of minification.
* @param value New value to write (null to remove).
* @param suffix Suffix to add to style's value (optional).
* @param suffix Optional suffix. Used with scalar values to add unit such as `px`.
* @param sanitizer An optional function used to transform the value typically used for
* sanitization.
*/
export function elementStyle<T>(
index: number, styleName: string, value: T | NO_CHANGE, suffix?: string): void {
index: number, styleName: string, value: T | NO_CHANGE, suffix?: string): void;
export function elementStyle<T>(
index: number, styleName: string, value: T | NO_CHANGE, sanitizer?: Sanitizer): void;
export function elementStyle<T>(
index: number, styleName: string, value: T | NO_CHANGE,
suffixOrSanitizer?: string | Sanitizer): void {
if (value !== NO_CHANGE) {
const lElement = data[index] as LElementNode;
if (value == null) {
@ -853,7 +870,9 @@ export function elementStyle<T>(
renderer.removeStyle(lElement.native, styleName, RendererStyleFlags3.DashCase) :
lElement.native.style.removeProperty(styleName);
} else {
const strValue = suffix ? stringify(value) + suffix : stringify(value);
let strValue =
typeof suffixOrSanitizer == 'function' ? suffixOrSanitizer(value) : stringify(value);
if (typeof suffixOrSanitizer == 'string') strValue = strValue + suffixOrSanitizer;
isProceduralRenderer(renderer) ?
renderer.setStyle(lElement.native, styleName, strValue, RendererStyleFlags3.DashCase) :
lElement.native.style.setProperty(styleName, strValue);