mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-26 11:17:04 +08:00
Refactor application of text decoration, text transform, letter spacing and formatted text.
Related to #2427
This commit is contained in:
85
apps/.vscode/launch.json
vendored
Normal file
85
apps/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch on iOS Device",
|
||||
"type": "nativescript",
|
||||
"platform": "ios",
|
||||
"request": "launch",
|
||||
"appRoot": "${workspaceRoot}",
|
||||
"sourceMaps": true,
|
||||
"diagnosticLogging": false,
|
||||
"emulator": false
|
||||
},
|
||||
{
|
||||
"name": "Attach on iOS Device",
|
||||
"type": "nativescript",
|
||||
"platform": "ios",
|
||||
"request": "attach",
|
||||
"appRoot": "${workspaceRoot}",
|
||||
"sourceMaps": true,
|
||||
"diagnosticLogging": false,
|
||||
"emulator": false
|
||||
},
|
||||
{
|
||||
"name": "Launch on iOS Emulator",
|
||||
"type": "nativescript",
|
||||
"platform": "ios",
|
||||
"request": "launch",
|
||||
"appRoot": "${workspaceRoot}",
|
||||
"sourceMaps": true,
|
||||
"diagnosticLogging": false,
|
||||
"emulator": true
|
||||
},
|
||||
{
|
||||
"name": "Attach on iOS Emulator",
|
||||
"type": "nativescript",
|
||||
"platform": "ios",
|
||||
"request": "attach",
|
||||
"appRoot": "${workspaceRoot}",
|
||||
"sourceMaps": true,
|
||||
"diagnosticLogging": false,
|
||||
"emulator": true
|
||||
},
|
||||
{
|
||||
"name": "Launch on Android Device",
|
||||
"type": "nativescript",
|
||||
"platform": "android",
|
||||
"request": "launch",
|
||||
"appRoot": "${workspaceRoot}",
|
||||
"sourceMaps": true,
|
||||
"diagnosticLogging": false,
|
||||
"emulator": false
|
||||
},
|
||||
{
|
||||
"name": "Launch on Android Emulator",
|
||||
"type": "nativescript",
|
||||
"platform": "android",
|
||||
"request": "launch",
|
||||
"appRoot": "${workspaceRoot}",
|
||||
"sourceMaps": true,
|
||||
"diagnosticLogging": false,
|
||||
"emulator": true
|
||||
},
|
||||
{
|
||||
"name": "Attach on Android Device",
|
||||
"type": "nativescript",
|
||||
"platform": "android",
|
||||
"request": "attach",
|
||||
"appRoot": "${workspaceRoot}",
|
||||
"sourceMaps": true,
|
||||
"diagnosticLogging": false,
|
||||
"emulator": false
|
||||
},
|
||||
{
|
||||
"name": "Attach on Android Emulator",
|
||||
"type": "nativescript",
|
||||
"platform": "android",
|
||||
"request": "attach",
|
||||
"appRoot": "${workspaceRoot}",
|
||||
"sourceMaps": true,
|
||||
"diagnosticLogging": false,
|
||||
"emulator": true
|
||||
}
|
||||
]
|
||||
}
|
@ -301,3 +301,67 @@ export var test_WhenFormattedTextPropertyChanges_TextIsUpdated_Button = function
|
||||
TKUnit.assertEqual(view.text, "");
|
||||
});
|
||||
}
|
||||
|
||||
export var test_IntegrationTest_Transform_Decoration_Spacing_WithoutFormattedText_DoesNotCrash = function () {
|
||||
let view = new buttonModule.Button();
|
||||
helper.buildUIAndRunTest(view, function (views: Array<viewModule.View>) {
|
||||
TKUnit.assertEqual(view.text, "", "Text");
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.none, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.none, "TextDecoration");
|
||||
TKUnit.assertTrue(isNaN(view.style.letterSpacing), "LetterSpacing");
|
||||
|
||||
view.text = "NormalText";
|
||||
view.setInlineStyle("text-transform: uppercase; text-decoration: underline; letter-spacing: 10;");
|
||||
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.uppercase, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.underline, "TextDecoration");
|
||||
TKUnit.assertEqual(view.style.letterSpacing, 10, "LetterSpacing");
|
||||
});
|
||||
}
|
||||
|
||||
export var test_IntegrationTest_Transform_Decoration_Spacing_WithFormattedText_DoesNotCrash = function () {
|
||||
let view = new buttonModule.Button();
|
||||
let formattedString = _generateFormattedString();
|
||||
helper.buildUIAndRunTest(view, function (views: Array<viewModule.View>) {
|
||||
TKUnit.assertEqual(view.text, "", "Text");
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.none, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.none, "TextDecoration");
|
||||
TKUnit.assertTrue(isNaN(view.style.letterSpacing), "LetterSpacing");
|
||||
|
||||
view.formattedText = formattedString;
|
||||
view.setInlineStyle("text-transform: uppercase; text-decoration: underline; letter-spacing: 10;");
|
||||
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.uppercase, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.underline, "TextDecoration");
|
||||
TKUnit.assertEqual(view.style.letterSpacing, 10, "LetterSpacing");
|
||||
});
|
||||
}
|
||||
|
||||
function _generateFormattedString(): formattedStringModule.FormattedString{
|
||||
let formattedString = new formattedStringModule.FormattedString();
|
||||
let span: spanModule.Span;
|
||||
|
||||
span = new spanModule.Span();
|
||||
span.fontFamily = "serif";
|
||||
span.fontSize = 10;
|
||||
span.fontAttributes = enums.FontAttributes.Bold;
|
||||
span.foregroundColor = new colorModule.Color("red");
|
||||
span.backgroundColor = new colorModule.Color("blue");
|
||||
span.underline = 0;
|
||||
span.strikethrough = 1;
|
||||
span.text = "Formatted";
|
||||
formattedString.spans.push(span);
|
||||
|
||||
span = new spanModule.Span();
|
||||
span.fontFamily = "sans-serif";
|
||||
span.fontSize = 20;
|
||||
span.fontAttributes = enums.FontAttributes.Italic;
|
||||
span.foregroundColor = new colorModule.Color("green");
|
||||
span.backgroundColor = new colorModule.Color("yellow");
|
||||
span.underline = 1;
|
||||
span.strikethrough = 0;
|
||||
span.text = "Text";
|
||||
formattedString.spans.push(span);
|
||||
|
||||
return formattedString;
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ import {isIOS} from "platform";
|
||||
import {Label} from "ui/label";
|
||||
import {LayoutBase} from "ui/layouts/layout-base";
|
||||
import * as helper from "../helper";
|
||||
import viewModule = require("ui/core/view");
|
||||
import formattedStringModule = require("text/formatted-string");
|
||||
import spanModule = require("text/span");
|
||||
|
||||
export class LabelTest extends testModule.UITest<LabelModule.Label> {
|
||||
|
||||
@ -596,3 +599,66 @@ export function createTestCase(): LabelTest {
|
||||
return new LabelTest();
|
||||
}
|
||||
|
||||
export var test_IntegrationTest_Transform_Decoration_Spacing_WithoutFormattedText_DoesNotCrash = function () {
|
||||
let view = new LabelModule.Label();
|
||||
helper.buildUIAndRunTest(view, function (views: Array<viewModule.View>) {
|
||||
TKUnit.assertEqual(view.text, "", "Text");
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.none, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.none, "TextDecoration");
|
||||
TKUnit.assertTrue(isNaN(view.style.letterSpacing), "LetterSpacing");
|
||||
|
||||
view.text = "NormalText";
|
||||
view.setInlineStyle("text-transform: uppercase; text-decoration: underline; letter-spacing: 10;");
|
||||
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.uppercase, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.underline, "TextDecoration");
|
||||
TKUnit.assertEqual(view.style.letterSpacing, 10, "LetterSpacing");
|
||||
});
|
||||
}
|
||||
|
||||
export var test_IntegrationTest_Transform_Decoration_Spacing_WithFormattedText_DoesNotCrash = function () {
|
||||
let view = new LabelModule.Label();
|
||||
let formattedString = _generateFormattedString();
|
||||
helper.buildUIAndRunTest(view, function (views: Array<viewModule.View>) {
|
||||
TKUnit.assertEqual(view.text, "", "Text");
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.none, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.none, "TextDecoration");
|
||||
TKUnit.assertTrue(isNaN(view.style.letterSpacing), "LetterSpacing");
|
||||
|
||||
view.formattedText = formattedString;
|
||||
view.setInlineStyle("text-transform: uppercase; text-decoration: underline; letter-spacing: 10;");
|
||||
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.uppercase, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.underline, "TextDecoration");
|
||||
TKUnit.assertEqual(view.style.letterSpacing, 10, "LetterSpacing");
|
||||
});
|
||||
}
|
||||
|
||||
function _generateFormattedString(): formattedStringModule.FormattedString{
|
||||
let formattedString = new formattedStringModule.FormattedString();
|
||||
let span: spanModule.Span;
|
||||
|
||||
span = new spanModule.Span();
|
||||
span.fontFamily = "serif";
|
||||
span.fontSize = 10;
|
||||
span.fontAttributes = enums.FontAttributes.Bold;
|
||||
span.foregroundColor = new colorModule.Color("red");
|
||||
span.backgroundColor = new colorModule.Color("blue");
|
||||
span.underline = 0;
|
||||
span.strikethrough = 1;
|
||||
span.text = "Formatted";
|
||||
formattedString.spans.push(span);
|
||||
|
||||
span = new spanModule.Span();
|
||||
span.fontFamily = "sans-serif";
|
||||
span.fontSize = 20;
|
||||
span.fontAttributes = enums.FontAttributes.Italic;
|
||||
span.foregroundColor = new colorModule.Color("green");
|
||||
span.backgroundColor = new colorModule.Color("yellow");
|
||||
span.underline = 1;
|
||||
span.strikethrough = 0;
|
||||
span.text = "Text";
|
||||
formattedString.spans.push(span);
|
||||
|
||||
return formattedString;
|
||||
}
|
||||
|
@ -535,3 +535,67 @@ export var test_WhenFormattedTextPropertyChanges_TextIsUpdated_TextBase = functi
|
||||
TKUnit.assertEqual(view.text, "");
|
||||
});
|
||||
}
|
||||
|
||||
export var test_IntegrationTest_Transform_Decoration_Spacing_WithoutFormattedText_DoesNotCrash = function () {
|
||||
let view = new textFieldModule.TextField();
|
||||
helper.buildUIAndRunTest(view, function (views: Array<viewModule.View>) {
|
||||
TKUnit.assertEqual(view.text, "", "Text");
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.none, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.none, "TextDecoration");
|
||||
TKUnit.assertTrue(isNaN(view.style.letterSpacing), "LetterSpacing");
|
||||
|
||||
view.text = "NormalText";
|
||||
view.setInlineStyle("text-transform: uppercase; text-decoration: underline; letter-spacing: 10;");
|
||||
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.uppercase, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.underline, "TextDecoration");
|
||||
TKUnit.assertEqual(view.style.letterSpacing, 10, "LetterSpacing");
|
||||
});
|
||||
}
|
||||
|
||||
export var test_IntegrationTest_Transform_Decoration_Spacing_WithFormattedText_DoesNotCrash = function () {
|
||||
let view = new textFieldModule.TextField();
|
||||
let formattedString = _generateFormattedString();
|
||||
helper.buildUIAndRunTest(view, function (views: Array<viewModule.View>) {
|
||||
TKUnit.assertEqual(view.text, "", "Text");
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.none, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.none, "TextDecoration");
|
||||
TKUnit.assertTrue(isNaN(view.style.letterSpacing), "LetterSpacing");
|
||||
|
||||
view.formattedText = formattedString;
|
||||
view.setInlineStyle("text-transform: uppercase; text-decoration: underline; letter-spacing: 10;");
|
||||
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.uppercase, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.underline, "TextDecoration");
|
||||
TKUnit.assertEqual(view.style.letterSpacing, 10, "LetterSpacing");
|
||||
});
|
||||
}
|
||||
|
||||
function _generateFormattedString(): formattedStringModule.FormattedString{
|
||||
let formattedString = new formattedStringModule.FormattedString();
|
||||
let span: spanModule.Span;
|
||||
|
||||
span = new spanModule.Span();
|
||||
span.fontFamily = "serif";
|
||||
span.fontSize = 10;
|
||||
span.fontAttributes = enums.FontAttributes.Bold;
|
||||
span.foregroundColor = new colorModule.Color("red");
|
||||
span.backgroundColor = new colorModule.Color("blue");
|
||||
span.underline = 0;
|
||||
span.strikethrough = 1;
|
||||
span.text = "Formatted";
|
||||
formattedString.spans.push(span);
|
||||
|
||||
span = new spanModule.Span();
|
||||
span.fontFamily = "sans-serif";
|
||||
span.fontSize = 20;
|
||||
span.fontAttributes = enums.FontAttributes.Italic;
|
||||
span.foregroundColor = new colorModule.Color("green");
|
||||
span.backgroundColor = new colorModule.Color("yellow");
|
||||
span.underline = 1;
|
||||
span.strikethrough = 0;
|
||||
span.text = "Text";
|
||||
formattedString.spans.push(span);
|
||||
|
||||
return formattedString;
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import textViewTestsNative = require("./text-view-tests-native");
|
||||
import colorModule = require("color");
|
||||
import enums = require("ui/enums");
|
||||
import platform = require("platform");
|
||||
import formattedStringModule = require("text/formatted-string");
|
||||
import spanModule = require("text/span");
|
||||
|
||||
// >> require-textmodules
|
||||
import textViewModule = require("ui/text-view");
|
||||
@ -494,3 +496,67 @@ export function test_watch_listerer_is_removed_at_onDetach() {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export var test_IntegrationTest_Transform_Decoration_Spacing_WithoutFormattedText_DoesNotCrash = function () {
|
||||
let view = new textViewModule.TextView();
|
||||
helper.buildUIAndRunTest(view, function (views: Array<viewModule.View>) {
|
||||
TKUnit.assertEqual(view.text, "", "Text");
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.none, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.none, "TextDecoration");
|
||||
TKUnit.assertTrue(isNaN(view.style.letterSpacing), "LetterSpacing");
|
||||
|
||||
view.text = "NormalText";
|
||||
view.setInlineStyle("text-transform: uppercase; text-decoration: underline; letter-spacing: 10;");
|
||||
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.uppercase, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.underline, "TextDecoration");
|
||||
TKUnit.assertEqual(view.style.letterSpacing, 10, "LetterSpacing");
|
||||
});
|
||||
}
|
||||
|
||||
export var test_IntegrationTest_Transform_Decoration_Spacing_WithFormattedText_DoesNotCrash = function () {
|
||||
let view = new textViewModule.TextView();
|
||||
let formattedString = _generateFormattedString();
|
||||
helper.buildUIAndRunTest(view, function (views: Array<viewModule.View>) {
|
||||
TKUnit.assertEqual(view.text, "", "Text");
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.none, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.none, "TextDecoration");
|
||||
TKUnit.assertTrue(isNaN(view.style.letterSpacing), "LetterSpacing");
|
||||
|
||||
view.formattedText = formattedString;
|
||||
view.setInlineStyle("text-transform: uppercase; text-decoration: underline; letter-spacing: 10;");
|
||||
|
||||
TKUnit.assertEqual(view.style.textTransform, enums.TextTransform.uppercase, "TextTransform");
|
||||
TKUnit.assertEqual(view.style.textDecoration, enums.TextDecoration.underline, "TextDecoration");
|
||||
TKUnit.assertEqual(view.style.letterSpacing, 10, "LetterSpacing");
|
||||
});
|
||||
}
|
||||
|
||||
function _generateFormattedString(): formattedStringModule.FormattedString{
|
||||
let formattedString = new formattedStringModule.FormattedString();
|
||||
let span: spanModule.Span;
|
||||
|
||||
span = new spanModule.Span();
|
||||
span.fontFamily = "serif";
|
||||
span.fontSize = 10;
|
||||
span.fontAttributes = enums.FontAttributes.Bold;
|
||||
span.foregroundColor = new colorModule.Color("red");
|
||||
span.backgroundColor = new colorModule.Color("blue");
|
||||
span.underline = 0;
|
||||
span.strikethrough = 1;
|
||||
span.text = "Formatted";
|
||||
formattedString.spans.push(span);
|
||||
|
||||
span = new spanModule.Span();
|
||||
span.fontFamily = "sans-serif";
|
||||
span.fontSize = 20;
|
||||
span.fontAttributes = enums.FontAttributes.Italic;
|
||||
span.foregroundColor = new colorModule.Color("green");
|
||||
span.backgroundColor = new colorModule.Color("yellow");
|
||||
span.underline = 1;
|
||||
span.strikethrough = 0;
|
||||
span.text = "Text";
|
||||
formattedString.spans.push(span);
|
||||
|
||||
return formattedString;
|
||||
}
|
||||
|
@ -234,4 +234,8 @@ export class FormattedString extends observable.Observable implements definition
|
||||
view.formattedText = value;
|
||||
}
|
||||
}
|
||||
|
||||
public _updateCharactersInRangeReplacementString(rangeLocation: number, rangeLength: number, replacementString: string): void {
|
||||
//
|
||||
}
|
||||
}
|
5
tns-core-modules/text/formatted-string.d.ts
vendored
5
tns-core-modules/text/formatted-string.d.ts
vendored
@ -98,5 +98,10 @@ declare module "text/formatted-string" {
|
||||
* A static method used to add child elements of the FormattedString class to a View declared in xml.
|
||||
*/
|
||||
public static addFormattedStringToView(view: FormattedStringView, name: string, value: any): void;
|
||||
|
||||
//@private
|
||||
createFormattedStringCore(): void;
|
||||
_updateCharactersInRangeReplacementString(rangeLocation: number, rangeLength: number, replacementString: string): void;
|
||||
//@endprivate
|
||||
}
|
||||
}
|
@ -27,4 +27,29 @@ export class FormattedString extends formattedStringCommon.FormattedString {
|
||||
}
|
||||
this._formattedText = mas;
|
||||
}
|
||||
|
||||
public _updateCharactersInRangeReplacementString(rangeLocation: number, rangeLength: number, replacementString: string): void {
|
||||
let deletingText = !replacementString;
|
||||
let currentLocation = 0;
|
||||
for (let i = 0; i < this.spans.length; i++) {
|
||||
let span = <spanModule.Span>this.spans.getItem(i);
|
||||
if (currentLocation <= rangeLocation && rangeLocation < (currentLocation + span.text.length)){
|
||||
(<any>span)._text = splice(span.text, rangeLocation - currentLocation, deletingText ? rangeLength : 0, replacementString);
|
||||
//console.log(`>>> ${span.text}`);
|
||||
return;
|
||||
}
|
||||
currentLocation += span.text.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @param {String} value The string to splice.
|
||||
* @param {number} start Index at which to start changing the string.
|
||||
* @param {number} delCount An integer indicating the number of old chars to remove.
|
||||
* @param {string} newSubStr The String that is spliced in.
|
||||
* @return {string} A new string with the spliced substring.function splice(value: string, start: number, delCount: number, newSubStr: string) {
|
||||
*/
|
||||
function splice(value: string, start: number, delCount: number, newSubStr: string) {
|
||||
return value.slice(0, start) + newSubStr + value.slice(start + Math.abs(delCount));
|
||||
};
|
@ -28,6 +28,7 @@ function onTextPropertyChanged(data: PropertyChangeData) {
|
||||
|
||||
button._onTextPropertyChanged(data);
|
||||
|
||||
//RemoveThisDoubleCall
|
||||
button.style._updateTextDecoration();
|
||||
button.style._updateTextTransform();
|
||||
}
|
||||
@ -53,6 +54,8 @@ export class Button extends view.View implements definition.Button {
|
||||
this.formattedText.updateSpansBindingContext(newValue);
|
||||
}
|
||||
|
||||
//This is because of ListView virtualization
|
||||
//RemoveThisDoubleCall
|
||||
this.style._updateTextDecoration();
|
||||
this.style._updateTextTransform();
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import view = require("ui/core/view");
|
||||
import utils = require("utils/utils");
|
||||
import enums = require("ui/enums");
|
||||
import dependencyObservable = require("ui/core/dependency-observable");
|
||||
import types = require("utils/types");
|
||||
import {PseudoClassHandler} from "ui/core/view";
|
||||
|
||||
class TapHandlerImpl extends NSObject {
|
||||
@ -63,7 +64,9 @@ export class Button extends common.Button {
|
||||
// set the value for the normal state.
|
||||
let newText = value ? value._formattedText : null;
|
||||
this.ios.setAttributedTitleForState(newText, UIControlState.UIControlStateNormal);
|
||||
//RemoveThisDoubleCall
|
||||
this.style._updateTextDecoration();
|
||||
this.style._updateTextTransform();
|
||||
}
|
||||
|
||||
@PseudoClassHandler("normal", "highlighted")
|
||||
@ -164,29 +167,29 @@ export class ButtonStyler implements style.Styler {
|
||||
|
||||
// text-decoration
|
||||
private static setTextDecorationProperty(view: view.View, newValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, newValue, view.style.textTransform, view.style.letterSpacing);
|
||||
ButtonStyler._setButtonTextDecorationAndTransform(<Button>view, newValue, view.style.textTransform, view.style.letterSpacing);
|
||||
}
|
||||
|
||||
private static resetTextDecorationProperty(view: view.View, nativeValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, enums.TextDecoration.none, view.style.textTransform, view.style.letterSpacing);
|
||||
ButtonStyler._setButtonTextDecorationAndTransform(<Button>view, enums.TextDecoration.none, view.style.textTransform, view.style.letterSpacing);
|
||||
}
|
||||
|
||||
// text-transform
|
||||
private static setTextTransformProperty(view: view.View, newValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, newValue, view.style.letterSpacing);
|
||||
ButtonStyler._setButtonTextDecorationAndTransform(<Button>view, view.style.textDecoration, newValue, view.style.letterSpacing);
|
||||
}
|
||||
|
||||
private static resetTextTransformProperty(view: view.View, nativeValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, enums.TextTransform.none, view.style.letterSpacing);
|
||||
ButtonStyler._setButtonTextDecorationAndTransform(<Button>view, view.style.textDecoration, enums.TextTransform.none, view.style.letterSpacing);
|
||||
}
|
||||
|
||||
// letter-spacing
|
||||
private static setLetterSpacingProperty(view: view.View, newValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, view.style.textTransform, newValue);
|
||||
ButtonStyler._setButtonTextDecorationAndTransform(<Button>view, view.style.textDecoration, view.style.textTransform, newValue);
|
||||
}
|
||||
|
||||
private static resetLetterSpacingProperty(view: view.View, nativeValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, view.style.textTransform, 0);
|
||||
ButtonStyler._setButtonTextDecorationAndTransform(<Button>view, view.style.textDecoration, view.style.textTransform, 0);
|
||||
}
|
||||
|
||||
// white-space
|
||||
@ -234,6 +237,77 @@ export class ButtonStyler implements style.Styler {
|
||||
ButtonStyler.setWhiteSpaceProperty,
|
||||
ButtonStyler.resetWhiteSpaceProperty), "Button");
|
||||
}
|
||||
|
||||
private static _setButtonTextDecorationAndTransform(button: Button, decoration: string, transform: string, letterSpacing: number) {
|
||||
let hasLetterSpacing = types.isNumber(letterSpacing) && !isNaN(letterSpacing);
|
||||
|
||||
if (button.formattedText) {
|
||||
if (button.style.textDecoration.indexOf(enums.TextDecoration.none) === -1) {
|
||||
|
||||
if (button.style.textDecoration.indexOf(enums.TextDecoration.underline) !== -1) {
|
||||
button.formattedText.underline = NSUnderlineStyle.NSUnderlineStyleSingle;
|
||||
}
|
||||
|
||||
if (button.style.textDecoration.indexOf(enums.TextDecoration.lineThrough) !== -1) {
|
||||
button.formattedText.strikethrough = NSUnderlineStyle.NSUnderlineStyleSingle;
|
||||
}
|
||||
}
|
||||
else {
|
||||
button.formattedText.underline = NSUnderlineStyle.NSUnderlineStyleNone;
|
||||
}
|
||||
|
||||
for (let i = 0; i < button.formattedText.spans.length; i++) {
|
||||
let span = button.formattedText.spans.getItem(i);
|
||||
span.text = utils.ios.getTransformedText(button, span.text, transform);
|
||||
}
|
||||
|
||||
if (hasLetterSpacing) {
|
||||
let attrText = NSMutableAttributedString.alloc().initWithAttributedString(button.ios.attributedTitleForState(UIControlState.UIControlStateNormal));
|
||||
attrText.addAttributeValueRange(NSKernAttributeName, letterSpacing, { location: 0, length: attrText.length });
|
||||
button.ios.setAttributedTitleForState(attrText, UIControlState.UIControlStateNormal);
|
||||
}
|
||||
}
|
||||
else {
|
||||
let source = button.text;
|
||||
let attributes = new Array();
|
||||
let range = { location: 0, length: source.length };
|
||||
|
||||
var decorationValues = (decoration + "").split(" ");
|
||||
|
||||
if (decorationValues.indexOf(enums.TextDecoration.none) === -1 || hasLetterSpacing) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (hasLetterSpacing) {
|
||||
dict.set(NSKernAttributeName, letterSpacing);
|
||||
}
|
||||
|
||||
attributes.push({ attrs: dict, range: NSValue.valueWithRange(range) });
|
||||
}
|
||||
|
||||
source = utils.ios.getTransformedText(button, source, transform);
|
||||
|
||||
if (attributes.length > 0) {
|
||||
let result = NSMutableAttributedString.alloc().initWithString(source);
|
||||
for (let i = 0; i < attributes.length; i++) {
|
||||
result.setAttributesRange(attributes[i]["attrs"], attributes[i]["range"].rangeValue);
|
||||
}
|
||||
|
||||
button.ios.setAttributedTitleForState(result, UIControlState.UIControlStateNormal);
|
||||
}
|
||||
else {
|
||||
button.ios.setAttributedTitleForState(NSMutableAttributedString.alloc().initWithString(source), UIControlState.UIControlStateNormal);
|
||||
button.ios.setTitleForState(source, UIControlState.UIControlStateNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ButtonStyler.registerHandlers();
|
||||
|
@ -34,7 +34,11 @@ export class EditableTextBase extends common.EditableTextBase {
|
||||
}
|
||||
var selectionStart = owner.android.getSelectionStart();
|
||||
owner.android.removeTextChangedListener(owner._textWatcher);
|
||||
|
||||
//RemoveThisDoubleCall
|
||||
owner.style._updateTextDecoration();
|
||||
owner.style._updateTextTransform();
|
||||
|
||||
owner.android.addTextChangedListener(owner._textWatcher);
|
||||
owner.android.setSelection(selectionStart);
|
||||
},
|
||||
|
@ -42,9 +42,6 @@ export class Label extends common.Label {
|
||||
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
|
||||
this.style._updateTextDecoration();
|
||||
this.style._updateTextTransform();
|
||||
}
|
||||
|
||||
_requestLayoutOnTextChanged(): void {
|
||||
|
@ -986,39 +986,32 @@ export class Style extends DependencyObservable implements styling.Style {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let handler: definition.StylePropertyChangedHandler = getHandler(property, this._view);
|
||||
if (!handler) {
|
||||
if (trace.enabled) {
|
||||
trace.write("No handler for property: " + property.name + " with id: " + property.id + ", view:" + this._view, trace.categories.Style);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (trace.enabled) {
|
||||
trace.write("Found handler for property: " + property.name + ", view:" + this._view, trace.categories.Style);
|
||||
}
|
||||
|
||||
let shouldReset = false;
|
||||
if (property.equalityComparer) {
|
||||
shouldReset = property.equalityComparer(newValue, property.defaultValue);
|
||||
}
|
||||
else {
|
||||
shouldReset = (newValue === property.defaultValue);
|
||||
}
|
||||
|
||||
if (shouldReset) {
|
||||
(<any>handler).resetProperty(property, this._view);
|
||||
} else {
|
||||
(<any>handler).applyProperty(property, this._view, newValue);
|
||||
}
|
||||
|
||||
this._view._onStylePropertyChanged(property);
|
||||
let handler: definition.StylePropertyChangedHandler = getHandler(property, this._view);
|
||||
if (!handler) {
|
||||
if (trace.enabled) {
|
||||
trace.write("No handler for property: " + property.name + " with id: " + property.id + ", view:" + this._view, trace.categories.Style);
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
else {
|
||||
if (trace.enabled) {
|
||||
trace.write("Error setting property: " + property.name + " on " + this._view + ": " + ex, trace.categories.Style, trace.messageType.error);
|
||||
trace.write("Found handler for property: " + property.name + ", view:" + this._view, trace.categories.Style);
|
||||
}
|
||||
|
||||
let shouldReset = false;
|
||||
if (property.equalityComparer) {
|
||||
shouldReset = property.equalityComparer(newValue, property.defaultValue);
|
||||
}
|
||||
else {
|
||||
shouldReset = (newValue === property.defaultValue);
|
||||
}
|
||||
|
||||
if (shouldReset) {
|
||||
(<any>handler).resetProperty(property, this._view);
|
||||
} else {
|
||||
(<any>handler).applyProperty(property, this._view, newValue);
|
||||
}
|
||||
|
||||
this._view._onStylePropertyChanged(property);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ function onTextPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
|
||||
textBase._onTextPropertyChanged(data);
|
||||
|
||||
//RemoveThisDoubleCall
|
||||
textBase.style._updateTextTransform();
|
||||
textBase.style._updateTextDecoration();
|
||||
}
|
||||
@ -54,6 +55,8 @@ export class TextBase extends view.View implements definition.TextBase, formatte
|
||||
this.formattedText.updateSpansBindingContext(newValue);
|
||||
}
|
||||
|
||||
//This is because of ListView virtualization
|
||||
//RemoveThisDoubleCall
|
||||
this.style._updateTextTransform();
|
||||
this.style._updateTextDecoration();
|
||||
}
|
||||
@ -133,4 +136,4 @@ export class TextBase extends view.View implements definition.TextBase, formatte
|
||||
}
|
||||
}
|
||||
|
||||
tbs.TextBaseStyler.registerHandlers()
|
||||
tbs.TextBaseStyler.registerHandlers();
|
||||
|
@ -3,88 +3,90 @@ import utils = require("utils/utils");
|
||||
import style = require("ui/styling/style");
|
||||
import font = require("ui/styling/font");
|
||||
import enums = require("ui/enums");
|
||||
import types = require("utils/types");
|
||||
import { TextBase } from "ui/text-base";
|
||||
|
||||
export class TextBaseStyler implements style.Styler {
|
||||
// font
|
||||
private static setFontInternalProperty(view: view.View, newValue: any, nativeValue?: any) {
|
||||
var ios = <utils.ios.TextUIView>view._nativeView;
|
||||
private static setFontInternalProperty(textBase: TextBase, newValue: any, nativeValue?: any) {
|
||||
var ios = <utils.ios.TextUIView>textBase._nativeView;
|
||||
ios.font = (<font.Font>newValue).getUIFont(nativeValue);
|
||||
}
|
||||
|
||||
private static resetFontInternalProperty(view: view.View, nativeValue: any) {
|
||||
var ios = <utils.ios.TextUIView>view._nativeView;
|
||||
private static resetFontInternalProperty(textBase: TextBase, nativeValue: any) {
|
||||
var ios = <utils.ios.TextUIView>textBase._nativeView;
|
||||
ios.font = nativeValue;
|
||||
}
|
||||
|
||||
private static getNativeFontInternalValue(view: view.View): any {
|
||||
var ios = <utils.ios.TextUIView>view._nativeView;
|
||||
private static getNativeFontInternalValue(textBase: TextBase): any {
|
||||
var ios = <utils.ios.TextUIView>textBase._nativeView;
|
||||
return ios.font;
|
||||
}
|
||||
|
||||
// text-align
|
||||
private static setTextAlignmentProperty(view: view.View, newValue: any) {
|
||||
utils.ios.setTextAlignment(view._nativeView, newValue);
|
||||
private static setTextAlignmentProperty(textBase: TextBase, newValue: any) {
|
||||
utils.ios.setTextAlignment(textBase._nativeView, newValue);
|
||||
}
|
||||
|
||||
private static resetTextAlignmentProperty(view: view.View, nativeValue: any) {
|
||||
var ios = <utils.ios.TextUIView>view._nativeView;
|
||||
private static resetTextAlignmentProperty(textBase: TextBase, nativeValue: any) {
|
||||
var ios = <utils.ios.TextUIView>textBase._nativeView;
|
||||
ios.textAlignment = nativeValue;
|
||||
}
|
||||
|
||||
private static getNativeTextAlignmentValue(view: view.View): any {
|
||||
var ios = <utils.ios.TextUIView>view._nativeView;
|
||||
private static getNativeTextAlignmentValue(textBase: TextBase): any {
|
||||
var ios = <utils.ios.TextUIView>textBase._nativeView;
|
||||
return ios.textAlignment;
|
||||
}
|
||||
|
||||
// text-decoration
|
||||
private static setTextDecorationProperty(view: view.View, newValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, newValue, view.style.textTransform, view.style.letterSpacing);
|
||||
private static setTextDecorationProperty(textBase: TextBase, newValue: any) {
|
||||
TextBaseStyler._setTextBaseTextDecorationAndTransform(textBase, newValue, textBase.style.textTransform, textBase.style.letterSpacing);
|
||||
}
|
||||
|
||||
private static resetTextDecorationProperty(view: view.View, nativeValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, enums.TextDecoration.none, view.style.textTransform, view.style.letterSpacing);
|
||||
private static resetTextDecorationProperty(textBase: TextBase, nativeValue: any) {
|
||||
TextBaseStyler._setTextBaseTextDecorationAndTransform(textBase, enums.TextDecoration.none, textBase.style.textTransform, textBase.style.letterSpacing);
|
||||
}
|
||||
|
||||
// text-transform
|
||||
private static setTextTransformProperty(view: view.View, newValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, newValue, view.style.letterSpacing);
|
||||
private static setTextTransformProperty(textBase: TextBase, newValue: any) {
|
||||
TextBaseStyler._setTextBaseTextDecorationAndTransform(textBase, textBase.style.textDecoration, newValue, textBase.style.letterSpacing);
|
||||
}
|
||||
|
||||
private static resetTextTransformProperty(view: view.View, nativeValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, enums.TextTransform.none, view.style.letterSpacing);
|
||||
}
|
||||
|
||||
// white-space
|
||||
private static setWhiteSpaceProperty(view: view.View, newValue: any) {
|
||||
utils.ios.setWhiteSpace(view._nativeView, newValue);
|
||||
}
|
||||
|
||||
private static resetWhiteSpaceProperty(view: view.View, nativeValue: any) {
|
||||
utils.ios.setWhiteSpace(view._nativeView, enums.WhiteSpace.normal);
|
||||
private static resetTextTransformProperty(textBase: TextBase, nativeValue: any) {
|
||||
TextBaseStyler._setTextBaseTextDecorationAndTransform(textBase, textBase.style.textDecoration, enums.TextTransform.none, textBase.style.letterSpacing);
|
||||
}
|
||||
|
||||
// letter-spacing
|
||||
private static setLetterSpacingProperty(view: view.View, newValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, enums.TextTransform.none, newValue);
|
||||
private static setLetterSpacingProperty(textBase: TextBase, newValue: any) {
|
||||
TextBaseStyler._setTextBaseTextDecorationAndTransform(textBase, textBase.style.textDecoration, textBase.style.textTransform, newValue);
|
||||
}
|
||||
|
||||
private static resetLetterSpacingProperty(view: view.View, nativeValue: any) {
|
||||
utils.ios.setTextDecorationAndTransform(view, view.style.textDecoration, enums.TextTransform.none, 0);
|
||||
private static resetLetterSpacingProperty(textBase: TextBase, nativeValue: any) {
|
||||
TextBaseStyler._setTextBaseTextDecorationAndTransform(textBase, textBase.style.textDecoration, textBase.style.textTransform, 0);
|
||||
}
|
||||
|
||||
// white-space
|
||||
private static setWhiteSpaceProperty(textBase: view.View, newValue: any) {
|
||||
utils.ios.setWhiteSpace(textBase._nativeView, newValue);
|
||||
}
|
||||
|
||||
private static resetWhiteSpaceProperty(textBase: view.View, nativeValue: any) {
|
||||
utils.ios.setWhiteSpace(textBase._nativeView, enums.WhiteSpace.normal);
|
||||
}
|
||||
|
||||
// color
|
||||
private static setColorProperty(view: view.View, newValue: any) {
|
||||
var ios = <utils.ios.TextUIView>view._nativeView;
|
||||
private static setColorProperty(textBase: view.View, newValue: any) {
|
||||
var ios = <utils.ios.TextUIView>textBase._nativeView;
|
||||
ios.textColor = newValue;
|
||||
}
|
||||
|
||||
private static resetColorProperty(view: view.View, nativeValue: any) {
|
||||
var ios = <utils.ios.TextUIView>view._nativeView;
|
||||
private static resetColorProperty(textBase: view.View, nativeValue: any) {
|
||||
var ios = <utils.ios.TextUIView>textBase._nativeView;
|
||||
ios.textColor = nativeValue;
|
||||
}
|
||||
|
||||
private static getNativeColorValue(view: view.View): any {
|
||||
var ios = <utils.ios.TextUIView>view._nativeView;
|
||||
private static getNativeColorValue(textBase: view.View): any {
|
||||
var ios = <utils.ios.TextUIView>textBase._nativeView;
|
||||
return ios.textColor;
|
||||
}
|
||||
|
||||
@ -120,4 +122,80 @@ export class TextBaseStyler implements style.Styler {
|
||||
TextBaseStyler.setLetterSpacingProperty,
|
||||
TextBaseStyler.resetLetterSpacingProperty), "TextBase");
|
||||
}
|
||||
|
||||
private static _setTextBaseTextDecorationAndTransform(textBase: TextBase, decoration: string, transform: string, letterSpacing: number) {
|
||||
// if (!textBase["counter"]){
|
||||
// textBase["counter"] = 0;
|
||||
// }
|
||||
// textBase["counter"]++;
|
||||
// console.log(`>>> ${textBase["counter"]} ${textBase} ${decoration}; ${transform}; ${letterSpacing}; text: ${textBase.text}; formattedText: ${textBase.formattedText}; isLoaded: ${textBase.isLoaded};`);
|
||||
|
||||
let hasLetterSpacing = types.isNumber(letterSpacing) && !isNaN(letterSpacing);
|
||||
let nativeView = <utils.ios.TextUIView>textBase._nativeView;
|
||||
|
||||
if (textBase.formattedText) {
|
||||
if (textBase.style.textDecoration.indexOf(enums.TextDecoration.none) === -1) {
|
||||
|
||||
if (textBase.style.textDecoration.indexOf(enums.TextDecoration.underline) !== -1) {
|
||||
textBase.formattedText.underline = NSUnderlineStyle.NSUnderlineStyleSingle;
|
||||
}
|
||||
|
||||
if (textBase.style.textDecoration.indexOf(enums.TextDecoration.lineThrough) !== -1) {
|
||||
textBase.formattedText.strikethrough = NSUnderlineStyle.NSUnderlineStyleSingle;
|
||||
}
|
||||
}
|
||||
else {
|
||||
textBase.formattedText.underline = NSUnderlineStyle.NSUnderlineStyleNone;
|
||||
}
|
||||
|
||||
for (let i = 0; i < textBase.formattedText.spans.length; i++) {
|
||||
let span = textBase.formattedText.spans.getItem(i);
|
||||
span.text = utils.ios.getTransformedText(textBase, span.text, transform);
|
||||
}
|
||||
|
||||
if (hasLetterSpacing) {
|
||||
let attrText = NSMutableAttributedString.alloc().initWithAttributedString(nativeView.attributedText);
|
||||
attrText.addAttributeValueRange(NSKernAttributeName, letterSpacing, { location: 0, length: attrText.length });
|
||||
nativeView.attributedText = attrText;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let source = textBase.text;
|
||||
let attributes = new Array();
|
||||
let range = { location: 0, length: source.length };
|
||||
|
||||
var decorationValues = (decoration + "").split(" ");
|
||||
|
||||
if (decorationValues.indexOf(enums.TextDecoration.none) === -1 || hasLetterSpacing) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (hasLetterSpacing) {
|
||||
dict.set(NSKernAttributeName, letterSpacing);
|
||||
}
|
||||
|
||||
attributes.push({ attrs: dict, range: NSValue.valueWithRange(range) });
|
||||
}
|
||||
|
||||
source = utils.ios.getTransformedText(textBase, 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);
|
||||
}
|
||||
nativeView.attributedText = result;
|
||||
}
|
||||
else {
|
||||
nativeView.text = source;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,16 +6,22 @@ export class TextBase extends common.TextBase {
|
||||
public _onTextPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
var newValue = types.toUIString(data.newValue);
|
||||
this.ios.text = newValue;
|
||||
|
||||
//RemoveThisDoubleCall
|
||||
this.style._updateTextDecoration();
|
||||
this.style._updateTextTransform();
|
||||
|
||||
this._requestLayoutOnTextChanged();
|
||||
}
|
||||
|
||||
public _setFormattedTextPropertyToNative(value) {
|
||||
var newText = value ? value._formattedText : null;
|
||||
this.ios.attributedText = newText;
|
||||
|
||||
//RemoveThisDoubleCall
|
||||
this.style._updateTextDecoration();
|
||||
this.style._updateTextTransform();
|
||||
|
||||
this.requestLayout();
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,10 @@ class UITextFieldDelegateImpl extends NSObject implements UITextFieldDelegate {
|
||||
}
|
||||
|
||||
owner.dismissSoftInput();
|
||||
|
||||
if (owner.formattedText){
|
||||
owner.formattedText.createFormattedStringCore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,12 +75,6 @@ class UITextFieldDelegateImpl extends NSObject implements UITextFieldDelegate {
|
||||
public textFieldShouldChangeCharactersInRangeReplacementString(textField: UITextField, range: NSRange, replacementString: string): boolean {
|
||||
let owner = this._owner.get();
|
||||
if (owner) {
|
||||
|
||||
var r = textField.selectedTextRange;
|
||||
owner.style._updateTextDecoration();
|
||||
owner.style._updateTextTransform();
|
||||
textField.selectedTextRange = r;
|
||||
|
||||
if (owner.updateTextTrigger === UpdateTextTrigger.textChanged) {
|
||||
if (textField.secureTextEntry && this.firstEdit) {
|
||||
owner._onPropertyChangedFromNative(TextBase.textProperty, replacementString);
|
||||
@ -88,6 +86,10 @@ class UITextFieldDelegateImpl extends NSObject implements UITextFieldDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (owner.formattedText){
|
||||
owner.formattedText._updateCharactersInRangeReplacementString(range.location, range.length, replacementString);
|
||||
}
|
||||
}
|
||||
|
||||
this.firstEdit = false;
|
||||
@ -142,9 +144,6 @@ export class TextField extends common.TextField {
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this._ios.delegate = this._delegate;
|
||||
|
||||
this.style._updateTextDecoration();
|
||||
this.style._updateTextTransform();
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
|
@ -28,14 +28,6 @@ class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
|
||||
return true;
|
||||
}
|
||||
|
||||
public textViewDidBeginEditing(textView: UITextView) {
|
||||
let owner = this._owner.get();
|
||||
if (owner) {
|
||||
owner.style._updateTextDecoration();
|
||||
owner.style._updateTextTransform();
|
||||
}
|
||||
}
|
||||
|
||||
public textViewDidEndEditing(textView: UITextView) {
|
||||
let owner = this._owner.get();
|
||||
if (owner) {
|
||||
@ -46,6 +38,12 @@ class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
|
||||
owner.dismissSoftInput();
|
||||
owner._refreshHintState(owner.hint, textView.text);
|
||||
|
||||
if (owner.formattedText) {
|
||||
owner.formattedText.createFormattedStringCore();
|
||||
|
||||
}
|
||||
|
||||
//RemoveThisDoubleCall
|
||||
owner.style._updateTextDecoration();
|
||||
owner.style._updateTextTransform();
|
||||
}
|
||||
@ -54,16 +52,20 @@ class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
|
||||
public textViewDidChange(textView: UITextView) {
|
||||
let owner = this._owner.get();
|
||||
if (owner) {
|
||||
var range = textView.selectedRange;
|
||||
owner.style._updateTextDecoration();
|
||||
owner.style._updateTextTransform();
|
||||
textView.selectedRange = range;
|
||||
|
||||
if (owner.updateTextTrigger === UpdateTextTrigger.textChanged) {
|
||||
owner._onPropertyChangedFromNative(TextBase.textProperty, textView.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public textViewShouldChangeTextInRangeReplacementText(textView: UITextView, range: NSRange, replacementString: string): boolean {
|
||||
let owner = this._owner.get();
|
||||
if (owner && owner.formattedText) {
|
||||
owner.formattedText._updateCharactersInRangeReplacementString(range.location, range.length, replacementString);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class TextView extends common.TextView {
|
||||
@ -83,9 +85,6 @@ export class TextView extends common.TextView {
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this._ios.delegate = this._delegate;
|
||||
|
||||
this.style._updateTextDecoration();
|
||||
this.style._updateTextTransform();
|
||||
}
|
||||
|
||||
public onUnloaded() {
|
||||
|
3
tns-core-modules/utils/utils.d.ts
vendored
3
tns-core-modules/utils/utils.d.ts
vendored
@ -154,10 +154,11 @@
|
||||
* Module with ios specific utilities.
|
||||
*/
|
||||
module ios {
|
||||
export function setTextDecorationAndTransform(view: any, decoration: string, transform: string, letterSpacing : number);
|
||||
export function getTransformedText(view, source: string, transform: string): string;
|
||||
export function setWhiteSpace(view, value: string, parentView?: any);
|
||||
export function setTextAlignment(view, value: string);
|
||||
|
||||
// Common properties between UILabel, UITextView and UITextField
|
||||
export interface TextUIView {
|
||||
font: any;
|
||||
textAlignment: number;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import dts = require("utils/utils");
|
||||
import types = require("utils/types");
|
||||
import common = require("./utils-common");
|
||||
import {Color} from "color";
|
||||
import enums = require("ui/enums");
|
||||
@ -41,7 +40,6 @@ export module layout {
|
||||
}
|
||||
|
||||
export module ios {
|
||||
|
||||
export function setTextAlignment(view: dts.ios.TextUIView, value: string) {
|
||||
switch (value) {
|
||||
case enums.TextAlignment.left:
|
||||
@ -58,98 +56,7 @@ export module ios {
|
||||
}
|
||||
}
|
||||
|
||||
export function setTextDecorationAndTransform(v: any, decoration: string, transform: string, letterSpacing: number) {
|
||||
let hasLetterSpacing = types.isNumber(letterSpacing) && !isNaN(letterSpacing);
|
||||
|
||||
if (v.formattedText) {
|
||||
if (v.style.textDecoration.indexOf(enums.TextDecoration.none) === -1) {
|
||||
|
||||
if (v.style.textDecoration.indexOf(enums.TextDecoration.underline) !== -1) {
|
||||
(<any>v).formattedText.underline = NSUnderlineStyle.NSUnderlineStyleSingle;
|
||||
}
|
||||
|
||||
if (v.style.textDecoration.indexOf(enums.TextDecoration.lineThrough) !== -1) {
|
||||
(<any>v).formattedText.strikethrough = NSUnderlineStyle.NSUnderlineStyleSingle;
|
||||
}
|
||||
|
||||
} else {
|
||||
(<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);
|
||||
}
|
||||
|
||||
if (hasLetterSpacing) {
|
||||
let attrText;
|
||||
if(v._nativeView instanceof UIButton){
|
||||
attrText = (<UIButton>v._nativeView).attributedTitleForState(UIControlState.UIControlStateNormal);
|
||||
} else {
|
||||
attrText = v._nativeView.attributedText;
|
||||
}
|
||||
|
||||
attrText.addAttributeValueRange(NSKernAttributeName, letterSpacing, { location: 0, length: v._nativeView.attributedText.length });
|
||||
|
||||
if(v._nativeView instanceof UIButton){
|
||||
(<UIButton>v._nativeView).setAttributedTitleForState(attrText, UIControlState.UIControlStateNormal);
|
||||
}
|
||||
}
|
||||
|
||||
} 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 || hasLetterSpacing) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (hasLetterSpacing) {
|
||||
dict.set(NSKernAttributeName, letterSpacing);
|
||||
}
|
||||
|
||||
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).setAttributedTitleForState(NSMutableAttributedString.alloc().initWithString(source), UIControlState.UIControlStateNormal);
|
||||
(<UIButton>view).setTitleForState(<string>source, UIControlState.UIControlStateNormal);
|
||||
}
|
||||
else {
|
||||
(<dts.ios.TextUIView>view).text = <string>source;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getTransformedText(view, source: string, transform: string): string {
|
||||
export function getTransformedText(view, source: string, transform: string): string {
|
||||
let result = source;
|
||||
|
||||
switch (transform) {
|
||||
|
Reference in New Issue
Block a user