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

@@ -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();