mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
chore: default tabs
This commit is contained in:
@@ -13,48 +13,48 @@ import { TextDecoration } from '../text-base';
|
||||
* A class used to create a formatted (rich text) string.
|
||||
*/
|
||||
export class FormattedString extends ViewBase {
|
||||
/**
|
||||
* An observable collection of Span objects used to define common text properties.
|
||||
*/
|
||||
public spans: ObservableArray<Span>;
|
||||
/**
|
||||
* An observable collection of Span objects used to define common text properties.
|
||||
*/
|
||||
public spans: ObservableArray<Span>;
|
||||
|
||||
/**
|
||||
* A human readable representation of the formatted string.
|
||||
*/
|
||||
public toString(): string;
|
||||
/**
|
||||
* A human readable representation of the formatted string.
|
||||
*/
|
||||
public toString(): string;
|
||||
|
||||
/**
|
||||
* Gets or sets the font family which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public fontFamily: string;
|
||||
/**
|
||||
* Gets or sets the font family which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public fontFamily: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the font size which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public fontSize: number;
|
||||
/**
|
||||
* Gets or sets the font size which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public fontSize: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the font style which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public fontStyle: FontStyle;
|
||||
/**
|
||||
* Gets or sets the font style which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public fontStyle: FontStyle;
|
||||
|
||||
/**
|
||||
* Gets or sets the font weight which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public fontWeight: FontWeight;
|
||||
/**
|
||||
* Gets or sets the font weight which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public fontWeight: FontWeight;
|
||||
|
||||
/**
|
||||
* Gets or sets text decorations which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public textDecoration: TextDecoration;
|
||||
/**
|
||||
* Gets or sets text decorations which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public textDecoration: TextDecoration;
|
||||
|
||||
/**
|
||||
* Gets or sets the font foreground color which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public color: Color;
|
||||
/**
|
||||
* Gets or sets the font foreground color which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public color: Color;
|
||||
|
||||
/**
|
||||
* Gets or sets the font background color which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public backgroundColor: Color;
|
||||
/**
|
||||
* Gets or sets the font background color which will be used for all spans that doesn't have a specific value.
|
||||
*/
|
||||
public backgroundColor: Color;
|
||||
}
|
||||
|
||||
@@ -9,155 +9,155 @@ import { FontStyle, FontWeight } from '../styling/font';
|
||||
import { TextDecoration } from '../text-base';
|
||||
|
||||
export module knownCollections {
|
||||
export const spans = 'spans';
|
||||
export const spans = 'spans';
|
||||
}
|
||||
|
||||
export class FormattedString extends ViewBase implements FormattedStringDefinition, AddArrayFromBuilder, AddChildFromBuilder {
|
||||
private _spans: ObservableArray<Span>;
|
||||
private _spans: ObservableArray<Span>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._spans = new ObservableArray<Span>();
|
||||
this._spans.addEventListener(ObservableArray.changeEvent, this.onSpansCollectionChanged, this);
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this._spans = new ObservableArray<Span>();
|
||||
this._spans.addEventListener(ObservableArray.changeEvent, this.onSpansCollectionChanged, this);
|
||||
}
|
||||
|
||||
get fontFamily(): string {
|
||||
return this.style.fontFamily;
|
||||
}
|
||||
set fontFamily(value: string) {
|
||||
this.style.fontFamily = value;
|
||||
}
|
||||
get fontFamily(): string {
|
||||
return this.style.fontFamily;
|
||||
}
|
||||
set fontFamily(value: string) {
|
||||
this.style.fontFamily = value;
|
||||
}
|
||||
|
||||
get fontSize(): number {
|
||||
return this.style.fontSize;
|
||||
}
|
||||
set fontSize(value: number) {
|
||||
this.style.fontSize = value;
|
||||
}
|
||||
get fontSize(): number {
|
||||
return this.style.fontSize;
|
||||
}
|
||||
set fontSize(value: number) {
|
||||
this.style.fontSize = value;
|
||||
}
|
||||
|
||||
get fontStyle(): FontStyle {
|
||||
return this.style.fontStyle;
|
||||
}
|
||||
set fontStyle(value: FontStyle) {
|
||||
this.style.fontStyle = value;
|
||||
}
|
||||
get fontStyle(): FontStyle {
|
||||
return this.style.fontStyle;
|
||||
}
|
||||
set fontStyle(value: FontStyle) {
|
||||
this.style.fontStyle = value;
|
||||
}
|
||||
|
||||
get fontWeight(): FontWeight {
|
||||
return this.style.fontWeight;
|
||||
}
|
||||
set fontWeight(value: FontWeight) {
|
||||
this.style.fontWeight = value;
|
||||
}
|
||||
get fontWeight(): FontWeight {
|
||||
return this.style.fontWeight;
|
||||
}
|
||||
set fontWeight(value: FontWeight) {
|
||||
this.style.fontWeight = value;
|
||||
}
|
||||
|
||||
get textDecoration(): TextDecoration {
|
||||
return this.style.textDecoration;
|
||||
}
|
||||
set textDecoration(value: TextDecoration) {
|
||||
this.style.textDecoration = value;
|
||||
}
|
||||
get textDecoration(): TextDecoration {
|
||||
return this.style.textDecoration;
|
||||
}
|
||||
set textDecoration(value: TextDecoration) {
|
||||
this.style.textDecoration = value;
|
||||
}
|
||||
|
||||
get color(): Color {
|
||||
return this.style.color;
|
||||
}
|
||||
set color(value: Color) {
|
||||
this.style.color = value;
|
||||
}
|
||||
get color(): Color {
|
||||
return this.style.color;
|
||||
}
|
||||
set color(value: Color) {
|
||||
this.style.color = value;
|
||||
}
|
||||
|
||||
get backgroundColor(): Color {
|
||||
return this.style.backgroundColor;
|
||||
}
|
||||
set backgroundColor(value: Color) {
|
||||
this.style.backgroundColor = value;
|
||||
}
|
||||
get backgroundColor(): Color {
|
||||
return this.style.backgroundColor;
|
||||
}
|
||||
set backgroundColor(value: Color) {
|
||||
this.style.backgroundColor = value;
|
||||
}
|
||||
|
||||
get spans(): ObservableArray<Span> {
|
||||
if (!this._spans) {
|
||||
this._spans = new ObservableArray<Span>();
|
||||
}
|
||||
get spans(): ObservableArray<Span> {
|
||||
if (!this._spans) {
|
||||
this._spans = new ObservableArray<Span>();
|
||||
}
|
||||
|
||||
return this._spans;
|
||||
}
|
||||
return this._spans;
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
let result = '';
|
||||
for (let i = 0, length = this._spans.length; i < length; i++) {
|
||||
result += this._spans.getItem(i).text;
|
||||
}
|
||||
public toString(): string {
|
||||
let result = '';
|
||||
for (let i = 0, length = this._spans.length; i < length; i++) {
|
||||
result += this._spans.getItem(i).text;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public _addArrayFromBuilder(name: string, value: Array<any>) {
|
||||
if (name === knownCollections.spans) {
|
||||
this.spans.push(value);
|
||||
}
|
||||
}
|
||||
public _addArrayFromBuilder(name: string, value: Array<any>) {
|
||||
if (name === knownCollections.spans) {
|
||||
this.spans.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
public _addChildFromBuilder(name: string, value: any): void {
|
||||
if (value instanceof Span) {
|
||||
this.spans.push(value);
|
||||
}
|
||||
}
|
||||
public _addChildFromBuilder(name: string, value: any): void {
|
||||
if (value instanceof Span) {
|
||||
this.spans.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
private onSpansCollectionChanged(eventData: ChangedData<Span>) {
|
||||
if (eventData.addedCount > 0) {
|
||||
for (let i = 0; i < eventData.addedCount; i++) {
|
||||
const span = (<ObservableArray<Span>>eventData.object).getItem(eventData.index + i);
|
||||
private onSpansCollectionChanged(eventData: ChangedData<Span>) {
|
||||
if (eventData.addedCount > 0) {
|
||||
for (let i = 0; i < eventData.addedCount; i++) {
|
||||
const span = (<ObservableArray<Span>>eventData.object).getItem(eventData.index + i);
|
||||
|
||||
// First add to logical tree so that inherited properties are set.
|
||||
this._addView(<any>span);
|
||||
// First add to logical tree so that inherited properties are set.
|
||||
this._addView(<any>span);
|
||||
|
||||
// Then attach handlers - we skip the first nofitication because
|
||||
// we raise change for the whole instance.
|
||||
this.addPropertyChangeHandler(span);
|
||||
}
|
||||
}
|
||||
// Then attach handlers - we skip the first nofitication because
|
||||
// we raise change for the whole instance.
|
||||
this.addPropertyChangeHandler(span);
|
||||
}
|
||||
}
|
||||
|
||||
if (eventData.removed && eventData.removed.length > 0) {
|
||||
for (let p = 0; p < eventData.removed.length; p++) {
|
||||
const span = eventData.removed[p];
|
||||
if (eventData.removed && eventData.removed.length > 0) {
|
||||
for (let p = 0; p < eventData.removed.length; p++) {
|
||||
const span = eventData.removed[p];
|
||||
|
||||
// First remove handlers so that we don't listen for changes
|
||||
// on inherited properties.
|
||||
this.removePropertyChangeHandler(span);
|
||||
// First remove handlers so that we don't listen for changes
|
||||
// on inherited properties.
|
||||
this.removePropertyChangeHandler(span);
|
||||
|
||||
// Then remove the element.
|
||||
this._removeView(span);
|
||||
}
|
||||
}
|
||||
// Then remove the element.
|
||||
this._removeView(span);
|
||||
}
|
||||
}
|
||||
|
||||
this.notifyPropertyChange('.', this);
|
||||
}
|
||||
this.notifyPropertyChange('.', this);
|
||||
}
|
||||
|
||||
private addPropertyChangeHandler(span: Span) {
|
||||
const style = span.style;
|
||||
span.on(Observable.propertyChangeEvent, this.onPropertyChange, this);
|
||||
style.on('fontFamilyChange', this.onPropertyChange, this);
|
||||
style.on('fontSizeChange', this.onPropertyChange, this);
|
||||
style.on('fontStyleChange', this.onPropertyChange, this);
|
||||
style.on('fontWeightChange', this.onPropertyChange, this);
|
||||
style.on('textDecorationChange', this.onPropertyChange, this);
|
||||
style.on('colorChange', this.onPropertyChange, this);
|
||||
style.on('backgroundColorChange', this.onPropertyChange, this);
|
||||
}
|
||||
private addPropertyChangeHandler(span: Span) {
|
||||
const style = span.style;
|
||||
span.on(Observable.propertyChangeEvent, this.onPropertyChange, this);
|
||||
style.on('fontFamilyChange', this.onPropertyChange, this);
|
||||
style.on('fontSizeChange', this.onPropertyChange, this);
|
||||
style.on('fontStyleChange', this.onPropertyChange, this);
|
||||
style.on('fontWeightChange', this.onPropertyChange, this);
|
||||
style.on('textDecorationChange', this.onPropertyChange, this);
|
||||
style.on('colorChange', this.onPropertyChange, this);
|
||||
style.on('backgroundColorChange', this.onPropertyChange, this);
|
||||
}
|
||||
|
||||
private removePropertyChangeHandler(span: Span) {
|
||||
const style = span.style;
|
||||
span.off(Observable.propertyChangeEvent, this.onPropertyChange, this);
|
||||
style.off('fontFamilyChange', this.onPropertyChange, this);
|
||||
style.off('fontSizeChange', this.onPropertyChange, this);
|
||||
style.off('fontStyleChange', this.onPropertyChange, this);
|
||||
style.off('fontWeightChange', this.onPropertyChange, this);
|
||||
style.off('textDecorationChange', this.onPropertyChange, this);
|
||||
style.off('colorChange', this.onPropertyChange, this);
|
||||
style.off('backgroundColorChange', this.onPropertyChange, this);
|
||||
}
|
||||
private removePropertyChangeHandler(span: Span) {
|
||||
const style = span.style;
|
||||
span.off(Observable.propertyChangeEvent, this.onPropertyChange, this);
|
||||
style.off('fontFamilyChange', this.onPropertyChange, this);
|
||||
style.off('fontSizeChange', this.onPropertyChange, this);
|
||||
style.off('fontStyleChange', this.onPropertyChange, this);
|
||||
style.off('fontWeightChange', this.onPropertyChange, this);
|
||||
style.off('textDecorationChange', this.onPropertyChange, this);
|
||||
style.off('colorChange', this.onPropertyChange, this);
|
||||
style.off('backgroundColorChange', this.onPropertyChange, this);
|
||||
}
|
||||
|
||||
private onPropertyChange(data: PropertyChangeData) {
|
||||
this.notifyPropertyChange(data.propertyName, this);
|
||||
}
|
||||
private onPropertyChange(data: PropertyChangeData) {
|
||||
this.notifyPropertyChange(data.propertyName, this);
|
||||
}
|
||||
|
||||
eachChild(callback: (child: ViewBase) => boolean): void {
|
||||
this.spans.forEach((v, i, arr) => callback(v));
|
||||
}
|
||||
eachChild(callback: (child: ViewBase) => boolean): void {
|
||||
this.spans.forEach((v, i, arr) => callback(v));
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
170
nativescript-core/ui/text-base/index.d.ts
vendored
170
nativescript-core/ui/text-base/index.d.ts
vendored
@@ -5,112 +5,112 @@ import { Length } from '../styling/style-properties';
|
||||
import { Property, CssProperty, InheritedCssProperty } from '../core/properties';
|
||||
|
||||
export class TextBase extends View implements AddChildFromBuilder {
|
||||
/**
|
||||
* Gets of the text widget. In some cases(android TextInputLayout) the TextView is made of 2 views: the layout and the text view
|
||||
* So we need a different getter for the layout and text functions
|
||||
*/
|
||||
public readonly nativeTextViewProtected: any;
|
||||
/**
|
||||
* Gets of the text widget. In some cases(android TextInputLayout) the TextView is made of 2 views: the layout and the text view
|
||||
* So we need a different getter for the layout and text functions
|
||||
*/
|
||||
public readonly nativeTextViewProtected: any;
|
||||
|
||||
/**
|
||||
* Gets or sets the text.
|
||||
*/
|
||||
text: string;
|
||||
/**
|
||||
* Gets or sets the text.
|
||||
*/
|
||||
text: string;
|
||||
|
||||
/**
|
||||
* Gets or sets a formatted string.
|
||||
*/
|
||||
formattedText: FormattedString;
|
||||
/**
|
||||
* Gets or sets a formatted string.
|
||||
*/
|
||||
formattedText: FormattedString;
|
||||
|
||||
/**
|
||||
* Gets or sets font-size style property.
|
||||
*/
|
||||
fontSize: number;
|
||||
/**
|
||||
* Gets or sets font-size style property.
|
||||
*/
|
||||
fontSize: number;
|
||||
|
||||
/**
|
||||
* Gets or sets letterSpace style property.
|
||||
*/
|
||||
letterSpacing: number;
|
||||
/**
|
||||
* Gets or sets letterSpace style property.
|
||||
*/
|
||||
letterSpacing: number;
|
||||
|
||||
/**
|
||||
* Gets or sets lineHeight style property.
|
||||
*/
|
||||
lineHeight: number;
|
||||
/**
|
||||
* Gets or sets lineHeight style property.
|
||||
*/
|
||||
lineHeight: number;
|
||||
|
||||
/**
|
||||
* Gets or sets text-alignment style property.
|
||||
*/
|
||||
textAlignment: TextAlignment;
|
||||
/**
|
||||
* Gets or sets text-alignment style property.
|
||||
*/
|
||||
textAlignment: TextAlignment;
|
||||
|
||||
/**
|
||||
* Gets or sets text decorations style property.
|
||||
*/
|
||||
textDecoration: TextDecoration;
|
||||
/**
|
||||
* Gets or sets text decorations style property.
|
||||
*/
|
||||
textDecoration: TextDecoration;
|
||||
|
||||
/**
|
||||
* Gets or sets text transform style property.
|
||||
*/
|
||||
textTransform: TextTransform;
|
||||
/**
|
||||
* Gets or sets text transform style property.
|
||||
*/
|
||||
textTransform: TextTransform;
|
||||
|
||||
/**
|
||||
* Gets or sets white space style property.
|
||||
*/
|
||||
whiteSpace: WhiteSpace;
|
||||
/**
|
||||
* Gets or sets white space style property.
|
||||
*/
|
||||
whiteSpace: WhiteSpace;
|
||||
|
||||
/**
|
||||
* Gets or sets padding style property.
|
||||
*/
|
||||
padding: string | Length;
|
||||
/**
|
||||
* Gets or sets padding style property.
|
||||
*/
|
||||
padding: string | Length;
|
||||
|
||||
/**
|
||||
* Specify the bottom padding of this layout.
|
||||
*/
|
||||
paddingBottom: Length;
|
||||
/**
|
||||
* Specify the bottom padding of this layout.
|
||||
*/
|
||||
paddingBottom: Length;
|
||||
|
||||
/**
|
||||
* Specify the left padding of this layout.
|
||||
*/
|
||||
paddingLeft: Length;
|
||||
/**
|
||||
* Specify the left padding of this layout.
|
||||
*/
|
||||
paddingLeft: Length;
|
||||
|
||||
/**
|
||||
* Specify the right padding of this layout.
|
||||
*/
|
||||
paddingRight: Length;
|
||||
/**
|
||||
* Specify the right padding of this layout.
|
||||
*/
|
||||
paddingRight: Length;
|
||||
|
||||
/**
|
||||
* Specify the top padding of this layout.
|
||||
*/
|
||||
paddingTop: Length;
|
||||
/**
|
||||
* Specify the top padding of this layout.
|
||||
*/
|
||||
paddingTop: Length;
|
||||
|
||||
/**
|
||||
* Called for every child element declared in xml.
|
||||
* This method will add a child element (value) to current element.
|
||||
* @private
|
||||
* @param name - Name of the element.
|
||||
* @param value - Value of the element.
|
||||
*/
|
||||
_addChildFromBuilder(name: string, value: any): void;
|
||||
/**
|
||||
* Called for every child element declared in xml.
|
||||
* This method will add a child element (value) to current element.
|
||||
* @private
|
||||
* @param name - Name of the element.
|
||||
* @param value - Value of the element.
|
||||
*/
|
||||
_addChildFromBuilder(name: string, value: any): void;
|
||||
|
||||
//@private
|
||||
/**
|
||||
* Called when the text property is changed to request layout.
|
||||
* @private
|
||||
*/
|
||||
_requestLayoutOnTextChanged(): void;
|
||||
//@private
|
||||
/**
|
||||
* Called when the text property is changed to request layout.
|
||||
* @private
|
||||
*/
|
||||
_requestLayoutOnTextChanged(): void;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_setNativeText(reset?: boolean): void;
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_setNativeText(reset?: boolean): void;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_isSingleLine: boolean;
|
||||
//@endprivate
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_isSingleLine: boolean;
|
||||
//@endprivate
|
||||
}
|
||||
|
||||
export interface TextTransformation {
|
||||
new (owner: TextBase): any /* android.text.method.TransformationMethod */;
|
||||
new (owner: TextBase): any /* android.text.method.TransformationMethod */;
|
||||
}
|
||||
|
||||
export const textProperty: Property<TextBase, string>;
|
||||
|
||||
@@ -16,465 +16,465 @@ export * from './text-base-common';
|
||||
const majorVersion = ios.MajorVersion;
|
||||
|
||||
class UILabelClickHandlerImpl extends NSObject {
|
||||
private _owner: WeakRef<TextBase>;
|
||||
private _owner: WeakRef<TextBase>;
|
||||
|
||||
public static initWithOwner(owner: WeakRef<TextBase>): UILabelClickHandlerImpl {
|
||||
let handler = <UILabelClickHandlerImpl>UILabelClickHandlerImpl.new();
|
||||
handler._owner = owner;
|
||||
public static initWithOwner(owner: WeakRef<TextBase>): UILabelClickHandlerImpl {
|
||||
let handler = <UILabelClickHandlerImpl>UILabelClickHandlerImpl.new();
|
||||
handler._owner = owner;
|
||||
|
||||
return handler;
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
public linkTap(tapGesture: UITapGestureRecognizer) {
|
||||
let owner = this._owner.get();
|
||||
if (owner) {
|
||||
// https://stackoverflow.com/a/35789589
|
||||
let label = <UILabel>owner.nativeTextViewProtected;
|
||||
let layoutManager = NSLayoutManager.alloc().init();
|
||||
let textContainer = NSTextContainer.alloc().initWithSize(CGSizeZero);
|
||||
let textStorage = NSTextStorage.alloc().initWithAttributedString(owner.nativeTextViewProtected['attributedText']);
|
||||
public linkTap(tapGesture: UITapGestureRecognizer) {
|
||||
let owner = this._owner.get();
|
||||
if (owner) {
|
||||
// https://stackoverflow.com/a/35789589
|
||||
let label = <UILabel>owner.nativeTextViewProtected;
|
||||
let layoutManager = NSLayoutManager.alloc().init();
|
||||
let textContainer = NSTextContainer.alloc().initWithSize(CGSizeZero);
|
||||
let textStorage = NSTextStorage.alloc().initWithAttributedString(owner.nativeTextViewProtected['attributedText']);
|
||||
|
||||
layoutManager.addTextContainer(textContainer);
|
||||
textStorage.addLayoutManager(layoutManager);
|
||||
layoutManager.addTextContainer(textContainer);
|
||||
textStorage.addLayoutManager(layoutManager);
|
||||
|
||||
textContainer.lineFragmentPadding = 0;
|
||||
textContainer.lineBreakMode = label.lineBreakMode;
|
||||
textContainer.maximumNumberOfLines = label.numberOfLines;
|
||||
let labelSize = label.bounds.size;
|
||||
textContainer.size = labelSize;
|
||||
textContainer.lineFragmentPadding = 0;
|
||||
textContainer.lineBreakMode = label.lineBreakMode;
|
||||
textContainer.maximumNumberOfLines = label.numberOfLines;
|
||||
let labelSize = label.bounds.size;
|
||||
textContainer.size = labelSize;
|
||||
|
||||
let locationOfTouchInLabel = tapGesture.locationInView(label);
|
||||
let textBoundingBox = layoutManager.usedRectForTextContainer(textContainer);
|
||||
let locationOfTouchInLabel = tapGesture.locationInView(label);
|
||||
let textBoundingBox = layoutManager.usedRectForTextContainer(textContainer);
|
||||
|
||||
let textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
|
||||
let textContainerOffset = CGPointMake((labelSize.width - textBoundingBox.size.width) * 0.5 - textBoundingBox.origin.x, (labelSize.height - textBoundingBox.size.height) * 0.5 - textBoundingBox.origin.y);
|
||||
|
||||
let locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x, locationOfTouchInLabel.y - textContainerOffset.y);
|
||||
let locationOfTouchInTextContainer = CGPointMake(locationOfTouchInLabel.x - textContainerOffset.x, locationOfTouchInLabel.y - textContainerOffset.y);
|
||||
|
||||
let indexOfCharacter = layoutManager.characterIndexForPointInTextContainerFractionOfDistanceBetweenInsertionPoints(locationOfTouchInTextContainer, textContainer, null);
|
||||
let indexOfCharacter = layoutManager.characterIndexForPointInTextContainerFractionOfDistanceBetweenInsertionPoints(locationOfTouchInTextContainer, textContainer, null);
|
||||
|
||||
let span: Span = null;
|
||||
// try to find the corresponding span using the spanRanges
|
||||
for (let i = 0; i < owner._spanRanges.length; i++) {
|
||||
let range = owner._spanRanges[i];
|
||||
if (range.location <= indexOfCharacter && range.location + range.length > indexOfCharacter) {
|
||||
if (owner.formattedText && owner.formattedText.spans.length > i) {
|
||||
span = owner.formattedText.spans.getItem(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
let span: Span = null;
|
||||
// try to find the corresponding span using the spanRanges
|
||||
for (let i = 0; i < owner._spanRanges.length; i++) {
|
||||
let range = owner._spanRanges[i];
|
||||
if (range.location <= indexOfCharacter && range.location + range.length > indexOfCharacter) {
|
||||
if (owner.formattedText && owner.formattedText.spans.length > i) {
|
||||
span = owner.formattedText.spans.getItem(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (span && span.tappable) {
|
||||
// if the span is found and tappable emit the linkTap event
|
||||
span._emit(Span.linkTapEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (span && span.tappable) {
|
||||
// if the span is found and tappable emit the linkTap event
|
||||
span._emit(Span.linkTapEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ObjCExposedMethods = {
|
||||
linkTap: { returns: interop.types.void, params: [interop.types.id] },
|
||||
};
|
||||
public static ObjCExposedMethods = {
|
||||
linkTap: { returns: interop.types.void, params: [interop.types.id] },
|
||||
};
|
||||
}
|
||||
|
||||
export class TextBase extends TextBaseCommon {
|
||||
public nativeViewProtected: UITextField | UITextView | UILabel | UIButton;
|
||||
public nativeTextViewProtected: UITextField | UITextView | UILabel | UIButton;
|
||||
private _tappable: boolean = false;
|
||||
private _tapGestureRecognizer: UITapGestureRecognizer;
|
||||
public _spanRanges: NSRange[];
|
||||
public nativeViewProtected: UITextField | UITextView | UILabel | UIButton;
|
||||
public nativeTextViewProtected: UITextField | UITextView | UILabel | UIButton;
|
||||
private _tappable: boolean = false;
|
||||
private _tapGestureRecognizer: UITapGestureRecognizer;
|
||||
public _spanRanges: NSRange[];
|
||||
|
||||
public initNativeView(): void {
|
||||
super.initNativeView();
|
||||
this._setTappableState(false);
|
||||
}
|
||||
public initNativeView(): void {
|
||||
super.initNativeView();
|
||||
this._setTappableState(false);
|
||||
}
|
||||
|
||||
_setTappableState(tappable: boolean) {
|
||||
if (this._tappable !== tappable) {
|
||||
this._tappable = tappable;
|
||||
if (this._tappable) {
|
||||
const tapHandler = UILabelClickHandlerImpl.initWithOwner(new WeakRef(this));
|
||||
// associate handler with menuItem or it will get collected by JSC.
|
||||
(<any>this).handler = tapHandler;
|
||||
_setTappableState(tappable: boolean) {
|
||||
if (this._tappable !== tappable) {
|
||||
this._tappable = tappable;
|
||||
if (this._tappable) {
|
||||
const tapHandler = UILabelClickHandlerImpl.initWithOwner(new WeakRef(this));
|
||||
// associate handler with menuItem or it will get collected by JSC.
|
||||
(<any>this).handler = tapHandler;
|
||||
|
||||
this._tapGestureRecognizer = UITapGestureRecognizer.alloc().initWithTargetAction(tapHandler, 'linkTap');
|
||||
this.nativeViewProtected.userInteractionEnabled = true;
|
||||
this.nativeViewProtected.addGestureRecognizer(this._tapGestureRecognizer);
|
||||
} else {
|
||||
this.nativeViewProtected.userInteractionEnabled = false;
|
||||
this.nativeViewProtected.removeGestureRecognizer(this._tapGestureRecognizer);
|
||||
}
|
||||
}
|
||||
}
|
||||
this._tapGestureRecognizer = UITapGestureRecognizer.alloc().initWithTargetAction(tapHandler, 'linkTap');
|
||||
this.nativeViewProtected.userInteractionEnabled = true;
|
||||
this.nativeViewProtected.addGestureRecognizer(this._tapGestureRecognizer);
|
||||
} else {
|
||||
this.nativeViewProtected.userInteractionEnabled = false;
|
||||
this.nativeViewProtected.removeGestureRecognizer(this._tapGestureRecognizer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[textProperty.getDefault](): number | symbol {
|
||||
return resetSymbol;
|
||||
}
|
||||
[textProperty.setNative](value: string | number | symbol) {
|
||||
const reset = value === resetSymbol;
|
||||
if (!reset && this.formattedText) {
|
||||
return;
|
||||
}
|
||||
[textProperty.getDefault](): number | symbol {
|
||||
return resetSymbol;
|
||||
}
|
||||
[textProperty.setNative](value: string | number | symbol) {
|
||||
const reset = value === resetSymbol;
|
||||
if (!reset && this.formattedText) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._setNativeText(reset);
|
||||
this._requestLayoutOnTextChanged();
|
||||
}
|
||||
this._setNativeText(reset);
|
||||
this._requestLayoutOnTextChanged();
|
||||
}
|
||||
|
||||
[formattedTextProperty.setNative](value: FormattedString) {
|
||||
this._setNativeText();
|
||||
this._setTappableState(isStringTappable(value));
|
||||
textProperty.nativeValueChange(this, !value ? '' : value.toString());
|
||||
this._requestLayoutOnTextChanged();
|
||||
}
|
||||
[formattedTextProperty.setNative](value: FormattedString) {
|
||||
this._setNativeText();
|
||||
this._setTappableState(isStringTappable(value));
|
||||
textProperty.nativeValueChange(this, !value ? '' : value.toString());
|
||||
this._requestLayoutOnTextChanged();
|
||||
}
|
||||
|
||||
[colorProperty.getDefault](): UIColor {
|
||||
let nativeView = this.nativeTextViewProtected;
|
||||
if (nativeView instanceof UIButton) {
|
||||
return nativeView.titleColorForState(UIControlState.Normal);
|
||||
} else {
|
||||
return nativeView.textColor;
|
||||
}
|
||||
}
|
||||
[colorProperty.setNative](value: Color | UIColor) {
|
||||
const color = value instanceof Color ? value.ios : value;
|
||||
this._setColor(color);
|
||||
}
|
||||
[colorProperty.getDefault](): UIColor {
|
||||
let nativeView = this.nativeTextViewProtected;
|
||||
if (nativeView instanceof UIButton) {
|
||||
return nativeView.titleColorForState(UIControlState.Normal);
|
||||
} else {
|
||||
return nativeView.textColor;
|
||||
}
|
||||
}
|
||||
[colorProperty.setNative](value: Color | UIColor) {
|
||||
const color = value instanceof Color ? value.ios : value;
|
||||
this._setColor(color);
|
||||
}
|
||||
|
||||
[fontInternalProperty.getDefault](): UIFont {
|
||||
let nativeView = this.nativeTextViewProtected;
|
||||
nativeView = nativeView instanceof UIButton ? nativeView.titleLabel : nativeView;
|
||||
[fontInternalProperty.getDefault](): UIFont {
|
||||
let nativeView = this.nativeTextViewProtected;
|
||||
nativeView = nativeView instanceof UIButton ? nativeView.titleLabel : nativeView;
|
||||
|
||||
return nativeView.font;
|
||||
}
|
||||
[fontInternalProperty.setNative](value: Font | UIFont) {
|
||||
if (!(value instanceof Font) || !this.formattedText) {
|
||||
let nativeView = this.nativeTextViewProtected;
|
||||
nativeView = nativeView instanceof UIButton ? nativeView.titleLabel : nativeView;
|
||||
const font = value instanceof Font ? value.getUIFont(nativeView.font) : value;
|
||||
nativeView.font = font;
|
||||
}
|
||||
}
|
||||
return nativeView.font;
|
||||
}
|
||||
[fontInternalProperty.setNative](value: Font | UIFont) {
|
||||
if (!(value instanceof Font) || !this.formattedText) {
|
||||
let nativeView = this.nativeTextViewProtected;
|
||||
nativeView = nativeView instanceof UIButton ? nativeView.titleLabel : nativeView;
|
||||
const font = value instanceof Font ? value.getUIFont(nativeView.font) : value;
|
||||
nativeView.font = font;
|
||||
}
|
||||
}
|
||||
|
||||
[textAlignmentProperty.setNative](value: TextAlignment) {
|
||||
const nativeView = <UITextField | UITextView | UILabel>this.nativeTextViewProtected;
|
||||
switch (value) {
|
||||
case 'initial':
|
||||
case 'left':
|
||||
nativeView.textAlignment = NSTextAlignment.Left;
|
||||
break;
|
||||
case 'center':
|
||||
nativeView.textAlignment = NSTextAlignment.Center;
|
||||
break;
|
||||
case 'right':
|
||||
nativeView.textAlignment = NSTextAlignment.Right;
|
||||
break;
|
||||
}
|
||||
}
|
||||
[textAlignmentProperty.setNative](value: TextAlignment) {
|
||||
const nativeView = <UITextField | UITextView | UILabel>this.nativeTextViewProtected;
|
||||
switch (value) {
|
||||
case 'initial':
|
||||
case 'left':
|
||||
nativeView.textAlignment = NSTextAlignment.Left;
|
||||
break;
|
||||
case 'center':
|
||||
nativeView.textAlignment = NSTextAlignment.Center;
|
||||
break;
|
||||
case 'right':
|
||||
nativeView.textAlignment = NSTextAlignment.Right;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
[textDecorationProperty.setNative](value: TextDecoration) {
|
||||
this._setNativeText();
|
||||
}
|
||||
[textDecorationProperty.setNative](value: TextDecoration) {
|
||||
this._setNativeText();
|
||||
}
|
||||
|
||||
[textTransformProperty.setNative](value: TextTransform) {
|
||||
this._setNativeText();
|
||||
}
|
||||
[textTransformProperty.setNative](value: TextTransform) {
|
||||
this._setNativeText();
|
||||
}
|
||||
|
||||
[letterSpacingProperty.setNative](value: number) {
|
||||
this._setNativeText();
|
||||
}
|
||||
[letterSpacingProperty.setNative](value: number) {
|
||||
this._setNativeText();
|
||||
}
|
||||
|
||||
[lineHeightProperty.setNative](value: number) {
|
||||
this._setNativeText();
|
||||
}
|
||||
[lineHeightProperty.setNative](value: number) {
|
||||
this._setNativeText();
|
||||
}
|
||||
|
||||
_setNativeText(reset: boolean = false): void {
|
||||
if (reset) {
|
||||
const nativeView = this.nativeTextViewProtected;
|
||||
if (nativeView instanceof UIButton) {
|
||||
// Clear attributedText or title won't be affected.
|
||||
nativeView.setAttributedTitleForState(null, UIControlState.Normal);
|
||||
nativeView.setTitleForState(null, UIControlState.Normal);
|
||||
} else {
|
||||
// Clear attributedText or text won't be affected.
|
||||
nativeView.attributedText = null;
|
||||
nativeView.text = null;
|
||||
}
|
||||
_setNativeText(reset: boolean = false): void {
|
||||
if (reset) {
|
||||
const nativeView = this.nativeTextViewProtected;
|
||||
if (nativeView instanceof UIButton) {
|
||||
// Clear attributedText or title won't be affected.
|
||||
nativeView.setAttributedTitleForState(null, UIControlState.Normal);
|
||||
nativeView.setTitleForState(null, UIControlState.Normal);
|
||||
} else {
|
||||
// Clear attributedText or text won't be affected.
|
||||
nativeView.attributedText = null;
|
||||
nativeView.text = null;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.formattedText) {
|
||||
this.setFormattedTextDecorationAndTransform();
|
||||
} else {
|
||||
this.setTextDecorationAndTransform();
|
||||
}
|
||||
}
|
||||
if (this.formattedText) {
|
||||
this.setFormattedTextDecorationAndTransform();
|
||||
} else {
|
||||
this.setTextDecorationAndTransform();
|
||||
}
|
||||
}
|
||||
|
||||
_setColor(color: UIColor): void {
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
this.nativeTextViewProtected.setTitleColorForState(color, UIControlState.Normal);
|
||||
this.nativeTextViewProtected.titleLabel.textColor = color;
|
||||
} else {
|
||||
this.nativeTextViewProtected.textColor = color;
|
||||
}
|
||||
}
|
||||
_setColor(color: UIColor): void {
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
this.nativeTextViewProtected.setTitleColorForState(color, UIControlState.Normal);
|
||||
this.nativeTextViewProtected.titleLabel.textColor = color;
|
||||
} else {
|
||||
this.nativeTextViewProtected.textColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
setFormattedTextDecorationAndTransform() {
|
||||
const attrText = this.createNSMutableAttributedString(this.formattedText);
|
||||
// TODO: letterSpacing should be applied per Span.
|
||||
if (this.letterSpacing !== 0) {
|
||||
attrText.addAttributeValueRange(NSKernAttributeName, this.letterSpacing * this.nativeTextViewProtected.font.pointSize, { location: 0, length: attrText.length });
|
||||
}
|
||||
setFormattedTextDecorationAndTransform() {
|
||||
const attrText = this.createNSMutableAttributedString(this.formattedText);
|
||||
// TODO: letterSpacing should be applied per Span.
|
||||
if (this.letterSpacing !== 0) {
|
||||
attrText.addAttributeValueRange(NSKernAttributeName, this.letterSpacing * this.nativeTextViewProtected.font.pointSize, { location: 0, length: attrText.length });
|
||||
}
|
||||
|
||||
if (this.style.lineHeight) {
|
||||
const paragraphStyle = NSMutableParagraphStyle.alloc().init();
|
||||
paragraphStyle.minimumLineHeight = this.lineHeight;
|
||||
// make sure a possible previously set text alignment setting is not lost when line height is specified
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
paragraphStyle.alignment = (<UIButton>this.nativeTextViewProtected).titleLabel.textAlignment;
|
||||
} else {
|
||||
paragraphStyle.alignment = (<UITextField | UITextView | UILabel>this.nativeTextViewProtected).textAlignment;
|
||||
}
|
||||
if (this.style.lineHeight) {
|
||||
const paragraphStyle = NSMutableParagraphStyle.alloc().init();
|
||||
paragraphStyle.minimumLineHeight = this.lineHeight;
|
||||
// make sure a possible previously set text alignment setting is not lost when line height is specified
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
paragraphStyle.alignment = (<UIButton>this.nativeTextViewProtected).titleLabel.textAlignment;
|
||||
} else {
|
||||
paragraphStyle.alignment = (<UITextField | UITextView | UILabel>this.nativeTextViewProtected).textAlignment;
|
||||
}
|
||||
|
||||
if (this.nativeTextViewProtected instanceof UILabel) {
|
||||
// make sure a possible previously set line break mode is not lost when line height is specified
|
||||
paragraphStyle.lineBreakMode = this.nativeTextViewProtected.lineBreakMode;
|
||||
}
|
||||
attrText.addAttributeValueRange(NSParagraphStyleAttributeName, paragraphStyle, { location: 0, length: attrText.length });
|
||||
} else if (this.nativeTextViewProtected instanceof UITextView) {
|
||||
const paragraphStyle = NSMutableParagraphStyle.alloc().init();
|
||||
paragraphStyle.alignment = (<UITextView>this.nativeTextViewProtected).textAlignment;
|
||||
attrText.addAttributeValueRange(NSParagraphStyleAttributeName, paragraphStyle, { location: 0, length: attrText.length });
|
||||
}
|
||||
if (this.nativeTextViewProtected instanceof UILabel) {
|
||||
// make sure a possible previously set line break mode is not lost when line height is specified
|
||||
paragraphStyle.lineBreakMode = this.nativeTextViewProtected.lineBreakMode;
|
||||
}
|
||||
attrText.addAttributeValueRange(NSParagraphStyleAttributeName, paragraphStyle, { location: 0, length: attrText.length });
|
||||
} else if (this.nativeTextViewProtected instanceof UITextView) {
|
||||
const paragraphStyle = NSMutableParagraphStyle.alloc().init();
|
||||
paragraphStyle.alignment = (<UITextView>this.nativeTextViewProtected).textAlignment;
|
||||
attrText.addAttributeValueRange(NSParagraphStyleAttributeName, paragraphStyle, { location: 0, length: attrText.length });
|
||||
}
|
||||
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
this.nativeTextViewProtected.setAttributedTitleForState(attrText, UIControlState.Normal);
|
||||
} else {
|
||||
if (majorVersion >= 13 && UIColor.labelColor) {
|
||||
this.nativeTextViewProtected.textColor = UIColor.labelColor;
|
||||
}
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
this.nativeTextViewProtected.setAttributedTitleForState(attrText, UIControlState.Normal);
|
||||
} else {
|
||||
if (majorVersion >= 13 && UIColor.labelColor) {
|
||||
this.nativeTextViewProtected.textColor = UIColor.labelColor;
|
||||
}
|
||||
|
||||
this.nativeTextViewProtected.attributedText = attrText;
|
||||
}
|
||||
}
|
||||
this.nativeTextViewProtected.attributedText = attrText;
|
||||
}
|
||||
}
|
||||
|
||||
setTextDecorationAndTransform() {
|
||||
const style = this.style;
|
||||
const dict = new Map<string, any>();
|
||||
switch (style.textDecoration) {
|
||||
case 'none':
|
||||
break;
|
||||
case 'underline':
|
||||
dict.set(NSUnderlineStyleAttributeName, NSUnderlineStyle.Single);
|
||||
break;
|
||||
case 'line-through':
|
||||
dict.set(NSStrikethroughStyleAttributeName, NSUnderlineStyle.Single);
|
||||
break;
|
||||
case 'underline line-through':
|
||||
dict.set(NSUnderlineStyleAttributeName, NSUnderlineStyle.Single);
|
||||
dict.set(NSStrikethroughStyleAttributeName, NSUnderlineStyle.Single);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Invalid text decoration value: ${style.textDecoration}. Valid values are: 'none', 'underline', 'line-through', 'underline line-through'.`);
|
||||
}
|
||||
setTextDecorationAndTransform() {
|
||||
const style = this.style;
|
||||
const dict = new Map<string, any>();
|
||||
switch (style.textDecoration) {
|
||||
case 'none':
|
||||
break;
|
||||
case 'underline':
|
||||
dict.set(NSUnderlineStyleAttributeName, NSUnderlineStyle.Single);
|
||||
break;
|
||||
case 'line-through':
|
||||
dict.set(NSStrikethroughStyleAttributeName, NSUnderlineStyle.Single);
|
||||
break;
|
||||
case 'underline line-through':
|
||||
dict.set(NSUnderlineStyleAttributeName, NSUnderlineStyle.Single);
|
||||
dict.set(NSStrikethroughStyleAttributeName, NSUnderlineStyle.Single);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Invalid text decoration value: ${style.textDecoration}. Valid values are: 'none', 'underline', 'line-through', 'underline line-through'.`);
|
||||
}
|
||||
|
||||
if (style.letterSpacing !== 0 && this.nativeTextViewProtected.font) {
|
||||
const kern = style.letterSpacing * this.nativeTextViewProtected.font.pointSize;
|
||||
dict.set(NSKernAttributeName, kern);
|
||||
if (this.nativeTextViewProtected instanceof UITextField) {
|
||||
this.nativeTextViewProtected.defaultTextAttributes.setValueForKey(kern, NSKernAttributeName);
|
||||
}
|
||||
}
|
||||
if (style.letterSpacing !== 0 && this.nativeTextViewProtected.font) {
|
||||
const kern = style.letterSpacing * this.nativeTextViewProtected.font.pointSize;
|
||||
dict.set(NSKernAttributeName, kern);
|
||||
if (this.nativeTextViewProtected instanceof UITextField) {
|
||||
this.nativeTextViewProtected.defaultTextAttributes.setValueForKey(kern, NSKernAttributeName);
|
||||
}
|
||||
}
|
||||
|
||||
const isTextView = this.nativeTextViewProtected instanceof UITextView;
|
||||
if (style.lineHeight) {
|
||||
const paragraphStyle = NSMutableParagraphStyle.alloc().init();
|
||||
paragraphStyle.lineSpacing = style.lineHeight;
|
||||
// make sure a possible previously set text alignment setting is not lost when line height is specified
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
paragraphStyle.alignment = (<UIButton>this.nativeTextViewProtected).titleLabel.textAlignment;
|
||||
} else {
|
||||
paragraphStyle.alignment = (<UITextField | UITextView | UILabel>this.nativeTextViewProtected).textAlignment;
|
||||
}
|
||||
const isTextView = this.nativeTextViewProtected instanceof UITextView;
|
||||
if (style.lineHeight) {
|
||||
const paragraphStyle = NSMutableParagraphStyle.alloc().init();
|
||||
paragraphStyle.lineSpacing = style.lineHeight;
|
||||
// make sure a possible previously set text alignment setting is not lost when line height is specified
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
paragraphStyle.alignment = (<UIButton>this.nativeTextViewProtected).titleLabel.textAlignment;
|
||||
} else {
|
||||
paragraphStyle.alignment = (<UITextField | UITextView | UILabel>this.nativeTextViewProtected).textAlignment;
|
||||
}
|
||||
|
||||
if (this.nativeTextViewProtected instanceof UILabel) {
|
||||
// make sure a possible previously set line break mode is not lost when line height is specified
|
||||
paragraphStyle.lineBreakMode = this.nativeTextViewProtected.lineBreakMode;
|
||||
}
|
||||
dict.set(NSParagraphStyleAttributeName, paragraphStyle);
|
||||
} else if (isTextView) {
|
||||
const paragraphStyle = NSMutableParagraphStyle.alloc().init();
|
||||
paragraphStyle.alignment = (<UITextView>this.nativeTextViewProtected).textAlignment;
|
||||
dict.set(NSParagraphStyleAttributeName, paragraphStyle);
|
||||
}
|
||||
if (this.nativeTextViewProtected instanceof UILabel) {
|
||||
// make sure a possible previously set line break mode is not lost when line height is specified
|
||||
paragraphStyle.lineBreakMode = this.nativeTextViewProtected.lineBreakMode;
|
||||
}
|
||||
dict.set(NSParagraphStyleAttributeName, paragraphStyle);
|
||||
} else if (isTextView) {
|
||||
const paragraphStyle = NSMutableParagraphStyle.alloc().init();
|
||||
paragraphStyle.alignment = (<UITextView>this.nativeTextViewProtected).textAlignment;
|
||||
dict.set(NSParagraphStyleAttributeName, paragraphStyle);
|
||||
}
|
||||
|
||||
const source = getTransformedText(isNullOrUndefined(this.text) ? '' : `${this.text}`, this.textTransform);
|
||||
if (dict.size > 0 || isTextView) {
|
||||
if (isTextView && this.nativeTextViewProtected.font) {
|
||||
// UITextView's font seems to change inside.
|
||||
dict.set(NSFontAttributeName, this.nativeTextViewProtected.font);
|
||||
}
|
||||
const source = getTransformedText(isNullOrUndefined(this.text) ? '' : `${this.text}`, this.textTransform);
|
||||
if (dict.size > 0 || isTextView) {
|
||||
if (isTextView && this.nativeTextViewProtected.font) {
|
||||
// UITextView's font seems to change inside.
|
||||
dict.set(NSFontAttributeName, this.nativeTextViewProtected.font);
|
||||
}
|
||||
|
||||
const result = NSMutableAttributedString.alloc().initWithString(source);
|
||||
result.setAttributesRange(<any>dict, {
|
||||
location: 0,
|
||||
length: source.length,
|
||||
});
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
this.nativeTextViewProtected.setAttributedTitleForState(result, UIControlState.Normal);
|
||||
} else {
|
||||
this.nativeTextViewProtected.attributedText = result;
|
||||
}
|
||||
} else {
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
// Clear attributedText or title won't be affected.
|
||||
this.nativeTextViewProtected.setAttributedTitleForState(null, UIControlState.Normal);
|
||||
this.nativeTextViewProtected.setTitleForState(source, UIControlState.Normal);
|
||||
} else {
|
||||
// Clear attributedText or text won't be affected.
|
||||
this.nativeTextViewProtected.attributedText = undefined;
|
||||
this.nativeTextViewProtected.text = source;
|
||||
}
|
||||
}
|
||||
const result = NSMutableAttributedString.alloc().initWithString(source);
|
||||
result.setAttributesRange(<any>dict, {
|
||||
location: 0,
|
||||
length: source.length,
|
||||
});
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
this.nativeTextViewProtected.setAttributedTitleForState(result, UIControlState.Normal);
|
||||
} else {
|
||||
this.nativeTextViewProtected.attributedText = result;
|
||||
}
|
||||
} else {
|
||||
if (this.nativeTextViewProtected instanceof UIButton) {
|
||||
// Clear attributedText or title won't be affected.
|
||||
this.nativeTextViewProtected.setAttributedTitleForState(null, UIControlState.Normal);
|
||||
this.nativeTextViewProtected.setTitleForState(source, UIControlState.Normal);
|
||||
} else {
|
||||
// Clear attributedText or text won't be affected.
|
||||
this.nativeTextViewProtected.attributedText = undefined;
|
||||
this.nativeTextViewProtected.text = source;
|
||||
}
|
||||
}
|
||||
|
||||
if (!style.color && majorVersion >= 13 && UIColor.labelColor) {
|
||||
this._setColor(UIColor.labelColor);
|
||||
}
|
||||
}
|
||||
if (!style.color && majorVersion >= 13 && UIColor.labelColor) {
|
||||
this._setColor(UIColor.labelColor);
|
||||
}
|
||||
}
|
||||
|
||||
createNSMutableAttributedString(formattedString: FormattedString): NSMutableAttributedString {
|
||||
let mas = NSMutableAttributedString.alloc().init();
|
||||
this._spanRanges = [];
|
||||
if (formattedString && formattedString.parent) {
|
||||
for (let i = 0, spanStart = 0, length = formattedString.spans.length; i < length; i++) {
|
||||
const span = formattedString.spans.getItem(i);
|
||||
const text = span.text;
|
||||
const textTransform = (<TextBase>formattedString.parent).textTransform;
|
||||
let spanText = isNullOrUndefined(text) ? '' : `${text}`;
|
||||
if (textTransform !== 'none' && textTransform !== 'initial') {
|
||||
spanText = getTransformedText(spanText, textTransform);
|
||||
}
|
||||
createNSMutableAttributedString(formattedString: FormattedString): NSMutableAttributedString {
|
||||
let mas = NSMutableAttributedString.alloc().init();
|
||||
this._spanRanges = [];
|
||||
if (formattedString && formattedString.parent) {
|
||||
for (let i = 0, spanStart = 0, length = formattedString.spans.length; i < length; i++) {
|
||||
const span = formattedString.spans.getItem(i);
|
||||
const text = span.text;
|
||||
const textTransform = (<TextBase>formattedString.parent).textTransform;
|
||||
let spanText = isNullOrUndefined(text) ? '' : `${text}`;
|
||||
if (textTransform !== 'none' && textTransform !== 'initial') {
|
||||
spanText = getTransformedText(spanText, textTransform);
|
||||
}
|
||||
|
||||
const nsAttributedString = this.createMutableStringForSpan(span, spanText);
|
||||
mas.insertAttributedStringAtIndex(nsAttributedString, spanStart);
|
||||
this._spanRanges.push({
|
||||
location: spanStart,
|
||||
length: spanText.length,
|
||||
});
|
||||
spanStart += spanText.length;
|
||||
}
|
||||
}
|
||||
const nsAttributedString = this.createMutableStringForSpan(span, spanText);
|
||||
mas.insertAttributedStringAtIndex(nsAttributedString, spanStart);
|
||||
this._spanRanges.push({
|
||||
location: spanStart,
|
||||
length: spanText.length,
|
||||
});
|
||||
spanStart += spanText.length;
|
||||
}
|
||||
}
|
||||
|
||||
return mas;
|
||||
}
|
||||
return mas;
|
||||
}
|
||||
|
||||
getBaselineOffset(font: UIFont, align?: VerticalAlignment): number {
|
||||
if (!align || ['stretch', 'baseline'].includes(align)) {
|
||||
return 0;
|
||||
}
|
||||
getBaselineOffset(font: UIFont, align?: VerticalAlignment): number {
|
||||
if (!align || ['stretch', 'baseline'].includes(align)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (align === 'top') {
|
||||
return -this.fontSize - font.descender - font.ascender - font.leading / 2;
|
||||
}
|
||||
if (align === 'top') {
|
||||
return -this.fontSize - font.descender - font.ascender - font.leading / 2;
|
||||
}
|
||||
|
||||
if (align === 'bottom') {
|
||||
return font.descender + font.leading / 2;
|
||||
}
|
||||
if (align === 'bottom') {
|
||||
return font.descender + font.leading / 2;
|
||||
}
|
||||
|
||||
if (align === 'text-top') {
|
||||
return -this.fontSize - font.descender - font.ascender;
|
||||
}
|
||||
if (align === 'text-top') {
|
||||
return -this.fontSize - font.descender - font.ascender;
|
||||
}
|
||||
|
||||
if (align === 'text-bottom') {
|
||||
return font.descender;
|
||||
}
|
||||
if (align === 'text-bottom') {
|
||||
return font.descender;
|
||||
}
|
||||
|
||||
if (align === 'middle') {
|
||||
return (font.descender - font.ascender) / 2 - font.descender;
|
||||
}
|
||||
if (align === 'middle') {
|
||||
return (font.descender - font.ascender) / 2 - font.descender;
|
||||
}
|
||||
|
||||
if (align === 'super') {
|
||||
return -this.fontSize * 0.4;
|
||||
}
|
||||
if (align === 'super') {
|
||||
return -this.fontSize * 0.4;
|
||||
}
|
||||
|
||||
if (align === 'sub') {
|
||||
return (font.descender - font.ascender) * 0.4;
|
||||
}
|
||||
}
|
||||
if (align === 'sub') {
|
||||
return (font.descender - font.ascender) * 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
createMutableStringForSpan(span: Span, text: string): NSMutableAttributedString {
|
||||
const viewFont = this.nativeTextViewProtected.font;
|
||||
const attrDict = <{ key: string; value: any }>{};
|
||||
const style = span.style;
|
||||
const align = style.verticalAlignment;
|
||||
createMutableStringForSpan(span: Span, text: string): NSMutableAttributedString {
|
||||
const viewFont = this.nativeTextViewProtected.font;
|
||||
const attrDict = <{ key: string; value: any }>{};
|
||||
const style = span.style;
|
||||
const align = style.verticalAlignment;
|
||||
|
||||
const font = new Font(style.fontFamily, style.fontSize, style.fontStyle, style.fontWeight);
|
||||
const iosFont = font.getUIFont(viewFont);
|
||||
const font = new Font(style.fontFamily, style.fontSize, style.fontStyle, style.fontWeight);
|
||||
const iosFont = font.getUIFont(viewFont);
|
||||
|
||||
attrDict[NSFontAttributeName] = iosFont;
|
||||
attrDict[NSFontAttributeName] = iosFont;
|
||||
|
||||
if (span.color) {
|
||||
attrDict[NSForegroundColorAttributeName] = span.color.ios;
|
||||
}
|
||||
if (span.color) {
|
||||
attrDict[NSForegroundColorAttributeName] = span.color.ios;
|
||||
}
|
||||
|
||||
// We don't use isSet function here because defaultValue for backgroundColor is null.
|
||||
const backgroundColor = <Color>(style.backgroundColor || (<FormattedString>span.parent).backgroundColor || (<TextBase>span.parent.parent).backgroundColor);
|
||||
if (backgroundColor) {
|
||||
attrDict[NSBackgroundColorAttributeName] = backgroundColor.ios;
|
||||
}
|
||||
// We don't use isSet function here because defaultValue for backgroundColor is null.
|
||||
const backgroundColor = <Color>(style.backgroundColor || (<FormattedString>span.parent).backgroundColor || (<TextBase>span.parent.parent).backgroundColor);
|
||||
if (backgroundColor) {
|
||||
attrDict[NSBackgroundColorAttributeName] = backgroundColor.ios;
|
||||
}
|
||||
|
||||
const textDecoration: TextDecoration = getClosestPropertyValue(textDecorationProperty, span);
|
||||
const textDecoration: TextDecoration = getClosestPropertyValue(textDecorationProperty, span);
|
||||
|
||||
if (textDecoration) {
|
||||
const underline = textDecoration.indexOf('underline') !== -1;
|
||||
if (underline) {
|
||||
attrDict[NSUnderlineStyleAttributeName] = underline;
|
||||
}
|
||||
if (textDecoration) {
|
||||
const underline = textDecoration.indexOf('underline') !== -1;
|
||||
if (underline) {
|
||||
attrDict[NSUnderlineStyleAttributeName] = underline;
|
||||
}
|
||||
|
||||
const strikethrough = textDecoration.indexOf('line-through') !== -1;
|
||||
if (strikethrough) {
|
||||
attrDict[NSStrikethroughStyleAttributeName] = strikethrough;
|
||||
}
|
||||
}
|
||||
const strikethrough = textDecoration.indexOf('line-through') !== -1;
|
||||
if (strikethrough) {
|
||||
attrDict[NSStrikethroughStyleAttributeName] = strikethrough;
|
||||
}
|
||||
}
|
||||
|
||||
if (align) {
|
||||
attrDict[NSBaselineOffsetAttributeName] = this.getBaselineOffset(iosFont, align);
|
||||
}
|
||||
if (align) {
|
||||
attrDict[NSBaselineOffsetAttributeName] = this.getBaselineOffset(iosFont, align);
|
||||
}
|
||||
|
||||
return NSMutableAttributedString.alloc().initWithStringAttributes(text, <any>attrDict);
|
||||
}
|
||||
return NSMutableAttributedString.alloc().initWithStringAttributes(text, <any>attrDict);
|
||||
}
|
||||
}
|
||||
|
||||
export function getTransformedText(text: string, textTransform: TextTransform): string {
|
||||
if (!text || !isString(text)) {
|
||||
return '';
|
||||
}
|
||||
if (!text || !isString(text)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
switch (textTransform) {
|
||||
case 'uppercase':
|
||||
return NSStringFromNSAttributedString(text).uppercaseString;
|
||||
case 'lowercase':
|
||||
return NSStringFromNSAttributedString(text).lowercaseString;
|
||||
case 'capitalize':
|
||||
return NSStringFromNSAttributedString(text).capitalizedString;
|
||||
default:
|
||||
return text;
|
||||
}
|
||||
switch (textTransform) {
|
||||
case 'uppercase':
|
||||
return NSStringFromNSAttributedString(text).uppercaseString;
|
||||
case 'lowercase':
|
||||
return NSStringFromNSAttributedString(text).lowercaseString;
|
||||
case 'capitalize':
|
||||
return NSStringFromNSAttributedString(text).capitalizedString;
|
||||
default:
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
function NSStringFromNSAttributedString(source: NSAttributedString | string): NSString {
|
||||
return NSString.stringWithString((source instanceof NSAttributedString && source.string) || <string>source);
|
||||
return NSString.stringWithString((source instanceof NSAttributedString && source.string) || <string>source);
|
||||
}
|
||||
|
||||
function isStringTappable(formattedString: FormattedString) {
|
||||
if (!formattedString) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0, length = formattedString.spans.length; i < length; i++) {
|
||||
const span = formattedString.spans.getItem(i);
|
||||
if (span.tappable) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!formattedString) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0, length = formattedString.spans.length; i < length; i++) {
|
||||
const span = formattedString.spans.getItem(i);
|
||||
if (span.tappable) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
92
nativescript-core/ui/text-base/span.d.ts
vendored
92
nativescript-core/ui/text-base/span.d.ts
vendored
@@ -7,59 +7,59 @@ import { TextDecoration } from '../text-base';
|
||||
* A class used to create a single part of formatted string with a common text properties.
|
||||
*/
|
||||
export class Span extends ViewBase {
|
||||
/**
|
||||
* Gets or sets the font family of the span.
|
||||
*/
|
||||
public fontFamily: string;
|
||||
/**
|
||||
* Gets or sets the font family of the span.
|
||||
*/
|
||||
public fontFamily: string;
|
||||
|
||||
/**
|
||||
* Gets or sets the font size of the span.
|
||||
*/
|
||||
public fontSize: number;
|
||||
/**
|
||||
* Gets or sets the font size of the span.
|
||||
*/
|
||||
public fontSize: number;
|
||||
|
||||
/**
|
||||
* Gets or sets the font style of the span.
|
||||
*/
|
||||
public fontStyle: FontStyle;
|
||||
/**
|
||||
* Gets or sets the font style of the span.
|
||||
*/
|
||||
public fontStyle: FontStyle;
|
||||
|
||||
/**
|
||||
* Gets or sets the font weight of the span.
|
||||
*/
|
||||
public fontWeight: FontWeight;
|
||||
/**
|
||||
* Gets or sets the font weight of the span.
|
||||
*/
|
||||
public fontWeight: FontWeight;
|
||||
|
||||
/**
|
||||
* Gets or sets text decorations for the span.
|
||||
*/
|
||||
public textDecoration: TextDecoration;
|
||||
/**
|
||||
* Gets or sets text decorations for the span.
|
||||
*/
|
||||
public textDecoration: TextDecoration;
|
||||
|
||||
/**
|
||||
* Gets or sets the font foreground color of the span.
|
||||
*/
|
||||
public color: Color;
|
||||
/**
|
||||
* Gets or sets the font foreground color of the span.
|
||||
*/
|
||||
public color: Color;
|
||||
|
||||
/**
|
||||
* Gets or sets the font background color of the span.
|
||||
*/
|
||||
public backgroundColor: Color;
|
||||
/**
|
||||
* Gets or sets the font background color of the span.
|
||||
*/
|
||||
public backgroundColor: Color;
|
||||
|
||||
/**
|
||||
* Gets or sets the text for the span.
|
||||
*/
|
||||
public text: string;
|
||||
/**
|
||||
* String value used when hooking to linkTap event.
|
||||
*/
|
||||
public static linkTapEvent: string;
|
||||
/**
|
||||
* Gets or sets the text for the span.
|
||||
*/
|
||||
public text: string;
|
||||
/**
|
||||
* String value used when hooking to linkTap event.
|
||||
*/
|
||||
public static linkTapEvent: string;
|
||||
|
||||
/**
|
||||
* Gets if the span is tappable or not.
|
||||
*/
|
||||
public readonly tappable: boolean;
|
||||
/**
|
||||
* Gets if the span is tappable or not.
|
||||
*/
|
||||
public readonly tappable: boolean;
|
||||
|
||||
//@private
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_setTextInternal(value: string): void;
|
||||
//@endprivate
|
||||
//@private
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_setTextInternal(value: string): void;
|
||||
//@endprivate
|
||||
}
|
||||
|
||||
@@ -7,98 +7,98 @@ import { EventData } from '../../data/observable';
|
||||
import { isNullOrUndefined, isString } from '../../utils/types';
|
||||
|
||||
export class Span extends ViewBase implements SpanDefinition {
|
||||
static linkTapEvent = 'linkTap';
|
||||
private _text: string;
|
||||
private _tappable: boolean = false;
|
||||
static linkTapEvent = 'linkTap';
|
||||
private _text: string;
|
||||
private _tappable: boolean = false;
|
||||
|
||||
get fontFamily(): string {
|
||||
return this.style.fontFamily;
|
||||
}
|
||||
set fontFamily(value: string) {
|
||||
this.style.fontFamily = value;
|
||||
}
|
||||
get fontFamily(): string {
|
||||
return this.style.fontFamily;
|
||||
}
|
||||
set fontFamily(value: string) {
|
||||
this.style.fontFamily = value;
|
||||
}
|
||||
|
||||
get fontSize(): number {
|
||||
return this.style.fontSize;
|
||||
}
|
||||
set fontSize(value: number) {
|
||||
this.style.fontSize = value;
|
||||
}
|
||||
get fontSize(): number {
|
||||
return this.style.fontSize;
|
||||
}
|
||||
set fontSize(value: number) {
|
||||
this.style.fontSize = value;
|
||||
}
|
||||
|
||||
// Italic
|
||||
get fontStyle(): FontStyle {
|
||||
return this.style.fontStyle;
|
||||
}
|
||||
set fontStyle(value: FontStyle) {
|
||||
this.style.fontStyle = value;
|
||||
}
|
||||
// Italic
|
||||
get fontStyle(): FontStyle {
|
||||
return this.style.fontStyle;
|
||||
}
|
||||
set fontStyle(value: FontStyle) {
|
||||
this.style.fontStyle = value;
|
||||
}
|
||||
|
||||
// Bold
|
||||
get fontWeight(): FontWeight {
|
||||
return this.style.fontWeight;
|
||||
}
|
||||
set fontWeight(value: FontWeight) {
|
||||
this.style.fontWeight = value;
|
||||
}
|
||||
// Bold
|
||||
get fontWeight(): FontWeight {
|
||||
return this.style.fontWeight;
|
||||
}
|
||||
set fontWeight(value: FontWeight) {
|
||||
this.style.fontWeight = value;
|
||||
}
|
||||
|
||||
get textDecoration(): TextDecoration {
|
||||
return this.style.textDecoration;
|
||||
}
|
||||
set textDecoration(value: TextDecoration) {
|
||||
this.style.textDecoration = value;
|
||||
}
|
||||
get textDecoration(): TextDecoration {
|
||||
return this.style.textDecoration;
|
||||
}
|
||||
set textDecoration(value: TextDecoration) {
|
||||
this.style.textDecoration = value;
|
||||
}
|
||||
|
||||
get color(): Color {
|
||||
return this.style.color;
|
||||
}
|
||||
set color(value: Color) {
|
||||
this.style.color = value;
|
||||
}
|
||||
get color(): Color {
|
||||
return this.style.color;
|
||||
}
|
||||
set color(value: Color) {
|
||||
this.style.color = value;
|
||||
}
|
||||
|
||||
get backgroundColor(): Color {
|
||||
return this.style.backgroundColor;
|
||||
}
|
||||
set backgroundColor(value: Color) {
|
||||
this.style.backgroundColor = value;
|
||||
}
|
||||
get backgroundColor(): Color {
|
||||
return this.style.backgroundColor;
|
||||
}
|
||||
set backgroundColor(value: Color) {
|
||||
this.style.backgroundColor = value;
|
||||
}
|
||||
|
||||
get text(): string {
|
||||
return this._text;
|
||||
}
|
||||
set text(value: string) {
|
||||
if (this._text !== value) {
|
||||
if (isNullOrUndefined(value)) {
|
||||
this._text = '';
|
||||
} else {
|
||||
// value can be a number
|
||||
this._text = isString(value) ? `${value}`.replace('\\n', '\n').replace('\\t', '\t') : `${value}`;
|
||||
}
|
||||
this.notifyPropertyChange('text', this._text);
|
||||
}
|
||||
}
|
||||
get text(): string {
|
||||
return this._text;
|
||||
}
|
||||
set text(value: string) {
|
||||
if (this._text !== value) {
|
||||
if (isNullOrUndefined(value)) {
|
||||
this._text = '';
|
||||
} else {
|
||||
// value can be a number
|
||||
this._text = isString(value) ? `${value}`.replace('\\n', '\n').replace('\\t', '\t') : `${value}`;
|
||||
}
|
||||
this.notifyPropertyChange('text', this._text);
|
||||
}
|
||||
}
|
||||
|
||||
get tappable(): boolean {
|
||||
return this._tappable;
|
||||
}
|
||||
get tappable(): boolean {
|
||||
return this._tappable;
|
||||
}
|
||||
|
||||
addEventListener(arg: string, callback: (data: EventData) => void, thisArg?: any) {
|
||||
super.addEventListener(arg, callback, thisArg);
|
||||
this._setTappable(this.hasListeners(Span.linkTapEvent));
|
||||
}
|
||||
addEventListener(arg: string, callback: (data: EventData) => void, thisArg?: any) {
|
||||
super.addEventListener(arg, callback, thisArg);
|
||||
this._setTappable(this.hasListeners(Span.linkTapEvent));
|
||||
}
|
||||
|
||||
removeEventListener(arg: string, callback?: any, thisArg?: any) {
|
||||
super.removeEventListener(arg, callback, thisArg);
|
||||
this._setTappable(this.hasListeners(Span.linkTapEvent));
|
||||
}
|
||||
removeEventListener(arg: string, callback?: any, thisArg?: any) {
|
||||
super.removeEventListener(arg, callback, thisArg);
|
||||
this._setTappable(this.hasListeners(Span.linkTapEvent));
|
||||
}
|
||||
|
||||
_setTextInternal(value: string): void {
|
||||
this._text = value;
|
||||
}
|
||||
_setTextInternal(value: string): void {
|
||||
this._text = value;
|
||||
}
|
||||
|
||||
private _setTappable(value: boolean): void {
|
||||
if (this._tappable !== value) {
|
||||
this._tappable = value;
|
||||
this.notifyPropertyChange('tappable', value);
|
||||
}
|
||||
}
|
||||
private _setTappable(value: boolean): void {
|
||||
if (this._tappable !== value) {
|
||||
this._tappable = value;
|
||||
this.notifyPropertyChange('tappable', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,256 +23,256 @@ const CHILD_FORMATTED_TEXT = 'formattedText';
|
||||
const CHILD_FORMATTED_STRING = 'FormattedString';
|
||||
|
||||
export abstract class TextBaseCommon extends View implements TextBaseDefinition {
|
||||
public _isSingleLine: boolean;
|
||||
public text: string;
|
||||
public formattedText: FormattedString;
|
||||
public _isSingleLine: boolean;
|
||||
public text: string;
|
||||
public formattedText: FormattedString;
|
||||
|
||||
get nativeTextViewProtected() {
|
||||
return this.nativeViewProtected;
|
||||
}
|
||||
get nativeTextViewProtected() {
|
||||
return this.nativeViewProtected;
|
||||
}
|
||||
|
||||
get fontFamily(): string {
|
||||
return this.style.fontFamily;
|
||||
}
|
||||
set fontFamily(value: string) {
|
||||
this.style.fontFamily = value;
|
||||
}
|
||||
get fontFamily(): string {
|
||||
return this.style.fontFamily;
|
||||
}
|
||||
set fontFamily(value: string) {
|
||||
this.style.fontFamily = value;
|
||||
}
|
||||
|
||||
get fontSize(): number {
|
||||
return this.style.fontSize;
|
||||
}
|
||||
set fontSize(value: number) {
|
||||
this.style.fontSize = value;
|
||||
}
|
||||
get fontSize(): number {
|
||||
return this.style.fontSize;
|
||||
}
|
||||
set fontSize(value: number) {
|
||||
this.style.fontSize = value;
|
||||
}
|
||||
|
||||
get fontStyle(): FontStyle {
|
||||
return this.style.fontStyle;
|
||||
}
|
||||
set fontStyle(value: FontStyle) {
|
||||
this.style.fontStyle = value;
|
||||
}
|
||||
get fontStyle(): FontStyle {
|
||||
return this.style.fontStyle;
|
||||
}
|
||||
set fontStyle(value: FontStyle) {
|
||||
this.style.fontStyle = value;
|
||||
}
|
||||
|
||||
get fontWeight(): FontWeight {
|
||||
return this.style.fontWeight;
|
||||
}
|
||||
set fontWeight(value: FontWeight) {
|
||||
this.style.fontWeight = value;
|
||||
}
|
||||
get fontWeight(): FontWeight {
|
||||
return this.style.fontWeight;
|
||||
}
|
||||
set fontWeight(value: FontWeight) {
|
||||
this.style.fontWeight = value;
|
||||
}
|
||||
|
||||
get letterSpacing(): number {
|
||||
return this.style.letterSpacing;
|
||||
}
|
||||
set letterSpacing(value: number) {
|
||||
this.style.letterSpacing = value;
|
||||
}
|
||||
get letterSpacing(): number {
|
||||
return this.style.letterSpacing;
|
||||
}
|
||||
set letterSpacing(value: number) {
|
||||
this.style.letterSpacing = value;
|
||||
}
|
||||
|
||||
get lineHeight(): number {
|
||||
return this.style.lineHeight;
|
||||
}
|
||||
set lineHeight(value: number) {
|
||||
this.style.lineHeight = value;
|
||||
}
|
||||
get lineHeight(): number {
|
||||
return this.style.lineHeight;
|
||||
}
|
||||
set lineHeight(value: number) {
|
||||
this.style.lineHeight = value;
|
||||
}
|
||||
|
||||
get textAlignment(): TextAlignment {
|
||||
return this.style.textAlignment;
|
||||
}
|
||||
set textAlignment(value: TextAlignment) {
|
||||
this.style.textAlignment = value;
|
||||
}
|
||||
get textAlignment(): TextAlignment {
|
||||
return this.style.textAlignment;
|
||||
}
|
||||
set textAlignment(value: TextAlignment) {
|
||||
this.style.textAlignment = value;
|
||||
}
|
||||
|
||||
get textDecoration(): TextDecoration {
|
||||
return this.style.textDecoration;
|
||||
}
|
||||
set textDecoration(value: TextDecoration) {
|
||||
this.style.textDecoration = value;
|
||||
}
|
||||
get textDecoration(): TextDecoration {
|
||||
return this.style.textDecoration;
|
||||
}
|
||||
set textDecoration(value: TextDecoration) {
|
||||
this.style.textDecoration = value;
|
||||
}
|
||||
|
||||
get textTransform(): TextTransform {
|
||||
return this.style.textTransform;
|
||||
}
|
||||
set textTransform(value: TextTransform) {
|
||||
this.style.textTransform = value;
|
||||
}
|
||||
get textTransform(): TextTransform {
|
||||
return this.style.textTransform;
|
||||
}
|
||||
set textTransform(value: TextTransform) {
|
||||
this.style.textTransform = value;
|
||||
}
|
||||
|
||||
get whiteSpace(): WhiteSpace {
|
||||
return this.style.whiteSpace;
|
||||
}
|
||||
set whiteSpace(value: WhiteSpace) {
|
||||
this.style.whiteSpace = value;
|
||||
}
|
||||
get whiteSpace(): WhiteSpace {
|
||||
return this.style.whiteSpace;
|
||||
}
|
||||
set whiteSpace(value: WhiteSpace) {
|
||||
this.style.whiteSpace = value;
|
||||
}
|
||||
|
||||
get padding(): string | Length {
|
||||
return this.style.padding;
|
||||
}
|
||||
set padding(value: string | Length) {
|
||||
this.style.padding = value;
|
||||
}
|
||||
get padding(): string | Length {
|
||||
return this.style.padding;
|
||||
}
|
||||
set padding(value: string | Length) {
|
||||
this.style.padding = value;
|
||||
}
|
||||
|
||||
get paddingTop(): Length {
|
||||
return this.style.paddingTop;
|
||||
}
|
||||
set paddingTop(value: Length) {
|
||||
this.style.paddingTop = value;
|
||||
}
|
||||
get paddingTop(): Length {
|
||||
return this.style.paddingTop;
|
||||
}
|
||||
set paddingTop(value: Length) {
|
||||
this.style.paddingTop = value;
|
||||
}
|
||||
|
||||
get paddingRight(): Length {
|
||||
return this.style.paddingRight;
|
||||
}
|
||||
set paddingRight(value: Length) {
|
||||
this.style.paddingRight = value;
|
||||
}
|
||||
get paddingRight(): Length {
|
||||
return this.style.paddingRight;
|
||||
}
|
||||
set paddingRight(value: Length) {
|
||||
this.style.paddingRight = value;
|
||||
}
|
||||
|
||||
get paddingBottom(): Length {
|
||||
return this.style.paddingBottom;
|
||||
}
|
||||
set paddingBottom(value: Length) {
|
||||
this.style.paddingBottom = value;
|
||||
}
|
||||
get paddingBottom(): Length {
|
||||
return this.style.paddingBottom;
|
||||
}
|
||||
set paddingBottom(value: Length) {
|
||||
this.style.paddingBottom = value;
|
||||
}
|
||||
|
||||
get paddingLeft(): Length {
|
||||
return this.style.paddingLeft;
|
||||
}
|
||||
set paddingLeft(value: Length) {
|
||||
this.style.paddingLeft = value;
|
||||
}
|
||||
get paddingLeft(): Length {
|
||||
return this.style.paddingLeft;
|
||||
}
|
||||
set paddingLeft(value: Length) {
|
||||
this.style.paddingLeft = value;
|
||||
}
|
||||
|
||||
public _onFormattedTextContentsChanged(data: PropertyChangeData) {
|
||||
if (this.nativeViewProtected) {
|
||||
// Notifications from the FormattedString start arriving before the Android view is even created.
|
||||
this[formattedTextProperty.setNative](data.value);
|
||||
}
|
||||
}
|
||||
public _onFormattedTextContentsChanged(data: PropertyChangeData) {
|
||||
if (this.nativeViewProtected) {
|
||||
// Notifications from the FormattedString start arriving before the Android view is even created.
|
||||
this[formattedTextProperty.setNative](data.value);
|
||||
}
|
||||
}
|
||||
|
||||
public _addChildFromBuilder(name: string, value: any): void {
|
||||
if (name === CHILD_SPAN) {
|
||||
if (!this.formattedText) {
|
||||
const formattedText = new FormattedString();
|
||||
formattedText.spans.push(value);
|
||||
this.formattedText = formattedText;
|
||||
} else {
|
||||
this.formattedText.spans.push(value);
|
||||
}
|
||||
} else if (name === CHILD_FORMATTED_TEXT || name === CHILD_FORMATTED_STRING) {
|
||||
this.formattedText = value;
|
||||
}
|
||||
}
|
||||
public _addChildFromBuilder(name: string, value: any): void {
|
||||
if (name === CHILD_SPAN) {
|
||||
if (!this.formattedText) {
|
||||
const formattedText = new FormattedString();
|
||||
formattedText.spans.push(value);
|
||||
this.formattedText = formattedText;
|
||||
} else {
|
||||
this.formattedText.spans.push(value);
|
||||
}
|
||||
} else if (name === CHILD_FORMATTED_TEXT || name === CHILD_FORMATTED_STRING) {
|
||||
this.formattedText = value;
|
||||
}
|
||||
}
|
||||
|
||||
_requestLayoutOnTextChanged(): void {
|
||||
this.requestLayout();
|
||||
}
|
||||
_requestLayoutOnTextChanged(): void {
|
||||
this.requestLayout();
|
||||
}
|
||||
|
||||
eachChild(callback: (child: ViewBase) => boolean): void {
|
||||
let text = this.formattedText;
|
||||
if (text) {
|
||||
callback(text);
|
||||
}
|
||||
}
|
||||
eachChild(callback: (child: ViewBase) => boolean): void {
|
||||
let text = this.formattedText;
|
||||
if (text) {
|
||||
callback(text);
|
||||
}
|
||||
}
|
||||
|
||||
_setNativeText(reset: boolean = false): void {
|
||||
//
|
||||
}
|
||||
_setNativeText(reset: boolean = false): void {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
TextBaseCommon.prototype._isSingleLine = false;
|
||||
|
||||
export function isBold(fontWeight: FontWeight): boolean {
|
||||
return fontWeight === 'bold' || fontWeight === '700' || fontWeight === '800' || fontWeight === '900';
|
||||
return fontWeight === 'bold' || fontWeight === '700' || fontWeight === '800' || fontWeight === '900';
|
||||
}
|
||||
|
||||
export const textProperty = new Property<TextBaseCommon, string>({
|
||||
name: 'text',
|
||||
defaultValue: '',
|
||||
affectsLayout: isAndroid,
|
||||
name: 'text',
|
||||
defaultValue: '',
|
||||
affectsLayout: isAndroid,
|
||||
});
|
||||
textProperty.register(TextBaseCommon);
|
||||
|
||||
export const formattedTextProperty = new Property<TextBaseCommon, FormattedString>({
|
||||
name: 'formattedText',
|
||||
affectsLayout: true,
|
||||
valueChanged: onFormattedTextPropertyChanged,
|
||||
name: 'formattedText',
|
||||
affectsLayout: true,
|
||||
valueChanged: onFormattedTextPropertyChanged,
|
||||
});
|
||||
formattedTextProperty.register(TextBaseCommon);
|
||||
|
||||
function onFormattedTextPropertyChanged(textBase: TextBaseCommon, oldValue: FormattedString, newValue: FormattedString) {
|
||||
if (oldValue) {
|
||||
oldValue.off(Observable.propertyChangeEvent, textBase._onFormattedTextContentsChanged, textBase);
|
||||
textBase._removeView(oldValue);
|
||||
}
|
||||
if (oldValue) {
|
||||
oldValue.off(Observable.propertyChangeEvent, textBase._onFormattedTextContentsChanged, textBase);
|
||||
textBase._removeView(oldValue);
|
||||
}
|
||||
|
||||
if (newValue) {
|
||||
const oldParent = newValue.parent;
|
||||
// In case formattedString is attached to new TextBase
|
||||
if (oldParent) {
|
||||
oldParent._removeView(newValue);
|
||||
}
|
||||
textBase._addView(newValue);
|
||||
newValue.on(Observable.propertyChangeEvent, textBase._onFormattedTextContentsChanged, textBase);
|
||||
}
|
||||
if (newValue) {
|
||||
const oldParent = newValue.parent;
|
||||
// In case formattedString is attached to new TextBase
|
||||
if (oldParent) {
|
||||
oldParent._removeView(newValue);
|
||||
}
|
||||
textBase._addView(newValue);
|
||||
newValue.on(Observable.propertyChangeEvent, textBase._onFormattedTextContentsChanged, textBase);
|
||||
}
|
||||
}
|
||||
|
||||
export function getClosestPropertyValue<T>(property: CssProperty<any, T>, span: Span): T {
|
||||
if (property.isSet(span.style)) {
|
||||
return span.style[property.name];
|
||||
} else if (property.isSet(span.parent.style)) {
|
||||
// parent is FormattedString
|
||||
return span.parent.style[property.name];
|
||||
} else if (property.isSet(span.parent.parent.style)) {
|
||||
// parent.parent is TextBase
|
||||
return span.parent.parent.style[property.name];
|
||||
}
|
||||
if (property.isSet(span.style)) {
|
||||
return span.style[property.name];
|
||||
} else if (property.isSet(span.parent.style)) {
|
||||
// parent is FormattedString
|
||||
return span.parent.style[property.name];
|
||||
} else if (property.isSet(span.parent.parent.style)) {
|
||||
// parent.parent is TextBase
|
||||
return span.parent.parent.style[property.name];
|
||||
}
|
||||
}
|
||||
|
||||
const textAlignmentConverter = makeParser<TextAlignment>(makeValidator<TextAlignment>('initial', 'left', 'center', 'right'));
|
||||
export const textAlignmentProperty = new InheritedCssProperty<Style, TextAlignment>({
|
||||
name: 'textAlignment',
|
||||
cssName: 'text-align',
|
||||
defaultValue: 'initial',
|
||||
valueConverter: textAlignmentConverter,
|
||||
name: 'textAlignment',
|
||||
cssName: 'text-align',
|
||||
defaultValue: 'initial',
|
||||
valueConverter: textAlignmentConverter,
|
||||
});
|
||||
textAlignmentProperty.register(Style);
|
||||
|
||||
const textTransformConverter = makeParser<TextTransform>(makeValidator<TextTransform>('initial', 'none', 'capitalize', 'uppercase', 'lowercase'));
|
||||
export const textTransformProperty = new CssProperty<Style, TextTransform>({
|
||||
name: 'textTransform',
|
||||
cssName: 'text-transform',
|
||||
defaultValue: 'initial',
|
||||
valueConverter: textTransformConverter,
|
||||
name: 'textTransform',
|
||||
cssName: 'text-transform',
|
||||
defaultValue: 'initial',
|
||||
valueConverter: textTransformConverter,
|
||||
});
|
||||
textTransformProperty.register(Style);
|
||||
|
||||
const whiteSpaceConverter = makeParser<WhiteSpace>(makeValidator<WhiteSpace>('initial', 'normal', 'nowrap'));
|
||||
export const whiteSpaceProperty = new CssProperty<Style, WhiteSpace>({
|
||||
name: 'whiteSpace',
|
||||
cssName: 'white-space',
|
||||
defaultValue: 'initial',
|
||||
affectsLayout: isIOS,
|
||||
valueConverter: whiteSpaceConverter,
|
||||
name: 'whiteSpace',
|
||||
cssName: 'white-space',
|
||||
defaultValue: 'initial',
|
||||
affectsLayout: isIOS,
|
||||
valueConverter: whiteSpaceConverter,
|
||||
});
|
||||
whiteSpaceProperty.register(Style);
|
||||
|
||||
const textDecorationConverter = makeParser<TextDecoration>(makeValidator<TextDecoration>('none', 'underline', 'line-through', 'underline line-through'));
|
||||
export const textDecorationProperty = new CssProperty<Style, TextDecoration>({
|
||||
name: 'textDecoration',
|
||||
cssName: 'text-decoration',
|
||||
defaultValue: 'none',
|
||||
valueConverter: textDecorationConverter,
|
||||
name: 'textDecoration',
|
||||
cssName: 'text-decoration',
|
||||
defaultValue: 'none',
|
||||
valueConverter: textDecorationConverter,
|
||||
});
|
||||
textDecorationProperty.register(Style);
|
||||
|
||||
export const letterSpacingProperty = new InheritedCssProperty<Style, number>({
|
||||
name: 'letterSpacing',
|
||||
cssName: 'letter-spacing',
|
||||
defaultValue: 0,
|
||||
affectsLayout: isIOS,
|
||||
valueConverter: (v) => parseFloat(v),
|
||||
name: 'letterSpacing',
|
||||
cssName: 'letter-spacing',
|
||||
defaultValue: 0,
|
||||
affectsLayout: isIOS,
|
||||
valueConverter: (v) => parseFloat(v),
|
||||
});
|
||||
letterSpacingProperty.register(Style);
|
||||
|
||||
export const lineHeightProperty = new InheritedCssProperty<Style, number>({
|
||||
name: 'lineHeight',
|
||||
cssName: 'line-height',
|
||||
affectsLayout: isIOS,
|
||||
valueConverter: (v) => parseFloat(v),
|
||||
name: 'lineHeight',
|
||||
cssName: 'line-height',
|
||||
affectsLayout: isIOS,
|
||||
valueConverter: (v) => parseFloat(v),
|
||||
});
|
||||
lineHeightProperty.register(Style);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user