feat(ivy): provide groundwork for animations in core (#25234)

PR Close #25234
This commit is contained in:
Matias Niemelä
2018-08-28 16:49:52 -07:00
committed by Kara Erickson
parent a880686081
commit 82a14dc107
24 changed files with 2379 additions and 267 deletions

View File

@ -0,0 +1,60 @@
/**
* @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 {CorePlayerHandler} from '../../../src/render3/animations/core_player_handler';
import {PlayState} from '../../../src/render3/animations/interfaces';
import {MockPlayer} from './mock_player';
describe('CorePlayerHandler', () => {
it('should kick off any animation players that have been queued once flushed', () => {
const handler = new CorePlayerHandler();
const p1 = new MockPlayer();
const p2 = new MockPlayer();
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Pending);
handler.queuePlayer(p1);
handler.queuePlayer(p2);
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Pending);
handler.flushPlayers();
expect(p1.state).toEqual(PlayState.Running);
expect(p2.state).toEqual(PlayState.Running);
});
it('should only kick off animation players that have not been adopted by a parent player once flushed',
() => {
const handler = new CorePlayerHandler();
const pRoot = new MockPlayer();
const p1 = new MockPlayer();
const p2 = new MockPlayer();
expect(pRoot.state).toEqual(PlayState.Pending);
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Pending);
handler.queuePlayer(pRoot);
handler.queuePlayer(p1);
handler.queuePlayer(p2);
expect(pRoot.state).toEqual(PlayState.Pending);
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Pending);
p1.parent = pRoot;
handler.flushPlayers();
expect(pRoot.state).toEqual(PlayState.Running);
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Running);
});
});

View File

@ -0,0 +1,58 @@
/**
* @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 {PlayState, Player} from '../../../src/render3/animations/interfaces';
export class MockPlayer implements Player {
parent: Player|null = null;
log: string[] = [];
state: PlayState = PlayState.Pending;
private _listeners: {[state: string]: (() => any)[]} = {};
play(): void {
if (this.state === PlayState.Running) return;
this.state = PlayState.Running;
this._emit(PlayState.Running);
}
pause(): void {
if (this.state === PlayState.Paused) return;
this.state = PlayState.Paused;
this._emit(PlayState.Paused);
}
finish(): void {
if (this.state >= PlayState.Finished) return;
this.state = PlayState.Finished;
this._emit(PlayState.Finished);
}
destroy(): void {
if (this.state >= PlayState.Destroyed) return;
this.state = PlayState.Destroyed;
this._emit(PlayState.Destroyed);
}
addEventListener(state: PlayState|number, cb: () => any): void {
const key = state.toString();
const arr = this._listeners[key] || (this._listeners[key] = []);
arr.push(cb);
}
private _emit(state: PlayState) {
const callbacks = this._listeners[state] || [];
for (let i = 0; i < callbacks.length; i++) {
const cb = callbacks[i];
cb();
}
}
}

View File

@ -0,0 +1,311 @@
/**
* @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 {RenderFlags} from '@angular/core/src/render3';
import {AnimationContext, PlayState, Player, PlayerHandler} from '../../../src/render3/animations/interfaces';
import {addPlayer, getOrCreateAnimationContext, getPlayers} from '../../../src/render3/animations/players';
import {QUERY_READ_FROM_NODE, defineComponent, getHostElement} from '../../../src/render3/index';
import {element, elementEnd, elementStart, elementStyling, elementStylingApply, load, markDirty} from '../../../src/render3/instructions';
import {RElement} from '../../../src/render3/interfaces/renderer';
import {QueryList, query, queryRefresh} from '../../../src/render3/query';
import {ComponentFixture} from '../render_util';
import {MockPlayer} from './mock_player';
describe('animation player access', () => {
it('should add a player to the element', () => {
const element = buildElement();
expect(getPlayers(element)).toEqual([]);
const player = new MockPlayer();
addPlayer(element, player);
expect(getPlayers(element)).toEqual([player]);
});
it('should add a player to the component host element', () => {
const fixture = buildSuperComponent();
const superComp = fixture.component;
const component = superComp.query.first as Comp;
expect(component.name).toEqual('child-comp');
expect(getPlayers(component)).toEqual([]);
const player = new MockPlayer();
addPlayer(component, player);
expect(getPlayers(component)).toEqual([player]);
const hostElement = getHostElement(component);
expect(getPlayers(hostElement)).toEqual([player]);
});
it('should add a player to an element that already contains styling', () => {
const element = buildElementWithStyling();
expect(getPlayers(element)).toEqual([]);
const player = new MockPlayer();
addPlayer(element, player);
expect(getPlayers(element)).toEqual([player]);
});
it('should add a player to the element animation context and remove it once it completes', () => {
const element = buildElement();
const context = getOrCreateAnimationContext(element);
expect(context).toEqual([]);
const player = new MockPlayer();
addPlayer(element, player);
expect(readPlayers(context)).toEqual([player]);
player.destroy();
expect(readPlayers(context)).toEqual([]);
});
it('should flush all pending animation players after change detection', () => {
const fixture = buildComponent();
const element = fixture.hostElement.querySelector('div') !;
const player = new MockPlayer();
addPlayer(element, player);
expect(player.state).toEqual(PlayState.Pending);
fixture.update();
expect(player.state).toEqual(PlayState.Running);
});
it('should flush all animations in the given animation handler is apart of the component', () => {
const handler = new MockPlayerHandler();
const fixture = new ComponentFixture(Comp, {playerHandler: handler});
fixture.update();
const element = fixture.hostElement.querySelector('div') !;
const p1 = new MockPlayer();
const p2 = new MockPlayer();
addPlayer(element, p1);
addPlayer(element, p2);
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Pending);
fixture.update();
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Pending);
expect(handler.lastFlushedPlayers).toEqual([p1, p2]);
});
it('should only play animation players that are not associated with a parent player', () => {
const fixture = buildComponent();
const element = fixture.hostElement.querySelector('div') !;
const p1 = new MockPlayer();
const p2 = new MockPlayer();
const pParent = new MockPlayer();
p1.parent = pParent;
addPlayer(element, p1);
addPlayer(element, p2);
addPlayer(element, pParent);
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Pending);
expect(pParent.state).toEqual(PlayState.Pending);
fixture.update();
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Running);
expect(pParent.state).toEqual(PlayState.Running);
});
it('should not replay any previously queued players once change detection has run', () => {
const fixture = buildComponent();
const element = fixture.hostElement.querySelector('div') !;
const p1 = new MockPlayer();
const p2 = new MockPlayer();
const p3 = new MockPlayer();
addPlayer(element, p1);
addPlayer(element, p2);
expect(p1.state).toEqual(PlayState.Pending);
expect(p2.state).toEqual(PlayState.Pending);
expect(p3.state).toEqual(PlayState.Pending);
fixture.update();
expect(p1.state).toEqual(PlayState.Running);
expect(p2.state).toEqual(PlayState.Running);
expect(p3.state).toEqual(PlayState.Pending);
p1.pause();
p2.pause();
addPlayer(element, p3);
expect(p1.state).toEqual(PlayState.Paused);
expect(p2.state).toEqual(PlayState.Paused);
expect(p3.state).toEqual(PlayState.Pending);
fixture.update();
expect(p1.state).toEqual(PlayState.Paused);
expect(p2.state).toEqual(PlayState.Paused);
expect(p3.state).toEqual(PlayState.Running);
});
it('should not run change detection on a template if only players are being added', () => {
const fixture = buildComponent();
const element = fixture.hostElement.querySelector('div') !;
let dcCount = 0;
fixture.component.logger = () => { dcCount++; };
const p1 = new MockPlayer();
addPlayer(element, p1);
expect(p1.state).toEqual(PlayState.Pending);
expect(dcCount).toEqual(0);
fixture.requestAnimationFrame.flush();
expect(p1.state).toEqual(PlayState.Running);
expect(dcCount).toEqual(0);
const p2 = new MockPlayer();
addPlayer(element, p2);
markDirty(fixture.component);
expect(p2.state).toEqual(PlayState.Pending);
fixture.requestAnimationFrame.flush();
expect(p2.state).toEqual(PlayState.Running);
expect(p1.state).toEqual(PlayState.Running);
expect(dcCount).toEqual(1);
const p3 = new MockPlayer();
addPlayer(element, p3);
fixture.requestAnimationFrame.flush();
expect(p3.state).toEqual(PlayState.Running);
expect(p2.state).toEqual(PlayState.Running);
expect(p1.state).toEqual(PlayState.Running);
expect(dcCount).toEqual(1);
});
});
function buildElement() {
return buildComponent().hostElement.querySelector('div') as RElement;
}
function buildComponent() {
const fixture = new ComponentFixture(Comp);
fixture.update();
return fixture;
}
function buildSuperComponent() {
const fixture = new ComponentFixture(SuperComp);
fixture.update();
return fixture;
}
function buildElementWithStyling() {
const fixture = new ComponentFixture(CompWithStyling);
fixture.update();
return fixture.hostElement.querySelector('div') as RElement;
}
function readPlayers(context: AnimationContext): Player[] {
return context;
}
class Comp {
static ngComponentDef = defineComponent({
type: Comp,
exportAs: 'child',
selectors: [['child-comp']],
factory: () => new Comp(),
consts: 1,
vars: 0,
template: (rf: RenderFlags, ctx: Comp) => {
if (rf & RenderFlags.Create) {
element(0, 'div');
}
ctx.logger();
}
});
name = 'child-comp';
logger: () => any = () => {};
}
class CompWithStyling {
static ngComponentDef = defineComponent({
type: CompWithStyling,
exportAs: 'child-styled',
selectors: [['child-styled-comp']],
factory: () => new CompWithStyling(),
consts: 1,
vars: 0,
template: (rf: RenderFlags, ctx: CompWithStyling) => {
if (rf & RenderFlags.Create) {
elementStart(0, 'div');
elementStyling(['fooClass']);
elementEnd();
}
if (rf & RenderFlags.Update) {
elementStylingApply(0);
}
}
});
name = 'child-styled-comp';
}
class SuperComp {
static ngComponentDef = defineComponent({
type: SuperComp,
selectors: [['super-comp']],
factory: () => new SuperComp(),
consts: 3,
vars: 0,
template: (rf: RenderFlags, ctx: SuperComp) => {
if (rf & RenderFlags.Create) {
elementStart(1, 'div');
element(2, 'child-comp', ['child', ''], ['child', 'child']);
elementEnd();
}
},
viewQuery: function(rf: RenderFlags, ctx: SuperComp) {
if (rf & RenderFlags.Create) {
query(0, ['child'], true, QUERY_READ_FROM_NODE);
}
if (rf & RenderFlags.Update) {
let tmp: any;
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}
},
directives: [Comp]
});
name = 'super-comp';
query !: QueryList<any>;
}
class MockPlayerHandler implements PlayerHandler {
players: Player[] = [];
lastFlushedPlayers: Player[] = [];
flushPlayers(): void {
this.lastFlushedPlayers = [...this.players];
this.players = [];
}
queuePlayer(player: Player): void { this.players.push(player); }
}

View File

@ -9,6 +9,7 @@
import {stringifyElement} from '@angular/platform-browser/testing/src/browser_util';
import {Injector} from '../../src/di/injector';
import {PlayerHandler} from '../../src/render3/animations/interfaces';
import {CreateComponentOptions} from '../../src/render3/component';
import {getContext, isComponentInstance} from '../../src/render3/context_discovery';
import {extractDirectiveDef, extractPipeDef} from '../../src/render3/definition';
@ -103,9 +104,12 @@ export class ComponentFixture<T> extends BaseFixture {
component: T;
requestAnimationFrame: {(fn: () => void): void; flush(): void; queue: (() => void)[];};
constructor(
private componentType: ComponentType<T>,
opts: {injector?: Injector, sanitizer?: Sanitizer, rendererFactory?: RendererFactory3} = {}) {
constructor(private componentType: ComponentType<T>, opts: {
injector?: Injector,
sanitizer?: Sanitizer,
rendererFactory?: RendererFactory3,
playerHandler?: PlayerHandler
} = {}) {
super();
this.requestAnimationFrame = function(fn: () => void) {
requestAnimationFrame.queue.push(fn);
@ -122,7 +126,8 @@ export class ComponentFixture<T> extends BaseFixture {
scheduler: this.requestAnimationFrame,
injector: opts.injector,
sanitizer: opts.sanitizer,
rendererFactory: opts.rendererFactory || domRendererFactory3
rendererFactory: opts.rendererFactory || domRendererFactory3,
playerHandler: opts.playerHandler
});
}

View File

@ -109,7 +109,7 @@ describe('styling', () => {
describe('createStylingContextTemplate', () => {
it('should initialize empty template', () => {
const template = initContext();
expect(template).toEqual([element, null, [null], cleanStyle(0, 6), 0, null]);
expect(template).toEqual([element, null, null, [null], cleanStyle(0, 7), 0, null]);
});
it('should initialize static styles', () => {
@ -118,28 +118,29 @@ describe('styling', () => {
expect(template).toEqual([
element,
null,
null,
[null, 'red', '10px'],
dirtyStyle(0, 12), //
dirtyStyle(0, 13), //
0,
null,
// #6
cleanStyle(1, 12),
// #7
cleanStyle(1, 13),
'color',
null,
// #9
cleanStyle(2, 15),
// #10
cleanStyle(2, 16),
'width',
null,
// #12
dirtyStyle(1, 6),
// #13
dirtyStyle(1, 7),
'color',
null,
// #15
dirtyStyle(2, 9),
// #16
dirtyStyle(2, 10),
'width',
null,
]);
@ -320,28 +321,29 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 12), //
dirtyStyle(0, 13), //
2,
null,
// #6
cleanStyle(0, 12),
// #7
cleanStyle(0, 13),
'width',
null,
// #9
cleanStyle(0, 15),
// #10
cleanStyle(0, 16),
'height',
null,
// #12
dirtyStyle(0, 6),
// #13
dirtyStyle(0, 7),
'width',
'100px',
// #15
dirtyStyle(0, 9),
// #16
dirtyStyle(0, 10),
'height',
'100px',
]);
@ -352,33 +354,34 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 12), //
dirtyStyle(0, 13), //
2,
null,
// #6
cleanStyle(0, 12),
// #7
cleanStyle(0, 13),
'width',
null,
// #9
cleanStyle(0, 18),
// #10
cleanStyle(0, 19),
'height',
null,
// #12
dirtyStyle(0, 6),
// #13
dirtyStyle(0, 7),
'width',
'200px',
// #15
// #16
dirtyStyle(),
'opacity',
'0',
// #18
dirtyStyle(0, 9),
// #19
dirtyStyle(0, 10),
'height',
null,
]);
@ -387,33 +390,34 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
cleanStyle(0, 12), //
cleanStyle(0, 13), //
2,
null,
// #6
cleanStyle(0, 12),
// #7
cleanStyle(0, 13),
'width',
null,
// #9
cleanStyle(0, 18),
// #10
cleanStyle(0, 19),
'height',
null,
// #12
cleanStyle(0, 6),
// #13
cleanStyle(0, 7),
'width',
'200px',
// #15
// #16
cleanStyle(),
'opacity',
'0',
// #18
cleanStyle(0, 9),
// #19
cleanStyle(0, 10),
'height',
null,
]);
@ -424,33 +428,34 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 12), //
dirtyStyle(0, 13), //
2,
null,
// #6
dirtyStyle(0, 12),
// #7
dirtyStyle(0, 13),
'width',
'300px',
// #9
cleanStyle(0, 18),
// #10
cleanStyle(0, 19),
'height',
null,
// #12
cleanStyle(0, 6),
// #13
cleanStyle(0, 7),
'width',
null,
// #15
// #16
dirtyStyle(),
'opacity',
null,
// #18
cleanStyle(0, 9),
// #19
cleanStyle(0, 10),
'height',
null,
]);
@ -461,33 +466,34 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 12), //
dirtyStyle(0, 13), //
2,
null,
// #6
dirtyStyle(0, 12),
// #7
dirtyStyle(0, 13),
'width',
null,
// #9
cleanStyle(0, 18),
// #10
cleanStyle(0, 19),
'height',
null,
// #12
cleanStyle(0, 6),
// #13
cleanStyle(0, 7),
'width',
null,
// #15
// #16
cleanStyle(),
'opacity',
null,
// #18
cleanStyle(0, 9),
// #19
cleanStyle(0, 10),
'height',
null,
]);
@ -503,33 +509,34 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 9), //
dirtyStyle(0, 10), //
1,
null,
// #6
cleanStyle(0, 18),
// #7
cleanStyle(0, 19),
'lineHeight',
null,
// #9
// #10
dirtyStyle(),
'width',
'100px',
// #12
// #13
dirtyStyle(),
'height',
'100px',
// #15
// #16
dirtyStyle(),
'opacity',
'0.5',
// #18
cleanStyle(0, 6),
// #19
cleanStyle(0, 7),
'lineHeight',
null,
]);
@ -540,33 +547,34 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 9), //
dirtyStyle(0, 10), //
1,
null,
// #6
cleanStyle(0, 18),
// #7
cleanStyle(0, 19),
'lineHeight',
null,
// #9
// #10
dirtyStyle(),
'width',
null,
// #12
// #13
dirtyStyle(),
'height',
null,
// #15
// #16
dirtyStyle(),
'opacity',
null,
// #18
cleanStyle(0, 6),
// #19
cleanStyle(0, 7),
'lineHeight',
null,
]);
@ -579,38 +587,39 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 9), //
dirtyStyle(0, 10), //
1,
null,
// #6
cleanStyle(0, 21),
// #7
cleanStyle(0, 22),
'lineHeight',
null,
// #9
// #10
dirtyStyle(),
'borderWidth',
'5px',
// #12
// #13
cleanStyle(),
'width',
null,
// #15
// #16
cleanStyle(),
'height',
null,
// #18
// #19
cleanStyle(),
'opacity',
null,
// #21
cleanStyle(0, 6),
// #22
cleanStyle(0, 7),
'lineHeight',
null,
]);
@ -620,38 +629,39 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 9), //
dirtyStyle(0, 10), //
1,
null,
// #6
dirtyStyle(0, 21),
// #7
dirtyStyle(0, 22),
'lineHeight',
'200px',
// #9
// #10
dirtyStyle(),
'borderWidth',
'5px',
// #12
// #13
cleanStyle(),
'width',
null,
// #15
// #16
cleanStyle(),
'height',
null,
// #18
// #19
cleanStyle(),
'opacity',
null,
// #21
cleanStyle(0, 6),
// #22
cleanStyle(0, 7),
'lineHeight',
null,
]);
@ -661,43 +671,44 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 9), //
dirtyStyle(0, 10), //
1,
null,
// #6
dirtyStyle(0, 24),
// #7
dirtyStyle(0, 25),
'lineHeight',
'200px',
// #9
// #10
dirtyStyle(),
'borderWidth',
'15px',
// #12
// #13
dirtyStyle(),
'borderColor',
'red',
// #15
// #16
cleanStyle(),
'width',
null,
// #18
// #19
cleanStyle(),
'height',
null,
// #21
// #22
cleanStyle(),
'opacity',
null,
// #24
cleanStyle(0, 6),
// #25
cleanStyle(0, 7),
'lineHeight',
null,
]);
@ -716,23 +727,24 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
dirtyStyle(0, 9), //
dirtyStyle(0, 10), //
1,
null,
// #6
dirtyStyle(0, 12),
// #7
dirtyStyle(0, 13),
'height',
'200px',
// #6
// #7
dirtyStyle(),
'width',
'100px',
// #12
cleanStyle(0, 6),
// #13
cleanStyle(0, 7),
'height',
null,
]);
@ -742,23 +754,24 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null],
cleanStyle(0, 9), //
cleanStyle(0, 10), //
1,
null,
// #6
cleanStyle(0, 12),
// #7
cleanStyle(0, 13),
'height',
'200px',
// #6
// #7
cleanStyle(),
'width',
'100px',
// #12
cleanStyle(0, 6),
// #13
cleanStyle(0, 7),
'height',
null,
]);
@ -776,29 +789,30 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
styleSanitizer,
[null],
dirtyStyle(0, 12), //
dirtyStyle(0, 13), //
2,
null,
// #6
dirtyStyleWithSanitization(0, 12),
// #7
dirtyStyleWithSanitization(0, 13),
'border-image',
'url(foo.jpg)',
// #9
dirtyStyle(0, 15),
// #10
dirtyStyle(0, 16),
'border-width',
'100px',
// #12
cleanStyleWithSanitization(0, 6),
// #13
cleanStyleWithSanitization(0, 7),
'border-image',
null,
// #15
cleanStyle(0, 9),
// #16
cleanStyle(0, 10),
'border-width',
null,
]);
@ -807,34 +821,35 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
styleSanitizer,
[null],
dirtyStyle(0, 12), //
dirtyStyle(0, 13), //
2,
null,
// #6
dirtyStyleWithSanitization(0, 15),
// #7
dirtyStyleWithSanitization(0, 16),
'border-image',
'url(foo.jpg)',
// #9
dirtyStyle(0, 18),
// #10
dirtyStyle(0, 19),
'border-width',
'100px',
// #12
// #13
dirtyStyleWithSanitization(0, 0),
'background-image',
'unsafe',
// #15
cleanStyleWithSanitization(0, 6),
// #16
cleanStyleWithSanitization(0, 7),
'border-image',
null,
// #18
cleanStyle(0, 9),
// #19
cleanStyle(0, 10),
'border-width',
null,
]);
@ -843,34 +858,35 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
styleSanitizer,
[null],
cleanStyle(0, 12), //
cleanStyle(0, 13), //
2,
null,
// #6
cleanStyleWithSanitization(0, 15),
// #7
cleanStyleWithSanitization(0, 16),
'border-image',
'url(foo.jpg)',
// #9
cleanStyle(0, 18),
// #10
cleanStyle(0, 19),
'border-width',
'100px',
// #12
// #13
cleanStyleWithSanitization(0, 0),
'background-image',
'unsafe',
// #15
cleanStyleWithSanitization(0, 6),
// #16
cleanStyleWithSanitization(0, 7),
'border-image',
null,
// #18
cleanStyle(0, 9),
// #19
cleanStyle(0, 10),
'border-width',
null,
]);
@ -883,20 +899,20 @@ describe('styling', () => {
const template =
initContext(null, [InitialStylingFlags.VALUES_MODE, 'one', true, 'two', true]);
expect(template).toEqual([
element, null, [null, true, true], dirtyStyle(0, 12), //
element, null, null, [null, true, true], dirtyStyle(0, 13), //
0, null,
// #6
cleanClass(1, 12), 'one', null,
// #7
cleanClass(1, 13), 'one', null,
// #9
cleanClass(2, 15), 'two', null,
// #10
cleanClass(2, 16), 'two', null,
// #12
dirtyClass(1, 6), 'one', null,
// #13
dirtyClass(1, 7), 'one', null,
// #15
dirtyClass(2, 9), 'two', null
// #16
dirtyClass(2, 10), 'two', null
]);
});
@ -948,48 +964,49 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null, '100px', true],
dirtyStyle(0, 18), //
dirtyStyle(0, 19), //
2,
null,
// #6
cleanStyle(1, 18),
// #7
cleanStyle(1, 19),
'width',
null,
// #9
cleanStyle(0, 21),
// #10
cleanStyle(0, 22),
'height',
null,
// #12
cleanClass(2, 24),
// #13
cleanClass(2, 25),
'wide',
null,
// #15
cleanClass(0, 27),
// #16
cleanClass(0, 28),
'tall',
null,
// #18
dirtyStyle(1, 6),
// #19
dirtyStyle(1, 7),
'width',
null,
// #21
cleanStyle(0, 9),
// #22
cleanStyle(0, 10),
'height',
null,
// #24
dirtyClass(2, 12),
// #25
dirtyClass(2, 13),
'wide',
null,
// #27
cleanClass(0, 15),
// #28
cleanClass(0, 16),
'tall',
null,
]);
@ -1000,58 +1017,59 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null, '100px', true],
dirtyStyle(0, 18), //
dirtyStyle(0, 19), //
2,
'tall round',
// #6
cleanStyle(1, 18),
// #7
cleanStyle(1, 19),
'width',
null,
// #9
cleanStyle(0, 33),
// #10
cleanStyle(0, 34),
'height',
null,
// #12
cleanClass(2, 30),
// #13
cleanClass(2, 31),
'wide',
null,
// #15
cleanClass(0, 24),
// #16
cleanClass(0, 25),
'tall',
null,
// #18
dirtyStyle(1, 6),
// #19
dirtyStyle(1, 7),
'width',
'200px',
// #21
// #22
dirtyStyle(0, 0),
'opacity',
'0.5',
// #24
dirtyClass(0, 15),
// #25
dirtyClass(0, 16),
'tall',
true,
// #27
// #28
dirtyClass(0, 0),
'round',
true,
// #30
cleanClass(2, 12),
// #31
cleanClass(2, 13),
'wide',
null,
// #33
cleanStyle(0, 9),
// #34
cleanStyle(0, 10),
'height',
null,
]);
@ -1066,58 +1084,59 @@ describe('styling', () => {
expect(stylingContext).toEqual([
element,
null,
null,
[null, '100px', true],
dirtyStyle(0, 18), //
dirtyStyle(0, 19), //
2,
null,
// #6
dirtyStyle(1, 18),
// #7
dirtyStyle(1, 19),
'width',
'300px',
// #9
cleanStyle(0, 33),
// #10
cleanStyle(0, 34),
'height',
null,
// #12
cleanClass(2, 24),
// #13
cleanClass(2, 25),
'wide',
null,
// #15
cleanClass(0, 21),
// #16
cleanClass(0, 22),
'tall',
null,
// #18
cleanStyle(1, 6),
// #19
cleanStyle(1, 7),
'width',
'500px',
// #21
cleanClass(0, 15),
// #22
cleanClass(0, 16),
'tall',
true,
// #24
cleanClass(2, 12),
// #25
cleanClass(2, 13),
'wide',
true,
// #27
// #28
dirtyClass(0, 0),
'round',
null,
// #30
// #31
dirtyStyle(0, 0),
'opacity',
null,
// #33
cleanStyle(0, 9),
// #34
cleanStyle(0, 10),
'height',
null,
]);