test(ivy): add canonical compiler spec for class/style (#22719)
Adds a stub for `elementStyle` and `elementClass` instruction with a canonical spec for the compiler. The spec shows the the compiler should be using `elementStyle` and `elementClass` instruction in place of `[class]` and `[style]` bindings respectively. PR Close #22719
This commit is contained in:

committed by
Kara Erickson

parent
a0a01f1e1e
commit
112431db69
@ -63,7 +63,9 @@ export {
|
||||
p as ɵp,
|
||||
pD as ɵpD,
|
||||
a as ɵa,
|
||||
s as ɵs,
|
||||
sn as ɵsn,
|
||||
k as ɵk,
|
||||
kn as ɵkn,
|
||||
t as ɵt,
|
||||
v as ɵv,
|
||||
|
@ -50,4 +50,15 @@ export function getExported() { return exported; }
|
||||
export function setExported(v) { exported = v; }
|
||||
```
|
||||
|
||||
Also writing to a property of `exports` might change its hidden class resulting in megamorphic access.
|
||||
Also writing to a property of `exports` might change its hidden class resulting in megamorphic access.
|
||||
|
||||
## Iterating over Keys of an Object.
|
||||
|
||||
https://jsperf.com/object-keys-vs-for-in-with-closure/3 implies that `Object.keys` is the fastest way of iterating
|
||||
over properties of an object.
|
||||
|
||||
```
|
||||
for (var i = 0, keys = Object.keys(obj); i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
}
|
||||
```
|
@ -45,10 +45,12 @@ export {
|
||||
containerRefreshEnd as cr,
|
||||
|
||||
elementAttribute as a,
|
||||
elementClass as k,
|
||||
elementClassNamed as kn,
|
||||
elementEnd as e,
|
||||
elementProperty as p,
|
||||
elementStart as E,
|
||||
elementStyle as s,
|
||||
elementStyleNamed as sn,
|
||||
|
||||
listener as L,
|
||||
|
@ -866,7 +866,7 @@ function generatePropertyAliases(lNodeFlags: number, direction: BindingDirection
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or remove a class in a classList.
|
||||
* Add or remove a class in a `classList` on a DOM element.
|
||||
*
|
||||
* This instruction is meant to handle the [class.foo]="exp" case
|
||||
*
|
||||
@ -889,6 +889,29 @@ export function elementClassNamed<T>(index: number, className: string, value: T
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the `className` property on a DOM element.
|
||||
*
|
||||
* This instruction is meant to handle the `[class]="exp"` usage.
|
||||
*
|
||||
* `elementClass` instruction writes the value to the "element's" `className` property.
|
||||
*
|
||||
* @param index The index of the element to update in the data array
|
||||
* @param value A value indicating a set of classes which should be applied. The method overrides
|
||||
* any existing classes. The value is stringified (`toString`) before it is applied to the
|
||||
* element.
|
||||
*/
|
||||
export function elementClass<T>(index: number, value: T | NO_CHANGE): void {
|
||||
if (value !== NO_CHANGE) {
|
||||
// TODO: This is a naive implementation which simply writes value to the `className`. In the
|
||||
// future
|
||||
// we will add logic here which would work with the animation code.
|
||||
const lElement: LElementNode = data[index];
|
||||
isProceduralRenderer(renderer) ? renderer.setProperty(lElement.native, 'className', value) :
|
||||
lElement.native['className'] = stringify(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a given style on an Element.
|
||||
*
|
||||
@ -908,22 +931,56 @@ export function elementStyleNamed<T>(
|
||||
index: number, styleName: string, value: T | NO_CHANGE,
|
||||
suffixOrSanitizer?: string | Sanitizer): void {
|
||||
if (value !== NO_CHANGE) {
|
||||
const lElement = data[index] as LElementNode;
|
||||
const lElement: LElementNode = data[index];
|
||||
if (value == null) {
|
||||
isProceduralRenderer(renderer) ?
|
||||
renderer.removeStyle(lElement.native, styleName, RendererStyleFlags3.DashCase) :
|
||||
lElement.native.style.removeProperty(styleName);
|
||||
lElement.native['style'].removeProperty(styleName);
|
||||
} else {
|
||||
let strValue =
|
||||
typeof suffixOrSanitizer == 'function' ? suffixOrSanitizer(value) : stringify(value);
|
||||
if (typeof suffixOrSanitizer == 'string') strValue = strValue + suffixOrSanitizer;
|
||||
isProceduralRenderer(renderer) ?
|
||||
renderer.setStyle(lElement.native, styleName, strValue, RendererStyleFlags3.DashCase) :
|
||||
lElement.native.style.setProperty(styleName, strValue);
|
||||
lElement.native['style'].setProperty(styleName, strValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the `style` property on a DOM element.
|
||||
*
|
||||
* This instruction is meant to handle the `[style]="exp"` usage.
|
||||
*
|
||||
*
|
||||
* @param index The index of the element to update in the data array
|
||||
* @param value A value indicating if a given style should be added or removed.
|
||||
* The expected shape of `value` is an object where keys are style names and the values
|
||||
* are their corresponding values to set. If value is falsy than the style is remove. An absence
|
||||
* of style does not cause that style to be removed. `NO_CHANGE` implies that no update should be
|
||||
* performed.
|
||||
*/
|
||||
export function elementStyle<T>(
|
||||
index: number, value: {[styleName: string]: any} | NO_CHANGE): void {
|
||||
if (value !== NO_CHANGE) {
|
||||
// TODO: This is a naive implementation which simply writes value to the `style`. In the future
|
||||
// we will add logic here which would work with the animation code.
|
||||
const lElement = data[index] as LElementNode;
|
||||
if (isProceduralRenderer(renderer)) {
|
||||
renderer.setProperty(lElement.native, 'style', value);
|
||||
} else {
|
||||
const style = lElement.native['style'];
|
||||
for (let i = 0, keys = Object.keys(value); i < keys.length; i++) {
|
||||
const styleName: string = keys[i];
|
||||
const styleValue: any = (value as any)[styleName];
|
||||
styleValue == null ? style.removeProperty(styleName) :
|
||||
style.setProperty(styleName, styleValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////
|
||||
//// Text
|
||||
|
@ -121,6 +121,7 @@ export interface RNode {
|
||||
export interface RElement extends RNode {
|
||||
style: RCssStyleDeclaration;
|
||||
classList: RDomTokenList;
|
||||
className: string;
|
||||
setAttribute(name: string, value: string): void;
|
||||
removeAttribute(name: string): void;
|
||||
setAttributeNS(namespaceURI: string, qualifiedName: string, value: string): void;
|
||||
|
Reference in New Issue
Block a user