Extract single style property resolution to an exported API.

Used by CSS selectors, and now the Angular `setElementStyle` renderer API.
This commit is contained in:
Hristo Deshev
2016-05-16 17:30:51 +03:00
parent b8785afd74
commit 59b45f8d35
3 changed files with 41 additions and 28 deletions

View File

@ -2,7 +2,7 @@
import observable = require("ui/core/dependency-observable"); import observable = require("ui/core/dependency-observable");
import cssParser = require("css"); import cssParser = require("css");
import * as trace from "trace"; import * as trace from "trace";
import * as styleProperty from "ui/styling/style-property"; import {StyleProperty, ResolvedStylePropertyHandler, withStyleProperty} from "ui/styling/style-property";
import * as types from "utils/types"; import * as types from "utils/types";
import * as utils from "utils/utils"; import * as utils from "utils/utils";
import keyframeAnimation = require("ui/animation/keyframe-animation"); import keyframeAnimation = require("ui/animation/keyframe-animation");
@ -69,22 +69,24 @@ export class CssSelector {
let modifier = valueSourceModifier || this.valueSourceModifier; let modifier = valueSourceModifier || this.valueSourceModifier;
this.eachSetter((property, value) => { this.eachSetter((property, value) => {
if (types.isString(property)) { if (types.isString(property)) {
const propertyName = <string>property;
let attrHandled = false; let attrHandled = false;
let specialSetter = getSpecialPropertySetter(property); let specialSetter = getSpecialPropertySetter(propertyName);
if (!attrHandled && specialSetter) { if (!attrHandled && specialSetter) {
specialSetter(view, value); specialSetter(view, value);
attrHandled = true; attrHandled = true;
} }
if (!attrHandled && property in view) { if (!attrHandled && propertyName in view) {
view[property] = utils.convertString(value); view[propertyName] = utils.convertString(value);
} }
} else { } else {
const resolvedProperty = <StyleProperty>property;
try { try {
view.style._setValue(property, value, modifier); view.style._setValue(resolvedProperty, value, modifier);
} catch (ex) { } catch (ex) {
trace.write("Error setting property: " + property.name + " view: " + view + " value: " + value + " " + ex, trace.categories.Style, trace.messageType.error); trace.write("Error setting property: " + resolvedProperty.name + " view: " + view + " value: " + value + " " + ex, trace.categories.Style, trace.messageType.error);
} }
} }
}); });
@ -102,29 +104,12 @@ export class CssSelector {
} }
} }
public eachSetter(callback: (property, resolvedValue: any) => void) { public eachSetter(callback: ResolvedStylePropertyHandler) {
for (let i = 0; i < this._declarations.length; i++) { for (let i = 0; i < this._declarations.length; i++) {
let declaration = this._declarations[i]; let declaration = this._declarations[i];
let name = declaration.property; let name = declaration.property;
let resolvedValue = declaration.value; let resolvedValue = declaration.value;
withStyleProperty(name, resolvedValue, callback);
let property = styleProperty.getPropertyByCssName(name);
if (property) {
// The property.valueConverter is now used to convert the value later on in DependencyObservable._setValueInternal.
callback(property, resolvedValue);
}
else {
let pairs = styleProperty.getShorthandPairs(name, resolvedValue);
if (pairs) {
for (let j = 0; j < pairs.length; j++) {
let pair = pairs[j];
callback(pair.property, pair.value);
}
} else {
callback(declaration.property, declaration.value);
}
}
} }
} }
@ -483,7 +468,8 @@ class InlineStyleSelector extends CssSelector {
public apply(view: view.View) { public apply(view: view.View) {
this.eachSetter((property, value) => { this.eachSetter((property, value) => {
view.style._setValue(property, value, observable.ValueSource.Local); const resolvedProperty = <StyleProperty>property;
view.style._setValue(resolvedProperty, value, observable.ValueSource.Local);
}); });
} }

View File

@ -2,6 +2,9 @@
import definition = require("ui/styling"); import definition = require("ui/styling");
import observable = require("ui/core/dependency-observable"); import observable = require("ui/core/dependency-observable");
export type StyleProperty = Property;
export type ResolvedStylePropertyHandler = (property: Property | string, value: any) => void;
export function withStyleProperty(name: string, value: any, resolvedCallback: ResolvedStylePropertyHandler): void;
export function getShorthandPairs(name: string, value: any): Array<KeyValuePair<Property, any>>; export function getShorthandPairs(name: string, value: any): Array<KeyValuePair<Property, any>>;
export function registerShorthandCallback(name: string, callback: (value: any) => Array<KeyValuePair<Property, any>>): void; export function registerShorthandCallback(name: string, callback: (value: any) => Array<KeyValuePair<Property, any>>): void;

View File

@ -20,6 +20,30 @@ function registerProperty(property: Property) {
} }
} }
export type StyleProperty = definition.Property;
export type ResolvedStylePropertyHandler = (property: definition.Property | string, value: any) => void;
export function withStyleProperty(name: string, value: any, resolvedCallback: ResolvedStylePropertyHandler): void {
let property = getPropertyByCssName(name);
if (property) {
// The property.valueConverter is now used to convert the value later on in DependencyObservable._setValueInternal.
resolvedCallback(property, value);
}
else {
let pairs = getShorthandPairs(name, value);
if (pairs) {
for (let j = 0; j < pairs.length; j++) {
let pair = pairs[j];
resolvedCallback(pair.property, pair.value);
}
} else {
//Fall back to the string property name as a last resort and let
//the callback handle it further.
resolvedCallback(name, value);
}
}
}
export function getShorthandPairs(name: string, value: any): Array<definition.KeyValuePair<definition.Property, any>> { export function getShorthandPairs(name: string, value: any): Array<definition.KeyValuePair<definition.Property, any>> {
var callback = callbackByShorthandName.get(name); var callback = callbackByShorthandName.get(name);
if (callback) { if (callback) {