diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj index 3f6a20a01..1e8e0aeef 100644 --- a/CrossPlatformModules.csproj +++ b/CrossPlatformModules.csproj @@ -377,6 +377,9 @@ trace.d.ts + + border.d.ts + repeater.d.ts @@ -774,15 +777,6 @@ switch.d.ts - - border.d.ts - - - border.d.ts - - - border.d.ts - activity-indicator.d.ts @@ -1680,7 +1674,7 @@ False - + \ No newline at end of file diff --git a/apps/tests/pages/background-test.ts b/apps/tests/pages/background-test.ts index d3fc95ba5..17f9c2096 100644 --- a/apps/tests/pages/background-test.ts +++ b/apps/tests/pages/background-test.ts @@ -1,10 +1,13 @@ import view = require("ui/core/view"); +import pages = require("ui/page"); + export function applyTap(args) { - var el = view.getViewById(view.getAncestor(args.object, "Page"), "test-element"); - (el).style = args.object.tag; + var page = view.getAncestor(args.object, "Page"); + var css = "#test-element { " + args.object.tag + " }"; + page.css = css; } export function resetTap(args) { - var el = view.getViewById(view.getAncestor(args.object, "Page"), "test-element"); - (el).style = ""; + var page = view.getAncestor(args.object, "Page"); + page.css = ""; } \ No newline at end of file diff --git a/apps/tests/ui/style/style-properties-tests.ts b/apps/tests/ui/style/style-properties-tests.ts index 729dc2051..a0ce35e5d 100644 --- a/apps/tests/ui/style/style-properties-tests.ts +++ b/apps/tests/ui/style/style-properties-tests.ts @@ -310,7 +310,7 @@ export function test_setting_font_shorthand_property() { function test_font_shorthand_property(short: string, family: string, size: number, style: string, weight:string) { var testView = new buttonModule.Button(); - (testView).style = "font: " + short; + (testView.style)["font"] = short; TKUnit.assertEqual(testView.style.fontFamily, family, "style.fontFamily"); TKUnit.assertEqual(testView.style.fontStyle, style, "style.fontStyle"); diff --git a/apps/tests/ui/style/style-tests.ts b/apps/tests/ui/style/style-tests.ts index e022d9efd..66a35a762 100644 --- a/apps/tests/ui/style/style-tests.ts +++ b/apps/tests/ui/style/style-tests.ts @@ -99,23 +99,23 @@ export function test_type_selector() { var pageFactory = function (): pageModule.Page { page = new pageModule.Page(); - // - // ### Using type selector - // ``` JavaScript - page.css = "button { color: red; }"; + // + // ### Using type selector + // ``` JavaScript + page.css = "button { color: red; }"; - //// Will be styled + //// Will be styled btn = new buttonModule.Button(); - //// Won't be styled + //// Won't be styled label = new labelModule.Label(); - // ``` - // + // ``` + // - var stack = new stackModule.StackLayout(); - page.content = stack; - stack.addChild(label); - stack.addChild(btn); + var stack = new stackModule.StackLayout(); + page.content = stack; + stack.addChild(label); + stack.addChild(btn); return page; }; @@ -135,24 +135,24 @@ export function test_class_selector() { var pageFactory = function (): pageModule.Page { page = new pageModule.Page(); - // - // ### Using class selector - // ``` JavaScript - page.css = ".test { color: red; }"; + // + // ### Using class selector + // ``` JavaScript + page.css = ".test { color: red; }"; - //// Will be styled + //// Will be styled btnWithClass = new buttonModule.Button(); - btnWithClass.cssClass = "test"; + btnWithClass.cssClass = "test"; - //// Won't be styled + //// Won't be styled btnWithNoClass = new buttonModule.Button(); - // ``` - // + // ``` + // - var stack = new stackModule.StackLayout(); - page.content = stack; - stack.addChild(btnWithClass); - stack.addChild(btnWithNoClass); + var stack = new stackModule.StackLayout(); + page.content = stack; + stack.addChild(btnWithClass); + stack.addChild(btnWithNoClass); return page; }; @@ -199,24 +199,24 @@ export function test_id_selector() { var pageFactory = function (): pageModule.Page { page = new pageModule.Page(); - // - // ### Using id selector - // ``` JavaScript - page.css = "#myButton { color: red; }"; + // + // ### Using id selector + // ``` JavaScript + page.css = "#myButton { color: red; }"; - //// Will be styled + //// Will be styled btnWithId = new buttonModule.Button(); - btnWithId.id = "myButton"; + btnWithId.id = "myButton"; - //// Won't be styled + //// Won't be styled btnWithNoId = new buttonModule.Button(); - // ``` - // + // ``` + // - var stack = new stackModule.StackLayout(); - page.content = stack; - stack.addChild(btnWithId); - stack.addChild(btnWithNoId); + var stack = new stackModule.StackLayout(); + page.content = stack; + stack.addChild(btnWithId); + stack.addChild(btnWithNoId); return page; }; @@ -234,13 +234,13 @@ export function test_state_selector() { var page: pageModule.Page; var btn: buttonModule.Button; var pageFactory = function (): pageModule.Page { - // Arrange + // Arrange page = new pageModule.Page(); - var testStack = new stackModule.StackLayout(); + var testStack = new stackModule.StackLayout(); page.content = testStack; btn = new buttonModule.Button(); - testStack.addChild(btn); + testStack.addChild(btn); page.css = ":pressed { color: red; }"; return page; @@ -260,18 +260,18 @@ export function test_type_and_state_selector() { var pageFactory = function (): pageModule.Page { page = new pageModule.Page(); - // - // ### Using state selector - // ``` JavaScript - page.css = "button:pressed { color: red; }"; + // + // ### Using state selector + // ``` JavaScript + page.css = "button:pressed { color: red; }"; - //// Will be red when pressed + //// Will be red when pressed btn = new buttonModule.Button(); - // ``` - // - var stack = new stackModule.StackLayout(); - page.content = stack; - stack.addChild(btn); + // ``` + // + var stack = new stackModule.StackLayout(); + page.content = stack; + stack.addChild(btn); return page; }; @@ -287,14 +287,14 @@ export function test_class_and_state_selector() { var page: pageModule.Page; var btn: buttonModule.Button; var pageFactory = function (): pageModule.Page { - // Arrange + // Arrange page = new pageModule.Page(); - var testStack = new stackModule.StackLayout(); + var testStack = new stackModule.StackLayout(); page.content = testStack; btn = new buttonModule.Button(); - btn.cssClass = "test" - testStack.addChild(btn); + btn.cssClass = "test" + testStack.addChild(btn); page.css = ".test:pressed { color: red; }"; return page; @@ -337,14 +337,14 @@ export function test_id_and_state_selector() { var page: pageModule.Page; var btn: buttonModule.Button; var pageFactory = function (): pageModule.Page { - // Arrange + // Arrange page = new pageModule.Page(); - var testStack = new stackModule.StackLayout(); + var testStack = new stackModule.StackLayout(); page.content = testStack; btn = new buttonModule.Button(); - btn.id = "myButton"; - testStack.addChild(btn); + btn.id = "myButton"; + testStack.addChild(btn); page.css = "#myButton:pressed { color: red; }"; return page; @@ -362,16 +362,16 @@ export function test_restore_original_values_when_state_is_changed() { var page: pageModule.Page; var btn: buttonModule.Button; var pageFactory = function (): pageModule.Page { - // Arrange + // Arrange page = new pageModule.Page(); - var testStack = new stackModule.StackLayout(); + var testStack = new stackModule.StackLayout(); page.content = testStack; btn = new buttonModule.Button(); - testStack.addChild(btn); + testStack.addChild(btn); page.css = "button { color: blue; } " + - "button:pressed { color: red; } "; + "button:pressed { color: red; } "; return page; }; @@ -483,7 +483,7 @@ export var test_style_is_applied_when_control_is_added_after_load = function () }; helper.navigate(pageFactory); - + testStack.addChild(btn); TKUnit.assert(btn.style.color, "Color property no applied correctly."); TKUnit.assert(btn.style.color.hex === "#FF0000", "Color property no applied correctly."); @@ -657,20 +657,20 @@ function testSelectorsPrioritiesTemplate(css: string) { var btnWithId: buttonModule.Button; var pageFactory = function (): pageModule.Page { page = new pageModule.Page(); - var testStack = new stackModule.StackLayout(); + var testStack = new stackModule.StackLayout(); page.content = testStack; btn = new buttonModule.Button(); - testStack.addChild(btn); + testStack.addChild(btn); btnWithClass = new buttonModule.Button(); - btnWithClass.cssClass = "button-class"; - testStack.addChild(btnWithClass); + btnWithClass.cssClass = "button-class"; + testStack.addChild(btnWithClass); btnWithId = new buttonModule.Button(); - btnWithId.cssClass = "button-class"; - btnWithId.id = "myButton" - testStack.addChild(btnWithId); + btnWithId.cssClass = "button-class"; + btnWithId.id = "myButton" + testStack.addChild(btnWithId); page.css = css; return page; @@ -748,19 +748,12 @@ export function test_setInlineStyle_setsLocalValues() { }); } -export function test_setInlineStyle_resetsLocalValues() { +export function test_setStyle_throws() { var testButton = new buttonModule.Button(); - testButton.text = "Test"; - testButton.style.fontSize = 10; - var stack = new stackModule.StackLayout(); - stack.addChild(testButton); - helper.buildUIAndRunTest(stack, function (views: Array) { - (testButton)._applyInlineStyle("color: red;"); - helper.assertViewColor(testButton, "#FF0000", dependencyObservableModule.ValueSource.Local); - TKUnit.assert(types.isUndefined(testButton.style.fontSize), "Setting inline style should reset font size"); - TKUnit.assertEqual(testButton.style._getValueSource(styling.properties.fontSizeProperty), dependencyObservableModule.ValueSource.Default, "valueSource"); - }); + TKUnit.assertThrows(function () { + (testButton).style = "background-color: red;"; + }, "View.style property is read-only."); } export var test_CSS_isAppliedOnPage = function () { diff --git a/apps/ui-tests-app/pages/background.ts b/apps/ui-tests-app/pages/background.ts index d3fc95ba5..17f9c2096 100644 --- a/apps/ui-tests-app/pages/background.ts +++ b/apps/ui-tests-app/pages/background.ts @@ -1,10 +1,13 @@ import view = require("ui/core/view"); +import pages = require("ui/page"); + export function applyTap(args) { - var el = view.getViewById(view.getAncestor(args.object, "Page"), "test-element"); - (el).style = args.object.tag; + var page = view.getAncestor(args.object, "Page"); + var css = "#test-element { " + args.object.tag + " }"; + page.css = css; } export function resetTap(args) { - var el = view.getViewById(view.getAncestor(args.object, "Page"), "test-element"); - (el).style = ""; + var page = view.getAncestor(args.object, "Page"); + page.css = ""; } \ No newline at end of file diff --git a/text/span-common.ts b/text/span-common.ts index f2acb5ca1..f52826de9 100644 --- a/text/span-common.ts +++ b/text/span-common.ts @@ -18,7 +18,7 @@ export class Span extends bindable.Bindable implements definition.Span, view.App private _spanModifiers: Array; private _parentFormattedString: formattedString.FormattedString; private _isInEditMode: boolean; - + get fontFamily(): string { return this._fontFamily; } @@ -157,7 +157,7 @@ export class Span extends bindable.Bindable implements definition.Span, view.App } public updateSpanModifiers(parent: formattedString.FormattedString) { - // a virtual method overriden in platform specific implementations. + // a virtual method overridden in platform specific implementations. if (this._isInEditMode) { throw new Error("Cannot update span modifiers during update!"); } @@ -180,7 +180,7 @@ export class Span extends bindable.Bindable implements definition.Span, view.App this.updateAndNotify(); } - public applyXmlAttribute(attribute, value): boolean { + public _applyXmlAttribute(attribute, value): boolean { if (attribute === "fontAttributes") { if (value.indexOf(",")) { var fontAttr = value.split(","); diff --git a/ui/border/border.android.ts b/ui/border/border.android.ts deleted file mode 100644 index ab3d128ef..000000000 --- a/ui/border/border.android.ts +++ /dev/null @@ -1,51 +0,0 @@ -import borderCommon = require("ui/border/border-common"); -import proxy = require("ui/core/proxy"); -import dependencyObservable = require("ui/core/dependency-observable"); -import utils = require("utils/utils"); - -// merge the exports of the common file with the exports of this file -declare var exports; -require("utils/module-merge").merge(borderCommon, exports); - -function onBorderPropertyChanged(data: dependencyObservable.PropertyChangeData) { - var border = data.object; - border._updateAndroidBorder(); -} - -(borderCommon.Border.cornerRadiusProperty.metadata).onSetNativeValue = onBorderPropertyChanged; -(borderCommon.Border.borderWidthProperty.metadata).onSetNativeValue = onBorderPropertyChanged; -(borderCommon.Border.borderColorProperty.metadata).onSetNativeValue = onBorderPropertyChanged; - -export class Border extends borderCommon.Border { - public _updateAndroidBorder() { - if (!this._nativeView) { - return; - } - - var nativeView = this._nativeView; - - var backgroundDrawable = nativeView.getBackground(); - if (!(backgroundDrawable instanceof android.graphics.drawable.GradientDrawable)) { - backgroundDrawable = new android.graphics.drawable.GradientDrawable(); - nativeView.setBackgroundDrawable(backgroundDrawable); - } - - var gd = backgroundDrawable; - var density = utils.layout.getDisplayDensity(); - gd.setCornerRadius(this.cornerRadius * density); - - if (this.borderColor) { - gd.setStroke(this.borderWidth * density, this.borderColor.android); - } - else { - gd.setStroke(this.borderWidth * density, android.graphics.Color.TRANSPARENT); - } - - if (this.backgroundColor) { - gd.setColor(this.backgroundColor.android); - } - else { - gd.setColor(android.graphics.Color.TRANSPARENT); - } - } -} diff --git a/ui/border/border.d.ts b/ui/border/border.d.ts index 6f8770306..91988aabe 100644 --- a/ui/border/border.d.ts +++ b/ui/border/border.d.ts @@ -10,10 +10,6 @@ declare module "ui/border" { * Represents a UI border component. */ export class Border extends contentView.ContentView { - public static cornerRadiusProperty : dependencyObservable.Property; - public static borderWidthProperty: dependencyObservable.Property; - public static borderColorProperty: dependencyObservable.Property; - /** * Gets or sets the corner radius of the border component. */ @@ -28,9 +24,5 @@ declare module "ui/border" { * Gets or sets the border color of the border component. */ borderColor: color.Color; - - //@private - _updateAndroidBorder(); - //@endprivate } } \ No newline at end of file diff --git a/ui/border/border.ios.ts b/ui/border/border.ios.ts deleted file mode 100644 index e3064d920..000000000 --- a/ui/border/border.ios.ts +++ /dev/null @@ -1,48 +0,0 @@ -import borderCommon = require("ui/border/border-common"); -import dependencyObservable = require("ui/core/dependency-observable"); -import proxy = require("ui/core/proxy"); -import color = require("color"); - -// merge the exports of the common file with the exports of this file -declare var exports; -require("utils/module-merge").merge(borderCommon, exports); - -function onCornerRadiusPropertyChanged(data: dependencyObservable.PropertyChangeData) { - var view = data.object; - if (!view._nativeView) { - return; - } - - if (view._nativeView instanceof UIView) { - (view._nativeView).layer.cornerRadius = data.newValue; - } -} -(borderCommon.Border.cornerRadiusProperty.metadata).onSetNativeValue = onCornerRadiusPropertyChanged; - -function onBorderWidthPropertyChanged(data: dependencyObservable.PropertyChangeData) { - var view = data.object; - if (!view._nativeView) { - return; - } - - if (view._nativeView instanceof UIView) { - (view._nativeView).layer.borderWidth = data.newValue; - } -} -(borderCommon.Border.borderWidthProperty.metadata).onSetNativeValue = onBorderWidthPropertyChanged; - -function onBorderColorPropertyChanged(data: dependencyObservable.PropertyChangeData) { - var view = data.object; - if (!view._nativeView) { - return; - } - - if (view._nativeView instanceof UIView && data.newValue instanceof color.Color) { - (view._nativeView).layer.borderColor = (data.newValue).ios.CGColor; - } -} -(borderCommon.Border.borderColorProperty.metadata).onSetNativeValue = onBorderColorPropertyChanged; - -export class Border extends borderCommon.Border { - // -} \ No newline at end of file diff --git a/ui/border/border-common.ts b/ui/border/border.ts similarity index 54% rename from ui/border/border-common.ts rename to ui/border/border.ts index c3d50a4a6..784c7a999 100644 --- a/ui/border/border-common.ts +++ b/ui/border/border.ts @@ -7,54 +7,13 @@ import types = require("utils/types"); import viewModule = require("ui/core/view"); import utils = require("utils/utils"); -var cornerRadiusProperty = new dependencyObservable.Property( - "cornerRadius", - "Border", - new proxy.PropertyMetadata(0, dependencyObservable.PropertyMetadataSettings.AffectsStyle) - ); - -var borderWidthProperty = new dependencyObservable.Property( - "borderWidth", - "Border", - new proxy.PropertyMetadata(0, dependencyObservable.PropertyMetadataSettings.AffectsStyle) - ); - -var borderColorProperty = new dependencyObservable.Property( - "borderColor", - "Border", - new proxy.PropertyMetadata(undefined, dependencyObservable.PropertyMetadataSettings.AffectsStyle) - ); - @Deprecated export class Border extends contentView.ContentView implements definition.Border { - - public static cornerRadiusProperty = cornerRadiusProperty; - public static borderWidthProperty = borderWidthProperty; - public static borderColorProperty = borderColorProperty; - get cornerRadius(): number { - return this._getValue(Border.cornerRadiusProperty); + return this.borderRadius; } set cornerRadius(value: number) { - this._setValue(Border.cornerRadiusProperty, value); - } - - get borderWidth(): number { - return this._getValue(Border.borderWidthProperty); - } - set borderWidth(value: number) { - this._setValue(Border.borderWidthProperty, value); - } - - get borderColor(): color.Color { - return this._getValue(Border.borderColorProperty); - } - set borderColor(value: color.Color) { - if (types.isString(value) || types.isNumber(value)) { - this._setValue(Border.borderColorProperty, new color.Color(value)); - } else { - this._setValue(Border.borderColorProperty, value); - } + this.borderRadius = value; } public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void { @@ -82,8 +41,4 @@ export class Border extends contentView.ContentView implements definition.Border var borderSize = this.borderWidth * density; viewModule.View.layoutChild(this, this.content, borderSize, borderSize, right - left - borderSize, bottom - top - borderSize); } - - public _updateAndroidBorder() { - // This is android specific method. - } } \ No newline at end of file diff --git a/ui/builder/component-builder.ts b/ui/builder/component-builder.ts index 5f2c66dee..7d20422c1 100644 --- a/ui/builder/component-builder.ts +++ b/ui/builder/component-builder.ts @@ -174,8 +174,8 @@ export function setPropertyValue(instance: view.View, instanceModule: Object, ex } else { var attrHandled = false; - if ((instance).applyXmlAttribute) { - attrHandled = (instance).applyXmlAttribute(propertyName, propertyValue); + if ((instance)._applyXmlAttribute) { + attrHandled = (instance)._applyXmlAttribute(propertyName, propertyValue); } if (!attrHandled) { diff --git a/ui/core/view-common.ts b/ui/core/view-common.ts index c3b6f3f9a..8e63e4621 100644 --- a/ui/core/view-common.ts +++ b/ui/core/view-common.ts @@ -389,7 +389,7 @@ export class View extends proxy.ProxyObject implements definition.View { return this._style; } set style(value) { - this._applyInlineStyle(value); + throw new Error("View.style property is read-only."); } get isLayoutValid(): boolean { @@ -763,7 +763,6 @@ export class View extends proxy.ProxyObject implements definition.View { if (types.isString(inlineStyle)) { try { this.style._beginUpdate(); - this.style._resetLocalValues(); styleScope.applyInlineSyle(this, inlineStyle); } finally { this.style._endUpdate(); @@ -942,6 +941,15 @@ export class View extends proxy.ProxyObject implements definition.View { this._requestedVisualState = state; } + public _applyXmlAttribute(attribute, value): boolean { + if (attribute === "style") { + this._applyInlineStyle(value); + return true; + } + + return false; + } + public _updateLayout() { // needed for iOS. } diff --git a/ui/core/view.d.ts b/ui/core/view.d.ts index be8c9bb3a..b2011359a 100644 --- a/ui/core/view.d.ts +++ b/ui/core/view.d.ts @@ -94,7 +94,7 @@ declare module "ui/core/view" { * This class is the base class for all UI components. * A View occupies a rectangular area on the screen and is responsible for drawing and layouting of all UI components within. */ - export class View extends proxy.ProxyObject { + export class View extends proxy.ProxyObject implements ApplyXmlAttributes { /** * Gets or sets the corner radius of the view. */ @@ -441,6 +441,8 @@ declare module "ui/core/view" { _updateLayout(): void; + _applyXmlAttribute(attribute, value): boolean; + /** * Called my measure method to cache measureSpecs. */ @@ -515,6 +517,6 @@ declare module "ui/core/view" { * @param attrValue - the value of the attribute (bold) * Should return true if this attribute is handled and there is no need default handler to process it. */ - applyXmlAttribute(attributeName: string, attrValue: any): boolean; + _applyXmlAttribute(attributeName: string, attrValue: any): boolean; } } \ No newline at end of file diff --git a/ui/enums/enums.d.ts b/ui/enums/enums.d.ts index ef08a32cc..268302f8c 100644 --- a/ui/enums/enums.d.ts +++ b/ui/enums/enums.d.ts @@ -404,7 +404,7 @@ /** - * Specifies nackground repeat. + * Specifies background repeat. */ export module BackgroundRepeat { export var repeat: string; diff --git a/ui/layouts/grid-layout/grid-layout.ts b/ui/layouts/grid-layout/grid-layout.ts index c62b96de0..df8bc5727 100644 --- a/ui/layouts/grid-layout/grid-layout.ts +++ b/ui/layouts/grid-layout/grid-layout.ts @@ -446,7 +446,7 @@ export class GridLayout extends layouts.Layout implements definition.GridLayout, } } - applyXmlAttribute(attributeName: string, attributeValue: any): boolean { + _applyXmlAttribute(attributeName: string, attributeValue: any): boolean { if (attributeName === "columns") { this.setColumns(attributeValue); return true; @@ -456,7 +456,7 @@ export class GridLayout extends layouts.Layout implements definition.GridLayout, return true; } - return false; + return super._applyXmlAttribute(attributeName, attributeValue); } private static parseItemSpecs(value: string): Array { diff --git a/ui/styling/style.ts b/ui/styling/style.ts index 6040fb794..e52f2d263 100644 --- a/ui/styling/style.ts +++ b/ui/styling/style.ts @@ -25,7 +25,7 @@ var noStylingClasses = {}; export class Style extends observable.DependencyObservable implements styling.Style { private _view: view.View; - private _inUpdate = false; + private _updateCounter = 0; private _nativeSetters = new Map(); get color(): color.Color { @@ -265,13 +265,18 @@ export class Style extends observable.DependencyObservable implements styling.St } public _beginUpdate() { - this._inUpdate = true; + this._updateCounter++; } public _endUpdate() { - this._inUpdate = false; - this._nativeSetters.forEach((newValue, property, map) => { this._applyStyleProperty(property, newValue); }); - this._nativeSetters.clear(); + this._updateCounter--; + if (this._updateCounter < 0) { + throw new Error("style._endUpdate() called, but no update is in progress."); + } + if (this._updateCounter === 0) { + this._nativeSetters.forEach((newValue, property, map) => { this._applyStyleProperty(property, newValue); }); + this._nativeSetters.clear(); + } } public _resetCssValues() { @@ -334,7 +339,7 @@ export class Style extends observable.DependencyObservable implements styling.St } private _applyStyleProperty(property: dependencyObservable.Property, newValue: any) { - if (this._inUpdate) { + if (this._updateCounter > 0) { this._nativeSetters.set(property, newValue); return; } @@ -486,6 +491,7 @@ function onBackgroundImagePropertyChanged(data: observable.PropertyChangeData) { var style =