Merge pull request #1345 from NativeScript/text-transform-fix

text-transform and text-decoration with formattedText fixed
This commit is contained in:
Vladimir Enchev
2016-01-12 10:58:22 +02:00
10 changed files with 156 additions and 113 deletions

View File

@ -591,7 +591,7 @@ export var test_setting_button_textTransform_sets_native = function () {
testView.text = initial;
testView.style.textTransform = enums.TextTransform.capitalize;
executeTransformTest(testView, androidText, function (v) { return (<UIButton>v.ios).attributedTitleForState(UIControlState.UIControlStateNormal).string; });
executeTransformTest(testView, androidText, function (v) { return (<UIButton>v.ios).titleForState(UIControlState.UIControlStateNormal); });
}
export var test_setting_label_textTransform_and_textDecoration_sets_native = function () {

View File

@ -0,0 +1,27 @@
<Page>
<StackLayout>
<Label text="textText" style="text-transform: uppercase; text-decoration: underline line-through;" />
<Label style="text-transform: uppercase; text-decoration: underline line-through;">
<Label.formattedText>
<FormattedString>
<FormattedString.spans>
<Span text="text" fontAttributes="Bold" foregroundColor="#ff0000" />
<Span text="Text" fontAttributes="Italic" foregroundColor="#00ff00" />
</FormattedString.spans>
</FormattedString>
</Label.formattedText>
</Label>
<Button text="textText" style="text-transform: uppercase; text-decoration: underline line-through;" />
<Button style="text-transform: uppercase; text-decoration: underline line-through;">
<Button.formattedText>
<FormattedString>
<FormattedString.spans>
<Span text="text" fontAttributes="Bold" foregroundColor="#ff0000" />
<Span text="Text" fontAttributes="Italic" foregroundColor="#00ff00" />
</FormattedString.spans>
</FormattedString>
</Button.formattedText>
</Button>
</StackLayout>
</Page>

View File

@ -27,6 +27,28 @@
<Button text="button Button" style="text-transform:lowercase" />
<Button text="button Button" style="text-transform:uppercase; text-decoration:underline;" />
<Label style="text-transform: uppercase; text-decoration: underline line-through;">
<Label.formattedText>
<FormattedString>
<FormattedString.spans>
<Span text="text" fontAttributes="Bold" foregroundColor="#ff0000" />
<Span text="Text" fontAttributes="Italic" foregroundColor="#00ff00" />
</FormattedString.spans>
</FormattedString>
</Label.formattedText>
</Label>
<Button style="text-transform: uppercase; text-decoration: underline line-through;">
<Button.formattedText>
<FormattedString>
<FormattedString.spans>
<Span text="text" fontAttributes="Bold" foregroundColor="#ff0000" />
<Span text="Text" fontAttributes="Italic" foregroundColor="#00ff00" />
</FormattedString.spans>
</FormattedString>
</Button.formattedText>
</Button>
</StackLayout>
</ScrollView>
</Page>

View File

@ -111,6 +111,7 @@ export class Button extends view.View implements definition.Button {
// then the property defaults to a system value. Therefore, at a minimum, you should
// set the value for the normal state.
this.ios.setAttributedTitleForState(value._formattedText, UIControlState.UIControlStateNormal);
this.style._updateTextDecoration();
}
}

View File

@ -135,20 +135,20 @@ export class ButtonStyler implements style.Styler {
// text-decoration
private static setTextDecorationProperty(view: view.View, newValue: any) {
utils.ios.setTextDecoration((<UIButton>view.ios).titleLabel, newValue);
utils.ios.setTextDecorationAndTransform(view, newValue, view.style.textTransform);
}
private static resetTextDecorationProperty(view: view.View, nativeValue: any) {
utils.ios.setTextDecoration((<UIButton>view.ios).titleLabel, enums.TextDecoration.none);
utils.ios.setTextDecorationAndTransform(view, enums.TextDecoration.none, view.style.textTransform);
}
// text-transform
private static setTextTransformProperty(view: view.View, newValue: any) {
utils.ios.setTextTransform(view.ios, newValue);
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, newValue);
}
private static resetTextTransformProperty(view: view.View, nativeValue: any) {
utils.ios.setTextTransform(view.ios, enums.TextTransform.none);
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, enums.TextTransform.none);
}
// white-space

View File

@ -94,11 +94,11 @@ export class TextBaseStyler implements style.Styler {
// text-transform
private static setTextTransformProperty(view: view.View, newValue: any) {
utils.ad.setTextTransform(view._nativeView, newValue);
utils.ad.setTextTransform(view, newValue);
}
private static resetTextTransformProperty(view: view.View, nativeValue: any) {
utils.ad.setTextTransform(view._nativeView, enums.TextTransform.none);
utils.ad.setTextTransform(view, enums.TextTransform.none);
}
// white-space

View File

@ -40,20 +40,20 @@ export class TextBaseStyler implements style.Styler {
// text-decoration
private static setTextDecorationProperty(view: view.View, newValue: any) {
utils.ios.setTextDecoration(view._nativeView, newValue);
utils.ios.setTextDecorationAndTransform(view, newValue, view.style.textTransform);
}
private static resetTextDecorationProperty(view: view.View, nativeValue: any) {
utils.ios.setTextDecoration(view._nativeView, enums.TextDecoration.none);
utils.ios.setTextDecorationAndTransform(view, enums.TextDecoration.none, view.style.textTransform);
}
// text-transform
private static setTextTransformProperty(view: view.View, newValue: any) {
utils.ios.setTextTransform(view._nativeView, newValue);
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, newValue);
}
private static resetTextTransformProperty(view: view.View, nativeValue: any) {
utils.ios.setTextTransform(view._nativeView, enums.TextTransform.none);
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, enums.TextTransform.none);
}
// white-space

View File

@ -77,38 +77,52 @@ export module ad {
}
}
export function setTextTransform(view: android.widget.TextView, value: string) {
export function setTextTransform(v, value: string) {
let view = v._nativeView;
let str = view.getText() + "";
let result = getTransformedString(value, view, str);
if (v.formattedText) {
for (var i = 0; i < v.formattedText.spans.length; i++) {
var span = v.formattedText.spans.getItem(i);
span.text = getTransformedString(value, view, span.text);
}
} else {
view.setText(result);
}
}
function getTransformedString(textTransform: string, view, stringToTransform: string): string {
let result: string;
switch (value) {
switch (textTransform) {
case enums.TextTransform.none:
default:
result = view["originalString"] || str;
result = view["originalString"] || stringToTransform;
if (view["transformationMethod"]) {
view.setTransformationMethod(view["transformationMethod"]);
}
break;
case enums.TextTransform.uppercase:
view.setTransformationMethod(null);
result = str.toUpperCase();
result = stringToTransform.toUpperCase();
break;
case enums.TextTransform.lowercase:
view.setTransformationMethod(null);
result = str.toLowerCase();
result = stringToTransform.toLowerCase();
break;
case enums.TextTransform.capitalize:
view.setTransformationMethod(null);
result = getCapitalizedString(str);
result = getCapitalizedString(stringToTransform);
break;
}
if (!view["originalString"]) {
view["originalString"] = str;
view["originalString"] = stringToTransform;
view["transformationMethod"] = view.getTransformationMethod();
}
view.setText(result);
return result;
}
function getCapitalizedString(str: string): string {

4
utils/utils.d.ts vendored
View File

@ -145,10 +145,8 @@
* Module with ios specific utilities.
*/
module ios {
export function setTextDecorationAndTransform(view: any, decoration: string, transform: string);
export function setWhiteSpace(view, value: string, parentView?: any);
export function setTextTransform(view, value: string);
export function setTextDecoration(view, value: string);
export function setTextAlignment(view, value: string);
export interface TextUIView {

View File

@ -49,108 +49,102 @@ export module ios {
}
}
export function setTextDecoration(view: dts.ios.TextUIView, value: string) {
var attributes: NSMutableDictionary = NSMutableDictionary.alloc().init();
var values = (value + "").split(" ");
export function setTextDecorationAndTransform(v: any, decoration: string, transform: string) {
if (v.formattedText) {
if (v.style.textDecoration.indexOf(enums.TextDecoration.none) === -1) {
if (values.indexOf(enums.TextDecoration.underline) !== -1) {
attributes.setObjectForKey(NSUnderlineStyle.NSUnderlineStyleSingle, NSUnderlineStyleAttributeName);
if (v.style.textDecoration.indexOf(enums.TextDecoration.underline) !== -1) {
(<any>v).formattedText.underline = NSUnderlineStyle.NSUnderlineStyleSingle;
}
if (values.indexOf(enums.TextDecoration.lineThrough) !== -1) {
attributes.setObjectForKey(NSUnderlineStyle.NSUnderlineStyleSingle, NSStrikethroughStyleAttributeName);
if (v.style.textDecoration.indexOf(enums.TextDecoration.lineThrough) !== -1) {
(<any>v).formattedText.strikethrough = NSUnderlineStyle.NSUnderlineStyleSingle;
}
if (values.indexOf(enums.TextDecoration.none) === -1) {
setTextDecorationNative(view, view.text || view.attributedText, attributes);
} else {
setTextDecorationNative(view, view.text || view.attributedText, NSMutableDictionary.alloc().init());
(<any>v).formattedText.underline = NSUnderlineStyle.NSUnderlineStyleNone;
}
for (let i = 0; i < v.formattedText.spans.length; i++) {
let span = v.formattedText.spans.getItem(i);
span.text = getTransformedText(v, span.text, transform);
}
} else {
let source = v.text;
let attributes = new Array();
let range = { location: 0, length: source.length };
var decorationValues = (decoration + "").split(" ");
if (decorationValues.indexOf(enums.TextDecoration.none) === -1) {
let dict = new Map<string, number>();
if (decorationValues.indexOf(enums.TextDecoration.underline) !== -1) {
dict.set(NSUnderlineStyleAttributeName, NSUnderlineStyle.NSUnderlineStyleSingle);
}
if (decorationValues.indexOf(enums.TextDecoration.lineThrough) !== -1) {
dict.set(NSStrikethroughStyleAttributeName, NSUnderlineStyle.NSUnderlineStyleSingle);
}
attributes.push({ attrs: dict, range: NSValue.valueWithRange(range) });
}
let view: dts.ios.TextUIView | UIButton = v._nativeView;
source = getTransformedText(v, source, transform);
if (attributes.length > 0) {
let result = NSMutableAttributedString.alloc().initWithString(<string>source);
for (let i = 0; i < attributes.length; i++) {
result.setAttributesRange(attributes[i]["attrs"], attributes[i]["range"].rangeValue);
}
if (view instanceof UIButton) {
(<UIButton>view).setAttributedTitleForState(result, UIControlState.UIControlStateNormal);
}
else {
(<dts.ios.TextUIView>view).attributedText = result;
}
} else {
if (view instanceof UIButton) {
(<UIButton>view).setTitleForState(<string>source, UIControlState.UIControlStateNormal);
}
else {
(<dts.ios.TextUIView>view).text = <string>source;
}
}
}
}
export function setTextTransform(view: dts.ios.TextUIView, value: string) {
let str = getNSStringFromView(view);
let result: string;
function getTransformedText(view, source: string, transform: string): string {
let result = source;
switch (value) {
switch (transform) {
case enums.TextTransform.none:
default:
result = view["originalString"] || str;
result = view["originalString"] || NSStringFromNSAttributedString(source);
break;
case enums.TextTransform.uppercase:
result = str.uppercaseString;
result = NSStringFromNSAttributedString(source).uppercaseString;
break;
case enums.TextTransform.lowercase:
result = str.lowercaseString;
result = NSStringFromNSAttributedString(source).lowercaseString;
break;
case enums.TextTransform.capitalize:
result = str.capitalizedString;
result = NSStringFromNSAttributedString(source).capitalizedString;
break;
}
if (!view["originalString"]) {
view["originalString"] = str;
}
let newStr = getAttributedStringFromView(view, result);
if (newStr) {
setAttributedStringToView(view, newStr);
} else {
setStringToView(view, result);
}
}
function getNSStringFromView(view: any): NSString {
let result: string;
if (view instanceof UIButton) {
let attrTitle = (<UIButton>view).titleLabel.attributedText;
result = attrTitle ? attrTitle.string : (<UIButton>view).titleLabel.text;
}
else {
let attrText = (<UITextView>view).attributedText;
result = attrText ? attrText.string : (<UITextView>view).text;
}
return NSString.alloc().initWithString(result || "");
}
function setStringToView(view: any, str: string) {
if (view instanceof UIButton) {
(<UIButton>view).setTitleForState(str, UIControlState.UIControlStateNormal);
}
else {
(<dts.ios.TextUIView>view).text = str;
}
}
function getAttributedStringFromView(view: any, value: string): NSMutableAttributedString {
let result: NSMutableAttributedString;
if (view instanceof UIButton) {
let attrTitle = (<UIButton>view).titleLabel.attributedText;
if (attrTitle) {
result = NSMutableAttributedString.alloc().initWithAttributedString(attrTitle);
}
} else if (view.attributedText) {
result = NSMutableAttributedString.alloc().initWithAttributedString(view.attributedText);
}
if (result) {
result.replaceCharactersInRangeWithString({ location: 0, length: result.length }, value);
view["originalString"] = NSStringFromNSAttributedString(source);
}
return result;
}
function setAttributedStringToView(view: any, str: NSMutableAttributedString) {
if (view instanceof UIButton) {
(<UIButton>view).setAttributedTitleForState(str, UIControlState.UIControlStateNormal);
}
else {
(<dts.ios.TextUIView>view).attributedText = str;
}
function NSStringFromNSAttributedString(source: NSAttributedString | string): NSString {
return NSString.stringWithString(source instanceof NSAttributedString && source.string || <string>source);
}
export function setWhiteSpace(view: dts.ios.TextUIView, value: string, parentView?: UIView) {
@ -168,19 +162,6 @@ export module ios {
}
}
function setTextDecorationNative(view: dts.ios.TextUIView, value: string | NSAttributedString, attributes: NSMutableDictionary) {
var attributedString: NSMutableAttributedString;
if (value instanceof NSAttributedString) {
attributedString = NSMutableAttributedString.alloc().initWithAttributedString(value);
attributedString.addAttributesRange(attributes, NSRangeFromString(attributedString.string));
} else {
var types: typeof typesModule = require("utils/types");
view.attributedText = NSAttributedString.alloc().initWithStringAttributes(types.isString(value) ? <string>value : "", attributes);
}
}
export module collections {
export function jsArrayToNSArray(str: string[]): NSArray {
return NSArray.arrayWithArray(<any>str);