refactor(ivy): Implement computeStaticStyling (#34418)

The `computeStaticStyling` will be used for computing static styling value during `firstCreatePass`.

The function takes into account static styling from the template as well as from the host bindings. The host bindings need to be merged in front of the template so that they have the correct priority.

PR Closes #34418
This commit is contained in:
Misko Hevery
2019-12-15 21:09:02 -08:00
committed by Miško Hevery
parent 6b20883c84
commit 904363528f
13 changed files with 179 additions and 38 deletions

View File

@ -0,0 +1,49 @@
/**
* @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 {createTNode} from '@angular/core/src/render3/instructions/shared';
import {AttributeMarker, TAttributes, TNode, TNodeType} from '@angular/core/src/render3/interfaces/node';
import {LView} from '@angular/core/src/render3/interfaces/view';
import {enterView} from '@angular/core/src/render3/state';
import {computeStaticStyling} from '@angular/core/src/render3/styling/static_styling';
describe('static styling', () => {
const mockFirstCreatePassLView: LView = [null, {firstCreatePass: true}] as any;
let tNode !: TNode;
beforeEach(() => {
enterView(mockFirstCreatePassLView, null);
tNode = createTNode(null !, null !, TNodeType.Element, 0, '', null);
});
it('should initialize when no attrs', () => {
computeStaticStyling(tNode, []);
expect(tNode.classes).toEqual(null);
expect(tNode.styles).toEqual(null);
});
it('should initialize from attrs', () => {
const tAttrs: TAttributes = [
'ignore', //
AttributeMarker.Classes, 'my-class', //
AttributeMarker.Styles, 'color', 'red' //
];
computeStaticStyling(tNode, tAttrs);
expect(tNode.classes).toEqual('my-class');
expect(tNode.styles).toEqual('color: red;');
});
it('should initialize from attrs when multiple', () => {
const tAttrs: TAttributes = [
'ignore', //
AttributeMarker.Classes, 'my-class', 'other', //
AttributeMarker.Styles, 'color', 'red', 'width', '100px' //
];
computeStaticStyling(tNode, tAttrs);
expect(tNode.classes).toEqual('my-class other');
expect(tNode.styles).toEqual('color: red; width: 100px;');
});
});

View File

@ -115,6 +115,7 @@ describe('TNode styling linked list', () => {
// ɵɵstyleProp('color', '#008'); // Binding index: 30
const tNode = createTNode(null !, null !, TNodeType.Element, 0, '', null);
tNode.styles = '';
const tData: TData = newArray(32, null);
const STYLE = STYLE_MAP_STYLING_KEY;
@ -408,7 +409,7 @@ describe('TNode styling linked list', () => {
it('should mark duplicate on static fields', () => {
const tNode = createTNode(null !, null !, TNodeType.Element, 0, '', null);
tNode.styles = [null, 'color', 'blue'];
tNode.styles = 'color: blue;';
const tData: TData = [null, null];
insertTStylingBinding(tData, tNode, 'width', 2, false, false);
expectPriorityOrder(tData, tNode, false).toEqual([
@ -636,6 +637,8 @@ class StylingFixture {
lView: LView = [null, null !] as any;
tNode: TNode = createTNode(null !, null !, TNodeType.Element, 0, '', null);
constructor(bindingSources: TStylingKey[][], public isClassBinding: boolean) {
this.tNode.classes = '';
this.tNode.styles = '';
let bindingIndex = this.tData.length;
for (let i = 0; i < bindingSources.length; i++) {
const bindings = bindingSources[i];

View File

@ -0,0 +1,27 @@
/**
* @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 {concatStringsWithSpace} from '@angular/core/src/util/stringify';
describe('stringify', () => {
describe('concatStringsWithSpace', () => {
it('should concat with null', () => {
expect(concatStringsWithSpace(null, null)).toEqual('');
expect(concatStringsWithSpace('a', null)).toEqual('a');
expect(concatStringsWithSpace(null, 'b')).toEqual('b');
});
it('should concat when empty', () => {
expect(concatStringsWithSpace('', '')).toEqual('');
expect(concatStringsWithSpace('a', '')).toEqual('a');
expect(concatStringsWithSpace('', 'b')).toEqual('b');
});
it('should concat when not empty',
() => { expect(concatStringsWithSpace('before', 'after')).toEqual('before after'); });
});
});