angular/packages/compiler/test/render3/style_parser_spec.ts
Alan Agius 1829542aea fix(compiler): do not unquote CSS values (#49460)
Currently we are unsafely unquoting CSS values which in some cases causes valid values to become invalid and invalid values to become valid.

Example:
```html
<div style="width:&quot;1px;&quot;"></div>
```

In the above case, `width` has an invalid value of `"1px"`, however the compiler will transform it to `1px` which makes it valid.

On the other hand,  in the below case
```html
<div style="content:&quot;foo&quot;"></div>
```

`content` has a valid value of `"foo"`, but since the compiler unwraps it to `foo` it becomes invalid. For correctness, we should not remove quotes.

```js
const div = document.createElement('div');
div.style.width='"1px"';
div.style.content='foo';

div.style.width; // ''
div.style.content; // ''

div.style.width='1px';
div.style.content='"foo"';

div.style.width; // '1px'
div.style.content; // '"foo"'
```

More information about values can be found https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier

PR Close #49460
2023-03-28 11:35:38 -07:00

83 lines
3.1 KiB
TypeScript

/**
* @license
* Copyright Google LLC 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 {hyphenate, parse as parseStyle} from '../../src/render3/view/style_parser';
describe('style parsing', () => {
it('should parse empty or blank strings', () => {
const result1 = parseStyle('');
expect(result1).toEqual([]);
const result2 = parseStyle(' ');
expect(result2).toEqual([]);
});
it('should parse a string into a key/value map', () => {
const result = parseStyle('width:100px;height:200px;opacity:0');
expect(result).toEqual(['width', '100px', 'height', '200px', 'opacity', '0']);
});
it('should allow empty values', () => {
const result = parseStyle('width:;height: ;');
expect(result).toEqual(['width', '', 'height', '']);
});
it('should trim values and properties', () => {
const result = parseStyle('width :333px ; height:666px ; opacity: 0.5;');
expect(result).toEqual(['width', '333px', 'height', '666px', 'opacity', '0.5']);
});
it('should not mess up with quoted strings that contain [:;] values', () => {
const result = parseStyle('content: "foo; man: guy"; width: 100px');
expect(result).toEqual(['content', '"foo; man: guy"', 'width', '100px']);
});
it('should not mess up with quoted strings that contain inner quote values', () => {
const quoteStr = '"one \'two\' three \"four\" five"';
const result = parseStyle(`content: ${quoteStr}; width: 123px`);
expect(result).toEqual(['content', quoteStr, 'width', '123px']);
});
it('should respect parenthesis that are placed within a style', () => {
const result = parseStyle('background-image: url("foo.jpg")');
expect(result).toEqual(['background-image', 'url("foo.jpg")']);
});
it('should respect multi-level parenthesis that contain special [:;] characters', () => {
const result = parseStyle('color: rgba(calc(50 * 4), var(--cool), :5;); height: 100px;');
expect(result).toEqual(['color', 'rgba(calc(50 * 4), var(--cool), :5;)', 'height', '100px']);
});
it('should hyphenate style properties from camel case', () => {
const result = parseStyle('borderWidth: 200px');
expect(result).toEqual(['border-width', '200px']);
});
describe('should not remove quotes', () => {
it('from string data types', () => {
const result = parseStyle('content: "foo"');
expect(result).toEqual(['content', '"foo"']);
});
it('that changes the value context from invalid to valid', () => {
const result = parseStyle('width: "1px"');
expect(result).toEqual(['width', '"1px"']);
});
});
describe('camelCasing => hyphenation', () => {
it('should convert a camel-cased value to a hyphenated value', () => {
expect(hyphenate('fooBar')).toEqual('foo-bar');
expect(hyphenate('fooBarMan')).toEqual('foo-bar-man');
expect(hyphenate('-fooBar-man')).toEqual('-foo-bar-man');
});
it('should make everything lowercase', () => {
expect(hyphenate('-WebkitAnimation')).toEqual('-webkit-animation');
});
});
});