From 958d6b41f0dc4f46523f7dcb06f03eea13370e99 Mon Sep 17 00:00:00 2001 From: Hristo Deshev Date: Thu, 10 Sep 2015 14:27:34 +0300 Subject: [PATCH] Move layout special properties sets out of the component builder. Setters registered by the respective modules on import. --- ui/builder/component-builder.ts | 64 ++++--------------- ui/builder/special-properties.ts | 23 +++++++ .../absolute-layout/absolute-layout-common.ts | 10 ++- ui/layouts/dock-layout/dock-layout-common.ts | 7 +- ui/layouts/grid-layout/grid-layout-common.ts | 16 ++++- 5 files changed, 67 insertions(+), 53 deletions(-) create mode 100644 ui/builder/special-properties.ts diff --git a/ui/builder/component-builder.ts b/ui/builder/component-builder.ts index c94788ec8..ba026e74b 100644 --- a/ui/builder/component-builder.ts +++ b/ui/builder/component-builder.ts @@ -1,9 +1,6 @@ import observable = require("data/observable"); import view = require("ui/core/view"); import bindable = require("ui/core/bindable"); -import dockLayoutDef = require("ui/layouts/dock-layout"); -import gridLayoutModule = require("ui/layouts/grid-layout"); -import absoluteLayoutDef = require("ui/layouts/absolute-layout"); import types = require("utils/types"); import definition = require("ui/builder/component-builder"); import fs = require("file-system"); @@ -12,6 +9,13 @@ import bindingBuilder = require("ui/builder/binding-builder"); import platform = require("platform"); import pages = require("ui/page"); +//the imports below are needed for special property registration +import "ui/layouts/dock-layout"; +import "ui/layouts/grid-layout"; +import "ui/layouts/absolute-layout"; + +import {getSpecialPropertySetter} from "ui/builder/special-properties"; + var UI_PATH = "ui/"; var MODULES = { "TabViewItem": "ui/tab-view", @@ -22,28 +26,9 @@ var MODULES = { "SegmentedBarItem": "ui/segmented-bar", }; -var ROW = "row"; -var COL = "col"; -var COL_SPAN = "colSpan"; -var ROW_SPAN = "rowSpan"; -var DOCK = "dock"; -var LEFT = "left"; -var TOP = "top"; var CODEFILE = "codeFile"; var CSSFILE = "cssFile"; -export var specialProperties: Array = [ - ROW, - COL, - COL_SPAN, - ROW_SPAN, - DOCK, - LEFT, - TOP, - CODEFILE, - CSSFILE -] - var eventHandlers = {}; export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object): definition.ComponentModule { @@ -163,28 +148,6 @@ export function getComponentModule(elementName: string, namespace: string, attri return componentModule; } -export function setSpecialPropertyValue(instance: view.View, propertyName: string, propertyValue: string) { - if (propertyName === ROW) { - gridLayoutModule.GridLayout.setRow(instance, !isNaN(+propertyValue) && +propertyValue); - } else if (propertyName === COL) { - gridLayoutModule.GridLayout.setColumn(instance, !isNaN(+propertyValue) && +propertyValue); - } else if (propertyName === COL_SPAN) { - gridLayoutModule.GridLayout.setColumnSpan(instance, !isNaN(+propertyValue) && +propertyValue); - } else if (propertyName === ROW_SPAN) { - gridLayoutModule.GridLayout.setRowSpan(instance, !isNaN(+propertyValue) && +propertyValue); - } else if (propertyName === LEFT) { - absoluteLayoutDef.AbsoluteLayout.setLeft(instance, !isNaN(+propertyValue) && +propertyValue); - } else if (propertyName === TOP) { - absoluteLayoutDef.AbsoluteLayout.setTop(instance, !isNaN(+propertyValue) && +propertyValue); - } else if (propertyName === DOCK) { - console.log('set dock: ' + propertyName + ' -> ' + propertyValue); - dockLayoutDef.DockLayout.setDock(instance, propertyValue); - } else { - return false; - } - return true; -} - export function setPropertyValue(instance: view.View, instanceModule: Object, exports: Object, propertyName: string, propertyValue: string) { // Note: instanceModule can be null if we are loading custom compnenet with no code-behind. var isEventOrGesture: boolean = isKnownEventOrGesture(propertyName, instance); @@ -209,15 +172,16 @@ export function setPropertyValue(instance: view.View, instanceModule: Object, ex if (types.isFunction(handler)) { instance.on(propertyName, handler); } - } else if (setSpecialPropertyValue(instance, propertyName, propertyValue)) { - // Already set by setSpecialPropertyValue } else { - var attrHandled = false; - - if ((instance)._applyXmlAttribute) { + let attrHandled = false; + let specialSetter = getSpecialPropertySetter(propertyName); + if (!attrHandled && specialSetter) { + specialSetter(instance, propertyValue); + attrHandled = true; + } + if (!attrHandled && (instance)._applyXmlAttribute) { attrHandled = (instance)._applyXmlAttribute(propertyName, propertyValue); } - if (!attrHandled) { // Try to convert value to number. var valueAsNumber = +propertyValue; diff --git a/ui/builder/special-properties.ts b/ui/builder/special-properties.ts new file mode 100644 index 000000000..77806ed28 --- /dev/null +++ b/ui/builder/special-properties.ts @@ -0,0 +1,23 @@ +import view = require("ui/core/view"); + +export type PropertySetter = (instance: view.View, propertyValue: string) => void; + +var specialProperties: Map = new Map(); + +function specialPropertyKey(name: string) { + return name.toLowerCase(); +} + +export function registerSpecialProperty(name: string, setter: PropertySetter) { + let propertyKey = specialPropertyKey(name); + if (specialProperties.has(propertyKey)) { + throw new Error(`Property for ${propertyKey} already registered`); + } else { + specialProperties.set(propertyKey, setter); + } +} + +export function getSpecialPropertySetter(name: string): PropertySetter { + let propertyKey = specialPropertyKey(name); + return specialProperties.get(propertyKey); +} diff --git a/ui/layouts/absolute-layout/absolute-layout-common.ts b/ui/layouts/absolute-layout/absolute-layout-common.ts index cbbb89b18..f828678cd 100644 --- a/ui/layouts/absolute-layout/absolute-layout-common.ts +++ b/ui/layouts/absolute-layout/absolute-layout-common.ts @@ -3,6 +3,7 @@ import definition = require("ui/layouts/absolute-layout"); import dependencyObservable = require("ui/core/dependency-observable"); import view = require("ui/core/view"); import proxy = require("ui/core/proxy"); +import {registerSpecialProperty} from "ui/builder/special-properties"; function validateArgs(element: view.View): view.View { if (!element) { @@ -11,6 +12,13 @@ function validateArgs(element: view.View): view.View { return element; } +registerSpecialProperty("left", (instance, propertyValue) => { + AbsoluteLayout.setLeft(instance, !isNaN(+propertyValue) && +propertyValue); +}); +registerSpecialProperty("top", (instance, propertyValue) => { + AbsoluteLayout.setTop(instance, !isNaN(+propertyValue) && +propertyValue); +}); + export class AbsoluteLayout extends layouts.LayoutBase implements definition.AbsoluteLayout { private static isValid(value: number): boolean { @@ -66,4 +74,4 @@ export class AbsoluteLayout extends layouts.LayoutBase implements definition.Abs protected onTopChanged(view: view.View, oldValue: number, newValue: number) { // } -} \ No newline at end of file +} diff --git a/ui/layouts/dock-layout/dock-layout-common.ts b/ui/layouts/dock-layout/dock-layout-common.ts index 9cc6f628f..80d00d222 100644 --- a/ui/layouts/dock-layout/dock-layout-common.ts +++ b/ui/layouts/dock-layout/dock-layout-common.ts @@ -4,6 +4,7 @@ import dependencyObservable = require("ui/core/dependency-observable"); import view = require("ui/core/view"); import enums = require("ui/enums"); import proxy = require("ui/core/proxy"); +import {registerSpecialProperty} from "ui/builder/special-properties"; // on Android we explicitly set propertySettings to None because android will invalidate its layout (skip unnecessary native call). var AffectsLayout = global.android ? dependencyObservable.PropertyMetadataSettings.None : dependencyObservable.PropertyMetadataSettings.AffectsLayout; @@ -19,6 +20,10 @@ function validateArgs(element: view.View): view.View { return element; } +registerSpecialProperty("dock", (instance, propertyValue) => { + DockLayout.setDock(instance, propertyValue); +}); + export class DockLayout extends layouts.LayoutBase implements definition.DockLayout { private static onDockPropertyChanged(data: dependencyObservable.PropertyChangeData) { @@ -55,4 +60,4 @@ export class DockLayout extends layouts.LayoutBase implements definition.DockLay protected onDockChanged(view: view.View, oldValue: number, newValue: number) { // } -} \ No newline at end of file +} diff --git a/ui/layouts/grid-layout/grid-layout-common.ts b/ui/layouts/grid-layout/grid-layout-common.ts index ad76cf6d0..867f56448 100644 --- a/ui/layouts/grid-layout/grid-layout-common.ts +++ b/ui/layouts/grid-layout/grid-layout-common.ts @@ -6,6 +6,7 @@ import bindable = require("ui/core/bindable"); import types = require("utils/types"); import numberUtils = require("utils/number-utils"); import proxy = require("ui/core/proxy"); +import {registerSpecialProperty} from "ui/builder/special-properties"; function validateArgs(element: view.View): view.View { if (!element) { @@ -20,6 +21,19 @@ export module GridUnitType { export var star: string = "star"; } +registerSpecialProperty("row", (instance, propertyValue) => { + GridLayout.setRow(instance, !isNaN(+propertyValue) && +propertyValue); +}); +registerSpecialProperty("col", (instance, propertyValue) => { + GridLayout.setColumn(instance, !isNaN(+propertyValue) && +propertyValue); +}); +registerSpecialProperty("colSpan", (instance, propertyValue) => { + GridLayout.setColumnSpan(instance, !isNaN(+propertyValue) && +propertyValue); +}); +registerSpecialProperty("rowSpan", (instance, propertyValue) => { + GridLayout.setRowSpan(instance, !isNaN(+propertyValue) && +propertyValue); +}); + export class ItemSpec extends bindable.Bindable implements definition.ItemSpec { private _value: number; @@ -365,4 +379,4 @@ export class GridLayout extends layouts.LayoutBase implements definition.GridLay this._rows = GridLayout.parseItemSpecs(value); this.invalidate(); } -} \ No newline at end of file +}