Merge pull request #1079 from NativeScript/white-space

white-space CSS support added
This commit is contained in:
Vladimir Enchev
2015-11-12 15:39:32 +02:00
23 changed files with 321 additions and 78 deletions

View File

@ -189,6 +189,9 @@
<SubType>Designer</SubType>
</Content>
<Content Include="apps\tests\pages\tab-view.xml" />
<Content Include="apps\ui-tests-app\css\white-space.xml">
<SubType>Designer</SubType>
</Content>
<Content Include="apps\ui-tests-app\html-view\html-view.xml">
<SubType>Designer</SubType>
</Content>
@ -239,6 +242,7 @@
<DependentUpon>color.xml</DependentUpon>
</TypeScriptCompile>
<TypeScriptCompile Include="apps\ui-tests-app\css\text-decoration.ts" />
<TypeScriptCompile Include="apps\ui-tests-app\css\white-space.ts" />
<TypeScriptCompile Include="apps\ui-tests-app\html-view\html-view.ts">
<DependentUpon>html-view.xml</DependentUpon>
</TypeScriptCompile>

View File

@ -1,12 +1,15 @@
import TKUnit = require("../../TKUnit");
import helper = require("../helper");
import buttonModule = require("ui/button");
import labelModule = require("ui/label");
import stackModule = require("ui/layouts/stack-layout");
import page = require("ui/page");
import color = require("color");
import observable = require("data/observable");
import enums = require("ui/enums");
import fontModule = require("ui/styling/font");
import platform = require("platform");
import viewModule = require("ui/core/view");
var testBtn: buttonModule.Button;
var testPage: page.Page;
@ -33,6 +36,14 @@ export function tearDown() {
testPage.css = "";
}
export function test_setting_textDecoration_property_from_CSS_is_applied_to_Style() {
test_property_from_CSS_is_applied_to_style("textDecoration", "text-decoration", "underline");
}
export function test_setting_whiteSpace_property_from_CSS_is_applied_to_Style() {
test_property_from_CSS_is_applied_to_style("whiteSpace", "white-space", "nowrap");
}
export function test_CSS_properties_are_applied_to_Style() {
test_property_from_CSS_is_applied_to_style("color", "color", new color.Color("#FF0000"), "#FF0000");
}
@ -244,6 +255,58 @@ export function test_setting_different_color_triggers_property_change() {
TKUnit.assert(changed, "Property changed not triggered.");
}
export function test_setting_same_textDecoration_does_not_trigger_property_change() {
var testView = new buttonModule.Button();
testView.style.textDecoration = "underline";
var changed = false;
testView.style.on(observable.Observable.propertyChangeEvent, (data) => {
changed = true;
});
testView.style.textDecoration = "underline";
TKUnit.assert(!changed, "Property changed triggered.");
}
export function test_setting_different_textDecoration_triggers_property_change() {
var testView = new buttonModule.Button();
testView.style.textDecoration = "underline";
var changed = false;
testView.style.on(observable.Observable.propertyChangeEvent, (data) => {
changed = true;
});
testView.style.textDecoration = "none";
TKUnit.assert(changed, "Property changed not triggered.");
}
export function test_setting_same_whiteSpace_does_not_trigger_property_change() {
var testView = new buttonModule.Button();
testView.style.whiteSpace = "normal";
var changed = false;
testView.style.on(observable.Observable.propertyChangeEvent, (data) => {
changed = true;
});
testView.style.whiteSpace = "normal";
TKUnit.assert(!changed, "Property changed triggered.");
}
export function test_setting_different_whiteSpace_triggers_property_change() {
var testView = new buttonModule.Button();
testView.style.whiteSpace = "normal";
var changed = false;
testView.style.on(observable.Observable.propertyChangeEvent, (data) => {
changed = true;
});
testView.style.whiteSpace = "nowrap";
TKUnit.assert(changed, "Property changed not triggered.");
}
export function test_setting_same_backgroundColor_does_not_trigger_property_change() {
var testView = new buttonModule.Button();
testView.style.backgroundColor = new color.Color("#FF0000");
@ -366,3 +429,63 @@ function test_native_font(style: string, weight: string) {
}
//TODO: If needed add tests for other platforms
}
export var test_setting_button_whiteSpace_normal_sets_native = function () {
var testView = new buttonModule.Button();
testView.style.whiteSpace = "nowrap";
helper.buildUIAndRunTest(testView, function (views: Array<viewModule.View>) {
if (platform.device.os === platform.platformNames.android) {
TKUnit.assertEqual((<android.widget.Button>testView.android).getEllipsize(), android.text.TextUtils.TruncateAt.END);
} else if (platform.device.os === platform.platformNames.ios) {
TKUnit.assertEqual((<UIButton>testView.ios).titleLabel.lineBreakMode, NSLineBreakMode.NSLineBreakByTruncatingMiddle);
TKUnit.assertEqual((<UIButton>testView.ios).titleLabel.numberOfLines, 1);
}
});
}
export var test_setting_label_whiteSpace_normal_sets_native = function () {
var testView = new labelModule.Label();
testView.style.whiteSpace = "nowrap";
helper.buildUIAndRunTest(testView, function (views: Array<viewModule.View>) {
if (platform.device.os === platform.platformNames.android) {
TKUnit.assertEqual((<android.widget.TextView>testView.android).getEllipsize(), android.text.TextUtils.TruncateAt.END);
} else if (platform.device.os === platform.platformNames.ios) {
TKUnit.assertEqual((<UILabel>testView.ios).lineBreakMode, NSLineBreakMode.NSLineBreakByTruncatingTail);
TKUnit.assertEqual((<UILabel>testView.ios).numberOfLines, 1);
}
});
}
export var test_setting_button_whiteSpace_nowrap_sets_native = function () {
var testView = new buttonModule.Button();
testView.style.whiteSpace = "normal";
helper.buildUIAndRunTest(testView, function (views: Array<viewModule.View>) {
if (platform.device.os === platform.platformNames.android) {
TKUnit.assertNull((<android.widget.Button>testView.android).getEllipsize(), null);
} else if (platform.device.os === platform.platformNames.ios) {
TKUnit.assertEqual((<UIButton>testView.ios).titleLabel.lineBreakMode, NSLineBreakMode.NSLineBreakByWordWrapping);
TKUnit.assertEqual((<UIButton>testView.ios).titleLabel.numberOfLines, 0);
}
});
}
export var test_setting_label_whiteSpace_nowrap_sets_native = function () {
var testView = new labelModule.Label();
testView.style.whiteSpace = "normal";
helper.buildUIAndRunTest(testView, function (views: Array<viewModule.View>) {
if (platform.device.os === platform.platformNames.android) {
TKUnit.assertNull((<android.widget.TextView>testView.android).getEllipsize(), null);
} else if (platform.device.os === platform.platformNames.ios) {
TKUnit.assertEqual((<UILabel>testView.ios).lineBreakMode, NSLineBreakMode.NSLineBreakByWordWrapping);
TKUnit.assertEqual((<UILabel>testView.ios).numberOfLines, 0);
}
});
}

View File

@ -1,17 +1,18 @@
var obj;
export function loaded(args) {
obj = args.object;
}
import view = require("ui/core/view");
import observable = require("data/observable");
import label = require("ui/label");
export function butonTap(args) {
if (obj.style.textDecoration === "underline") {
obj.style.textDecoration = "line-through";
} else if (obj.style.textDecoration === "line-through") {
obj.style.textDecoration = "line-through underline";
} else if (obj.style.textDecoration === "line-through underline") {
obj.style.textDecoration = "none";
} else if (obj.style.textDecoration === "none") {
obj.style.textDecoration = "underline";
var btn = <view.View>args.object;
var lbl = <label.Label>btn.parent.getViewById("Label1");
if (lbl.style.textDecoration === "underline") {
lbl.style.textDecoration = "line-through";
} else if (lbl.style.textDecoration === "line-through") {
lbl.style.textDecoration = "line-through underline";
} else if (lbl.style.textDecoration === "line-through underline") {
lbl.style.textDecoration = "none";
} else if (lbl.style.textDecoration === "none") {
lbl.style.textDecoration = "underline";
}
}

View File

@ -2,7 +2,7 @@
<ScrollView>
<StackLayout>
<Button text="Change" tap="butonTap" />
<Label text="Text" style.textDecoration="underline" loaded="loaded"/>
<Label id="Label1" text="Text" style.textDecoration="underline" />
<Label text="Label" style="text-decoration:none" />
<Label text="Label" style="text-decoration:underline" />

View File

@ -0,0 +1,14 @@
import view = require("ui/core/view");
import observable = require("data/observable");
import label = require("ui/label");
export function butonTap(args: observable.EventData) {
var btn = <view.View>args.object;
var lbl = <label.Label>btn.parent.getViewById("Label1");
if (lbl.style.whiteSpace === "normal") {
lbl.style.whiteSpace = "nowrap";
} else if (lbl.style.whiteSpace === "nowrap") {
lbl.style.whiteSpace = "normal";
}
}

View File

@ -0,0 +1,20 @@
<Page >
<ScrollView>
<StackLayout width="50">
<Button text="Change" tap="butonTap" />
<Label id="Label1" text="Text Text" style.whiteSpace="normal" />
<Label text="Label Normal" style="white-space:normal" />
<Label text="Label Nowrap" style="white-space:nowrap" />
<TextField text="TextField Normal" style="white-space:normal" />
<TextField text="TextField Nowrap" style="white-space:nowrap" />
<TextView text="TextView Normal" style="white-space:normal" />
<TextView text="TextView Nowrap" style="white-space:nowrap" />
<Button text="Button Normal" style="white-space:normal" />
<Button text="Button Nowrap" style="white-space:nowrap" />
</StackLayout>
</ScrollView>
</Page>

View File

@ -90,4 +90,6 @@ examples.set("webview", "web-view/web-view");
examples.set("webtest", "web-view/web-view-test");
examples.set("decoration", "css/text-decoration");
examples.set("whitespace", "css/white-space");
//VM.set("selected", "tabAll");

View File

@ -334,6 +334,7 @@
"apps/ui-tests-app/css/background.ts",
"apps/ui-tests-app/css/styles.ts",
"apps/ui-tests-app/css/text-decoration.ts",
"apps/ui-tests-app/css/white-space.ts",
"apps/ui-tests-app/dialogs/dialogs.ts",
"apps/ui-tests-app/dialogs/view-model.ts",
"apps/ui-tests-app/font/button.ts",

View File

@ -5,6 +5,7 @@ import proxy = require("ui/core/proxy");
import formattedString = require("text/formatted-string");
import observable = require("data/observable");
import weakEvents = require("ui/core/weak-event-listener");
import enums = require("ui/enums");
var textProperty = new dependencyObservable.Property(
"text",
@ -121,4 +122,11 @@ export class Button extends view.View implements definition.Button {
public _addChildFromBuilder(name: string, value: any): void {
formattedString.FormattedString.addFormattedStringToView(this, name, value);
}
}
}
function onTextWrapPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var v = <view.View>data.object;
v.style.whiteSpace = data.newValue ? enums.WhiteSpace.normal : enums.WhiteSpace.nowrap;
}
(<proxy.PropertyMetadata>Button.textWrapProperty.metadata).onSetNativeValue = onTextWrapPropertyChanged;

View File

@ -5,18 +5,6 @@ import proxy = require("ui/core/proxy");
global.moduleMerge(common, exports);
function onTextWrapPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var btn = <Button>data.object;
if (!btn.android) {
return;
}
btn.android.setSingleLine(data.newValue);
}
// register the setNativeValue callback
(<proxy.PropertyMetadata>common.Button.textWrapProperty.metadata).onSetNativeValue = onTextWrapPropertyChanged;
export class Button extends common.Button {
private _android: android.widget.Button;
private _isPressed: boolean;

View File

@ -16,6 +16,11 @@ declare module "ui/button" {
*/
public static textProperty: dependencyObservable.Property;
/**
* Dependency property used to support binding operations for the text wrapping of the current button instance.
*/
public static textWrapProperty: dependencyObservable.Property;
/**
* String value used when hooking to tap event.
*/

View File

@ -26,18 +26,6 @@ class TapHandlerImpl extends NSObject {
global.moduleMerge(common, exports);
function onTextWrapPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var btn = <Button>data.object;
if (!btn.ios) {
return;
}
btn.ios.titleLabel.lineBreakMode = data.newValue ? NSLineBreakMode.NSLineBreakByWordWrapping : 0;
}
// register the setNativeValue callback
(<proxy.PropertyMetadata>common.Button.textWrapProperty.metadata).onSetNativeValue = onTextWrapPropertyChanged;
export class Button extends common.Button {
private _ios: UIButton;
private _tapHandler: NSObject;

15
ui/enums/enums.d.ts vendored
View File

@ -437,6 +437,21 @@
*/
export var lineThrough: string;
}
/**
* Specifies different white spaces.
*/
export module WhiteSpace {
/**
* Normal wrap.
*/
export var normal: string;
/**
* No wrap.
*/
export var nowrap: string;
}
/**
* Specifies different font weights.

View File

@ -26,6 +26,11 @@ export module TextDecoration {
export var lineThrough = "line-through";
}
export module WhiteSpace {
export var normal = "normal";
export var nowrap = "nowrap";
}
export module Orientation {
export var horizontal = "horizontal";
export var vertical = "vertical";

View File

@ -2,6 +2,8 @@
import dependencyObservable = require("ui/core/dependency-observable");
import proxy = require("ui/core/proxy");
import textBase = require("ui/text-base");
import enums = require("ui/enums");
import view = require("ui/core/view");
export class Label extends textBase.TextBase implements definition.Label {
public static textWrapProperty = new dependencyObservable.Property(
@ -20,4 +22,11 @@ export class Label extends textBase.TextBase implements definition.Label {
set textWrap(value: boolean) {
this._setValue(Label.textWrapProperty, value);
}
}
}
function onTextWrapPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var v = <view.View>data.object;
v.style.whiteSpace = data.newValue ? enums.WhiteSpace.normal : enums.WhiteSpace.nowrap;
}
(<proxy.PropertyMetadata>Label.textWrapProperty.metadata).onSetNativeValue = onTextWrapPropertyChanged;

View File

@ -2,25 +2,6 @@
import dependencyObservable = require("ui/core/dependency-observable");
import proxy = require("ui/core/proxy");
function onTextWrapPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var label = <Label>data.object;
if (!label.android) {
return;
}
if (data.newValue) {
label.android.setSingleLine(false);
label.android.setEllipsize(null);
}
else {
label.android.setSingleLine(true);
label.android.setEllipsize(android.text.TextUtils.TruncateAt.END);
}
}
// register the setNativeValue callback
(<proxy.PropertyMetadata>common.Label.textWrapProperty.metadata).onSetNativeValue = onTextWrapPropertyChanged;
global.moduleMerge(common, exports);
export class Label extends common.Label {

View File

@ -4,22 +4,7 @@ import dependencyObservable = require("ui/core/dependency-observable");
import proxy = require("ui/core/proxy");
import utils = require("utils/utils");
import viewModule = require("ui/core/view");
function onTextWrapPropertyChanged(data: dependencyObservable.PropertyChangeData) {
var label = <Label>data.object;
if (data.newValue) {
label.ios.lineBreakMode = NSLineBreakMode.NSLineBreakByWordWrapping;
label.ios.numberOfLines = 0;
}
else {
label.ios.lineBreakMode = NSLineBreakMode.NSLineBreakByTruncatingTail;
label.ios.numberOfLines = 1;
}
}
// register the setNativeValue callback
(<proxy.PropertyMetadata>common.Label.textWrapProperty.metadata).onSetNativeValue = onTextWrapPropertyChanged;
import enums = require("ui/enums");
global.moduleMerge(common, exports);
@ -104,7 +89,7 @@ export class Label extends common.Label {
var nativeSize = nativeView.sizeThatFits(CGSizeMake(width, height));
var labelWidth = nativeSize.width;
if (!this.textWrap) {
if (!this.textWrap && this.style.whiteSpace !== enums.WhiteSpace.nowrap) {
labelWidth = Math.min(labelWidth, width);
}

View File

@ -32,6 +32,16 @@ export function textDecorationConverter(value: string): string {
}
}
export function whiteSpaceConverter(value: string): string {
switch (value) {
case enums.WhiteSpace.normal:
case enums.WhiteSpace.nowrap:
return value;
default:
throw new Error("CSS white-space \"" + value + "\" is not supported.");
}
}
export var numberConverter = parseFloat;
export function visibilityConverter(value: string): string {

View File

@ -63,6 +63,7 @@ declare module "ui/styling/style" {
public verticalAlignment: string;
public visibility: string;
public opacity: number;
public whiteSpace: string;
new(parentView: View);

View File

@ -245,6 +245,10 @@ function isTextDecorationValid(value: string): boolean {
return values.indexOf(enums.TextDecoration.none) !== -1 || values.indexOf(enums.TextDecoration.underline) !== -1 || values.indexOf(enums.TextDecoration.lineThrough) !== -1;
}
function isWhiteSpaceValid(value: string): boolean {
return value === enums.WhiteSpace.nowrap || value === enums.WhiteSpace.normal;
}
function onVisibilityChanged(data: PropertyChangeData) {
(<any>data.object)._view._isVisibleCache = data.newValue === enums.Visibility.visible;
}
@ -549,6 +553,13 @@ export class Style extends DependencyObservable implements styling.Style {
this._setValue(textDecorationProperty, value);
}
get whiteSpace(): string {
return this._getValue(whiteSpaceProperty);
}
set whiteSpace(value: string) {
this._setValue(whiteSpaceProperty, value);
}
public _updateTextDecoration() {
if (this._getValue(textDecorationProperty) !== enums.TextDecoration.none) {
this._applyProperty(textDecorationProperty, this._getValue(textDecorationProperty));
@ -810,6 +821,9 @@ export var opacityProperty = new styleProperty.Property("opacity", "opacity",
export var textDecorationProperty = new styleProperty.Property("textDecoration", "text-decoration",
new PropertyMetadata(enums.TextDecoration.none, PropertyMetadataSettings.None, undefined, isTextDecorationValid), converters.textDecorationConverter);
export var whiteSpaceProperty = new styleProperty.Property("whiteSpace", "white-space",
new PropertyMetadata(undefined, AffectsLayout, undefined, isWhiteSpaceValid), converters.whiteSpaceConverter);
// Helper property holding most layout related properties available in CSS.
// When layout related properties are set in CSS we chache them and send them to the native view in a single call.
export var nativeLayoutParamsProperty = new styleProperty.Property("nativeLayoutParams", "nativeLayoutParams",

View File

@ -438,6 +438,15 @@ export class TextViewStyler implements definition.stylers.Styler {
setTextDecoration(view._nativeView, enums.TextDecoration.none);
}
// white-space
private static setWhiteSpaceProperty(view: view.View, newValue: any) {
setWhiteSpace(view._nativeView, newValue);
}
private static resetWhiteSpaceProperty(view: view.View, nativeValue: any) {
setWhiteSpace(view._nativeView, enums.WhiteSpace.normal);
}
public static registerHandlers() {
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setColorProperty,
@ -458,6 +467,10 @@ export class TextViewStyler implements definition.stylers.Styler {
TextViewStyler.setTextDecorationProperty,
TextViewStyler.resetTextDecorationProperty), "TextBase");
style.registerHandler(style.whiteSpaceProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setWhiteSpaceProperty,
TextViewStyler.resetWhiteSpaceProperty), "TextBase");
// Register the same stylers for Button.
// It also derives from TextView but is not under TextBase in our View hierarchy.
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
@ -478,6 +491,10 @@ export class TextViewStyler implements definition.stylers.Styler {
style.registerHandler(style.textDecorationProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setTextDecorationProperty,
TextViewStyler.resetTextDecorationProperty), "Button");
style.registerHandler(style.whiteSpaceProperty, new stylersCommon.StylePropertyChangedHandler(
TextViewStyler.setWhiteSpaceProperty,
TextViewStyler.resetWhiteSpaceProperty), "Button");
}
}
@ -501,6 +518,11 @@ function setTextDecoration(view: android.widget.TextView, value: string) {
}
}
function setWhiteSpace(view: android.widget.TextView, value: string) {
view.setSingleLine(value === enums.WhiteSpace.nowrap);
view.setEllipsize(value === enums.WhiteSpace.nowrap ? android.text.TextUtils.TruncateAt.END : null);
}
export class ActivityIndicatorStyler implements definition.stylers.Styler {
private static setColorProperty(view: view.View, newValue: any) {
var bar = <android.widget.ProgressBar>view._nativeView;

View File

@ -8,6 +8,7 @@ import background = require("ui/styling/background");
import frame = require("ui/frame");
import tabView = require("ui/tab-view");
import formattedString = require("text/formatted-string");
import types = require("utils/types");
global.moduleMerge(stylersCommon, exports);
@ -16,7 +17,9 @@ interface TextUIView {
textAlignment: number;
textColor: UIColor;
text : string;
attributedText : NSAttributedString;
attributedText: NSAttributedString;
lineBreakMode: number;
numberOfLines: number;
}
var ignorePropertyHandler = new stylersCommon.StylePropertyChangedHandler(
@ -263,6 +266,15 @@ export class ButtonStyler implements definition.stylers.Styler {
setTextDecoration((<UIButton>view.ios).titleLabel, enums.TextDecoration.none);
}
// white-space
private static setWhiteSpaceProperty(view: view.View, newValue: any) {
setWhiteSpace((<UIButton>view.ios).titleLabel, newValue, view.ios);
}
private static resetWhiteSpaceProperty(view: view.View, nativeValue: any) {
setWhiteSpace((<UIButton>view.ios).titleLabel, enums.WhiteSpace.normal, view.ios);
}
public static registerHandlers() {
style.registerHandler(style.colorProperty, new stylersCommon.StylePropertyChangedHandler(
ButtonStyler.setColorProperty,
@ -286,6 +298,10 @@ export class ButtonStyler implements definition.stylers.Styler {
style.registerHandler(style.textDecorationProperty, new stylersCommon.StylePropertyChangedHandler(
ButtonStyler.setTextDecorationProperty,
ButtonStyler.resetTextDecorationProperty), "Button");
style.registerHandler(style.whiteSpaceProperty, new stylersCommon.StylePropertyChangedHandler(
ButtonStyler.setWhiteSpaceProperty,
ButtonStyler.resetWhiteSpaceProperty), "Button");
}
}
@ -330,6 +346,15 @@ export class TextBaseStyler implements definition.stylers.Styler {
setTextDecoration(view._nativeView, enums.TextDecoration.none);
}
// white-space
private static setWhiteSpaceProperty(view: view.View, newValue: any) {
setWhiteSpace(view._nativeView, newValue);
}
private static resetWhiteSpaceProperty(view: view.View, nativeValue: any) {
setWhiteSpace(view._nativeView, enums.WhiteSpace.normal);
}
// color
private static setColorProperty(view: view.View, newValue: any) {
var ios: TextUIView = <TextUIView>view._nativeView;
@ -365,6 +390,10 @@ export class TextBaseStyler implements definition.stylers.Styler {
style.registerHandler(style.textDecorationProperty, new stylersCommon.StylePropertyChangedHandler(
TextBaseStyler.setTextDecorationProperty,
TextBaseStyler.resetTextDecorationProperty), "TextBase");
style.registerHandler(style.whiteSpaceProperty, new stylersCommon.StylePropertyChangedHandler(
TextBaseStyler.setWhiteSpaceProperty,
TextBaseStyler.resetWhiteSpaceProperty), "TextBase");
}
}
@ -928,6 +957,21 @@ function setTextDecoration(view: TextUIView, value: string) {
}
}
function setWhiteSpace(view: TextUIView, value: string, parentView?: UIView) {
if (value === enums.WhiteSpace.normal) {
view.lineBreakMode = NSLineBreakMode.NSLineBreakByWordWrapping;
view.numberOfLines = 0;
}
else {
if (parentView) {
view.lineBreakMode = NSLineBreakMode.NSLineBreakByTruncatingMiddle;
} else {
view.lineBreakMode = NSLineBreakMode.NSLineBreakByTruncatingTail;
}
view.numberOfLines = 1;
}
}
function setTextDecorationNative(view: TextUIView, value: string | NSAttributedString, attributes: NSMutableDictionary) {
var attributedString: NSMutableAttributedString;
@ -935,7 +979,7 @@ function setTextDecorationNative(view: TextUIView, value: string | NSAttributedS
attributedString = NSMutableAttributedString.alloc().initWithAttributedString(value);
attributedString.addAttributesRange(attributes, NSRangeFromString(attributedString.string));
} else {
view.attributedText = NSAttributedString.alloc().initWithStringAttributes(<string>value, attributes);
view.attributedText = NSAttributedString.alloc().initWithStringAttributes(types.isString(value) ? <string>value : "", attributes);
}
}

View File

@ -198,6 +198,9 @@
*/
opacity: number;
textDecoration: string;
whiteSpace: string;
//@private
public _beginUpdate();
public _endUpdate();