Skip to content

Commit

Permalink
fix: NS8 and use createFormattedTextNative
Browse files Browse the repository at this point in the history
  • Loading branch information
farfromrefug committed Apr 14, 2021
1 parent c4e7bb5 commit ee76186
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 139 deletions.
50 changes: 24 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,36 +47,34 @@
"homepage": "https://github.com/nativescript-community/ui-label",
"readmeFilename": "README.md",
"devDependencies": {
"@angular/common": "^10.1.0",
"@angular/compiler": "~10.1.0",
"@angular/compiler-cli": "~10.1.0",
"@angular/core": "~10.1.0",
"@angular/forms": "~10.1.0",
"@angular/platform-browser": "~10.1.0",
"@angular/platform-browser-dynamic": "~10.1.0",
"@angular/router": "~10.1.0",
"@commitlint/cli": "^11.0.0",
"@commitlint/config-conventional": "^11.0.0",
"@nativescript-community/text": "^1.4.9",
"@nativescript/angular": "10.1.0",
"@nativescript/core": "7.2.1",
"@nativescript/types-android": "7.2.0",
"@nativescript/types-ios": "7.2.0",
"@nativescript/webpack": "4.1.0",
"@types/node": "^14.14.27",
"@typescript-eslint/eslint-plugin": "4.15.0",
"@typescript-eslint/parser": "4.15.0",
"eslint": "7.19.0",
"eslint-config-prettier": "^8.1.0",
"@angular/common": "^11.2.9",
"@angular/compiler": "~11.2.9",
"@angular/compiler-cli": "~11.2.9",
"@angular/core": "~11.2.9",
"@angular/forms": "~11.2.9",
"@angular/platform-browser": "~11.2.9",
"@angular/platform-browser-dynamic": "~11.2.9",
"@angular/router": "~11.2.9",
"@commitlint/cli": "^12.1.1",
"@commitlint/config-conventional": "^12.1.1",
"@nativescript-community/text": "^1.4.11",
"@nativescript/angular": "11.2.0",
"@nativescript/core": "8.0.1",
"@nativescript/types-android": "8.0.0",
"@nativescript/types-ios": "8.0.0",
"@nativescript/webpack": "5.0.0-beta.6",
"@types/node": "^14.14.37",
"@typescript-eslint/eslint-plugin": "4.22.0",
"@typescript-eslint/parser": "4.22.0",
"eslint": "7.24.0",
"eslint-config-prettier": "^8.2.0",
"eslint-plugin-prettier": "^3.3.1",
"husky": "^4.3.8",
"lerna": "^3.22.1",
"npm-watch": "^0.7.0",
"husky": "^6.0.0",
"lerna": "^4.0.0",
"prettier": "^2.2.1",
"prompt": "^1.1.0",
"rimraf": "^3.0.2",
"ts-patch": "^1.3.2",
"typescript": "~4.1.5"
"typescript": "~4.2.4"
},
"dependencies": {
"ts-node": "^9.1.1"
Expand Down
2 changes: 1 addition & 1 deletion plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
"license": "Apache-2.0",
"readmeFilename": "README.md",
"dependencies": {
"@nativescript-community/text": "^1.4.9"
"@nativescript-community/text": "^1.4.10"
}
}
4 changes: 2 additions & 2 deletions src/label-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { VerticalTextAlignment, cssProperty, init } from '@nativescript-communit
import {
CSSType,
Color,
CoreTypes,
CssProperty,
FormattedString,
Property,
Expand All @@ -10,7 +11,6 @@ import {
Label as TNLabel,
booleanConverter
} from '@nativescript/core';
import { dip } from '@nativescript/core/ui/core/view';
import { layout } from '@nativescript/core/utils/utils';
import { Label as LabelViewDefinition, LineBreak, TextShadow } from './label';

Expand Down Expand Up @@ -137,7 +137,7 @@ export const maxFontSizeProperty = new CssProperty<Style, number>({
});
maxFontSizeProperty.register(Style);

function parseDIPs(value: string): dip {
function parseDIPs(value: string): CoreTypes.dip {
if (value.indexOf('px') !== -1) {
return layout.toDeviceIndependentPixels(parseFloat(value.replace('px', '').trim()));
} else {
Expand Down
124 changes: 64 additions & 60 deletions src/label.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@
} from '@nativescript-community/text';
import {
CSSType,
CoreTypes,
FormattedString,
Observable,
Property,
PropertyChangeData,
Span,
View,
ViewBase,
booleanConverter,
profile
} from '@nativescript/core';
import { Color } from '@nativescript/core/color';
import { CSSShadow } from '@nativescript/core/ui/styling/css-shadow';
import { Font, FontStyle, FontWeight } from '@nativescript/core/ui/styling/font';
import {
Length,
Expand All @@ -31,10 +32,6 @@ import {
paddingTopProperty
} from '@nativescript/core/ui/styling/style-properties';
import {
TextAlignment,
TextDecoration,
TextTransform,
WhiteSpace,
letterSpacingProperty,
textAlignmentProperty,
textDecorationProperty,
Expand All @@ -48,13 +45,11 @@ import {
autoFontSizeProperty,
lineBreakProperty,
maxLinesProperty,
needFormattedStringComputation,
selectableProperty,
textShadowProperty
} from './label-common';

export { enableIOSDTCoreText, createNativeAttributedString } from '@nativescript-community/text';

export { createNativeAttributedString, enableIOSDTCoreText } from '@nativescript-community/text';
export * from './label-common';

let TextView: typeof com.nativescript.label.EllipsizingTextView;
Expand Down Expand Up @@ -98,7 +93,7 @@ export const htmlProperty = new Property<Label, string>({ name: 'html', defaultV

type ClickableSpan = new (owner: Span) => android.text.style.ClickableSpan;

function getHorizontalGravity(textAlignment: TextAlignment) {
function getHorizontalGravity(textAlignment: CoreTypes.TextAlignmentType) {
switch (textAlignment) {
case 'initial':
case 'left':
Expand Down Expand Up @@ -207,6 +202,7 @@ abstract class LabelBase extends View implements LabelViewDefinition {
@cssProperty maxFontSize: number;
@cssProperty verticalTextAlignment: VerticalTextAlignment;
@cssProperty linkColor: Color;
@cssProperty textShadow: CSSShadow;
@cssProperty linkUnderline: boolean;
public html: string;
@cssProperty selectable: boolean;
Expand All @@ -230,16 +226,16 @@ abstract class LabelBase extends View implements LabelViewDefinition {
@cssProperty letterSpacing: number;
@cssProperty lineHeight: number;
@cssProperty lineBreak: LineBreak;
@cssProperty textAlignment: TextAlignment;
@cssProperty textDecoration: TextDecoration;
@cssProperty textTransform: TextTransform;
@cssProperty whiteSpace: WhiteSpace;
@cssProperty textAlignment: CoreTypes.TextAlignmentType;
@cssProperty textDecoration: CoreTypes.TextDecorationType;
@cssProperty textTransform: CoreTypes.TextTransformType;
@cssProperty whiteSpace: CoreTypes.WhiteSpaceType;

@cssProperty padding: string | Length;
@cssProperty paddingTop: Length;
@cssProperty paddingRight: Length;
@cssProperty paddingBottom: Length;
@cssProperty paddingLeft: Length;
@cssProperty padding: string | CoreTypes.LengthType;
@cssProperty paddingTop: CoreTypes.LengthType;
@cssProperty paddingRight: CoreTypes.LengthType;
@cssProperty paddingBottom: CoreTypes.LengthType;
@cssProperty paddingLeft: CoreTypes.LengthType;

// for now code is duplicated as Android version is a full rewrite
_canChangeText = true;
Expand Down Expand Up @@ -358,7 +354,7 @@ export class Label extends LabelBase {
}
}

[whiteSpaceProperty.setNative](value: WhiteSpace) {
[whiteSpaceProperty.setNative](value: CoreTypes.WhiteSpaceType) {
if (!this.lineBreak) {
const nativeView = this.nativeTextViewProtected;
switch (value) {
Expand All @@ -374,11 +370,21 @@ export class Label extends LabelBase {
}
}
}
[textShadowProperty.setNative](value: TextShadow) {
[textShadowProperty.getDefault](value: number) {
return {
radius: this.nativeTextViewProtected.getShadowRadius(),
offsetX: this.nativeTextViewProtected.getShadowDx(),
offsetY: this.nativeTextViewProtected.getShadowDy(),
color: this.nativeTextViewProtected.getShadowColor()
};
}

[textShadowProperty.setNative](value: CSSShadow) {
// prettier-ignore
this.nativeViewProtected.setShadowLayer(
layout.toDevicePixels(value.blurRadius),
layout.toDevicePixels(value.offsetX),
layout.toDevicePixels(value.offsetY),
Length.toDevicePixels(value.blurRadius, java.lang.Float.MIN_VALUE),
Length.toDevicePixels(value.offsetX, 0),
Length.toDevicePixels(value.offsetY, 0),
value.color.android
);
}
Expand All @@ -404,11 +410,11 @@ export class Label extends LabelBase {
this._setNativeText();
}

[textTransformProperty.setNative](value: TextTransform) {
[textTransformProperty.setNative](value: CoreTypes.TextTransformType) {
this._setNativeText();
}

[textAlignmentProperty.setNative](value: TextAlignment) {
[textAlignmentProperty.setNative](value: CoreTypes.TextAlignmentType) {
const view = this.nativeTextViewProtected;
view.setGravity(getHorizontalGravity(value) | getVerticalGravity(this.verticalTextAlignment));
}
Expand Down Expand Up @@ -436,7 +442,7 @@ export class Label extends LabelBase {
this.nativeTextViewProtected.setTypeface(value instanceof Font ? value.getAndroidTypeface() : value);
}

[textDecorationProperty.setNative](value: number | TextDecoration) {
[textDecorationProperty.setNative](value: number | CoreTypes.TextDecorationType) {
switch (value) {
case 'none':
this.nativeTextViewProtected.setPaintFlags(0);
Expand All @@ -462,40 +468,40 @@ export class Label extends LabelBase {
org.nativescript.widgets.ViewHelper.setLetterspacing(this.nativeTextViewProtected, value);
}

[paddingTopProperty.getDefault](): Length {
[paddingTopProperty.getDefault](): CoreTypes.LengthType {
return { value: this._defaultPaddingTop, unit: 'px' };
}
[paddingTopProperty.setNative](value: Length) {
[paddingTopProperty.setNative](value: CoreTypes.LengthType) {
org.nativescript.widgets.ViewHelper.setPaddingTop(
this.nativeTextViewProtected,
Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderTopWidth, 0)
);
}

[paddingRightProperty.getDefault](): Length {
[paddingRightProperty.getDefault](): CoreTypes.LengthType {
return { value: this._defaultPaddingRight, unit: 'px' };
}
[paddingRightProperty.setNative](value: Length) {
[paddingRightProperty.setNative](value: CoreTypes.LengthType) {
org.nativescript.widgets.ViewHelper.setPaddingRight(
this.nativeTextViewProtected,
Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderRightWidth, 0)
);
}

[paddingBottomProperty.getDefault](): Length {
[paddingBottomProperty.getDefault](): CoreTypes.LengthType {
return { value: this._defaultPaddingBottom, unit: 'px' };
}
[paddingBottomProperty.setNative](value: Length) {
[paddingBottomProperty.setNative](value: CoreTypes.LengthType) {
org.nativescript.widgets.ViewHelper.setPaddingBottom(
this.nativeTextViewProtected,
Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderBottomWidth, 0)
);
}

[paddingLeftProperty.getDefault](): Length {
[paddingLeftProperty.getDefault](): CoreTypes.LengthType {
return { value: this._defaultPaddingLeft, unit: 'px' };
}
[paddingLeftProperty.setNative](value: Length) {
[paddingLeftProperty.setNative](value: CoreTypes.LengthType) {
org.nativescript.widgets.ViewHelper.setPaddingLeft(
this.nativeTextViewProtected,
Length.toDevicePixels(value, 0) + Length.toDevicePixels(this.style.borderLeftWidth, 0)
Expand All @@ -522,35 +528,15 @@ export class Label extends LabelBase {
[selectableProperty.setNative](value: boolean) {
this.nativeTextViewProtected.setTextIsSelectable(value);
}
createFormattedTextNative(value: any) {
const result = createNativeAttributedString(value, this);

@profile
createHTMLString() {
const result = createNativeAttributedString({ text: this.html }) as android.text.SpannableStringBuilder;
const urlSpan = result.getSpans(0, result.length(), android.text.style.URLSpan.class);
if (urlSpan.length > 0) {
this._setTappableState(true);
initializeURLClickableSpan();
for (let index = 0; index < urlSpan.length; index++) {
const span = urlSpan[index];
const text = span.getURL();
const start = result.getSpanStart(span);
const end = result.getSpanEnd(span);
result.removeSpan(span);
result.setSpan(new URLClickableSpan(text, this), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return result;
}
@profile
createSpannableStringBuilder() {
const formattedText = this.formattedText;
const result = createNativeAttributedString(formattedText as any);
let indexSearch = 0;
let str: string;
formattedText.spans.forEach((s) => {
value.spans.forEach((s) => {
if (s.tappable) {
if (!str) {
str = formattedText.toString();
str = value.toString();
this._setTappableState(true);
}
initializeClickableSpan();
Expand All @@ -564,6 +550,24 @@ export class Label extends LabelBase {
});
return result;
}
@profile
createHTMLString() {
const result = createNativeAttributedString({ text: this.html }, this) as android.text.SpannableStringBuilder;
const urlSpan = result.getSpans(0, result.length(), android.text.style.URLSpan.class);
if (urlSpan.length > 0) {
this._setTappableState(true);
initializeURLClickableSpan();
for (let index = 0; index < urlSpan.length; index++) {
const span = urlSpan[index];
const text = span.getURL();
const start = result.getSpanStart(span);
const end = result.getSpanEnd(span);
result.removeSpan(span);
result.setSpan(new URLClickableSpan(text, this), start, end, android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return result;
}
_tappable = false;
_setTappableState(tappable: boolean) {
if (this._tappable !== tappable) {
Expand Down Expand Up @@ -596,7 +600,7 @@ export class Label extends LabelBase {
transformedText = this.createHTMLString();
textProperty.nativeValueChange(this, this.html === null || this.html === undefined ? '' : this.html);
} else if (this.formattedText) {
transformedText = this.createSpannableStringBuilder();
transformedText = this.createFormattedTextNative(this.formattedText);
textProperty.nativeValueChange(
this,
this.formattedText === null || this.formattedText === undefined ? '' : this.formattedText.toString()
Expand Down Expand Up @@ -659,7 +663,7 @@ function getCapitalizedString(str: string): string {
return newWords.join(' ');
}

export function getTransformedText(text: string, textTransform: TextTransform): string {
export function getTransformedText(text: string, textTransform: CoreTypes.TextTransformType): string {
switch (textTransform) {
case 'uppercase':
return text.toUpperCase();
Expand Down
10 changes: 4 additions & 6 deletions src/label.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
* Contains the Label class, which represents a custom label widget which correctly supports html.
*/ /** */

import { Color, Label as TNLabel } from '@nativescript/core';
import { Color, CoreTypes, Label as TNLabel } from '@nativescript/core';
import { Property } from '@nativescript/core/ui/core/properties';
import { dip } from '@nativescript/core/ui/core/view';
import { TextAlignment } from '@nativescript/core/ui/text-base';
/**
* Represents a label with html content. Use this component instead WebView when you want to show just static HTML content.
* [iOS support](https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSAttributedString_UIKit_Additions/#//apple_ref/occ/instm/NSAttributedString/initWithData:options:documentAttributes:error:)
Expand Down Expand Up @@ -37,9 +35,9 @@ export declare const htmlProperty: Property<Label, string>;
export declare const verticalTextAlignmentProperty: Property<Label, VerticalTextAlignment>;

export interface TextShadow {
offsetX: dip;
offsetY: dip;
blurRadius: dip;
offsetX: CoreTypes.dip;
offsetY: CoreTypes.dip;
blurRadius: CoreTypes.dip;
color: Color;
}

Expand Down
Loading

0 comments on commit ee76186

Please sign in to comment.