import application = require("application"); import styling = require("ui/styling"); import types = require("utils/types"); import trace = require("trace"); import {DependencyObservable, PropertyMetadata, PropertyMetadataSettings, PropertyChangeData, Property, ValueSource, NativeValueResult} from "ui/core/dependency-observable"; import {View} from "ui/core/view"; import {Color} from "color"; import styleProperty = require("ui/styling/style-property"); import converters = require("./converters"); import enums = require("ui/enums"); import utils = require("utils/utils"); import font = require("ui/styling/font"); import background = require("ui/styling/background"); import platform = require("platform"); import definition = require("ui/styling/style"); import * as imageSourceModule from "image-source"; var imageSource: typeof imageSourceModule; function ensureImageSource() { if (!imageSource) { imageSource = require("image-source"); } } // key is the property id and value is Dictionary; var _registeredHandlers = Array(); // key is a className + property id and value is StylePropertyChangedHandler; var _handlersCache = {}; // classes like Frame that does not need to handle styling properties. var noStylingClasses = {}; // on Android we explicitly set propertySettings to None because android will invalidate its layout (skip unnecessary native call). var AffectsLayout = platform.device.os === platform.platformNames.android ? PropertyMetadataSettings.None : PropertyMetadataSettings.AffectsLayout; interface ThicknessValue { left: Object; top: Object; right: Object; bottom: Object; } interface PercentHelper { value: number; isPercent: boolean; isError: boolean; } function parseMargin(value: any): ThicknessValue { if (types.isString(value)) { let arr = (value).split(/[ ,]+/); let top: Object; let right: Object; let bottom: Object; let left: Object; if (arr.length === 1) { top = right = bottom = left = arr[0]; } else if (arr.length === 2) { top = bottom = arr[0]; right = left = arr[1]; } else if (arr.length === 3) { top = arr[0]; right = left = arr[1]; bottom = arr[2]; } else if (arr.length === 4) { top = arr[0]; right = arr[1]; bottom = arr[2]; left = arr[3]; } else { throw new Error("Invalid value for margin: " + value); } return { top: top, right: right, bottom: bottom, left: left } } else if (types.isNumber(value)) { return { top: value, right: value, bottom: value, left: value } } else { return value; } } function layoutParamsComparer(x: definition.CommonLayoutParams, y: definition.CommonLayoutParams): boolean { return x.width === y.width && x.height === y.height && x.leftMargin === y.leftMargin && x.topMargin === y.topMargin && x.rightMargin === y.rightMargin && x.bottomMargin === y.bottomMargin && x.horizontalAlignment === y.horizontalAlignment && x.verticalAlignment === y.verticalAlignment && x.widthPercent === y.widthPercent && x.heightPercent === y.heightPercent && x.leftMarginPercent === y.leftMarginPercent && x.topMarginPercent === y.topMarginPercent && x.rightMarginPercent === y.rightMarginPercent && x.bottomMarginPercent === y.bottomMarginPercent } function onLayoutParamsChanged(data: PropertyChangeData) { let style =