refactor(ivy): revert LNode.data into LViewData[HOST] (#26424)

PR Close #26424
This commit is contained in:
Kara Erickson
2018-10-12 15:02:54 -07:00
committed by Miško Hevery
parent 45732e5b91
commit 931e603f80
26 changed files with 634 additions and 518 deletions

View File

@ -14,21 +14,6 @@ import {InitialStyles, StylingContext, StylingFlags, StylingIndex} from '../inte
import {EMPTY_ARR, EMPTY_OBJ, createEmptyStylingContext} from './util';
/**
* Used clone a copy of a pre-computed template of a styling context.
*
* A pre-computed template is designed to be computed once for a given element
* (instructions.ts has logic for caching this).
*/
export function allocStylingContext(
lElement: LElementNode | null, templateStyleContext: StylingContext): StylingContext {
// each instance gets a copy
const context = templateStyleContext.slice() as any as StylingContext;
context[StylingIndex.ElementPosition] = lElement;
return context;
}
/**
* Creates a styling context template where styling information is stored.
* Any styles that are later referenced using `updateStyleProp` must be

View File

@ -5,11 +5,16 @@
* 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 {StyleSanitizeFn} from '../../sanitization/style_sanitizer';
import {LContext, getContext} from '../context_discovery';
import {getContext} from '../context_discovery';
import {ACTIVE_INDEX, LContainer} from '../interfaces/container';
import {LContext} from '../interfaces/context';
import {LElementNode} from '../interfaces/node';
import {PlayerContext} from '../interfaces/player';
import {InitialStyles, StylingContext, StylingIndex} from '../interfaces/styling';
import {FLAGS, HEADER_OFFSET, HOST, LViewData} from '../interfaces/view';
import {getTNode} from '../util';
export const EMPTY_ARR: any[] = [];
export const EMPTY_OBJ: {[key: string]: any} = {};
@ -18,10 +23,70 @@ export function createEmptyStylingContext(
element?: LElementNode | null, sanitizer?: StyleSanitizeFn | null,
initialStylingValues?: InitialStyles): StylingContext {
return [
element || null, null, sanitizer || null, initialStylingValues || [null], 0, 0, null, null
null, // PlayerContext
sanitizer || null, // StyleSanitizer
initialStylingValues || [null], // InitialStyles
0, // MasterFlags
0, // ClassOffset
element || null, // Element
null, // PreviousMultiClassValue
null // PreviousMultiStyleValue
];
}
/**
* Used clone a copy of a pre-computed template of a styling context.
*
* A pre-computed template is designed to be computed once for a given element
* (instructions.ts has logic for caching this).
*/
export function allocStylingContext(
lElement: LElementNode | null, templateStyleContext: StylingContext): StylingContext {
// each instance gets a copy
const context = templateStyleContext.slice() as any as StylingContext;
context[StylingIndex.ElementPosition] = lElement;
return context;
}
/**
* Retrieve the `StylingContext` at a given index.
*
* This method lazily creates the `StylingContext`. This is because in most cases
* we have styling without any bindings. Creating `StylingContext` eagerly would mean that
* every style declaration such as `<div style="color: red">` would result `StyleContext`
* which would create unnecessary memory pressure.
*
* @param index Index of the style allocation. See: `elementStyling`.
* @param viewData The view to search for the styling context
*/
export function getStylingContext(index: number, viewData: LViewData): StylingContext {
let storageIndex = index + HEADER_OFFSET;
let slotValue: LContainer|LViewData|StylingContext|LElementNode = viewData[storageIndex];
let wrapper: LContainer|LViewData|StylingContext = viewData;
while (Array.isArray(slotValue)) {
wrapper = slotValue;
slotValue = slotValue[HOST] as LViewData | StylingContext | LElementNode;
}
if (isStylingContext(wrapper)) {
return wrapper as StylingContext;
} else {
// This is an LViewData or an LContainer
const stylingTemplate = getTNode(index, viewData).stylingTemplate;
if (wrapper !== viewData) storageIndex = HOST;
return wrapper[storageIndex] = stylingTemplate ?
allocStylingContext(slotValue, stylingTemplate) :
createEmptyStylingContext(slotValue);
}
}
function isStylingContext(value: LViewData | LContainer | StylingContext) {
// Not an LViewData or an LContainer
return typeof value[FLAGS] !== 'number' && typeof value[ACTIVE_INDEX] !== 'number';
}
export function getOrCreatePlayerContext(target: {}, context?: LContext | null): PlayerContext {
context = context || getContext(target) !;
if (ngDevMode && !context) {
@ -30,11 +95,7 @@ export function getOrCreatePlayerContext(target: {}, context?: LContext | null):
}
const {lViewData, nodeIndex} = context;
const value = lViewData[nodeIndex];
let stylingContext = value as StylingContext;
if (!Array.isArray(value)) {
stylingContext = lViewData[nodeIndex] = createEmptyStylingContext(value as LElementNode);
}
const stylingContext = getStylingContext(nodeIndex - HEADER_OFFSET, lViewData);
return stylingContext[StylingIndex.PlayerContext] || allocPlayerContext(stylingContext);
}