diff --git a/goldens/public-api/core/core.d.ts b/goldens/public-api/core/core.d.ts index ad94e2c480..4d58fe41cc 100644 --- a/goldens/public-api/core/core.d.ts +++ b/goldens/public-api/core/core.d.ts @@ -723,8 +723,6 @@ export declare function ɵɵcontentQuery(directiveIndex: number, predicate: T export declare function ɵɵCopyDefinitionFeature(definition: ɵDirectiveDef | ɵComponentDef): void; -export declare const ɵɵdefaultStyleSanitizer: StyleSanitizeFn; - export declare function ɵɵdefineComponent(componentDefinition: { type: Type; selectors?: ɵCssSelectorList; @@ -1050,8 +1048,6 @@ export declare function ɵɵstylePropInterpolate8(prop: string, prefix: string, export declare function ɵɵstylePropInterpolateV(prop: string, values: any[], valueSuffix?: string | null): typeof ɵɵstylePropInterpolateV; -export declare function ɵɵstyleSanitizer(sanitizer: StyleSanitizeFn | null): void; - export declare function ɵɵtemplate(index: number, templateFn: ComponentTemplate | null, decls: number, vars: number, tagName?: string | null, attrsIndex?: number | null, localRefsIndex?: number | null, localRefExtractor?: LocalRefExtractor): void; export declare function ɵɵtemplateRefExtractor(tNode: TNode, currentView: ɵangular_packages_core_core_bo): TemplateRef | null; diff --git a/goldens/size-tracking/aio-payloads.json b/goldens/size-tracking/aio-payloads.json index ae822a944b..4f885fa06f 100755 --- a/goldens/size-tracking/aio-payloads.json +++ b/goldens/size-tracking/aio-payloads.json @@ -12,8 +12,8 @@ "master": { "uncompressed": { "runtime-es2015": 2987, - "main-es2015": 453518, - "polyfills-es2015": 52195 + "main-es2015": 452717, + "polyfills-es2015": 52628 } } }, diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts index 685b1ef69c..76082c6e3d 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts @@ -555,7 +555,7 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelement(0, "div"); } if (rf & 2) { - $r3$.ɵɵstyleProp("background-image", ctx.myImage, $r3$.ɵɵdefaultStyleSanitizer); + $r3$.ɵɵstyleProp("background-image", ctx.myImage); } }, encapsulation: 2 @@ -1151,15 +1151,15 @@ describe('compiler compliance: styling', () => { app: { 'spec.ts': ` import {Component, NgModule, HostBinding} from '@angular/core'; - + @Component({ selector: 'my-component', template: \`
-
-
-
-
+
+
+
+
@@ -1178,7 +1178,7 @@ describe('compiler compliance: styling', () => { p8 = 100; p9 = 100; } - + @NgModule({declarations: [MyComponent]}) export class MyModule {} ` @@ -1221,7 +1221,7 @@ describe('compiler compliance: styling', () => { app: { 'spec.ts': ` import {Component, NgModule, HostBinding} from '@angular/core'; - + @Component({ selector: 'my-component', template: \` @@ -1248,7 +1248,7 @@ describe('compiler compliance: styling', () => { p8 = 100; p9 = 100; } - + @NgModule({declarations: [MyComponent]}) export class MyModule {} ` @@ -1554,8 +1554,8 @@ describe('compiler compliance: styling', () => { const template = ` … if (rf & 2) { - $r3$.ɵɵstylePropInterpolate1("background", "url(", ctx.myUrl1, ")", $r3$.ɵɵdefaultStyleSanitizer); - $r3$.ɵɵstylePropInterpolate2("border-image", "url(", ctx.myUrl2, ") ", ctx.myRepeat, " auto", $r3$.ɵɵdefaultStyleSanitizer); + $r3$.ɵɵstylePropInterpolate1("background", "url(", ctx.myUrl1, ")"); + $r3$.ɵɵstylePropInterpolate2("border-image", "url(", ctx.myUrl2, ") ", ctx.myRepeat, " auto"); $r3$.ɵɵstylePropInterpolate3("box-shadow", "", ctx.myBoxX, " ", ctx.myBoxY, " ", ctx.myBoxWidth, " black"); } … @@ -2036,110 +2036,6 @@ describe('compiler compliance: styling', () => { }); describe('new styling refactor', () => { - it('should generate a `styleSanitizer` instruction when one or more sanitizable style properties are statically detected', - () => { - const files = { - app: { - 'spec.ts': ` - import {Component, NgModule} from '@angular/core'; - - @Component({ - selector: 'my-app', - template: \` -
- \` - }) - export class MyAppComp { - bgExp = ''; - } - ` - } - }; - - const template = ` - template: function MyAppComp_Template(rf, ctx) { - … - if (rf & 2) { - $r3$.ɵɵstyleProp("background-image", ctx.bgExp, $r3$.ɵɵdefaultStyleSanitizer); - } - … - } - `; - - const result = compile(files, angularFiles); - expectEmit(result.source, template, 'Incorrect template'); - }); - - it('should generate a `styleSanitizer` instruction when a `styleMap` instruction is used', - () => { - const files = { - app: { - 'spec.ts': ` - import {Component, NgModule} from '@angular/core'; - - @Component({ - selector: 'my-app', - template: \` -
- \` - }) - export class MyAppComp { - mapExp = {}; - } - ` - } - }; - - const template = ` - template: function MyAppComp_Template(rf, ctx) { - … - if (rf & 2) { - $r3$.ɵɵstyleMap(ctx.mapExp); - } - … - } - `; - - const result = compile(files, angularFiles); - expectEmit(result.source, template, 'Incorrect template'); - }); - - it('shouldn\'t generate a `styleSanitizer` instruction when class-based instructions are used', - () => { - const files = { - app: { - 'spec.ts': ` - import {Component, NgModule} from '@angular/core'; - - @Component({ - selector: 'my-app', - template: \` -
- \` - }) - export class MyAppComp { - mapExp = {}; - nameExp = true; - } - ` - } - }; - - const template = ` - template: function MyAppComp_Template(rf, ctx) { - … - if (rf & 2) { - $r3$.ɵɵclassMap(ctx.mapExp); - $r3$.ɵɵclassProp("name", ctx.nameExp); - } - … - } - `; - - const result = compile(files, angularFiles); - expectEmit(result.source, template, 'Incorrect template'); - }); - it('should generate the correct amount of host bindings when styling is present', () => { const files = { app: { diff --git a/packages/compiler/src/render3/r3_identifiers.ts b/packages/compiler/src/render3/r3_identifiers.ts index 8e072e6488..0dbd8d062c 100644 --- a/packages/compiler/src/render3/r3_identifiers.ts +++ b/packages/compiler/src/render3/r3_identifiers.ts @@ -315,8 +315,6 @@ export class Identifiers { // sanitization-related functions static sanitizeHtml: o.ExternalReference = {name: 'ɵɵsanitizeHtml', moduleName: CORE}; static sanitizeStyle: o.ExternalReference = {name: 'ɵɵsanitizeStyle', moduleName: CORE}; - static defaultStyleSanitizer: - o.ExternalReference = {name: 'ɵɵdefaultStyleSanitizer', moduleName: CORE}; static sanitizeResourceUrl: o.ExternalReference = {name: 'ɵɵsanitizeResourceUrl', moduleName: CORE}; static sanitizeScript: o.ExternalReference = {name: 'ɵɵsanitizeScript', moduleName: CORE}; diff --git a/packages/compiler/src/render3/view/styling_builder.ts b/packages/compiler/src/render3/view/styling_builder.ts index 6860d3e543..00867e7082 100644 --- a/packages/compiler/src/render3/view/styling_builder.ts +++ b/packages/compiler/src/render3/view/styling_builder.ts @@ -5,7 +5,6 @@ * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -import {ConstantPool} from '../../constant_pool'; import {AttributeMarker} from '../../core'; import {AST, ASTWithSource, BindingPipe, BindingType, Interpolation} from '../../expression_parser/ast'; import * as o from '../../output/output_ast'; @@ -92,9 +91,8 @@ export interface StylingInstructionCall { interface BoundStylingEntry { hasOverrideFlag: boolean; name: string|null; - unit: string|null; + suffix: string|null; sourceSpan: ParseSourceSpan; - sanitize: boolean; value: AST; } @@ -217,20 +215,15 @@ export class StylingBuilder { registerStyleInput( name: string, isMapBased: boolean, value: AST, sourceSpan: ParseSourceSpan, - unit?: string|null): BoundStylingEntry|null { + suffix?: string|null): BoundStylingEntry|null { if (isEmptyExpression(value)) { return null; } name = normalizePropName(name); - const {property, hasOverrideFlag, unit: bindingUnit} = parseProperty(name); - const entry: BoundStylingEntry = { - name: property, - sanitize: property ? isStyleSanitizable(property) : true, - unit: unit || bindingUnit, - value, - sourceSpan, - hasOverrideFlag - }; + const {property, hasOverrideFlag, suffix: bindingSuffix} = parseProperty(name); + suffix = typeof suffix === 'string' && suffix.length !== 0 ? suffix : bindingSuffix; + const entry: + BoundStylingEntry = {name: property, suffix: suffix, value, sourceSpan, hasOverrideFlag}; if (isMapBased) { this._styleMapInput = entry; } else { @@ -250,8 +243,8 @@ export class StylingBuilder { return null; } const {property, hasOverrideFlag} = parseProperty(name); - const entry: BoundStylingEntry = - {name: property, value, sourceSpan, sanitize: false, hasOverrideFlag, unit: null}; + const entry: + BoundStylingEntry = {name: property, value, sourceSpan, hasOverrideFlag, suffix: null}; if (isMapBased) { if (this._classMapInput) { throw new Error( @@ -430,7 +423,7 @@ export class StylingBuilder { allocateBindingSlots: totalBindingSlotsRequired, supportsInterpolation: !!getInterpolationExpressionFn, params: (convertFn: (value: any) => o.Expression | o.Expression[]) => { - // params => stylingProp(propName, value, suffix|sanitizer) + // params => stylingProp(propName, value, suffix) const params: o.Expression[] = []; params.push(o.literal(input.name)); @@ -441,16 +434,10 @@ export class StylingBuilder { params.push(convertResult); } - // [style.prop] bindings may use suffix values (e.g. px, em, etc...) and they - // can also use a sanitizer. Sanitization occurs for url-based entries. Having - // the suffix value and a sanitizer together into the instruction doesn't make - // any sense (url-based entries cannot be sanitized). - if (!isClassBased) { - if (input.unit) { - params.push(o.literal(input.unit)); - } else if (input.sanitize) { - params.push(o.importExpr(R3.defaultStyleSanitizer)); - } + // [style.prop] bindings may use suffix values (e.g. px, em, etc...), therefore, + // if that is detected then we need to pass that in as an optional param. + if (!isClassBased && input.suffix !== null) { + params.push(o.literal(input.suffix)); } return params; @@ -517,27 +504,8 @@ function registerIntoMap(map: Map, key: string) { } } -function isStyleSanitizable(prop: string): boolean { - // Note that browsers support both the dash case and - // camel case property names when setting through JS. - return prop === 'background-image' || prop === 'backgroundImage' || prop === 'background' || - prop === 'border-image' || prop === 'borderImage' || prop === 'border-image-source' || - prop === 'borderImageSource' || prop === 'filter' || prop === 'list-style' || - prop === 'listStyle' || prop === 'list-style-image' || prop === 'listStyleImage' || - prop === 'clip-path' || prop === 'clipPath'; -} - -/** - * Simple helper function to either provide the constant literal that will house the value - * here or a null value if the provided values are empty. - */ -function getConstantLiteralFromArray( - constantPool: ConstantPool, values: o.Expression[]): o.Expression { - return values.length ? constantPool.getConstLiteral(o.literalArr(values), true) : o.NULL_EXPR; -} - export function parseProperty(name: string): - {property: string, unit: string, hasOverrideFlag: boolean} { + {property: string, suffix: string|null, hasOverrideFlag: boolean} { let hasOverrideFlag = false; const overrideIndex = name.indexOf(IMPORTANT_FLAG); if (overrideIndex !== -1) { @@ -545,15 +513,15 @@ export function parseProperty(name: string): hasOverrideFlag = true; } - let unit = ''; + let suffix: string|null = null; let property = name; const unitIndex = name.lastIndexOf('.'); if (unitIndex > 0) { - unit = name.substr(unitIndex + 1); + suffix = name.substr(unitIndex + 1); property = name.substring(0, unitIndex); } - return {property, unit, hasOverrideFlag}; + return {property, suffix, hasOverrideFlag}; } /** diff --git a/packages/core/src/core_render3_private_export.ts b/packages/core/src/core_render3_private_export.ts index 5854e66094..cc7d4c0171 100644 --- a/packages/core/src/core_render3_private_export.ts +++ b/packages/core/src/core_render3_private_export.ts @@ -227,7 +227,6 @@ export { ɵɵstylePropInterpolate7, ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, - ɵɵstyleSanitizer, ɵɵtemplate, ɵɵtemplateRefExtractor, ɵɵtext, @@ -286,7 +285,6 @@ export { bypassSanitizationTrustUrl as ɵbypassSanitizationTrustUrl, } from './sanitization/bypass'; export { - ɵɵdefaultStyleSanitizer, ɵɵsanitizeHtml, ɵɵsanitizeResourceUrl, ɵɵsanitizeScript, diff --git a/packages/core/src/render3/index.ts b/packages/core/src/render3/index.ts index 34854caa2f..4663f3f4b3 100644 --- a/packages/core/src/render3/index.ts +++ b/packages/core/src/render3/index.ts @@ -113,7 +113,6 @@ export { ɵɵstylePropInterpolate8, ɵɵstylePropInterpolateV, - ɵɵstyleSanitizer, ɵɵtemplate, ɵɵtext, diff --git a/packages/core/src/render3/instructions/attribute.ts b/packages/core/src/render3/instructions/attribute.ts index 380eec1ba2..903399fd6b 100644 --- a/packages/core/src/render3/instructions/attribute.ts +++ b/packages/core/src/render3/instructions/attribute.ts @@ -7,7 +7,7 @@ */ import {bindingUpdated} from '../bindings'; import {SanitizerFn} from '../interfaces/sanitization'; -import {getLView, getSelectedIndex, getSelectedTNode, getTView, nextBindingIndex} from '../state'; +import {getLView, getSelectedTNode, getTView, nextBindingIndex} from '../state'; import {elementAttributeInternal, storePropertyBindingMetadata} from './shared'; diff --git a/packages/core/src/render3/instructions/styling.ts b/packages/core/src/render3/instructions/styling.ts index 3d6f09321e..9534975240 100644 --- a/packages/core/src/render3/instructions/styling.ts +++ b/packages/core/src/render3/instructions/styling.ts @@ -7,8 +7,6 @@ */ import {SafeValue, unwrapSafeValue} from '../../sanitization/bypass'; -import {stylePropNeedsSanitization, ɵɵsanitizeStyle} from '../../sanitization/sanitization'; -import {StyleSanitizeFn} from '../../sanitization/style_sanitizer'; import {KeyValueArray, keyValueArrayGet, keyValueArraySet} from '../../util/array_utils'; import {assertDefined, assertEqual, assertLessThan, assertNotEqual, throwError} from '../../util/assert'; import {EMPTY_ARRAY} from '../../util/empty'; @@ -18,11 +16,10 @@ import {bindingUpdated} from '../bindings'; import {DirectiveDef} from '../interfaces/definition'; import {AttributeMarker, TAttributes, TNode, TNodeFlags, TNodeType} from '../interfaces/node'; import {RElement, Renderer3} from '../interfaces/renderer'; -import {SanitizerFn} from '../interfaces/sanitization'; import {getTStylingRangeNext, getTStylingRangeNextDuplicate, getTStylingRangePrev, getTStylingRangePrevDuplicate, TStylingKey, TStylingRange} from '../interfaces/styling'; import {HEADER_OFFSET, LView, RENDERER, TData, TView} from '../interfaces/view'; import {applyStyling} from '../node_manipulation'; -import {getCurrentDirectiveDef, getCurrentStyleSanitizer, getLView, getSelectedIndex, getTView, incrementBindingIndex, setCurrentStyleSanitizer} from '../state'; +import {getCurrentDirectiveDef, getLView, getSelectedIndex, getTView, incrementBindingIndex} from '../state'; import {insertTStylingBinding} from '../styling/style_binding_list'; import {getLastParsedKey, getLastParsedValue, parseClassName, parseClassNameNext, parseStyle, parseStyleNext} from '../styling/styling_parser'; import {NO_CHANGE} from '../tokens'; @@ -31,26 +28,6 @@ import {getNativeByIndex} from '../util/view_utils'; import {setDirectiveInputsWhichShadowsStyling} from './property'; -/** - * Sets the current style sanitizer function which will then be used - * within all follow-up prop and map-based style binding instructions - * for the given element. - * - * Note that once styling has been applied to the element (i.e. once - * `advance(n)` is executed or the hostBindings/template function exits) - * then the active `sanitizerFn` will be set to `null`. This means that - * once styling is applied to another element then a another call to - * `styleSanitizer` will need to be made. - * - * @param sanitizerFn The sanitization function that will be used to - * process style prop/value entries. - * - * @codeGenApi - */ -export function ɵɵstyleSanitizer(sanitizer: StyleSanitizeFn|null): void { - setCurrentStyleSanitizer(sanitizer); -} - /** * Update a style binding on an element with the provided value. * @@ -64,8 +41,6 @@ export function ɵɵstyleSanitizer(sanitizer: StyleSanitizeFn|null): void { * @param prop A valid CSS property. * @param value New value to write (`null` or an empty string to remove). * @param suffix Optional suffix. Used with scalar values to add unit such as `px`. - * Note that when a suffix is provided then the underlying sanitizer will - * be ignored. * * Note that this will apply the provided style value to the host element if this function is called * within a host binding function. @@ -183,11 +158,11 @@ export function classStringParser(keyValueArray: KeyValueArray, text: strin * * @param prop property name. * @param value binding value. - * @param suffixOrSanitizer suffix or sanitization function + * @param suffix suffix for the property (e.g. `em` or `px`) * @param isClassBased `true` if `class` change (`false` if `style`) */ export function checkStylingProperty( - prop: string, value: any|NO_CHANGE, suffixOrSanitizer: SanitizerFn|string|undefined|null, + prop: string, value: any|NO_CHANGE, suffix: string|undefined|null, isClassBased: boolean): void { const lView = getLView(); const tView = getTView(); @@ -199,19 +174,10 @@ export function checkStylingProperty( stylingFirstUpdatePass(tView, prop, bindingIndex, isClassBased); } if (value !== NO_CHANGE && bindingUpdated(lView, bindingIndex, value)) { - // This is a work around. Once PR#34480 lands the sanitizer is passed explicitly and this line - // can be removed. - let styleSanitizer: StyleSanitizeFn|null; - if (suffixOrSanitizer == null) { - if (styleSanitizer = getCurrentStyleSanitizer()) { - suffixOrSanitizer = styleSanitizer as any; - } - } const tNode = tView.data[getSelectedIndex() + HEADER_OFFSET] as TNode; updateStyling( tView, tNode, lView, lView[RENDERER], prop, - lView[bindingIndex + 1] = normalizeAndApplySuffixOrSanitizer(value, suffixOrSanitizer), - isClassBased, bindingIndex); + lView[bindingIndex + 1] = normalizeSuffix(value, suffix), isClassBased, bindingIndex); } } @@ -219,9 +185,7 @@ export function checkStylingProperty( * Common code between `ɵɵclassMap` and `ɵɵstyleMap`. * * @param keyValueArraySet (See `keyValueArraySet` in "util/array_utils") Gets passed in as a - * function so that - * `style` can pass in version which does sanitization. This is done for tree shaking - * purposes. + * function so that `style` can be processed. This is done for tree shaking purposes. * @param stringParser Parser used to parse `value` if `string`. (Passed in as `style` and `class` * have different parsers.) * @param value bound value from application @@ -605,9 +569,8 @@ function collectStylingFromTAttrs( * keep additional `Map` to keep track of duplicates or items which have not yet been visited. * * @param keyValueArraySet (See `keyValueArraySet` in "util/array_utils") Gets passed in as a - * function so that - * `style` can pass in version which does sanitization. This is done for tree shaking - * purposes. + * function so that `style` can be processed. This is done + * for tree shaking purposes. * @param stringParser The parser is passed in so that it will be tree shakable. See * `styleStringParser` and `classStringParser` * @param value The value to parse/convert to `KeyValueArray` @@ -639,19 +602,16 @@ export function toStylingKeyValueArray( } /** - * Set a `value` for a `key` taking style sanitization into account. + * Set a `value` for a `key`. * * See: `keyValueArraySet` for details * * @param keyValueArray KeyValueArray to add to. - * @param key Style key to add. (This key will be checked if it needs sanitization) - * @param value The value to set (If key needs sanitization it will be sanitized) + * @param key Style key to add. + * @param value The value to set. */ export function styleKeyValueArraySet(keyValueArray: KeyValueArray, key: string, value: any) { - if (stylePropNeedsSanitization(key)) { - value = ɵɵsanitizeStyle(value); - } - keyValueArraySet(keyValueArray, key, value); + keyValueArraySet(keyValueArray, key, unwrapSafeValue(value)); } /** @@ -784,10 +744,7 @@ function updateStyling( * NOTE: The styling stores two values. * 1. The raw value which came from the application is stored at `index + 0` location. (This value * is used for dirty checking). - * 2. The normalized value (converted to `KeyValueArray` if map and sanitized) is stored at `index + - * 1`. - * The advantage of storing the sanitized value is that once the value is written we don't need - * to worry about sanitizing it later or keeping track of the sanitizer. + * 2. The normalized value is stored at `index + 1`. * * @param tData `TData` used for traversing the priority. * @param tNode `TNode` to use for resolving static styling. Also controls search direction. @@ -867,22 +824,17 @@ function isStylingValuePresent(value: any): boolean { } /** - * Sanitizes or adds suffix to the value. + * Normalizes and/or adds a suffix to the value. * * If value is `null`/`undefined` no suffix is added * @param value - * @param suffixOrSanitizer + * @param suffix */ -function normalizeAndApplySuffixOrSanitizer( - value: any, suffixOrSanitizer: SanitizerFn|string|undefined|null): string|null|undefined| - boolean { +function normalizeSuffix(value: any, suffix: string|undefined|null): string|null|undefined|boolean { if (value == null /** || value === undefined */) { // do nothing - } else if (typeof suffixOrSanitizer === 'function') { - // sanitize the value. - value = suffixOrSanitizer(value); - } else if (typeof suffixOrSanitizer === 'string') { - value = value + suffixOrSanitizer; + } else if (typeof suffix === 'string') { + value = value + suffix; } else if (typeof value === 'object') { value = stringify(unwrapSafeValue(value)); } diff --git a/packages/core/src/render3/jit/environment.ts b/packages/core/src/render3/jit/environment.ts index 11ae78c872..cea6b79dc8 100644 --- a/packages/core/src/render3/jit/environment.ts +++ b/packages/core/src/render3/jit/environment.ts @@ -133,7 +133,6 @@ export const angularCoreEnv: {[name: string]: Function} = 'ɵɵstylePropInterpolate7': r3.ɵɵstylePropInterpolate7, 'ɵɵstylePropInterpolate8': r3.ɵɵstylePropInterpolate8, 'ɵɵstylePropInterpolateV': r3.ɵɵstylePropInterpolateV, - 'ɵɵstyleSanitizer': r3.ɵɵstyleSanitizer, 'ɵɵclassProp': r3.ɵɵclassProp, 'ɵɵselect': r3.ɵɵselect, 'ɵɵadvance': r3.ɵɵadvance, @@ -164,7 +163,6 @@ export const angularCoreEnv: {[name: string]: Function} = 'ɵɵsanitizeHtml': sanitization.ɵɵsanitizeHtml, 'ɵɵsanitizeStyle': sanitization.ɵɵsanitizeStyle, - 'ɵɵdefaultStyleSanitizer': sanitization.ɵɵdefaultStyleSanitizer, 'ɵɵsanitizeResourceUrl': sanitization.ɵɵsanitizeResourceUrl, 'ɵɵsanitizeScript': sanitization.ɵɵsanitizeScript, 'ɵɵsanitizeUrl': sanitization.ɵɵsanitizeUrl, diff --git a/packages/core/src/render3/state.ts b/packages/core/src/render3/state.ts index 8d8a7d66a8..d892d7c632 100644 --- a/packages/core/src/render3/state.ts +++ b/packages/core/src/render3/state.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import {StyleSanitizeFn} from '../sanitization/style_sanitizer'; import {assertDefined, assertEqual} from '../util/assert'; import {assertLViewOrUndefined} from './assert'; import {DirectiveDef} from './interfaces/definition'; @@ -97,11 +96,6 @@ interface LFrame { */ currentNamespace: string|null; - /** - * Current sanitizer - */ - currentSanitizer: StyleSanitizeFn|null; - /** * The root index from which pure function instructions should calculate their binding @@ -421,7 +415,6 @@ export function enterView(newView: LView, tNode: TNode|null): void { assertEqual(newLFrame.elementDepthCount, 0, 'Expected clean LFrame'); assertEqual(newLFrame.currentDirectiveIndex, -1, 'Expected clean LFrame'); assertEqual(newLFrame.currentNamespace, null, 'Expected clean LFrame'); - assertEqual(newLFrame.currentSanitizer, null, 'Expected clean LFrame'); assertEqual(newLFrame.bindingRootIndex, -1, 'Expected clean LFrame'); assertEqual(newLFrame.currentQueryIndex, 0, 'Expected clean LFrame'); } @@ -454,7 +447,6 @@ function createLFrame(parent: LFrame|null): LFrame { contextLView: null!, // elementDepthCount: 0, // currentNamespace: null, // - currentSanitizer: null, // currentDirectiveIndex: -1, // bindingRootIndex: -1, // bindingIndex: -1, // @@ -508,7 +500,6 @@ export function leaveView() { oldLFrame.elementDepthCount = 0; oldLFrame.currentDirectiveIndex = -1; oldLFrame.currentNamespace = null; - oldLFrame.currentSanitizer = null; oldLFrame.bindingRootIndex = -1; oldLFrame.bindingIndex = -1; oldLFrame.currentQueryIndex = 0; @@ -602,18 +593,3 @@ export function namespaceHTMLInternal() { export function getNamespace(): string|null { return instructionState.lFrame.currentNamespace; } - -export function setCurrentStyleSanitizer(sanitizer: StyleSanitizeFn|null) { - instructionState.lFrame.currentSanitizer = sanitizer; -} - -export function resetCurrentStyleSanitizer() { - setCurrentStyleSanitizer(null); -} - -export function getCurrentStyleSanitizer() { - // TODO(misko): This should throw when there is no LView, but it turns out we can get here from - // `NodeStyleDebug` hence we return `null`. This should be fixed - const lFrame = instructionState.lFrame; - return lFrame === null ? null : lFrame.currentSanitizer; -} diff --git a/packages/core/src/sanitization/sanitization.ts b/packages/core/src/sanitization/sanitization.ts index 65246196e0..cb2f98eab1 100644 --- a/packages/core/src/sanitization/sanitization.ts +++ b/packages/core/src/sanitization/sanitization.ts @@ -15,7 +15,6 @@ import {allowSanitizationBypassAndThrow, BypassType, unwrapSafeValue} from './by import {_sanitizeHtml as _sanitizeHtml} from './html_sanitizer'; import {Sanitizer} from './sanitizer'; import {SecurityContext} from './security'; -import {StyleSanitizeFn, StyleSanitizeMode} from './style_sanitizer'; import {_sanitizeUrl as _sanitizeUrl} from './url_sanitizer'; @@ -176,47 +175,6 @@ export function ɵɵsanitizeUrlOrResourceUrl(unsafeUrl: any, tag: string, prop: return getUrlSanitizer(tag, prop)(unsafeUrl); } -/** - * The default style sanitizer will handle sanitization for style properties. - * - * Style sanitization is no longer apart of Angular because modern browsers no - * longer support javascript expressions. Therefore, the reason why this API - * exists is exclusively for unwrapping any style value expressions that were - * marked as `SafeValue` values. - * - * This API will be removed in a future release of Angular. - * - * @publicApi - */ -export const ɵɵdefaultStyleSanitizer = - (function(prop: string, value: string|null, mode?: StyleSanitizeMode): string|boolean|null { - if (value === undefined && mode === undefined) { - // This is a workaround for the fact that `StyleSanitizeFn` should not exist once PR#34480 - // lands. For now the `StyleSanitizeFn` and should act like `(value: any) => string` as a - // work around. - return ɵɵsanitizeStyle(prop); - } - mode = mode || StyleSanitizeMode.ValidateAndSanitize; - let doSanitizeValue = true; - if (mode & StyleSanitizeMode.ValidateProperty) { - doSanitizeValue = stylePropNeedsSanitization(prop); - } - - if (mode & StyleSanitizeMode.SanitizeOnly) { - return doSanitizeValue ? ɵɵsanitizeStyle(value) : unwrapSafeValue(value); - } else { - return doSanitizeValue; - } - } as StyleSanitizeFn); - -export function stylePropNeedsSanitization(prop: string): boolean { - return prop === 'background-image' || prop === 'backgroundImage' || prop === 'background' || - prop === 'border-image' || prop === 'borderImage' || prop === 'border-image-source' || - prop === 'borderImageSource' || prop === 'filter' || prop === 'list-style' || - prop === 'listStyle' || prop === 'list-style-image' || prop === 'listStyleImage' || - prop === 'clip-path' || prop === 'clipPath'; -} - export function validateAgainstEventProperties(name: string) { if (name.toLowerCase().startsWith('on')) { const msg = `Binding to event property '${name}' is disallowed for security reasons, ` + diff --git a/packages/core/src/sanitization/style_sanitizer.ts b/packages/core/src/sanitization/style_sanitizer.ts deleted file mode 100644 index 2217a7ce6f..0000000000 --- a/packages/core/src/sanitization/style_sanitizer.ts +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ -import {SafeValue} from './bypass'; - -/* - * ========== WARNING ========== - * - * Style sanitization in Angular (for `[style.prop]` and `[style]` bindings) - * is no longer required and has been removed. The reason why this feature - * has been removed is because style-based sanitization is no longer - * required with modern browsers. - * - * The contents of this file are still in flux. Various APIs and symbols will - * be removed in a future version of Angular. Please hold off from modifying this - * file for the time being. - * - * ============================= - */ - -/** - * A series of flags to instruct a style sanitizer to either validate - * or sanitize a value. - * - * Because sanitization is dependent on the style property (i.e. style - * sanitization for `width` is much different than for `background-image`) - * the sanitization function (e.g. `StyleSanitizerFn`) needs to check a - * property value first before it actually sanitizes any values. - * - * This enum exist to allow a style sanitization function to either only - * do validation (check the property to see whether a value will be - * sanitized or not) or to sanitize the value (or both). - * - * @publicApi - */ -export const enum StyleSanitizeMode { - /** Just check to see if the property is required to be sanitized or not */ - ValidateProperty = 0b01, - /** Skip checking the property; just sanitize the value */ - SanitizeOnly = 0b10, - /** Check the property and (if true) then sanitize the value */ - ValidateAndSanitize = 0b11, -} - -/** - * Used to intercept and sanitize style values before they are written to the renderer. - * - * This function is designed to be called in two modes. When a value is not provided - * then the function will return a boolean whether a property will be sanitized later. - * If a value is provided then the sanitized version of that will be returned. - */ -export interface StyleSanitizeFn { - (prop: string, value: string|SafeValue|null, mode?: StyleSanitizeMode): any; -} diff --git a/packages/core/test/acceptance/styling_spec.ts b/packages/core/test/acceptance/styling_spec.ts index 72f06e9c18..47b39072e4 100644 --- a/packages/core/test/acceptance/styling_spec.ts +++ b/packages/core/test/acceptance/styling_spec.ts @@ -1880,7 +1880,7 @@ describe('styling', () => { }); onlyInIvy('only ivy has [style.prop] support') - .it('should sanitize style values before writing them', () => { + .it('should not sanitize style values before writing them', () => { @Component({ template: `
{ }); onlyInIvy('only ivy has [style] support') - .it('should sanitize style values before writing them', () => { + .it('should not sanitize style values before writing them', () => { @Component({ template: `
{ return createDiv(); }, () => { - ɵɵstyleSanitizer(ɵɵdefaultStyleSanitizer); ɵɵstyleProp('background-image', backgroundImage); }, 2, 2); @@ -199,35 +198,6 @@ describe('instructions', () => { fixture.update(); expect(fixture.html).toEqual('
'); }); - - it('should sanitize new styles that may contain `url` properties', () => { - const detectedValues: string[] = []; - const sanitizerInterceptor = new MockSanitizerInterceptor(value => { - detectedValues.push(value); - }); - const fixture = new TemplateFixture( - () => { - return createDiv(); - }, // - () => { - ɵɵstyleSanitizer(sanitizerInterceptor.getStyleSanitizer()); - ɵɵstyleMap({ - 'background-image': 'background-image', - 'background': 'background', - 'border-image': 'border-image', - 'list-style': 'list-style', - 'list-style-image': 'list-style-image', - 'filter': 'filter', - 'width': 'width' - }); - }, - 1, 2, null, null, sanitizerInterceptor); - - const props = detectedValues.sort(); - expect(props).toEqual([ - 'background', 'background-image', 'border-image', 'filter', 'list-style', 'list-style-image' - ]); - }); }); describe('elementClass', () => { @@ -559,9 +529,6 @@ class LocalMockSanitizer implements Sanitizer { class MockSanitizerInterceptor { public lastValue: string|null = null; constructor(private _interceptorFn?: ((value: any) => any)|null) {} - getStyleSanitizer() { - return ɵɵdefaultStyleSanitizer; - } sanitize(context: SecurityContext, value: LocalSanitizedValue|string|null|any): string|null { if (this._interceptorFn) { this._interceptorFn(value);