mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
chore: format
This commit is contained in:
@@ -6,291 +6,335 @@ import { LinearGradient } from "./linear-gradient";
|
||||
import { Color } from "../../color";
|
||||
|
||||
export class Background implements BackgroundDefinition {
|
||||
public static default = new Background();
|
||||
public static default = new Background();
|
||||
|
||||
public color: Color;
|
||||
public image: string | LinearGradient;
|
||||
public repeat: BackgroundRepeat;
|
||||
public position: string;
|
||||
public size: string;
|
||||
public borderTopColor: Color;
|
||||
public borderRightColor: Color;
|
||||
public borderBottomColor: Color;
|
||||
public borderLeftColor: Color;
|
||||
public borderTopWidth: number = 0;
|
||||
public borderRightWidth: number = 0;
|
||||
public borderBottomWidth: number = 0;
|
||||
public borderLeftWidth: number = 0;
|
||||
public borderTopLeftRadius: number = 0;
|
||||
public borderTopRightRadius: number = 0;
|
||||
public borderBottomLeftRadius: number = 0;
|
||||
public borderBottomRightRadius: number = 0;
|
||||
public clipPath: string;
|
||||
public color: Color;
|
||||
public image: string | LinearGradient;
|
||||
public repeat: BackgroundRepeat;
|
||||
public position: string;
|
||||
public size: string;
|
||||
public borderTopColor: Color;
|
||||
public borderRightColor: Color;
|
||||
public borderBottomColor: Color;
|
||||
public borderLeftColor: Color;
|
||||
public borderTopWidth: number = 0;
|
||||
public borderRightWidth: number = 0;
|
||||
public borderBottomWidth: number = 0;
|
||||
public borderLeftWidth: number = 0;
|
||||
public borderTopLeftRadius: number = 0;
|
||||
public borderTopRightRadius: number = 0;
|
||||
public borderBottomLeftRadius: number = 0;
|
||||
public borderBottomRightRadius: number = 0;
|
||||
public clipPath: string;
|
||||
|
||||
private clone(): Background {
|
||||
const clone = new Background();
|
||||
private clone(): Background {
|
||||
const clone = new Background();
|
||||
|
||||
clone.color = this.color;
|
||||
clone.image = this.image;
|
||||
clone.repeat = this.repeat;
|
||||
clone.position = this.position;
|
||||
clone.size = this.size;
|
||||
clone.borderTopColor = this.borderTopColor;
|
||||
clone.borderRightColor = this.borderRightColor;
|
||||
clone.borderBottomColor = this.borderBottomColor;
|
||||
clone.borderLeftColor = this.borderLeftColor;
|
||||
clone.borderTopWidth = this.borderTopWidth;
|
||||
clone.borderRightWidth = this.borderRightWidth;
|
||||
clone.borderBottomWidth = this.borderBottomWidth;
|
||||
clone.borderLeftWidth = this.borderLeftWidth;
|
||||
clone.borderTopLeftRadius = this.borderTopLeftRadius;
|
||||
clone.borderTopRightRadius = this.borderTopRightRadius;
|
||||
clone.borderBottomRightRadius = this.borderBottomRightRadius;
|
||||
clone.borderBottomLeftRadius = this.borderBottomLeftRadius;
|
||||
clone.clipPath = this.clipPath;
|
||||
clone.color = this.color;
|
||||
clone.image = this.image;
|
||||
clone.repeat = this.repeat;
|
||||
clone.position = this.position;
|
||||
clone.size = this.size;
|
||||
clone.borderTopColor = this.borderTopColor;
|
||||
clone.borderRightColor = this.borderRightColor;
|
||||
clone.borderBottomColor = this.borderBottomColor;
|
||||
clone.borderLeftColor = this.borderLeftColor;
|
||||
clone.borderTopWidth = this.borderTopWidth;
|
||||
clone.borderRightWidth = this.borderRightWidth;
|
||||
clone.borderBottomWidth = this.borderBottomWidth;
|
||||
clone.borderLeftWidth = this.borderLeftWidth;
|
||||
clone.borderTopLeftRadius = this.borderTopLeftRadius;
|
||||
clone.borderTopRightRadius = this.borderTopRightRadius;
|
||||
clone.borderBottomRightRadius = this.borderBottomRightRadius;
|
||||
clone.borderBottomLeftRadius = this.borderBottomLeftRadius;
|
||||
clone.clipPath = this.clipPath;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.color = value;
|
||||
public withColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.color = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withImage(value: string | LinearGradient): Background {
|
||||
const clone = this.clone();
|
||||
clone.image = value;
|
||||
public withImage(value: string | LinearGradient): Background {
|
||||
const clone = this.clone();
|
||||
clone.image = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withRepeat(value: BackgroundRepeat): Background {
|
||||
const clone = this.clone();
|
||||
clone.repeat = value;
|
||||
public withRepeat(value: BackgroundRepeat): Background {
|
||||
const clone = this.clone();
|
||||
clone.repeat = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withPosition(value: string): Background {
|
||||
const clone = this.clone();
|
||||
clone.position = value;
|
||||
public withPosition(value: string): Background {
|
||||
const clone = this.clone();
|
||||
clone.position = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withSize(value: string): Background {
|
||||
const clone = this.clone();
|
||||
clone.size = value;
|
||||
public withSize(value: string): Background {
|
||||
const clone = this.clone();
|
||||
clone.size = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderTopColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderTopColor = value;
|
||||
public withBorderTopColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderTopColor = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderRightColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderRightColor = value;
|
||||
public withBorderRightColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderRightColor = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderBottomColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderBottomColor = value;
|
||||
public withBorderBottomColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderBottomColor = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderLeftColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderLeftColor = value;
|
||||
public withBorderLeftColor(value: Color): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderLeftColor = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderTopWidth(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderTopWidth = value;
|
||||
public withBorderTopWidth(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderTopWidth = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderRightWidth(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderRightWidth = value;
|
||||
public withBorderRightWidth(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderRightWidth = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderBottomWidth(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderBottomWidth = value;
|
||||
public withBorderBottomWidth(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderBottomWidth = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderLeftWidth(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderLeftWidth = value;
|
||||
public withBorderLeftWidth(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderLeftWidth = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderTopLeftRadius(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderTopLeftRadius = value;
|
||||
public withBorderTopLeftRadius(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderTopLeftRadius = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderTopRightRadius(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderTopRightRadius = value;
|
||||
public withBorderTopRightRadius(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderTopRightRadius = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderBottomRightRadius(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderBottomRightRadius = value;
|
||||
public withBorderBottomRightRadius(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderBottomRightRadius = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withBorderBottomLeftRadius(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderBottomLeftRadius = value;
|
||||
public withBorderBottomLeftRadius(value: number): Background {
|
||||
const clone = this.clone();
|
||||
clone.borderBottomLeftRadius = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public withClipPath(value: string): Background {
|
||||
const clone = this.clone();
|
||||
clone.clipPath = value;
|
||||
public withClipPath(value: string): Background {
|
||||
const clone = this.clone();
|
||||
clone.clipPath = value;
|
||||
|
||||
return clone;
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
public isEmpty(): boolean {
|
||||
return !this.color
|
||||
&& !this.image
|
||||
&& !this.hasBorderWidth()
|
||||
&& !this.hasBorderRadius()
|
||||
&& !this.clipPath;
|
||||
}
|
||||
public isEmpty(): boolean {
|
||||
return (
|
||||
!this.color &&
|
||||
!this.image &&
|
||||
!this.hasBorderWidth() &&
|
||||
!this.hasBorderRadius() &&
|
||||
!this.clipPath
|
||||
);
|
||||
}
|
||||
|
||||
public static equals(value1: Background, value2: Background): boolean {
|
||||
// both values are falsy
|
||||
if (!value1 && !value2) {
|
||||
return true;
|
||||
}
|
||||
public static equals(value1: Background, value2: Background): boolean {
|
||||
// both values are falsy
|
||||
if (!value1 && !value2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// only one is falsy
|
||||
if (!value1 || !value2) {
|
||||
return false;
|
||||
}
|
||||
// only one is falsy
|
||||
if (!value1 || !value2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let imagesEqual = false;
|
||||
if (value1 instanceof LinearGradient && value2 instanceof LinearGradient) {
|
||||
imagesEqual = LinearGradient.equals(value1, value2);
|
||||
} else {
|
||||
imagesEqual = value1.image === value2.image;
|
||||
}
|
||||
let imagesEqual = false;
|
||||
if (
|
||||
value1 instanceof LinearGradient &&
|
||||
value2 instanceof LinearGradient
|
||||
) {
|
||||
imagesEqual = LinearGradient.equals(value1, value2);
|
||||
} else {
|
||||
imagesEqual = value1.image === value2.image;
|
||||
}
|
||||
|
||||
return Color.equals(value1.color, value2.color)
|
||||
&& imagesEqual
|
||||
&& value1.position === value2.position
|
||||
&& value1.repeat === value2.repeat
|
||||
&& value1.size === value2.size
|
||||
&& Color.equals(value1.borderTopColor, value2.borderTopColor)
|
||||
&& Color.equals(value1.borderRightColor, value2.borderRightColor)
|
||||
&& Color.equals(value1.borderBottomColor, value2.borderBottomColor)
|
||||
&& Color.equals(value1.borderLeftColor, value2.borderLeftColor)
|
||||
&& value1.borderTopWidth === value2.borderTopWidth
|
||||
&& value1.borderRightWidth === value2.borderRightWidth
|
||||
&& value1.borderBottomWidth === value2.borderBottomWidth
|
||||
&& value1.borderLeftWidth === value2.borderLeftWidth
|
||||
&& value1.borderTopLeftRadius === value2.borderTopLeftRadius
|
||||
&& value1.borderTopRightRadius === value2.borderTopRightRadius
|
||||
&& value1.borderBottomRightRadius === value2.borderBottomRightRadius
|
||||
&& value1.borderBottomLeftRadius === value2.borderBottomLeftRadius
|
||||
&& value1.clipPath === value2.clipPath;
|
||||
}
|
||||
return (
|
||||
Color.equals(value1.color, value2.color) &&
|
||||
imagesEqual &&
|
||||
value1.position === value2.position &&
|
||||
value1.repeat === value2.repeat &&
|
||||
value1.size === value2.size &&
|
||||
Color.equals(value1.borderTopColor, value2.borderTopColor) &&
|
||||
Color.equals(value1.borderRightColor, value2.borderRightColor) &&
|
||||
Color.equals(value1.borderBottomColor, value2.borderBottomColor) &&
|
||||
Color.equals(value1.borderLeftColor, value2.borderLeftColor) &&
|
||||
value1.borderTopWidth === value2.borderTopWidth &&
|
||||
value1.borderRightWidth === value2.borderRightWidth &&
|
||||
value1.borderBottomWidth === value2.borderBottomWidth &&
|
||||
value1.borderLeftWidth === value2.borderLeftWidth &&
|
||||
value1.borderTopLeftRadius === value2.borderTopLeftRadius &&
|
||||
value1.borderTopRightRadius === value2.borderTopRightRadius &&
|
||||
value1.borderBottomRightRadius === value2.borderBottomRightRadius &&
|
||||
value1.borderBottomLeftRadius === value2.borderBottomLeftRadius &&
|
||||
value1.clipPath === value2.clipPath
|
||||
);
|
||||
}
|
||||
|
||||
public hasBorderColor(): boolean {
|
||||
return !!this.borderTopColor || !!this.borderRightColor || !!this.borderBottomColor || !!this.borderLeftColor;
|
||||
}
|
||||
public hasBorderColor(): boolean {
|
||||
return (
|
||||
!!this.borderTopColor ||
|
||||
!!this.borderRightColor ||
|
||||
!!this.borderBottomColor ||
|
||||
!!this.borderLeftColor
|
||||
);
|
||||
}
|
||||
|
||||
public hasBorderWidth(): boolean {
|
||||
return this.borderTopWidth > 0
|
||||
|| this.borderRightWidth > 0
|
||||
|| this.borderBottomWidth > 0
|
||||
|| this.borderLeftWidth > 0;
|
||||
}
|
||||
public hasBorderWidth(): boolean {
|
||||
return (
|
||||
this.borderTopWidth > 0 ||
|
||||
this.borderRightWidth > 0 ||
|
||||
this.borderBottomWidth > 0 ||
|
||||
this.borderLeftWidth > 0
|
||||
);
|
||||
}
|
||||
|
||||
public hasBorderRadius(): boolean {
|
||||
return this.borderTopLeftRadius > 0
|
||||
|| this.borderTopRightRadius > 0
|
||||
|| this.borderBottomRightRadius > 0
|
||||
|| this.borderBottomLeftRadius > 0;
|
||||
}
|
||||
public hasBorderRadius(): boolean {
|
||||
return (
|
||||
this.borderTopLeftRadius > 0 ||
|
||||
this.borderTopRightRadius > 0 ||
|
||||
this.borderBottomRightRadius > 0 ||
|
||||
this.borderBottomLeftRadius > 0
|
||||
);
|
||||
}
|
||||
|
||||
public hasUniformBorderColor(): boolean {
|
||||
return Color.equals(this.borderTopColor, this.borderRightColor)
|
||||
&& Color.equals(this.borderTopColor, this.borderBottomColor)
|
||||
&& Color.equals(this.borderTopColor, this.borderLeftColor);
|
||||
}
|
||||
public hasUniformBorderColor(): boolean {
|
||||
return (
|
||||
Color.equals(this.borderTopColor, this.borderRightColor) &&
|
||||
Color.equals(this.borderTopColor, this.borderBottomColor) &&
|
||||
Color.equals(this.borderTopColor, this.borderLeftColor)
|
||||
);
|
||||
}
|
||||
|
||||
public hasUniformBorderWidth(): boolean {
|
||||
return this.borderTopWidth === this.borderRightWidth
|
||||
&& this.borderTopWidth === this.borderBottomWidth
|
||||
&& this.borderTopWidth === this.borderLeftWidth;
|
||||
}
|
||||
public hasUniformBorderWidth(): boolean {
|
||||
return (
|
||||
this.borderTopWidth === this.borderRightWidth &&
|
||||
this.borderTopWidth === this.borderBottomWidth &&
|
||||
this.borderTopWidth === this.borderLeftWidth
|
||||
);
|
||||
}
|
||||
|
||||
public hasUniformBorderRadius(): boolean {
|
||||
return this.borderTopLeftRadius === this.borderTopRightRadius
|
||||
&& this.borderTopLeftRadius === this.borderBottomRightRadius
|
||||
&& this.borderTopLeftRadius === this.borderBottomLeftRadius;
|
||||
}
|
||||
public hasUniformBorderRadius(): boolean {
|
||||
return (
|
||||
this.borderTopLeftRadius === this.borderTopRightRadius &&
|
||||
this.borderTopLeftRadius === this.borderBottomRightRadius &&
|
||||
this.borderTopLeftRadius === this.borderBottomLeftRadius
|
||||
);
|
||||
}
|
||||
|
||||
public hasUniformBorder(): boolean {
|
||||
return this.hasUniformBorderColor()
|
||||
&& this.hasUniformBorderWidth()
|
||||
&& this.hasUniformBorderRadius();
|
||||
}
|
||||
public hasUniformBorder(): boolean {
|
||||
return (
|
||||
this.hasUniformBorderColor() &&
|
||||
this.hasUniformBorderWidth() &&
|
||||
this.hasUniformBorderRadius()
|
||||
);
|
||||
}
|
||||
|
||||
public getUniformBorderColor(): Color {
|
||||
if (this.hasUniformBorderColor()) {
|
||||
return this.borderTopColor;
|
||||
}
|
||||
public getUniformBorderColor(): Color {
|
||||
if (this.hasUniformBorderColor()) {
|
||||
return this.borderTopColor;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public getUniformBorderWidth(): number {
|
||||
if (this.hasUniformBorderWidth()) {
|
||||
return this.borderTopWidth;
|
||||
}
|
||||
public getUniformBorderWidth(): number {
|
||||
if (this.hasUniformBorderWidth()) {
|
||||
return this.borderTopWidth;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public getUniformBorderRadius(): number {
|
||||
if (this.hasUniformBorderRadius()) {
|
||||
return this.borderTopLeftRadius;
|
||||
}
|
||||
public getUniformBorderRadius(): number {
|
||||
if (this.hasUniformBorderRadius()) {
|
||||
return this.borderTopLeftRadius;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return `isEmpty: ${this.isEmpty()}; color: ${this.color}; image: ${this.image}; repeat: ${this.repeat}; position: ${this.position}; size: ${this.size}; borderTopColor: ${this.borderTopColor}; borderRightColor: ${this.borderRightColor}; borderBottomColor: ${this.borderBottomColor}; borderLeftColor: ${this.borderLeftColor}; borderTopWidth: ${this.borderTopWidth}; borderRightWidth: ${this.borderRightWidth}; borderBottomWidth: ${this.borderBottomWidth}; borderLeftWidth: ${this.borderLeftWidth}; borderTopLeftRadius: ${this.borderTopLeftRadius}; borderTopRightRadius: ${this.borderTopRightRadius}; borderBottomRightRadius: ${this.borderBottomRightRadius}; borderBottomLeftRadius: ${this.borderBottomLeftRadius}; clipPath: ${this.clipPath};`;
|
||||
}
|
||||
public toString(): string {
|
||||
return `isEmpty: ${this.isEmpty()}; color: ${this.color}; image: ${
|
||||
this.image
|
||||
}; repeat: ${this.repeat}; position: ${this.position}; size: ${
|
||||
this.size
|
||||
}; borderTopColor: ${this.borderTopColor}; borderRightColor: ${
|
||||
this.borderRightColor
|
||||
}; borderBottomColor: ${this.borderBottomColor}; borderLeftColor: ${
|
||||
this.borderLeftColor
|
||||
}; borderTopWidth: ${this.borderTopWidth}; borderRightWidth: ${
|
||||
this.borderRightWidth
|
||||
}; borderBottomWidth: ${this.borderBottomWidth}; borderLeftWidth: ${
|
||||
this.borderLeftWidth
|
||||
}; borderTopLeftRadius: ${
|
||||
this.borderTopLeftRadius
|
||||
}; borderTopRightRadius: ${
|
||||
this.borderTopRightRadius
|
||||
}; borderBottomRightRadius: ${
|
||||
this.borderBottomRightRadius
|
||||
}; borderBottomLeftRadius: ${this.borderBottomLeftRadius}; clipPath: ${
|
||||
this.clipPath
|
||||
};`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { View } from "../core/view";
|
||||
import { LinearGradient } from "./linear-gradient";
|
||||
|
||||
import { isDataURI, isFileOrResourcePath, layout, RESOURCE_PREFIX, FILE_PREFIX } from "../../utils/utils";
|
||||
import {
|
||||
isDataURI,
|
||||
isFileOrResourcePath,
|
||||
layout,
|
||||
RESOURCE_PREFIX,
|
||||
FILE_PREFIX,
|
||||
} from "../../utils/utils";
|
||||
import { parse } from "../../css-value";
|
||||
import { path, knownFolders } from "../../file-system";
|
||||
import * as application from "../../application";
|
||||
@@ -9,288 +15,367 @@ import { profile } from "../../profiling";
|
||||
export * from "./background-common";
|
||||
|
||||
interface AndroidView {
|
||||
_cachedDrawable: android.graphics.drawable.Drawable.ConstantState | android.graphics.drawable.Drawable;
|
||||
_cachedDrawable:
|
||||
| android.graphics.drawable.Drawable.ConstantState
|
||||
| android.graphics.drawable.Drawable;
|
||||
}
|
||||
|
||||
// TODO: Change this implementation to use
|
||||
// We are using "ad" here to avoid namespace collision with the global android object
|
||||
export module ad {
|
||||
let SDK: number;
|
||||
function getSDK() {
|
||||
if (!SDK) {
|
||||
SDK = android.os.Build.VERSION.SDK_INT;
|
||||
}
|
||||
let SDK: number;
|
||||
function getSDK() {
|
||||
if (!SDK) {
|
||||
SDK = android.os.Build.VERSION.SDK_INT;
|
||||
}
|
||||
|
||||
return SDK;
|
||||
}
|
||||
return SDK;
|
||||
}
|
||||
|
||||
function isSetColorFilterOnlyWidget(nativeView: android.view.View): boolean {
|
||||
return (
|
||||
nativeView instanceof android.widget.Button ||
|
||||
(nativeView instanceof androidx.appcompat.widget.Toolbar
|
||||
&& getSDK() >= 21 // There is an issue with the DrawableContainer which was fixed for API version 21 and above: https://code.google.com/p/android/issues/detail?id=60183
|
||||
)
|
||||
);
|
||||
}
|
||||
function isSetColorFilterOnlyWidget(
|
||||
nativeView: android.view.View
|
||||
): boolean {
|
||||
return (
|
||||
nativeView instanceof android.widget.Button ||
|
||||
(nativeView instanceof androidx.appcompat.widget.Toolbar &&
|
||||
getSDK() >= 21) // There is an issue with the DrawableContainer which was fixed for API version 21 and above: https://code.google.com/p/android/issues/detail?id=60183
|
||||
);
|
||||
}
|
||||
|
||||
export function onBackgroundOrBorderPropertyChanged(view: View) {
|
||||
const nativeView = <android.view.View>view.nativeViewProtected;
|
||||
if (!nativeView) {
|
||||
return;
|
||||
}
|
||||
export function onBackgroundOrBorderPropertyChanged(view: View) {
|
||||
const nativeView = <android.view.View>view.nativeViewProtected;
|
||||
if (!nativeView) {
|
||||
return;
|
||||
}
|
||||
|
||||
const background = view.style.backgroundInternal;
|
||||
let drawable = nativeView.getBackground();
|
||||
const androidView = <any>view as AndroidView;
|
||||
// use undefined as not set. getBackground will never return undefined only Drawable or null;
|
||||
if (androidView._cachedDrawable === undefined && drawable) {
|
||||
const constantState = drawable.getConstantState();
|
||||
androidView._cachedDrawable = constantState || drawable;
|
||||
}
|
||||
const background = view.style.backgroundInternal;
|
||||
let drawable = nativeView.getBackground();
|
||||
const androidView = (<any>view) as AndroidView;
|
||||
// use undefined as not set. getBackground will never return undefined only Drawable or null;
|
||||
if (androidView._cachedDrawable === undefined && drawable) {
|
||||
const constantState = drawable.getConstantState();
|
||||
androidView._cachedDrawable = constantState || drawable;
|
||||
}
|
||||
|
||||
if (isSetColorFilterOnlyWidget(nativeView)
|
||||
&& drawable
|
||||
&& !background.hasBorderWidth()
|
||||
&& !background.hasBorderRadius()
|
||||
&& !background.clipPath
|
||||
&& !background.image
|
||||
&& background.color) {
|
||||
if (
|
||||
isSetColorFilterOnlyWidget(nativeView) &&
|
||||
drawable &&
|
||||
!background.hasBorderWidth() &&
|
||||
!background.hasBorderRadius() &&
|
||||
!background.clipPath &&
|
||||
!background.image &&
|
||||
background.color
|
||||
) {
|
||||
if (
|
||||
drawable instanceof org.nativescript.widgets.BorderDrawable &&
|
||||
androidView._cachedDrawable
|
||||
) {
|
||||
if (
|
||||
!(
|
||||
androidView._cachedDrawable instanceof
|
||||
android.graphics.drawable.Drawable.ConstantState
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (drawable instanceof org.nativescript.widgets.BorderDrawable && androidView._cachedDrawable) {
|
||||
if (!(androidView._cachedDrawable instanceof android.graphics.drawable.Drawable.ConstantState)) {
|
||||
return;
|
||||
}
|
||||
drawable = androidView._cachedDrawable.newDrawable(
|
||||
nativeView.getResources()
|
||||
);
|
||||
nativeView.setBackground(drawable);
|
||||
}
|
||||
|
||||
drawable = androidView._cachedDrawable.newDrawable(nativeView.getResources());
|
||||
nativeView.setBackground(drawable);
|
||||
}
|
||||
const backgroundColor = ((<any>drawable).backgroundColor =
|
||||
background.color.android);
|
||||
drawable.mutate();
|
||||
drawable.setColorFilter(
|
||||
backgroundColor,
|
||||
android.graphics.PorterDuff.Mode.SRC_IN
|
||||
);
|
||||
drawable.invalidateSelf(); // Make sure the drawable is invalidated. Android forgets to invalidate it in some cases: toolbar
|
||||
(<any>drawable).backgroundColor = backgroundColor;
|
||||
} else if (!background.isEmpty()) {
|
||||
let backgroundDrawable = drawable as org.nativescript.widgets.BorderDrawable;
|
||||
if (
|
||||
!(drawable instanceof org.nativescript.widgets.BorderDrawable)
|
||||
) {
|
||||
backgroundDrawable = new org.nativescript.widgets.BorderDrawable(
|
||||
layout.getDisplayDensity(),
|
||||
view.toString()
|
||||
);
|
||||
refreshBorderDrawable(view, backgroundDrawable);
|
||||
nativeView.setBackground(backgroundDrawable);
|
||||
} else {
|
||||
refreshBorderDrawable(view, backgroundDrawable);
|
||||
}
|
||||
} else {
|
||||
const cachedDrawable = androidView._cachedDrawable;
|
||||
let defaultDrawable: android.graphics.drawable.Drawable = null;
|
||||
if (cachedDrawable) {
|
||||
if (
|
||||
cachedDrawable instanceof
|
||||
android.graphics.drawable.Drawable.ConstantState
|
||||
) {
|
||||
defaultDrawable = cachedDrawable.newDrawable(
|
||||
nativeView.getResources()
|
||||
);
|
||||
} else if (
|
||||
cachedDrawable instanceof android.graphics.drawable.Drawable
|
||||
) {
|
||||
defaultDrawable = cachedDrawable;
|
||||
}
|
||||
}
|
||||
|
||||
const backgroundColor = (<any>drawable).backgroundColor = background.color.android;
|
||||
drawable.mutate();
|
||||
drawable.setColorFilter(backgroundColor, android.graphics.PorterDuff.Mode.SRC_IN);
|
||||
drawable.invalidateSelf(); // Make sure the drawable is invalidated. Android forgets to invalidate it in some cases: toolbar
|
||||
(<any>drawable).backgroundColor = backgroundColor;
|
||||
} else if (!background.isEmpty()) {
|
||||
let backgroundDrawable = drawable as org.nativescript.widgets.BorderDrawable;
|
||||
if (!(drawable instanceof org.nativescript.widgets.BorderDrawable)) {
|
||||
backgroundDrawable = new org.nativescript.widgets.BorderDrawable(layout.getDisplayDensity(), view.toString());
|
||||
refreshBorderDrawable(view, backgroundDrawable);
|
||||
nativeView.setBackground(backgroundDrawable);
|
||||
} else {
|
||||
refreshBorderDrawable(view, backgroundDrawable);
|
||||
}
|
||||
} else {
|
||||
const cachedDrawable = androidView._cachedDrawable;
|
||||
let defaultDrawable: android.graphics.drawable.Drawable = null;
|
||||
if (cachedDrawable) {
|
||||
if (cachedDrawable instanceof android.graphics.drawable.Drawable.ConstantState) {
|
||||
defaultDrawable = cachedDrawable.newDrawable(nativeView.getResources());
|
||||
} else if (cachedDrawable instanceof android.graphics.drawable.Drawable) {
|
||||
defaultDrawable = cachedDrawable;
|
||||
}
|
||||
}
|
||||
nativeView.setBackground(defaultDrawable);
|
||||
}
|
||||
|
||||
nativeView.setBackground(defaultDrawable);
|
||||
}
|
||||
// TODO: Can we move BorderWidths as separate native setter?
|
||||
// This way we could skip setPadding if borderWidth is not changed.
|
||||
const leftPadding = Math.ceil(
|
||||
view.effectiveBorderLeftWidth + view.effectivePaddingLeft
|
||||
);
|
||||
const topPadding = Math.ceil(
|
||||
view.effectiveBorderTopWidth + view.effectivePaddingTop
|
||||
);
|
||||
const rightPadding = Math.ceil(
|
||||
view.effectiveBorderRightWidth + view.effectivePaddingRight
|
||||
);
|
||||
const bottomPadding = Math.ceil(
|
||||
view.effectiveBorderBottomWidth + view.effectivePaddingBottom
|
||||
);
|
||||
|
||||
// TODO: Can we move BorderWidths as separate native setter?
|
||||
// This way we could skip setPadding if borderWidth is not changed.
|
||||
const leftPadding = Math.ceil(view.effectiveBorderLeftWidth + view.effectivePaddingLeft);
|
||||
const topPadding = Math.ceil(view.effectiveBorderTopWidth + view.effectivePaddingTop);
|
||||
const rightPadding = Math.ceil(view.effectiveBorderRightWidth + view.effectivePaddingRight);
|
||||
const bottomPadding = Math.ceil(view.effectiveBorderBottomWidth + view.effectivePaddingBottom);
|
||||
|
||||
nativeView.setPadding(
|
||||
leftPadding,
|
||||
topPadding,
|
||||
rightPadding,
|
||||
bottomPadding
|
||||
);
|
||||
}
|
||||
nativeView.setPadding(
|
||||
leftPadding,
|
||||
topPadding,
|
||||
rightPadding,
|
||||
bottomPadding
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function fromBase64(source: string): android.graphics.Bitmap {
|
||||
const bytes = android.util.Base64.decode(source, android.util.Base64.DEFAULT);
|
||||
const bytes = android.util.Base64.decode(
|
||||
source,
|
||||
android.util.Base64.DEFAULT
|
||||
);
|
||||
|
||||
return android.graphics.BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
||||
return android.graphics.BitmapFactory.decodeByteArray(
|
||||
bytes,
|
||||
0,
|
||||
bytes.length
|
||||
);
|
||||
}
|
||||
|
||||
function fromGradient(gradient: LinearGradient): org.nativescript.widgets.LinearGradientDefinition {
|
||||
const colors = Array.create("int", gradient.colorStops.length);
|
||||
const stops = Array.create("float", gradient.colorStops.length);
|
||||
let hasStops = false;
|
||||
gradient.colorStops.forEach((stop, index) => {
|
||||
colors[index] = stop.color.android;
|
||||
if (stop.offset) {
|
||||
stops[index] = stop.offset.value;
|
||||
hasStops = true;
|
||||
}
|
||||
});
|
||||
function fromGradient(
|
||||
gradient: LinearGradient
|
||||
): org.nativescript.widgets.LinearGradientDefinition {
|
||||
const colors = Array.create("int", gradient.colorStops.length);
|
||||
const stops = Array.create("float", gradient.colorStops.length);
|
||||
let hasStops = false;
|
||||
gradient.colorStops.forEach((stop, index) => {
|
||||
colors[index] = stop.color.android;
|
||||
if (stop.offset) {
|
||||
stops[index] = stop.offset.value;
|
||||
hasStops = true;
|
||||
}
|
||||
});
|
||||
|
||||
const alpha = gradient.angle / (Math.PI * 2);
|
||||
const startX = Math.pow(
|
||||
Math.sin(Math.PI * (alpha + 0.75)),
|
||||
2
|
||||
);
|
||||
const startY = Math.pow(
|
||||
Math.sin(Math.PI * (alpha + 0.5)),
|
||||
2
|
||||
);
|
||||
const endX = Math.pow(
|
||||
Math.sin(Math.PI * (alpha + 0.25)),
|
||||
2
|
||||
);
|
||||
const endY = Math.pow(
|
||||
Math.sin(Math.PI * alpha),
|
||||
2
|
||||
);
|
||||
const alpha = gradient.angle / (Math.PI * 2);
|
||||
const startX = Math.pow(Math.sin(Math.PI * (alpha + 0.75)), 2);
|
||||
const startY = Math.pow(Math.sin(Math.PI * (alpha + 0.5)), 2);
|
||||
const endX = Math.pow(Math.sin(Math.PI * (alpha + 0.25)), 2);
|
||||
const endY = Math.pow(Math.sin(Math.PI * alpha), 2);
|
||||
|
||||
return new org.nativescript.widgets.LinearGradientDefinition(startX, startY, endX, endY, colors, hasStops ? stops : null);
|
||||
return new org.nativescript.widgets.LinearGradientDefinition(
|
||||
startX,
|
||||
startY,
|
||||
endX,
|
||||
endY,
|
||||
colors,
|
||||
hasStops ? stops : null
|
||||
);
|
||||
}
|
||||
|
||||
const pattern: RegExp = /url\(('|")(.*?)\1\)/;
|
||||
function refreshBorderDrawable(this: void, view: View, borderDrawable: org.nativescript.widgets.BorderDrawable) {
|
||||
const nativeView = <android.view.View>view.nativeViewProtected;
|
||||
const context = nativeView.getContext();
|
||||
function refreshBorderDrawable(
|
||||
this: void,
|
||||
view: View,
|
||||
borderDrawable: org.nativescript.widgets.BorderDrawable
|
||||
) {
|
||||
const nativeView = <android.view.View>view.nativeViewProtected;
|
||||
const context = nativeView.getContext();
|
||||
|
||||
const background = view.style.backgroundInternal;
|
||||
if (background) {
|
||||
const backgroundPositionParsedCSSValues = createNativeCSSValueArray(background.position);
|
||||
const backgroundSizeParsedCSSValues = createNativeCSSValueArray(background.size);
|
||||
const blackColor = -16777216; //android.graphics.Color.BLACK;
|
||||
const background = view.style.backgroundInternal;
|
||||
if (background) {
|
||||
const backgroundPositionParsedCSSValues = createNativeCSSValueArray(
|
||||
background.position
|
||||
);
|
||||
const backgroundSizeParsedCSSValues = createNativeCSSValueArray(
|
||||
background.size
|
||||
);
|
||||
const blackColor = -16777216; //android.graphics.Color.BLACK;
|
||||
|
||||
let imageUri: string;
|
||||
if (background.image && typeof background.image === "string") {
|
||||
imageUri = background.image;
|
||||
const match = imageUri.match(pattern);
|
||||
if (match && match[2]) {
|
||||
imageUri = match[2];
|
||||
}
|
||||
}
|
||||
let imageUri: string;
|
||||
if (background.image && typeof background.image === "string") {
|
||||
imageUri = background.image;
|
||||
const match = imageUri.match(pattern);
|
||||
if (match && match[2]) {
|
||||
imageUri = match[2];
|
||||
}
|
||||
}
|
||||
|
||||
let bitmap: android.graphics.Bitmap = null;
|
||||
if (isDataURI(imageUri)) {
|
||||
const base64Data = imageUri.split(",")[1];
|
||||
if (base64Data !== undefined) {
|
||||
bitmap = fromBase64(base64Data);
|
||||
imageUri = null;
|
||||
}
|
||||
} else if (isFileOrResourcePath(imageUri)) {
|
||||
if (imageUri.indexOf(RESOURCE_PREFIX) !== 0) {
|
||||
let fileName = imageUri;
|
||||
if (fileName.indexOf("~/") === 0) {
|
||||
fileName = path.join(knownFolders.currentApp().path, fileName.replace("~/", ""));
|
||||
}
|
||||
let bitmap: android.graphics.Bitmap = null;
|
||||
if (isDataURI(imageUri)) {
|
||||
const base64Data = imageUri.split(",")[1];
|
||||
if (base64Data !== undefined) {
|
||||
bitmap = fromBase64(base64Data);
|
||||
imageUri = null;
|
||||
}
|
||||
} else if (isFileOrResourcePath(imageUri)) {
|
||||
if (imageUri.indexOf(RESOURCE_PREFIX) !== 0) {
|
||||
let fileName = imageUri;
|
||||
if (fileName.indexOf("~/") === 0) {
|
||||
fileName = path.join(
|
||||
knownFolders.currentApp().path,
|
||||
fileName.replace("~/", "")
|
||||
);
|
||||
}
|
||||
|
||||
imageUri = FILE_PREFIX + fileName;
|
||||
}
|
||||
}
|
||||
imageUri = FILE_PREFIX + fileName;
|
||||
}
|
||||
}
|
||||
|
||||
let gradient: org.nativescript.widgets.LinearGradientDefinition = null;
|
||||
if (background.image && background.image instanceof LinearGradient) {
|
||||
gradient = fromGradient(background.image);
|
||||
}
|
||||
let gradient: org.nativescript.widgets.LinearGradientDefinition = null;
|
||||
if (background.image && background.image instanceof LinearGradient) {
|
||||
gradient = fromGradient(background.image);
|
||||
}
|
||||
|
||||
borderDrawable.refresh(
|
||||
background.borderTopColor ? background.borderTopColor.android : blackColor,
|
||||
background.borderRightColor ? background.borderRightColor.android : blackColor,
|
||||
background.borderBottomColor ? background.borderBottomColor.android : blackColor,
|
||||
background.borderLeftColor ? background.borderLeftColor.android : blackColor,
|
||||
borderDrawable.refresh(
|
||||
background.borderTopColor
|
||||
? background.borderTopColor.android
|
||||
: blackColor,
|
||||
background.borderRightColor
|
||||
? background.borderRightColor.android
|
||||
: blackColor,
|
||||
background.borderBottomColor
|
||||
? background.borderBottomColor.android
|
||||
: blackColor,
|
||||
background.borderLeftColor
|
||||
? background.borderLeftColor.android
|
||||
: blackColor,
|
||||
|
||||
background.borderTopWidth,
|
||||
background.borderRightWidth,
|
||||
background.borderBottomWidth,
|
||||
background.borderLeftWidth,
|
||||
background.borderTopWidth,
|
||||
background.borderRightWidth,
|
||||
background.borderBottomWidth,
|
||||
background.borderLeftWidth,
|
||||
|
||||
background.borderTopLeftRadius,
|
||||
background.borderTopRightRadius,
|
||||
background.borderBottomRightRadius,
|
||||
background.borderBottomLeftRadius,
|
||||
background.borderTopLeftRadius,
|
||||
background.borderTopRightRadius,
|
||||
background.borderBottomRightRadius,
|
||||
background.borderBottomLeftRadius,
|
||||
|
||||
background.clipPath,
|
||||
background.clipPath,
|
||||
|
||||
background.color ? background.color.android : 0,
|
||||
imageUri,
|
||||
bitmap,
|
||||
gradient,
|
||||
context,
|
||||
background.repeat,
|
||||
background.position,
|
||||
backgroundPositionParsedCSSValues,
|
||||
background.size,
|
||||
backgroundSizeParsedCSSValues
|
||||
);
|
||||
//console.log(`>>> ${borderDrawable.toDebugString()}`);
|
||||
}
|
||||
background.color ? background.color.android : 0,
|
||||
imageUri,
|
||||
bitmap,
|
||||
gradient,
|
||||
context,
|
||||
background.repeat,
|
||||
background.position,
|
||||
backgroundPositionParsedCSSValues,
|
||||
background.size,
|
||||
backgroundSizeParsedCSSValues
|
||||
);
|
||||
//console.log(`>>> ${borderDrawable.toDebugString()}`);
|
||||
}
|
||||
}
|
||||
|
||||
function createNativeCSSValueArray(css: string): native.Array<org.nativescript.widgets.CSSValue> {
|
||||
if (!css) {
|
||||
return null;
|
||||
}
|
||||
function createNativeCSSValueArray(
|
||||
css: string
|
||||
): native.Array<org.nativescript.widgets.CSSValue> {
|
||||
if (!css) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const cssValues = parse(css);
|
||||
const nativeArray = Array.create(org.nativescript.widgets.CSSValue, cssValues.length);
|
||||
for (let i = 0, length = cssValues.length; i < length; i++) {
|
||||
nativeArray[i] = new org.nativescript.widgets.CSSValue(
|
||||
cssValues[i].type,
|
||||
cssValues[i].string,
|
||||
cssValues[i].unit,
|
||||
cssValues[i].value
|
||||
);
|
||||
}
|
||||
const cssValues = parse(css);
|
||||
const nativeArray = Array.create(
|
||||
org.nativescript.widgets.CSSValue,
|
||||
cssValues.length
|
||||
);
|
||||
for (let i = 0, length = cssValues.length; i < length; i++) {
|
||||
nativeArray[i] = new org.nativescript.widgets.CSSValue(
|
||||
cssValues[i].type,
|
||||
cssValues[i].string,
|
||||
cssValues[i].unit,
|
||||
cssValues[i].value
|
||||
);
|
||||
}
|
||||
|
||||
return nativeArray;
|
||||
return nativeArray;
|
||||
}
|
||||
|
||||
export enum CacheMode {
|
||||
none,
|
||||
memory,
|
||||
diskAndMemory
|
||||
none,
|
||||
memory,
|
||||
diskAndMemory,
|
||||
}
|
||||
|
||||
let currentCacheMode: CacheMode;
|
||||
let imageFetcher: org.nativescript.widgets.image.Fetcher;
|
||||
|
||||
export function initImageCache(context: android.content.Context, mode = CacheMode.diskAndMemory, memoryCacheSize: number = 0.25, diskCacheSize: number = 10 * 1024 * 1024): void {
|
||||
if (currentCacheMode === mode) {
|
||||
return;
|
||||
}
|
||||
export function initImageCache(
|
||||
context: android.content.Context,
|
||||
mode = CacheMode.diskAndMemory,
|
||||
memoryCacheSize: number = 0.25,
|
||||
diskCacheSize: number = 10 * 1024 * 1024
|
||||
): void {
|
||||
if (currentCacheMode === mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentCacheMode = mode;
|
||||
if (!imageFetcher) {
|
||||
imageFetcher = org.nativescript.widgets.image.Fetcher.getInstance(context);
|
||||
} else {
|
||||
imageFetcher.clearCache();
|
||||
}
|
||||
currentCacheMode = mode;
|
||||
if (!imageFetcher) {
|
||||
imageFetcher = org.nativescript.widgets.image.Fetcher.getInstance(
|
||||
context
|
||||
);
|
||||
} else {
|
||||
imageFetcher.clearCache();
|
||||
}
|
||||
|
||||
const params = new org.nativescript.widgets.image.Cache.CacheParams();
|
||||
params.memoryCacheEnabled = mode !== CacheMode.none;
|
||||
params.setMemCacheSizePercent(memoryCacheSize); // Set memory cache to % of app memory
|
||||
params.diskCacheEnabled = mode === CacheMode.diskAndMemory;
|
||||
params.diskCacheSize = diskCacheSize;
|
||||
const imageCache = org.nativescript.widgets.image.Cache.getInstance(params);
|
||||
imageFetcher.addImageCache(imageCache);
|
||||
imageFetcher.initCache();
|
||||
const params = new org.nativescript.widgets.image.Cache.CacheParams();
|
||||
params.memoryCacheEnabled = mode !== CacheMode.none;
|
||||
params.setMemCacheSizePercent(memoryCacheSize); // Set memory cache to % of app memory
|
||||
params.diskCacheEnabled = mode === CacheMode.diskAndMemory;
|
||||
params.diskCacheSize = diskCacheSize;
|
||||
const imageCache = org.nativescript.widgets.image.Cache.getInstance(params);
|
||||
imageFetcher.addImageCache(imageCache);
|
||||
imageFetcher.initCache();
|
||||
}
|
||||
|
||||
function onLivesync(args): void {
|
||||
if (imageFetcher) {
|
||||
imageFetcher.clearCache();
|
||||
}
|
||||
if (imageFetcher) {
|
||||
imageFetcher.clearCache();
|
||||
}
|
||||
}
|
||||
application.on("livesync", onLivesync);
|
||||
|
||||
application.android.on("activityStarted", <any>profile("initImageCache", args => {
|
||||
if (!imageFetcher) {
|
||||
initImageCache(args.activity);
|
||||
} else {
|
||||
imageFetcher.initCache();
|
||||
}
|
||||
}));
|
||||
application.android.on(
|
||||
"activityStarted",
|
||||
<any>profile("initImageCache", (args) => {
|
||||
if (!imageFetcher) {
|
||||
initImageCache(args.activity);
|
||||
} else {
|
||||
imageFetcher.initCache();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
application.android.on("activityStopped", <any>profile("closeImageCache", args => {
|
||||
if (imageFetcher) {
|
||||
imageFetcher.closeCache();
|
||||
}
|
||||
}));
|
||||
application.android.on(
|
||||
"activityStopped",
|
||||
<any>profile("closeImageCache", (args) => {
|
||||
if (imageFetcher) {
|
||||
imageFetcher.closeCache();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
106
nativescript-core/ui/styling/background.d.ts
vendored
106
nativescript-core/ui/styling/background.d.ts
vendored
@@ -4,65 +4,69 @@ import { BackgroundRepeat } from "../../css/parser";
|
||||
import { LinearGradient } from "../styling/linear-gradient";
|
||||
|
||||
export class Background {
|
||||
public static default: Background;
|
||||
public color: Color;
|
||||
public image: string | LinearGradient;
|
||||
public repeat: BackgroundRepeat;
|
||||
public position: string;
|
||||
public size: string;
|
||||
public borderTopColor: Color;
|
||||
public borderRightColor: Color;
|
||||
public borderBottomColor: Color;
|
||||
public borderLeftColor: Color;
|
||||
public borderTopWidth: number;
|
||||
public borderRightWidth: number;
|
||||
public borderBottomWidth: number;
|
||||
public borderLeftWidth: number;
|
||||
public borderTopLeftRadius: number;
|
||||
public borderTopRightRadius: number;
|
||||
public borderBottomRightRadius: number;
|
||||
public borderBottomLeftRadius: number;
|
||||
public clipPath: string;
|
||||
public static default: Background;
|
||||
public color: Color;
|
||||
public image: string | LinearGradient;
|
||||
public repeat: BackgroundRepeat;
|
||||
public position: string;
|
||||
public size: string;
|
||||
public borderTopColor: Color;
|
||||
public borderRightColor: Color;
|
||||
public borderBottomColor: Color;
|
||||
public borderLeftColor: Color;
|
||||
public borderTopWidth: number;
|
||||
public borderRightWidth: number;
|
||||
public borderBottomWidth: number;
|
||||
public borderLeftWidth: number;
|
||||
public borderTopLeftRadius: number;
|
||||
public borderTopRightRadius: number;
|
||||
public borderBottomRightRadius: number;
|
||||
public borderBottomLeftRadius: number;
|
||||
public clipPath: string;
|
||||
|
||||
public withColor(value: Color): Background;
|
||||
public withImage(value: string | LinearGradient): Background;
|
||||
public withRepeat(value: BackgroundRepeat): Background;
|
||||
public withPosition(value: string): Background;
|
||||
public withSize(value: string): Background;
|
||||
public withBorderTopColor(value: Color): Background;
|
||||
public withBorderRightColor(value: Color): Background;
|
||||
public withBorderBottomColor(value: Color): Background;
|
||||
public withBorderLeftColor(value: Color): Background;
|
||||
public withBorderTopWidth(value: number): Background;
|
||||
public withBorderRightWidth(value: number): Background;
|
||||
public withBorderBottomWidth(value: number): Background;
|
||||
public withBorderLeftWidth(value: number): Background;
|
||||
public withBorderTopLeftRadius(value: number): Background;
|
||||
public withBorderTopRightRadius(value: number): Background;
|
||||
public withBorderBottomRightRadius(value: number): Background;
|
||||
public withBorderBottomLeftRadius(value: number): Background;
|
||||
public withClipPath(value: string): Background;
|
||||
public withColor(value: Color): Background;
|
||||
public withImage(value: string | LinearGradient): Background;
|
||||
public withRepeat(value: BackgroundRepeat): Background;
|
||||
public withPosition(value: string): Background;
|
||||
public withSize(value: string): Background;
|
||||
public withBorderTopColor(value: Color): Background;
|
||||
public withBorderRightColor(value: Color): Background;
|
||||
public withBorderBottomColor(value: Color): Background;
|
||||
public withBorderLeftColor(value: Color): Background;
|
||||
public withBorderTopWidth(value: number): Background;
|
||||
public withBorderRightWidth(value: number): Background;
|
||||
public withBorderBottomWidth(value: number): Background;
|
||||
public withBorderLeftWidth(value: number): Background;
|
||||
public withBorderTopLeftRadius(value: number): Background;
|
||||
public withBorderTopRightRadius(value: number): Background;
|
||||
public withBorderBottomRightRadius(value: number): Background;
|
||||
public withBorderBottomLeftRadius(value: number): Background;
|
||||
public withClipPath(value: string): Background;
|
||||
|
||||
public isEmpty(): boolean;
|
||||
public isEmpty(): boolean;
|
||||
|
||||
public static equals(value1: Background, value2: Background): boolean;
|
||||
public static equals(value1: Background, value2: Background): boolean;
|
||||
|
||||
public hasBorderColor(): boolean;
|
||||
public hasBorderWidth(): boolean;
|
||||
public hasBorderRadius(): boolean;
|
||||
public hasUniformBorderColor(): boolean;
|
||||
public hasUniformBorderWidth(): boolean;
|
||||
public hasUniformBorderRadius(): boolean;
|
||||
public hasUniformBorder(): boolean;
|
||||
public getUniformBorderColor(): Color;
|
||||
public getUniformBorderWidth(): number;
|
||||
public getUniformBorderRadius(): number;
|
||||
public hasBorderColor(): boolean;
|
||||
public hasBorderWidth(): boolean;
|
||||
public hasBorderRadius(): boolean;
|
||||
public hasUniformBorderColor(): boolean;
|
||||
public hasUniformBorderWidth(): boolean;
|
||||
public hasUniformBorderRadius(): boolean;
|
||||
public hasUniformBorder(): boolean;
|
||||
public getUniformBorderColor(): Color;
|
||||
public getUniformBorderWidth(): number;
|
||||
public getUniformBorderRadius(): number;
|
||||
}
|
||||
|
||||
export module ios {
|
||||
export function createBackgroundUIColor(view: View, callback: (uiColor: any /* UIColor */) => void, flip?: boolean): void;
|
||||
export function createBackgroundUIColor(
|
||||
view: View,
|
||||
callback: (uiColor: any /* UIColor */) => void,
|
||||
flip?: boolean
|
||||
): void;
|
||||
}
|
||||
|
||||
export module ad {
|
||||
export function onBackgroundOrBorderPropertyChanged(v: View);
|
||||
export function onBackgroundOrBorderPropertyChanged(v: View);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,54 +1,54 @@
|
||||
import { AnimationCurve } from "../enums";
|
||||
|
||||
const STYLE_CURVE_MAP = Object.freeze({
|
||||
"ease": AnimationCurve.ease,
|
||||
"linear": AnimationCurve.linear,
|
||||
"ease-in": AnimationCurve.easeIn,
|
||||
"ease-out": AnimationCurve.easeOut,
|
||||
"ease-in-out": AnimationCurve.easeInOut,
|
||||
"spring": AnimationCurve.spring,
|
||||
ease: AnimationCurve.ease,
|
||||
linear: AnimationCurve.linear,
|
||||
"ease-in": AnimationCurve.easeIn,
|
||||
"ease-out": AnimationCurve.easeOut,
|
||||
"ease-in-out": AnimationCurve.easeInOut,
|
||||
spring: AnimationCurve.spring,
|
||||
});
|
||||
|
||||
export function timeConverter(value: string): number {
|
||||
let result = parseFloat(value);
|
||||
if (value.indexOf("ms") === -1) {
|
||||
result = result * 1000;
|
||||
}
|
||||
let result = parseFloat(value);
|
||||
if (value.indexOf("ms") === -1) {
|
||||
result = result * 1000;
|
||||
}
|
||||
|
||||
return Math.max(0.0, result);
|
||||
return Math.max(0.0, result);
|
||||
}
|
||||
|
||||
export function animationTimingFunctionConverter(value: string): any {
|
||||
return value ?
|
||||
STYLE_CURVE_MAP[value] || parseCubicBezierCurve(value) :
|
||||
AnimationCurve.ease;
|
||||
return value
|
||||
? STYLE_CURVE_MAP[value] || parseCubicBezierCurve(value)
|
||||
: AnimationCurve.ease;
|
||||
}
|
||||
|
||||
function parseCubicBezierCurve(value: string) {
|
||||
const coordsString = /\((.*?)\)/.exec(value);
|
||||
const coords = coordsString && coordsString[1]
|
||||
.split(",")
|
||||
.map(stringToBezieCoords);
|
||||
const coordsString = /\((.*?)\)/.exec(value);
|
||||
const coords =
|
||||
coordsString && coordsString[1].split(",").map(stringToBezieCoords);
|
||||
|
||||
if (value.startsWith("cubic-bezier") &&
|
||||
coordsString &&
|
||||
coords.length === 4) {
|
||||
if (
|
||||
value.startsWith("cubic-bezier") &&
|
||||
coordsString &&
|
||||
coords.length === 4
|
||||
) {
|
||||
const [x1, x2, y1, y2] = [...coords];
|
||||
|
||||
const [x1, x2, y1, y2] = [...coords];
|
||||
|
||||
return AnimationCurve.cubicBezier(x1, x2, y1, y2);
|
||||
} else {
|
||||
throw new Error(`Invalid value for animation: ${value}`);
|
||||
}
|
||||
return AnimationCurve.cubicBezier(x1, x2, y1, y2);
|
||||
} else {
|
||||
throw new Error(`Invalid value for animation: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
function stringToBezieCoords(value: string): number {
|
||||
let result = parseFloat(value);
|
||||
if (result < 0) {
|
||||
return 0;
|
||||
} else if (result > 1) {
|
||||
return 1;
|
||||
}
|
||||
let result = parseFloat(value);
|
||||
if (result < 0) {
|
||||
return 0;
|
||||
} else if (result > 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
import {
|
||||
KeyframeAnimationInfo,
|
||||
KeyframeDeclaration,
|
||||
KeyframeInfo,
|
||||
UnparsedKeyframe,
|
||||
KeyframeAnimationInfo,
|
||||
KeyframeDeclaration,
|
||||
KeyframeInfo,
|
||||
UnparsedKeyframe,
|
||||
} from "../animation/keyframe-animation";
|
||||
|
||||
export class CssAnimationParser {
|
||||
public static keyframeAnimationsFromCSSDeclarations(declarations: KeyframeDeclaration[]): KeyframeAnimationInfo[];
|
||||
public static keyframeAnimationsFromCSSDeclarations(
|
||||
declarations: KeyframeDeclaration[]
|
||||
): KeyframeAnimationInfo[];
|
||||
|
||||
public static keyframesArrayFromCSS(keyframes: UnparsedKeyframe[]): KeyframeInfo[];
|
||||
public static keyframesArrayFromCSS(
|
||||
keyframes: UnparsedKeyframe[]
|
||||
): KeyframeInfo[];
|
||||
}
|
||||
|
||||
export function parseKeyframeDeclarations(unparsedKeyframeDeclarations: KeyframeDeclaration[]) : KeyframeDeclaration[];
|
||||
export function parseKeyframeDeclarations(
|
||||
unparsedKeyframeDeclarations: KeyframeDeclaration[]
|
||||
): KeyframeDeclaration[];
|
||||
|
||||
@@ -1,147 +1,186 @@
|
||||
import { CssAnimationProperty } from "../core/properties";
|
||||
|
||||
import {
|
||||
KeyframeAnimationInfo,
|
||||
KeyframeDeclaration,
|
||||
KeyframeInfo,
|
||||
UnparsedKeyframe,
|
||||
KeyframeAnimationInfo,
|
||||
KeyframeDeclaration,
|
||||
KeyframeInfo,
|
||||
UnparsedKeyframe,
|
||||
} from "../animation/keyframe-animation";
|
||||
import { timeConverter, animationTimingFunctionConverter } from "../styling/converters";
|
||||
import {
|
||||
timeConverter,
|
||||
animationTimingFunctionConverter,
|
||||
} from "../styling/converters";
|
||||
|
||||
import { transformConverter } from "../styling/style-properties";
|
||||
|
||||
const ANIMATION_PROPERTY_HANDLERS = Object.freeze({
|
||||
"animation-name": (info: any, value: any) => info.name = value,
|
||||
"animation-duration": (info: any, value: any) => info.duration = timeConverter(value),
|
||||
"animation-delay": (info: any, value: any) => info.delay = timeConverter(value),
|
||||
"animation-timing-function": (info: any, value: any) => info.curve = animationTimingFunctionConverter(value),
|
||||
"animation-iteration-count": (info: any, value: any) => info.iterations = value === "infinite" ? Number.MAX_VALUE : parseFloat(value),
|
||||
"animation-direction": (info: any, value: any) => info.isReverse = value === "reverse",
|
||||
"animation-fill-mode": (info: any, value: any) => info.isForwards = value === "forwards"
|
||||
"animation-name": (info: any, value: any) => (info.name = value),
|
||||
"animation-duration": (info: any, value: any) =>
|
||||
(info.duration = timeConverter(value)),
|
||||
"animation-delay": (info: any, value: any) =>
|
||||
(info.delay = timeConverter(value)),
|
||||
"animation-timing-function": (info: any, value: any) =>
|
||||
(info.curve = animationTimingFunctionConverter(value)),
|
||||
"animation-iteration-count": (info: any, value: any) =>
|
||||
(info.iterations =
|
||||
value === "infinite" ? Number.MAX_VALUE : parseFloat(value)),
|
||||
"animation-direction": (info: any, value: any) =>
|
||||
(info.isReverse = value === "reverse"),
|
||||
"animation-fill-mode": (info: any, value: any) =>
|
||||
(info.isForwards = value === "forwards"),
|
||||
});
|
||||
|
||||
export class CssAnimationParser {
|
||||
public static keyframeAnimationsFromCSSDeclarations(declarations: KeyframeDeclaration[])
|
||||
: KeyframeAnimationInfo[] {
|
||||
public static keyframeAnimationsFromCSSDeclarations(
|
||||
declarations: KeyframeDeclaration[]
|
||||
): KeyframeAnimationInfo[] {
|
||||
if (declarations === null || declarations === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (declarations === null || declarations === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
let animations = new Array<KeyframeAnimationInfo>();
|
||||
let animationInfo: KeyframeAnimationInfo = undefined;
|
||||
|
||||
let animations = new Array<KeyframeAnimationInfo>();
|
||||
let animationInfo: KeyframeAnimationInfo = undefined;
|
||||
declarations.forEach(({ property, value }) => {
|
||||
if (property === "animation") {
|
||||
keyframeAnimationsFromCSSProperty(value, animations);
|
||||
} else {
|
||||
const propertyHandler = ANIMATION_PROPERTY_HANDLERS[property];
|
||||
if (propertyHandler) {
|
||||
if (animationInfo === undefined) {
|
||||
animationInfo = new KeyframeAnimationInfo();
|
||||
animations.push(animationInfo);
|
||||
}
|
||||
propertyHandler(animationInfo, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
declarations.forEach(({ property, value }) => {
|
||||
if (property === "animation") {
|
||||
keyframeAnimationsFromCSSProperty(value, animations);
|
||||
} else {
|
||||
const propertyHandler = ANIMATION_PROPERTY_HANDLERS[property];
|
||||
if (propertyHandler) {
|
||||
if (animationInfo === undefined) {
|
||||
animationInfo = new KeyframeAnimationInfo();
|
||||
animations.push(animationInfo);
|
||||
}
|
||||
propertyHandler(animationInfo, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
return animations.length === 0 ? undefined : animations;
|
||||
}
|
||||
|
||||
return animations.length === 0 ? undefined : animations;
|
||||
}
|
||||
public static keyframesArrayFromCSS(
|
||||
keyframes: UnparsedKeyframe[]
|
||||
): KeyframeInfo[] {
|
||||
let parsedKeyframes = new Array<KeyframeInfo>();
|
||||
for (let keyframe of keyframes) {
|
||||
let declarations = parseKeyframeDeclarations(keyframe.declarations);
|
||||
for (let time of keyframe.values) {
|
||||
if (time === "from") {
|
||||
time = 0;
|
||||
} else if (time === "to") {
|
||||
time = 1;
|
||||
} else {
|
||||
time = parseFloat(time) / 100;
|
||||
if (time < 0) {
|
||||
time = 0;
|
||||
}
|
||||
if (time > 100) {
|
||||
time = 100;
|
||||
}
|
||||
}
|
||||
let current = parsedKeyframes[time];
|
||||
if (current === undefined) {
|
||||
current = <KeyframeInfo>{};
|
||||
current.duration = time;
|
||||
parsedKeyframes[time] = current;
|
||||
}
|
||||
for (let declaration of keyframe.declarations) {
|
||||
if (declaration.property === "animation-timing-function") {
|
||||
current.curve = animationTimingFunctionConverter(
|
||||
declaration.value
|
||||
);
|
||||
}
|
||||
}
|
||||
current.declarations = declarations;
|
||||
}
|
||||
}
|
||||
let array = new Array();
|
||||
for (let parsedKeyframe in parsedKeyframes) {
|
||||
array.push(parsedKeyframes[parsedKeyframe]);
|
||||
}
|
||||
array.sort(function (a, b) {
|
||||
return a.duration - b.duration;
|
||||
});
|
||||
|
||||
public static keyframesArrayFromCSS(keyframes: UnparsedKeyframe[]): KeyframeInfo[] {
|
||||
let parsedKeyframes = new Array<KeyframeInfo>();
|
||||
for (let keyframe of keyframes) {
|
||||
let declarations = parseKeyframeDeclarations(keyframe.declarations);
|
||||
for (let time of keyframe.values) {
|
||||
if (time === "from") {
|
||||
time = 0;
|
||||
} else if (time === "to") {
|
||||
time = 1;
|
||||
} else {
|
||||
time = parseFloat(time) / 100;
|
||||
if (time < 0) {
|
||||
time = 0;
|
||||
}
|
||||
if (time > 100) {
|
||||
time = 100;
|
||||
}
|
||||
}
|
||||
let current = parsedKeyframes[time];
|
||||
if (current === undefined) {
|
||||
current = <KeyframeInfo>{};
|
||||
current.duration = time;
|
||||
parsedKeyframes[time] = current;
|
||||
}
|
||||
for (let declaration of keyframe.declarations) {
|
||||
if (declaration.property === "animation-timing-function") {
|
||||
current.curve = animationTimingFunctionConverter(declaration.value);
|
||||
}
|
||||
}
|
||||
current.declarations = declarations;
|
||||
}
|
||||
}
|
||||
let array = new Array();
|
||||
for (let parsedKeyframe in parsedKeyframes) {
|
||||
array.push(parsedKeyframes[parsedKeyframe]);
|
||||
}
|
||||
array.sort(function (a, b) { return a.duration - b.duration; });
|
||||
|
||||
return array;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
function keyframeAnimationsFromCSSProperty(value: any, animations: KeyframeAnimationInfo[]) {
|
||||
if (typeof value === "string") {
|
||||
let values = value.split(/[,]+/);
|
||||
for (let parsedValue of values) {
|
||||
let animationInfo = new KeyframeAnimationInfo();
|
||||
let arr = (<string>parsedValue).trim().split(/[ ]+/);
|
||||
function keyframeAnimationsFromCSSProperty(
|
||||
value: any,
|
||||
animations: KeyframeAnimationInfo[]
|
||||
) {
|
||||
if (typeof value === "string") {
|
||||
let values = value.split(/[,]+/);
|
||||
for (let parsedValue of values) {
|
||||
let animationInfo = new KeyframeAnimationInfo();
|
||||
let arr = (<string>parsedValue).trim().split(/[ ]+/);
|
||||
|
||||
if (arr.length > 0) {
|
||||
animationInfo.name = arr[0];
|
||||
}
|
||||
if (arr.length > 1) {
|
||||
animationInfo.duration = timeConverter(arr[1]);
|
||||
}
|
||||
if (arr.length > 2) {
|
||||
animationInfo.curve = animationTimingFunctionConverter(arr[2]);
|
||||
}
|
||||
if (arr.length > 3) {
|
||||
animationInfo.delay = timeConverter(arr[3]);
|
||||
}
|
||||
if (arr.length > 4) {
|
||||
animationInfo.iterations = parseInt(arr[4]);
|
||||
}
|
||||
if (arr.length > 5) {
|
||||
animationInfo.isReverse = arr[4] === "reverse";
|
||||
}
|
||||
if (arr.length > 6) {
|
||||
animationInfo.isForwards = arr[5] === "forwards";
|
||||
}
|
||||
if (arr.length > 7) {
|
||||
throw new Error("Invalid value for animation: " + value);
|
||||
}
|
||||
animations.push(animationInfo);
|
||||
}
|
||||
}
|
||||
if (arr.length > 0) {
|
||||
animationInfo.name = arr[0];
|
||||
}
|
||||
if (arr.length > 1) {
|
||||
animationInfo.duration = timeConverter(arr[1]);
|
||||
}
|
||||
if (arr.length > 2) {
|
||||
animationInfo.curve = animationTimingFunctionConverter(arr[2]);
|
||||
}
|
||||
if (arr.length > 3) {
|
||||
animationInfo.delay = timeConverter(arr[3]);
|
||||
}
|
||||
if (arr.length > 4) {
|
||||
animationInfo.iterations = parseInt(arr[4]);
|
||||
}
|
||||
if (arr.length > 5) {
|
||||
animationInfo.isReverse = arr[4] === "reverse";
|
||||
}
|
||||
if (arr.length > 6) {
|
||||
animationInfo.isForwards = arr[5] === "forwards";
|
||||
}
|
||||
if (arr.length > 7) {
|
||||
throw new Error("Invalid value for animation: " + value);
|
||||
}
|
||||
animations.push(animationInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function parseKeyframeDeclarations(unparsedKeyframeDeclarations: KeyframeDeclaration[]): KeyframeDeclaration[] {
|
||||
export function parseKeyframeDeclarations(
|
||||
unparsedKeyframeDeclarations: KeyframeDeclaration[]
|
||||
): KeyframeDeclaration[] {
|
||||
const declarations = unparsedKeyframeDeclarations.reduce(
|
||||
(
|
||||
declarations,
|
||||
{ property: unparsedProperty, value: unparsedValue }
|
||||
) => {
|
||||
const property = CssAnimationProperty._getByCssName(
|
||||
unparsedProperty
|
||||
);
|
||||
|
||||
const declarations = unparsedKeyframeDeclarations
|
||||
.reduce((declarations, { property: unparsedProperty, value: unparsedValue }) => {
|
||||
const property = CssAnimationProperty._getByCssName(unparsedProperty);
|
||||
if (
|
||||
typeof unparsedProperty === "string" &&
|
||||
property &&
|
||||
property._valueConverter
|
||||
) {
|
||||
declarations[property.name] = property._valueConverter(
|
||||
<string>unparsedValue
|
||||
);
|
||||
} else if (
|
||||
typeof unparsedValue === "string" &&
|
||||
unparsedProperty === "transform"
|
||||
) {
|
||||
const transformations = transformConverter(unparsedValue);
|
||||
Object.assign(declarations, transformations);
|
||||
}
|
||||
|
||||
if (typeof unparsedProperty === "string" && property && property._valueConverter) {
|
||||
declarations[property.name] = property._valueConverter(<string>unparsedValue);
|
||||
} else if (typeof unparsedValue === "string" && unparsedProperty === "transform") {
|
||||
const transformations = transformConverter(unparsedValue);
|
||||
Object.assign(declarations, transformations);
|
||||
}
|
||||
return declarations;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
return declarations;
|
||||
}, {});
|
||||
|
||||
return Object.keys(declarations).map(property => ({ property, value: declarations[property] }));
|
||||
return Object.keys(declarations).map((property) => ({
|
||||
property,
|
||||
value: declarations[property],
|
||||
}));
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,104 +5,128 @@ import { makeValidator, makeParser } from "../core/properties";
|
||||
export * from "./font-interfaces";
|
||||
|
||||
export abstract class Font implements FontDefinition {
|
||||
public static default = undefined;
|
||||
public static default = undefined;
|
||||
|
||||
get isItalic(): boolean {
|
||||
return this.fontStyle === FontStyle.ITALIC;
|
||||
}
|
||||
get isItalic(): boolean {
|
||||
return this.fontStyle === FontStyle.ITALIC;
|
||||
}
|
||||
|
||||
get isBold(): boolean {
|
||||
return this.fontWeight === FontWeight.SEMI_BOLD ||
|
||||
this.fontWeight === FontWeight.BOLD ||
|
||||
this.fontWeight === "700" ||
|
||||
this.fontWeight === FontWeight.EXTRA_BOLD ||
|
||||
this.fontWeight === FontWeight.BLACK;
|
||||
}
|
||||
get isBold(): boolean {
|
||||
return (
|
||||
this.fontWeight === FontWeight.SEMI_BOLD ||
|
||||
this.fontWeight === FontWeight.BOLD ||
|
||||
this.fontWeight === "700" ||
|
||||
this.fontWeight === FontWeight.EXTRA_BOLD ||
|
||||
this.fontWeight === FontWeight.BLACK
|
||||
);
|
||||
}
|
||||
|
||||
protected constructor(
|
||||
public readonly fontFamily: string,
|
||||
public readonly fontSize: number,
|
||||
public readonly fontStyle: FontStyle,
|
||||
public readonly fontWeight: FontWeight) {
|
||||
}
|
||||
protected constructor(
|
||||
public readonly fontFamily: string,
|
||||
public readonly fontSize: number,
|
||||
public readonly fontStyle: FontStyle,
|
||||
public readonly fontWeight: FontWeight
|
||||
) {}
|
||||
|
||||
public abstract getAndroidTypeface(): any /* android.graphics.Typeface */;
|
||||
public abstract getUIFont(defaultFont: any /* UIFont */): any /* UIFont */;
|
||||
public abstract withFontFamily(family: string): Font;
|
||||
public abstract withFontStyle(style: string): Font;
|
||||
public abstract withFontWeight(weight: string): Font;
|
||||
public abstract withFontSize(size: number): Font;
|
||||
public abstract getAndroidTypeface(): any /* android.graphics.Typeface */;
|
||||
public abstract getUIFont(defaultFont: any /* UIFont */): any /* UIFont */;
|
||||
public abstract withFontFamily(family: string): Font;
|
||||
public abstract withFontStyle(style: string): Font;
|
||||
public abstract withFontWeight(weight: string): Font;
|
||||
public abstract withFontSize(size: number): Font;
|
||||
|
||||
public static equals(value1: Font, value2: Font): boolean {
|
||||
// both values are falsy
|
||||
if (!value1 && !value2) {
|
||||
return true;
|
||||
}
|
||||
public static equals(value1: Font, value2: Font): boolean {
|
||||
// both values are falsy
|
||||
if (!value1 && !value2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// only one is falsy
|
||||
if (!value1 || !value2) {
|
||||
return false;
|
||||
}
|
||||
// only one is falsy
|
||||
if (!value1 || !value2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return value1.fontFamily === value2.fontFamily &&
|
||||
value1.fontSize === value2.fontSize &&
|
||||
value1.fontStyle === value2.fontStyle &&
|
||||
value1.fontWeight === value2.fontWeight;
|
||||
}
|
||||
return (
|
||||
value1.fontFamily === value2.fontFamily &&
|
||||
value1.fontSize === value2.fontSize &&
|
||||
value1.fontStyle === value2.fontStyle &&
|
||||
value1.fontWeight === value2.fontWeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export type FontStyle = "normal" | "italic";
|
||||
export namespace FontStyle {
|
||||
export const NORMAL: "normal" = "normal";
|
||||
export const ITALIC: "italic" = "italic";
|
||||
export const isValid = makeValidator<FontStyle>(NORMAL, ITALIC);
|
||||
export const parse = makeParser<FontStyle>(isValid);
|
||||
export const NORMAL: "normal" = "normal";
|
||||
export const ITALIC: "italic" = "italic";
|
||||
export const isValid = makeValidator<FontStyle>(NORMAL, ITALIC);
|
||||
export const parse = makeParser<FontStyle>(isValid);
|
||||
}
|
||||
|
||||
export type FontWeight = "100" | "200" | "300" | "normal" | "400" | "500" | "600" | "bold" | "700" | "800" | "900";
|
||||
export type FontWeight =
|
||||
| "100"
|
||||
| "200"
|
||||
| "300"
|
||||
| "normal"
|
||||
| "400"
|
||||
| "500"
|
||||
| "600"
|
||||
| "bold"
|
||||
| "700"
|
||||
| "800"
|
||||
| "900";
|
||||
export namespace FontWeight {
|
||||
export const THIN: "100" = "100";
|
||||
export const EXTRA_LIGHT: "200" = "200";
|
||||
export const LIGHT: "300" = "300";
|
||||
export const NORMAL: "normal" = "normal";
|
||||
export const MEDIUM: "500" = "500";
|
||||
export const SEMI_BOLD: "600" = "600";
|
||||
export const BOLD: "bold" = "bold";
|
||||
export const EXTRA_BOLD: "800" = "800";
|
||||
export const BLACK: "900" = "900";
|
||||
export const isValid = makeValidator<FontWeight>(THIN, EXTRA_LIGHT, LIGHT, NORMAL, "400", MEDIUM, SEMI_BOLD, BOLD, "700", EXTRA_BOLD, BLACK);
|
||||
export const parse = makeParser<FontStyle>(isValid);
|
||||
export const THIN: "100" = "100";
|
||||
export const EXTRA_LIGHT: "200" = "200";
|
||||
export const LIGHT: "300" = "300";
|
||||
export const NORMAL: "normal" = "normal";
|
||||
export const MEDIUM: "500" = "500";
|
||||
export const SEMI_BOLD: "600" = "600";
|
||||
export const BOLD: "bold" = "bold";
|
||||
export const EXTRA_BOLD: "800" = "800";
|
||||
export const BLACK: "900" = "900";
|
||||
export const isValid = makeValidator<FontWeight>(
|
||||
THIN,
|
||||
EXTRA_LIGHT,
|
||||
LIGHT,
|
||||
NORMAL,
|
||||
"400",
|
||||
MEDIUM,
|
||||
SEMI_BOLD,
|
||||
BOLD,
|
||||
"700",
|
||||
EXTRA_BOLD,
|
||||
BLACK
|
||||
);
|
||||
export const parse = makeParser<FontStyle>(isValid);
|
||||
}
|
||||
|
||||
export function parseFontFamily(value: string): Array<string> {
|
||||
const result = new Array<string>();
|
||||
if (!value) {
|
||||
return result;
|
||||
}
|
||||
const result = new Array<string>();
|
||||
if (!value) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const split = value.split(",");
|
||||
for (let i = 0; i < split.length; i++) {
|
||||
let str = split[i].trim().replace(/['"]+/g, "");
|
||||
if (str) {
|
||||
result.push(str);
|
||||
}
|
||||
}
|
||||
const split = value.split(",");
|
||||
for (let i = 0; i < split.length; i++) {
|
||||
let str = split[i].trim().replace(/['"]+/g, "");
|
||||
if (str) {
|
||||
result.push(str);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
export module genericFontFamilies {
|
||||
export const serif = "serif";
|
||||
export const sansSerif = "sans-serif";
|
||||
export const monospace = "monospace";
|
||||
export const system = "system";
|
||||
export const serif = "serif";
|
||||
export const sansSerif = "sans-serif";
|
||||
export const monospace = "monospace";
|
||||
export const system = "system";
|
||||
}
|
||||
|
||||
const styles = new Set();
|
||||
[
|
||||
FontStyle.NORMAL,
|
||||
FontStyle.ITALIC
|
||||
].forEach((val, i, a) => styles.add(val));
|
||||
[FontStyle.NORMAL, FontStyle.ITALIC].forEach((val, i, a) => styles.add(val));
|
||||
|
||||
// http://www.w3schools.com/cssref/pr_font_weight.asp
|
||||
//- normal(same as 400)
|
||||
@@ -118,55 +142,50 @@ const styles = new Set();
|
||||
//- 900(Black / Heavy) (API21 -black)
|
||||
const weights = new Set();
|
||||
[
|
||||
FontWeight.THIN,
|
||||
FontWeight.EXTRA_LIGHT,
|
||||
FontWeight.LIGHT,
|
||||
FontWeight.NORMAL,
|
||||
"400",
|
||||
FontWeight.MEDIUM,
|
||||
FontWeight.SEMI_BOLD,
|
||||
FontWeight.BOLD,
|
||||
"700",
|
||||
FontWeight.EXTRA_BOLD,
|
||||
FontWeight.BLACK
|
||||
FontWeight.THIN,
|
||||
FontWeight.EXTRA_LIGHT,
|
||||
FontWeight.LIGHT,
|
||||
FontWeight.NORMAL,
|
||||
"400",
|
||||
FontWeight.MEDIUM,
|
||||
FontWeight.SEMI_BOLD,
|
||||
FontWeight.BOLD,
|
||||
"700",
|
||||
FontWeight.EXTRA_BOLD,
|
||||
FontWeight.BLACK,
|
||||
].forEach((val, i, a) => weights.add(val));
|
||||
|
||||
export function parseFont(fontValue: string): ParsedFont {
|
||||
let result: ParsedFont = {
|
||||
fontStyle: "normal",
|
||||
fontVariant: "normal",
|
||||
fontWeight: "normal"
|
||||
};
|
||||
let result: ParsedFont = {
|
||||
fontStyle: "normal",
|
||||
fontVariant: "normal",
|
||||
fontWeight: "normal",
|
||||
};
|
||||
|
||||
const parts = fontValue.split(/\s+/);
|
||||
let part: string;
|
||||
while (part = parts.shift()) {
|
||||
if (part === "normal") {
|
||||
// nothing to do here
|
||||
}
|
||||
else if (part === "small-caps") {
|
||||
// The only supported font variant in shorthand font
|
||||
result.fontVariant = part;
|
||||
}
|
||||
else if (styles.has(part)) {
|
||||
result.fontStyle = <any>part;
|
||||
}
|
||||
else if (weights.has(part)) {
|
||||
result.fontWeight = <any>part;
|
||||
}
|
||||
else if (!result.fontSize) {
|
||||
let sizes = part.split("/");
|
||||
result.fontSize = sizes[0];
|
||||
result.lineHeight = sizes.length > 1 ? sizes[1] : undefined;
|
||||
}
|
||||
else {
|
||||
result.fontFamily = part;
|
||||
if (parts.length) {
|
||||
result.fontFamily += " " + parts.join(" ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
const parts = fontValue.split(/\s+/);
|
||||
let part: string;
|
||||
while ((part = parts.shift())) {
|
||||
if (part === "normal") {
|
||||
// nothing to do here
|
||||
} else if (part === "small-caps") {
|
||||
// The only supported font variant in shorthand font
|
||||
result.fontVariant = part;
|
||||
} else if (styles.has(part)) {
|
||||
result.fontStyle = <any>part;
|
||||
} else if (weights.has(part)) {
|
||||
result.fontWeight = <any>part;
|
||||
} else if (!result.fontSize) {
|
||||
let sizes = part.split("/");
|
||||
result.fontSize = sizes[0];
|
||||
result.lineHeight = sizes.length > 1 ? sizes[1] : undefined;
|
||||
} else {
|
||||
result.fontFamily = part;
|
||||
if (parts.length) {
|
||||
result.fontFamily += " " + parts.join(" ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
export type FontStyle = "normal" | "italic";
|
||||
|
||||
export type FontWeight = "100" | "200" | "300" | "normal" | "400" | "500" | "600" | "bold" | "700" | "800" | "900";
|
||||
export type FontWeight =
|
||||
| "100"
|
||||
| "200"
|
||||
| "300"
|
||||
| "normal"
|
||||
| "400"
|
||||
| "500"
|
||||
| "600"
|
||||
| "bold"
|
||||
| "700"
|
||||
| "800"
|
||||
| "900";
|
||||
|
||||
export interface ParsedFont {
|
||||
fontStyle?: FontStyle;
|
||||
fontVariant?: string;
|
||||
fontWeight?: FontWeight;
|
||||
lineHeight?: string;
|
||||
fontSize?: string;
|
||||
fontFamily?: string;
|
||||
fontStyle?: FontStyle;
|
||||
fontVariant?: string;
|
||||
fontWeight?: FontWeight;
|
||||
lineHeight?: string;
|
||||
fontSize?: string;
|
||||
fontFamily?: string;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { Font as FontBase, parseFontFamily, genericFontFamilies, FontWeight } from "./font-common";
|
||||
import {
|
||||
Font as FontBase,
|
||||
parseFontFamily,
|
||||
genericFontFamilies,
|
||||
FontWeight,
|
||||
} from "./font-common";
|
||||
import { Trace } from "../../trace";
|
||||
import * as application from "../../application";
|
||||
import * as fs from "../../file-system";
|
||||
@@ -10,154 +15,189 @@ const typefaceCache = new Map<string, android.graphics.Typeface>();
|
||||
let appAssets: android.content.res.AssetManager;
|
||||
|
||||
export class Font extends FontBase {
|
||||
public static default = new Font(undefined, undefined, "normal", "normal");
|
||||
public static default = new Font(undefined, undefined, "normal", "normal");
|
||||
|
||||
private _typeface: android.graphics.Typeface;
|
||||
private _typeface: android.graphics.Typeface;
|
||||
|
||||
constructor(family: string, size: number, style: "normal" | "italic", weight: FontWeight) {
|
||||
super(family, size, style, weight);
|
||||
}
|
||||
constructor(
|
||||
family: string,
|
||||
size: number,
|
||||
style: "normal" | "italic",
|
||||
weight: FontWeight
|
||||
) {
|
||||
super(family, size, style, weight);
|
||||
}
|
||||
|
||||
public withFontFamily(family: string): Font {
|
||||
return new Font(family, this.fontSize, this.fontStyle, this.fontWeight);
|
||||
}
|
||||
public withFontFamily(family: string): Font {
|
||||
return new Font(family, this.fontSize, this.fontStyle, this.fontWeight);
|
||||
}
|
||||
|
||||
public withFontStyle(style: "normal" | "italic"): Font {
|
||||
return new Font(this.fontFamily, this.fontSize, style, this.fontWeight);
|
||||
}
|
||||
public withFontStyle(style: "normal" | "italic"): Font {
|
||||
return new Font(this.fontFamily, this.fontSize, style, this.fontWeight);
|
||||
}
|
||||
|
||||
public withFontWeight(weight: FontWeight): Font {
|
||||
return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight);
|
||||
}
|
||||
public withFontWeight(weight: FontWeight): Font {
|
||||
return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight);
|
||||
}
|
||||
|
||||
public withFontSize(size: number): Font {
|
||||
return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight);
|
||||
}
|
||||
public withFontSize(size: number): Font {
|
||||
return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight);
|
||||
}
|
||||
|
||||
public getAndroidTypeface(): android.graphics.Typeface {
|
||||
if (!this._typeface) {
|
||||
this._typeface = createTypeface(this);
|
||||
}
|
||||
public getAndroidTypeface(): android.graphics.Typeface {
|
||||
if (!this._typeface) {
|
||||
this._typeface = createTypeface(this);
|
||||
}
|
||||
|
||||
return this._typeface;
|
||||
}
|
||||
return this._typeface;
|
||||
}
|
||||
|
||||
public getUIFont(defaultFont: UIFont): UIFont {
|
||||
return undefined;
|
||||
}
|
||||
public getUIFont(defaultFont: UIFont): UIFont {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function loadFontFromFile(fontFamily: string): android.graphics.Typeface {
|
||||
appAssets = appAssets || application.android.context.getAssets();
|
||||
if (!appAssets) {
|
||||
return null;
|
||||
}
|
||||
appAssets = appAssets || application.android.context.getAssets();
|
||||
if (!appAssets) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let result = typefaceCache.get(fontFamily);
|
||||
// Check for undefined explicitly as null mean we tried to load the font, but failed.
|
||||
if (result === undefined) {
|
||||
result = null;
|
||||
let result = typefaceCache.get(fontFamily);
|
||||
// Check for undefined explicitly as null mean we tried to load the font, but failed.
|
||||
if (result === undefined) {
|
||||
result = null;
|
||||
|
||||
let fontAssetPath: string;
|
||||
const basePath = fs.path.join(fs.knownFolders.currentApp().path, "fonts", fontFamily);
|
||||
if (fs.File.exists(basePath + ".ttf")) {
|
||||
fontAssetPath = FONTS_BASE_PATH + fontFamily + ".ttf";
|
||||
}
|
||||
else if (fs.File.exists(basePath + ".otf")) {
|
||||
fontAssetPath = FONTS_BASE_PATH + fontFamily + ".otf";
|
||||
}
|
||||
else {
|
||||
if (Trace.isEnabled()) {
|
||||
Trace.write("Could not find font file for " + fontFamily, Trace.categories.Error, Trace.messageType.error);
|
||||
}
|
||||
}
|
||||
let fontAssetPath: string;
|
||||
const basePath = fs.path.join(
|
||||
fs.knownFolders.currentApp().path,
|
||||
"fonts",
|
||||
fontFamily
|
||||
);
|
||||
if (fs.File.exists(basePath + ".ttf")) {
|
||||
fontAssetPath = FONTS_BASE_PATH + fontFamily + ".ttf";
|
||||
} else if (fs.File.exists(basePath + ".otf")) {
|
||||
fontAssetPath = FONTS_BASE_PATH + fontFamily + ".otf";
|
||||
} else {
|
||||
if (Trace.isEnabled()) {
|
||||
Trace.write(
|
||||
"Could not find font file for " + fontFamily,
|
||||
Trace.categories.Error,
|
||||
Trace.messageType.error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (fontAssetPath) {
|
||||
try {
|
||||
fontAssetPath = fs.path.join(fs.knownFolders.currentApp().path, fontAssetPath);
|
||||
result = android.graphics.Typeface.createFromFile(fontAssetPath);
|
||||
} catch (e) {
|
||||
if (Trace.isEnabled()) {
|
||||
Trace.write("Error loading font asset: " + fontAssetPath, Trace.categories.Error, Trace.messageType.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
typefaceCache.set(fontFamily, result);
|
||||
}
|
||||
if (fontAssetPath) {
|
||||
try {
|
||||
fontAssetPath = fs.path.join(
|
||||
fs.knownFolders.currentApp().path,
|
||||
fontAssetPath
|
||||
);
|
||||
result = android.graphics.Typeface.createFromFile(
|
||||
fontAssetPath
|
||||
);
|
||||
} catch (e) {
|
||||
if (Trace.isEnabled()) {
|
||||
Trace.write(
|
||||
"Error loading font asset: " + fontAssetPath,
|
||||
Trace.categories.Error,
|
||||
Trace.messageType.error
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
typefaceCache.set(fontFamily, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function createTypeface(font: Font): android.graphics.Typeface {
|
||||
let fontStyle = 0;
|
||||
if (font.isBold) {
|
||||
fontStyle |= android.graphics.Typeface.BOLD;
|
||||
}
|
||||
if (font.isItalic) {
|
||||
fontStyle |= android.graphics.Typeface.ITALIC;
|
||||
}
|
||||
let fontStyle = 0;
|
||||
if (font.isBold) {
|
||||
fontStyle |= android.graphics.Typeface.BOLD;
|
||||
}
|
||||
if (font.isItalic) {
|
||||
fontStyle |= android.graphics.Typeface.ITALIC;
|
||||
}
|
||||
|
||||
//http://stackoverflow.com/questions/19691530/valid-values-for-androidfontfamily-and-what-they-map-to
|
||||
const fonts = parseFontFamily(font.fontFamily);
|
||||
let result = null;
|
||||
for (let i = 0; i < fonts.length; i++) {
|
||||
switch (fonts[i].toLowerCase()) {
|
||||
case genericFontFamilies.serif:
|
||||
result = android.graphics.Typeface.create("serif" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
||||
break;
|
||||
//http://stackoverflow.com/questions/19691530/valid-values-for-androidfontfamily-and-what-they-map-to
|
||||
const fonts = parseFontFamily(font.fontFamily);
|
||||
let result = null;
|
||||
for (let i = 0; i < fonts.length; i++) {
|
||||
switch (fonts[i].toLowerCase()) {
|
||||
case genericFontFamilies.serif:
|
||||
result = android.graphics.Typeface.create(
|
||||
"serif" + getFontWeightSuffix(font.fontWeight),
|
||||
fontStyle
|
||||
);
|
||||
break;
|
||||
|
||||
case genericFontFamilies.sansSerif:
|
||||
case genericFontFamilies.system:
|
||||
result = android.graphics.Typeface.create("sans-serif" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
||||
break;
|
||||
case genericFontFamilies.sansSerif:
|
||||
case genericFontFamilies.system:
|
||||
result = android.graphics.Typeface.create(
|
||||
"sans-serif" + getFontWeightSuffix(font.fontWeight),
|
||||
fontStyle
|
||||
);
|
||||
break;
|
||||
|
||||
case genericFontFamilies.monospace:
|
||||
result = android.graphics.Typeface.create("monospace" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
||||
break;
|
||||
case genericFontFamilies.monospace:
|
||||
result = android.graphics.Typeface.create(
|
||||
"monospace" + getFontWeightSuffix(font.fontWeight),
|
||||
fontStyle
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
result = loadFontFromFile(fonts[i]);
|
||||
if (result && fontStyle) {
|
||||
result = android.graphics.Typeface.create(result, fontStyle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result = loadFontFromFile(fonts[i]);
|
||||
if (result && fontStyle) {
|
||||
result = android.graphics.Typeface.create(
|
||||
result,
|
||||
fontStyle
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
// Found the font!
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
// Found the font!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
result = android.graphics.Typeface.create("sans-serif" + getFontWeightSuffix(font.fontWeight), fontStyle);
|
||||
}
|
||||
if (!result) {
|
||||
result = android.graphics.Typeface.create(
|
||||
"sans-serif" + getFontWeightSuffix(font.fontWeight),
|
||||
fontStyle
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getFontWeightSuffix(fontWeight: FontWeight): string {
|
||||
switch (fontWeight) {
|
||||
case FontWeight.THIN:
|
||||
return android.os.Build.VERSION.SDK_INT >= 16 ? "-thin" : "";
|
||||
case FontWeight.EXTRA_LIGHT:
|
||||
case FontWeight.LIGHT:
|
||||
return android.os.Build.VERSION.SDK_INT >= 16 ? "-light" : "";
|
||||
case FontWeight.NORMAL:
|
||||
case "400":
|
||||
case undefined:
|
||||
case null:
|
||||
return "";
|
||||
case FontWeight.MEDIUM:
|
||||
case FontWeight.SEMI_BOLD:
|
||||
return android.os.Build.VERSION.SDK_INT >= 21 ? "-medium" : "";
|
||||
case FontWeight.BOLD:
|
||||
case "700":
|
||||
case FontWeight.EXTRA_BOLD:
|
||||
return "";
|
||||
case FontWeight.BLACK:
|
||||
return android.os.Build.VERSION.SDK_INT >= 21 ? "-black" : "";
|
||||
default:
|
||||
throw new Error(`Invalid font weight: "${fontWeight}"`);
|
||||
}
|
||||
switch (fontWeight) {
|
||||
case FontWeight.THIN:
|
||||
return android.os.Build.VERSION.SDK_INT >= 16 ? "-thin" : "";
|
||||
case FontWeight.EXTRA_LIGHT:
|
||||
case FontWeight.LIGHT:
|
||||
return android.os.Build.VERSION.SDK_INT >= 16 ? "-light" : "";
|
||||
case FontWeight.NORMAL:
|
||||
case "400":
|
||||
case undefined:
|
||||
case null:
|
||||
return "";
|
||||
case FontWeight.MEDIUM:
|
||||
case FontWeight.SEMI_BOLD:
|
||||
return android.os.Build.VERSION.SDK_INT >= 21 ? "-medium" : "";
|
||||
case FontWeight.BOLD:
|
||||
case "700":
|
||||
case FontWeight.EXTRA_BOLD:
|
||||
return "";
|
||||
case FontWeight.BLACK:
|
||||
return android.os.Build.VERSION.SDK_INT >= 21 ? "-black" : "";
|
||||
default:
|
||||
throw new Error(`Invalid font weight: "${fontWeight}"`);
|
||||
}
|
||||
}
|
||||
|
||||
92
nativescript-core/ui/styling/font.d.ts
vendored
92
nativescript-core/ui/styling/font.d.ts
vendored
@@ -1,61 +1,77 @@
|
||||
export class Font {
|
||||
public static default: Font;
|
||||
public static default: Font;
|
||||
|
||||
public fontFamily: string;
|
||||
public fontStyle: FontStyle;
|
||||
public fontWeight: FontWeight;
|
||||
public fontSize: number;
|
||||
public fontFamily: string;
|
||||
public fontStyle: FontStyle;
|
||||
public fontWeight: FontWeight;
|
||||
public fontSize: number;
|
||||
|
||||
public isBold: boolean;
|
||||
public isItalic: boolean;
|
||||
public isBold: boolean;
|
||||
public isItalic: boolean;
|
||||
|
||||
constructor(family: string, size: number, style: FontStyle, weight: FontWeight);
|
||||
constructor(
|
||||
family: string,
|
||||
size: number,
|
||||
style: FontStyle,
|
||||
weight: FontWeight
|
||||
);
|
||||
|
||||
public getAndroidTypeface(): any /* android.graphics.Typeface */;
|
||||
public getUIFont(defaultFont: any /* UIFont */): any /* UIFont */;
|
||||
public getAndroidTypeface(): any /* android.graphics.Typeface */;
|
||||
public getUIFont(defaultFont: any /* UIFont */): any /* UIFont */;
|
||||
|
||||
public withFontFamily(family: string): Font;
|
||||
public withFontStyle(style: string): Font;
|
||||
public withFontWeight(weight: string): Font;
|
||||
public withFontSize(size: number): Font;
|
||||
public withFontFamily(family: string): Font;
|
||||
public withFontStyle(style: string): Font;
|
||||
public withFontWeight(weight: string): Font;
|
||||
public withFontSize(size: number): Font;
|
||||
|
||||
public static equals(value1: Font, value2: Font): boolean;
|
||||
public static equals(value1: Font, value2: Font): boolean;
|
||||
}
|
||||
|
||||
export type FontStyle = "normal" | "italic";
|
||||
export namespace FontStyle {
|
||||
export const NORMAL: "normal";
|
||||
export const ITALIC: "italic";
|
||||
export function isValid(value: any): boolean;
|
||||
export function parse(value: string): FontStyle;
|
||||
export const NORMAL: "normal";
|
||||
export const ITALIC: "italic";
|
||||
export function isValid(value: any): boolean;
|
||||
export function parse(value: string): FontStyle;
|
||||
}
|
||||
|
||||
export type FontWeight = "100" | "200" | "300" | "normal" | "400" | "500" | "600" | "bold" | "700" | "800" | "900";
|
||||
export type FontWeight =
|
||||
| "100"
|
||||
| "200"
|
||||
| "300"
|
||||
| "normal"
|
||||
| "400"
|
||||
| "500"
|
||||
| "600"
|
||||
| "bold"
|
||||
| "700"
|
||||
| "800"
|
||||
| "900";
|
||||
export namespace FontWeight {
|
||||
export const THIN: "100";
|
||||
export const EXTRA_LIGHT: "200";
|
||||
export const LIGHT: "300";
|
||||
export const NORMAL: "normal";
|
||||
export const MEDIUM: "500";
|
||||
export const SEMI_BOLD: "600";
|
||||
export const BOLD: "bold";
|
||||
export const EXTRA_BOLD: "800";
|
||||
export const BLACK: "900";
|
||||
export function isValid(value: any): boolean;
|
||||
export function parse(value: string): FontWeight;
|
||||
export const THIN: "100";
|
||||
export const EXTRA_LIGHT: "200";
|
||||
export const LIGHT: "300";
|
||||
export const NORMAL: "normal";
|
||||
export const MEDIUM: "500";
|
||||
export const SEMI_BOLD: "600";
|
||||
export const BOLD: "bold";
|
||||
export const EXTRA_BOLD: "800";
|
||||
export const BLACK: "900";
|
||||
export function isValid(value: any): boolean;
|
||||
export function parse(value: string): FontWeight;
|
||||
}
|
||||
|
||||
export interface ParsedFont {
|
||||
fontStyle?: FontStyle;
|
||||
fontVariant?: string;
|
||||
fontWeight?: FontWeight,
|
||||
lineHeight?: string,
|
||||
fontSize?: string,
|
||||
fontFamily?: string
|
||||
fontStyle?: FontStyle;
|
||||
fontVariant?: string;
|
||||
fontWeight?: FontWeight;
|
||||
lineHeight?: string;
|
||||
fontSize?: string;
|
||||
fontFamily?: string;
|
||||
}
|
||||
|
||||
export function parseFont(fontValue: string): ParsedFont;
|
||||
|
||||
export module ios {
|
||||
export function registerFont(fontFile: string);
|
||||
export function registerFont(fontFile: string);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { Font as FontBase, parseFontFamily, genericFontFamilies, FontStyle, FontWeight } from "./font-common";
|
||||
import {
|
||||
Font as FontBase,
|
||||
parseFontFamily,
|
||||
genericFontFamilies,
|
||||
FontStyle,
|
||||
FontWeight,
|
||||
} from "./font-common";
|
||||
import { Trace } from "../../trace";
|
||||
import { device } from "../../platform";
|
||||
import * as fs from "../../file-system";
|
||||
@@ -11,216 +17,266 @@ const DEFAULT_MONOSPACE = "Courier New";
|
||||
const SUPPORT_FONT_WEIGHTS = parseFloat(device.osVersion) >= 10.0;
|
||||
|
||||
export class Font extends FontBase {
|
||||
public static default = new Font(undefined, undefined, FontStyle.NORMAL, FontWeight.NORMAL);
|
||||
public static default = new Font(
|
||||
undefined,
|
||||
undefined,
|
||||
FontStyle.NORMAL,
|
||||
FontWeight.NORMAL
|
||||
);
|
||||
|
||||
private _uiFont: UIFont;
|
||||
private _uiFont: UIFont;
|
||||
|
||||
constructor(family: string, size: number, style: FontStyle, weight: FontWeight) {
|
||||
super(family, size, style, weight);
|
||||
}
|
||||
constructor(
|
||||
family: string,
|
||||
size: number,
|
||||
style: FontStyle,
|
||||
weight: FontWeight
|
||||
) {
|
||||
super(family, size, style, weight);
|
||||
}
|
||||
|
||||
public withFontFamily(family: string): Font {
|
||||
return new Font(family, this.fontSize, this.fontStyle, this.fontWeight);
|
||||
}
|
||||
public withFontFamily(family: string): Font {
|
||||
return new Font(family, this.fontSize, this.fontStyle, this.fontWeight);
|
||||
}
|
||||
|
||||
public withFontStyle(style: FontStyle): Font {
|
||||
return new Font(this.fontFamily, this.fontSize, style, this.fontWeight);
|
||||
}
|
||||
public withFontStyle(style: FontStyle): Font {
|
||||
return new Font(this.fontFamily, this.fontSize, style, this.fontWeight);
|
||||
}
|
||||
|
||||
public withFontWeight(weight: FontWeight): Font {
|
||||
return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight);
|
||||
}
|
||||
public withFontWeight(weight: FontWeight): Font {
|
||||
return new Font(this.fontFamily, this.fontSize, this.fontStyle, weight);
|
||||
}
|
||||
|
||||
public withFontSize(size: number): Font {
|
||||
return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight);
|
||||
}
|
||||
public withFontSize(size: number): Font {
|
||||
return new Font(this.fontFamily, size, this.fontStyle, this.fontWeight);
|
||||
}
|
||||
|
||||
public getUIFont(defaultFont: UIFont): UIFont {
|
||||
if (!this._uiFont) {
|
||||
this._uiFont = createUIFont(this, defaultFont);
|
||||
}
|
||||
public getUIFont(defaultFont: UIFont): UIFont {
|
||||
if (!this._uiFont) {
|
||||
this._uiFont = createUIFont(this, defaultFont);
|
||||
}
|
||||
|
||||
return this._uiFont;
|
||||
}
|
||||
return this._uiFont;
|
||||
}
|
||||
|
||||
public getAndroidTypeface(): android.graphics.Typeface {
|
||||
return undefined;
|
||||
}
|
||||
public getAndroidTypeface(): android.graphics.Typeface {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function getFontFamilyRespectingGenericFonts(fontFamily: string): string {
|
||||
if (!fontFamily) {
|
||||
return fontFamily;
|
||||
}
|
||||
if (!fontFamily) {
|
||||
return fontFamily;
|
||||
}
|
||||
|
||||
switch (fontFamily.toLowerCase()) {
|
||||
case genericFontFamilies.serif:
|
||||
return DEFAULT_SERIF;
|
||||
switch (fontFamily.toLowerCase()) {
|
||||
case genericFontFamilies.serif:
|
||||
return DEFAULT_SERIF;
|
||||
|
||||
case genericFontFamilies.monospace:
|
||||
return DEFAULT_MONOSPACE;
|
||||
case genericFontFamilies.monospace:
|
||||
return DEFAULT_MONOSPACE;
|
||||
|
||||
default:
|
||||
return fontFamily;
|
||||
}
|
||||
default:
|
||||
return fontFamily;
|
||||
}
|
||||
}
|
||||
|
||||
function shouldUseSystemFont(fontFamily: string) {
|
||||
return !fontFamily ||
|
||||
fontFamily === genericFontFamilies.sansSerif ||
|
||||
fontFamily === genericFontFamilies.system;
|
||||
return (
|
||||
!fontFamily ||
|
||||
fontFamily === genericFontFamilies.sansSerif ||
|
||||
fontFamily === genericFontFamilies.system
|
||||
);
|
||||
}
|
||||
|
||||
function getNativeFontWeight(fontWeight: FontWeight): number {
|
||||
switch (fontWeight) {
|
||||
case FontWeight.THIN:
|
||||
return UIFontWeightUltraLight;
|
||||
case FontWeight.EXTRA_LIGHT:
|
||||
return UIFontWeightThin;
|
||||
case FontWeight.LIGHT:
|
||||
return UIFontWeightLight;
|
||||
case FontWeight.NORMAL:
|
||||
case "400":
|
||||
case undefined:
|
||||
case null:
|
||||
return UIFontWeightRegular;
|
||||
case FontWeight.MEDIUM:
|
||||
return UIFontWeightMedium;
|
||||
case FontWeight.SEMI_BOLD:
|
||||
return UIFontWeightSemibold;
|
||||
case FontWeight.BOLD:
|
||||
case "700":
|
||||
return UIFontWeightBold;
|
||||
case FontWeight.EXTRA_BOLD:
|
||||
return UIFontWeightHeavy;
|
||||
case FontWeight.BLACK:
|
||||
return UIFontWeightBlack;
|
||||
default:
|
||||
throw new Error(`Invalid font weight: "${fontWeight}"`);
|
||||
}
|
||||
switch (fontWeight) {
|
||||
case FontWeight.THIN:
|
||||
return UIFontWeightUltraLight;
|
||||
case FontWeight.EXTRA_LIGHT:
|
||||
return UIFontWeightThin;
|
||||
case FontWeight.LIGHT:
|
||||
return UIFontWeightLight;
|
||||
case FontWeight.NORMAL:
|
||||
case "400":
|
||||
case undefined:
|
||||
case null:
|
||||
return UIFontWeightRegular;
|
||||
case FontWeight.MEDIUM:
|
||||
return UIFontWeightMedium;
|
||||
case FontWeight.SEMI_BOLD:
|
||||
return UIFontWeightSemibold;
|
||||
case FontWeight.BOLD:
|
||||
case "700":
|
||||
return UIFontWeightBold;
|
||||
case FontWeight.EXTRA_BOLD:
|
||||
return UIFontWeightHeavy;
|
||||
case FontWeight.BLACK:
|
||||
return UIFontWeightBlack;
|
||||
default:
|
||||
throw new Error(`Invalid font weight: "${fontWeight}"`);
|
||||
}
|
||||
}
|
||||
|
||||
function getSystemFont(size: number, nativeWeight: number, italic: boolean, symbolicTraits: number): UIFont {
|
||||
let result = UIFont.systemFontOfSizeWeight(size, nativeWeight);
|
||||
if (italic) {
|
||||
let descriptor = result.fontDescriptor.fontDescriptorWithSymbolicTraits(symbolicTraits);
|
||||
result = UIFont.fontWithDescriptorSize(descriptor, size);
|
||||
}
|
||||
function getSystemFont(
|
||||
size: number,
|
||||
nativeWeight: number,
|
||||
italic: boolean,
|
||||
symbolicTraits: number
|
||||
): UIFont {
|
||||
let result = UIFont.systemFontOfSizeWeight(size, nativeWeight);
|
||||
if (italic) {
|
||||
let descriptor = result.fontDescriptor.fontDescriptorWithSymbolicTraits(
|
||||
symbolicTraits
|
||||
);
|
||||
result = UIFont.fontWithDescriptorSize(descriptor, size);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function createUIFont(font: Font, defaultFont: UIFont): UIFont {
|
||||
let result: UIFont;
|
||||
const size = font.fontSize || defaultFont.pointSize;
|
||||
const nativeWeight = getNativeFontWeight(font.fontWeight);
|
||||
const fontFamilies = parseFontFamily(font.fontFamily);
|
||||
let result: UIFont;
|
||||
const size = font.fontSize || defaultFont.pointSize;
|
||||
const nativeWeight = getNativeFontWeight(font.fontWeight);
|
||||
const fontFamilies = parseFontFamily(font.fontFamily);
|
||||
|
||||
let symbolicTraits: number = 0;
|
||||
if (font.isBold) {
|
||||
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitBold;
|
||||
}
|
||||
if (font.isItalic) {
|
||||
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitItalic;
|
||||
}
|
||||
let symbolicTraits: number = 0;
|
||||
if (font.isBold) {
|
||||
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitBold;
|
||||
}
|
||||
if (font.isItalic) {
|
||||
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitItalic;
|
||||
}
|
||||
|
||||
let fontDescriptorTraits = {
|
||||
[UIFontSymbolicTrait]: symbolicTraits
|
||||
};
|
||||
let fontDescriptorTraits = {
|
||||
[UIFontSymbolicTrait]: symbolicTraits,
|
||||
};
|
||||
|
||||
// IOS versions below 10 will not return the correct font when UIFontWeightTrait is set
|
||||
// In this case - rely on UIFontSymbolicTrait only
|
||||
if (SUPPORT_FONT_WEIGHTS) {
|
||||
fontDescriptorTraits[UIFontWeightTrait] = nativeWeight;
|
||||
}
|
||||
// IOS versions below 10 will not return the correct font when UIFontWeightTrait is set
|
||||
// In this case - rely on UIFontSymbolicTrait only
|
||||
if (SUPPORT_FONT_WEIGHTS) {
|
||||
fontDescriptorTraits[UIFontWeightTrait] = nativeWeight;
|
||||
}
|
||||
|
||||
for (let i = 0; i < fontFamilies.length; i++) {
|
||||
const fontFamily = getFontFamilyRespectingGenericFonts(fontFamilies[i]);
|
||||
for (let i = 0; i < fontFamilies.length; i++) {
|
||||
const fontFamily = getFontFamilyRespectingGenericFonts(fontFamilies[i]);
|
||||
|
||||
if (shouldUseSystemFont(fontFamily)) {
|
||||
result = getSystemFont(size, nativeWeight, font.isItalic, symbolicTraits);
|
||||
break;
|
||||
} else {
|
||||
const fontAttributes = {
|
||||
[UIFontDescriptorFamilyAttribute]: fontFamily,
|
||||
[UIFontDescriptorTraitsAttribute]: fontDescriptorTraits
|
||||
};
|
||||
if (shouldUseSystemFont(fontFamily)) {
|
||||
result = getSystemFont(
|
||||
size,
|
||||
nativeWeight,
|
||||
font.isItalic,
|
||||
symbolicTraits
|
||||
);
|
||||
break;
|
||||
} else {
|
||||
const fontAttributes = {
|
||||
[UIFontDescriptorFamilyAttribute]: fontFamily,
|
||||
[UIFontDescriptorTraitsAttribute]: fontDescriptorTraits,
|
||||
};
|
||||
|
||||
let descriptor = UIFontDescriptor.fontDescriptorWithFontAttributes(<any>fontAttributes);
|
||||
result = UIFont.fontWithDescriptorSize(descriptor, size);
|
||||
let descriptor = UIFontDescriptor.fontDescriptorWithFontAttributes(
|
||||
<any>fontAttributes
|
||||
);
|
||||
result = UIFont.fontWithDescriptorSize(descriptor, size);
|
||||
|
||||
let actualItalic = result.fontDescriptor.symbolicTraits & UIFontDescriptorSymbolicTraits.TraitItalic;
|
||||
if (font.isItalic && !actualItalic && EMULATE_OBLIQUE) {
|
||||
// The font we got is not actually italic so emulate that with a matrix
|
||||
descriptor = descriptor.fontDescriptorWithMatrix(OBLIQUE_TRANSFORM);
|
||||
result = UIFont.fontWithDescriptorSize(descriptor, size);
|
||||
}
|
||||
let actualItalic =
|
||||
result.fontDescriptor.symbolicTraits &
|
||||
UIFontDescriptorSymbolicTraits.TraitItalic;
|
||||
if (font.isItalic && !actualItalic && EMULATE_OBLIQUE) {
|
||||
// The font we got is not actually italic so emulate that with a matrix
|
||||
descriptor = descriptor.fontDescriptorWithMatrix(
|
||||
OBLIQUE_TRANSFORM
|
||||
);
|
||||
result = UIFont.fontWithDescriptorSize(descriptor, size);
|
||||
}
|
||||
|
||||
// Check if the resolved font has the correct font-family
|
||||
// If not - fallback to the next font-family
|
||||
if (result.familyName === fontFamily) {
|
||||
break;
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if the resolved font has the correct font-family
|
||||
// If not - fallback to the next font-family
|
||||
if (result.familyName === fontFamily) {
|
||||
break;
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't resolve font - fallback to the system font
|
||||
if (!result) {
|
||||
result = getSystemFont(size, nativeWeight, font.isItalic, symbolicTraits);
|
||||
}
|
||||
// Couldn't resolve font - fallback to the system font
|
||||
if (!result) {
|
||||
result = getSystemFont(
|
||||
size,
|
||||
nativeWeight,
|
||||
font.isItalic,
|
||||
symbolicTraits
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
export module ios {
|
||||
export function registerFont(fontFile: string) {
|
||||
let filePath = fs.path.join(fs.knownFolders.currentApp().path, "fonts", fontFile);
|
||||
if (!fs.File.exists(filePath)) {
|
||||
filePath = fs.path.join(fs.knownFolders.currentApp().path, fontFile);
|
||||
}
|
||||
const fontData = NSFileManager.defaultManager.contentsAtPath(filePath);
|
||||
if (!fontData) {
|
||||
throw new Error("Could not load font from: " + fontFile);
|
||||
}
|
||||
const provider = CGDataProviderCreateWithCFData(fontData);
|
||||
const font = CGFontCreateWithDataProvider(provider);
|
||||
export function registerFont(fontFile: string) {
|
||||
let filePath = fs.path.join(
|
||||
fs.knownFolders.currentApp().path,
|
||||
"fonts",
|
||||
fontFile
|
||||
);
|
||||
if (!fs.File.exists(filePath)) {
|
||||
filePath = fs.path.join(
|
||||
fs.knownFolders.currentApp().path,
|
||||
fontFile
|
||||
);
|
||||
}
|
||||
const fontData = NSFileManager.defaultManager.contentsAtPath(filePath);
|
||||
if (!fontData) {
|
||||
throw new Error("Could not load font from: " + fontFile);
|
||||
}
|
||||
const provider = CGDataProviderCreateWithCFData(fontData);
|
||||
const font = CGFontCreateWithDataProvider(provider);
|
||||
|
||||
if (!font) {
|
||||
throw new Error("Could not load font from: " + fontFile);
|
||||
}
|
||||
if (!font) {
|
||||
throw new Error("Could not load font from: " + fontFile);
|
||||
}
|
||||
|
||||
const error = new interop.Reference<NSError>();
|
||||
if (!CTFontManagerRegisterGraphicsFont(font, error)) {
|
||||
if (Trace.isEnabled()) {
|
||||
Trace.write("Error occur while registering font: " + CFErrorCopyDescription(<NSError>error.value), Trace.categories.Error, Trace.messageType.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
const error = new interop.Reference<NSError>();
|
||||
if (!CTFontManagerRegisterGraphicsFont(font, error)) {
|
||||
if (Trace.isEnabled()) {
|
||||
Trace.write(
|
||||
"Error occur while registering font: " +
|
||||
CFErrorCopyDescription(<NSError>error.value),
|
||||
Trace.categories.Error,
|
||||
Trace.messageType.error
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function registerFontsInFolder(fontsFolderPath) {
|
||||
const fontsFolder = fs.Folder.fromPath(fontsFolderPath);
|
||||
const fontsFolder = fs.Folder.fromPath(fontsFolderPath);
|
||||
|
||||
fontsFolder.eachEntity((fileEntity: fs.FileSystemEntity) => {
|
||||
if (fs.Folder.exists(fs.path.join(fontsFolderPath, fileEntity.name))) {
|
||||
return true;
|
||||
}
|
||||
if (fileEntity instanceof fs.File &&
|
||||
((<fs.File>fileEntity).extension === ".ttf" || (<fs.File>fileEntity).extension === ".otf")) {
|
||||
ios.registerFont(fileEntity.name);
|
||||
}
|
||||
fontsFolder.eachEntity((fileEntity: fs.FileSystemEntity) => {
|
||||
if (fs.Folder.exists(fs.path.join(fontsFolderPath, fileEntity.name))) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
fileEntity instanceof fs.File &&
|
||||
((<fs.File>fileEntity).extension === ".ttf" ||
|
||||
(<fs.File>fileEntity).extension === ".otf")
|
||||
) {
|
||||
ios.registerFont(fileEntity.name);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
function registerCustomFonts() {
|
||||
const appDir = fs.knownFolders.currentApp().path;
|
||||
const fontsDir = fs.path.join(appDir, "fonts");
|
||||
if (fs.Folder.exists(fontsDir)) {
|
||||
registerFontsInFolder(fontsDir);
|
||||
}
|
||||
const appDir = fs.knownFolders.currentApp().path;
|
||||
const fontsDir = fs.path.join(appDir, "fonts");
|
||||
if (fs.Folder.exists(fontsDir)) {
|
||||
registerFontsInFolder(fontsDir);
|
||||
}
|
||||
}
|
||||
registerCustomFonts();
|
||||
|
||||
17
nativescript-core/ui/styling/gradient.d.ts
vendored
17
nativescript-core/ui/styling/gradient.d.ts
vendored
@@ -3,15 +3,20 @@ import { Color } from "../../color";
|
||||
import { LinearGradient as LinearGradientDefinition } from "../../css/parser";
|
||||
|
||||
export class LinearGradient {
|
||||
public angle: number;
|
||||
public colorStops: ColorStop[];
|
||||
public angle: number;
|
||||
public colorStops: ColorStop[];
|
||||
|
||||
public static parse(value: LinearGradientDefinition): LinearGradientDefinition;
|
||||
public static parse(
|
||||
value: LinearGradientDefinition
|
||||
): LinearGradientDefinition;
|
||||
|
||||
public static equals(first: LinearGradientDefinition, second: LinearGradientDefinition): boolean;
|
||||
public static equals(
|
||||
first: LinearGradientDefinition,
|
||||
second: LinearGradientDefinition
|
||||
): boolean;
|
||||
}
|
||||
|
||||
export interface ColorStop {
|
||||
color: Color;
|
||||
offset?: LengthPercentUnit;
|
||||
color: Color;
|
||||
offset?: LengthPercentUnit;
|
||||
}
|
||||
|
||||
@@ -4,58 +4,61 @@ import { ColorStop } from "./gradient";
|
||||
import * as parser from "../../css/parser";
|
||||
|
||||
export class LinearGradient {
|
||||
public angle: number;
|
||||
public colorStops: ColorStop[];
|
||||
public angle: number;
|
||||
public colorStops: ColorStop[];
|
||||
|
||||
public static parse(value: parser.LinearGradient): LinearGradient {
|
||||
const result = new LinearGradient();
|
||||
result.angle = value.angle;
|
||||
result.colorStops = value.colors.map(color => {
|
||||
const offset = color.offset || null;
|
||||
let offsetUnit: LengthPercentUnit;
|
||||
public static parse(value: parser.LinearGradient): LinearGradient {
|
||||
const result = new LinearGradient();
|
||||
result.angle = value.angle;
|
||||
result.colorStops = value.colors.map((color) => {
|
||||
const offset = color.offset || null;
|
||||
let offsetUnit: LengthPercentUnit;
|
||||
|
||||
if (offset && offset.unit === "%") {
|
||||
offsetUnit = {
|
||||
unit: "%",
|
||||
value: offset.value
|
||||
};
|
||||
}
|
||||
if (offset && offset.unit === "%") {
|
||||
offsetUnit = {
|
||||
unit: "%",
|
||||
value: offset.value,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
color: new Color(color.argb),
|
||||
offset: offsetUnit
|
||||
};
|
||||
});
|
||||
return {
|
||||
color: new Color(color.argb),
|
||||
offset: offsetUnit,
|
||||
};
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static equals(first: LinearGradient, second: LinearGradient): boolean {
|
||||
if (!first && !second) {
|
||||
return true;
|
||||
} else if (!first || !second) {
|
||||
return false;
|
||||
}
|
||||
public static equals(
|
||||
first: LinearGradient,
|
||||
second: LinearGradient
|
||||
): boolean {
|
||||
if (!first && !second) {
|
||||
return true;
|
||||
} else if (!first || !second) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (first.angle !== second.angle) {
|
||||
return false;
|
||||
}
|
||||
if (first.angle !== second.angle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (first.colorStops.length !== second.colorStops.length) {
|
||||
return false;
|
||||
}
|
||||
if (first.colorStops.length !== second.colorStops.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < first.colorStops.length; i++) {
|
||||
const firstStop = first.colorStops[i];
|
||||
const secondStop = second.colorStops[i];
|
||||
if (firstStop.offset !== secondStop.offset) {
|
||||
return false;
|
||||
}
|
||||
if (!Color.equals(firstStop.color, secondStop.color)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < first.colorStops.length; i++) {
|
||||
const firstStop = first.colorStops[i];
|
||||
const secondStop = second.colorStops[i];
|
||||
if (firstStop.offset !== secondStop.offset) {
|
||||
return false;
|
||||
}
|
||||
if (!Color.equals(firstStop.color, secondStop.color)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +1,55 @@
|
||||
import { TransformFunctionsInfo } from "../animation/animation";
|
||||
import { Color } from "../../color";
|
||||
import { CssProperty, CssAnimationProperty, ShorthandProperty, InheritedCssProperty } from "../core/properties";
|
||||
import {
|
||||
CssProperty,
|
||||
CssAnimationProperty,
|
||||
ShorthandProperty,
|
||||
InheritedCssProperty,
|
||||
} from "../core/properties";
|
||||
import { Style } from "../styling/style";
|
||||
import { Font, FontStyle, FontWeight } from "./font";
|
||||
import { Background } from "./background";
|
||||
import { dip, px, percent } from "../core/view";
|
||||
|
||||
export type LengthDipUnit = { readonly unit: "dip", readonly value: dip };
|
||||
export type LengthPxUnit = { readonly unit: "px", readonly value: px };
|
||||
export type LengthPercentUnit = { readonly unit: "%", readonly value: percent };
|
||||
export type LengthDipUnit = { readonly unit: "dip"; readonly value: dip };
|
||||
export type LengthPxUnit = { readonly unit: "px"; readonly value: px };
|
||||
export type LengthPercentUnit = { readonly unit: "%"; readonly value: percent };
|
||||
|
||||
export type Length = "auto" | dip | LengthDipUnit | LengthPxUnit;
|
||||
export type PercentLength = "auto" | dip | LengthDipUnit | LengthPxUnit | LengthPercentUnit;
|
||||
export type PercentLength =
|
||||
| "auto"
|
||||
| dip
|
||||
| LengthDipUnit
|
||||
| LengthPxUnit
|
||||
| LengthPercentUnit;
|
||||
|
||||
export namespace Length {
|
||||
export function parse(text: string): Length;
|
||||
export function equals(a: Length, b: Length): boolean;
|
||||
/**
|
||||
* Converts Length unit to device pixels.
|
||||
* @param length The Length to convert.
|
||||
* @param auto Value to use for conversion of "auto". By default is Math.NaN.
|
||||
*/
|
||||
export function toDevicePixels(length: Length, auto?: number): number;
|
||||
export function convertToString(length: Length): string;
|
||||
export function parse(text: string): Length;
|
||||
export function equals(a: Length, b: Length): boolean;
|
||||
/**
|
||||
* Converts Length unit to device pixels.
|
||||
* @param length The Length to convert.
|
||||
* @param auto Value to use for conversion of "auto". By default is Math.NaN.
|
||||
*/
|
||||
export function toDevicePixels(length: Length, auto?: number): number;
|
||||
export function convertToString(length: Length): string;
|
||||
}
|
||||
|
||||
export namespace PercentLength {
|
||||
export function parse(text: string): PercentLength;
|
||||
export function equals(a: PercentLength, b: PercentLength): boolean;
|
||||
/**
|
||||
* Converts PercentLength unit to device pixels.
|
||||
* @param length The PercentLength to convert.
|
||||
* @param auto Value to use for conversion of "auto". By default is Math.NaN.
|
||||
* @param parentAvailableWidth Value to use as base when converting percent unit. By default is Math.NaN.
|
||||
*/
|
||||
export function toDevicePixels(length: PercentLength, auto?: number, parentAvailableWidth?: px): number;
|
||||
export function convertToString(length: PercentLength): string;
|
||||
export function parse(text: string): PercentLength;
|
||||
export function equals(a: PercentLength, b: PercentLength): boolean;
|
||||
/**
|
||||
* Converts PercentLength unit to device pixels.
|
||||
* @param length The PercentLength to convert.
|
||||
* @param auto Value to use for conversion of "auto". By default is Math.NaN.
|
||||
* @param parentAvailableWidth Value to use as base when converting percent unit. By default is Math.NaN.
|
||||
*/
|
||||
export function toDevicePixels(
|
||||
length: PercentLength,
|
||||
auto?: number,
|
||||
parentAvailableWidth?: px
|
||||
): number;
|
||||
export function convertToString(length: PercentLength): string;
|
||||
}
|
||||
|
||||
export const zeroLength: Length;
|
||||
@@ -80,8 +94,14 @@ export const zIndexProperty: CssProperty<Style, number>;
|
||||
export const visibilityProperty: CssProperty<Style, Visibility>;
|
||||
export const opacityProperty: CssAnimationProperty<Style, number>;
|
||||
|
||||
export const minWidthProperty: CssProperty<Style, dip | LengthDipUnit | LengthPxUnit>;
|
||||
export const minHeightProperty: CssProperty<Style, dip | LengthDipUnit | LengthPxUnit>;
|
||||
export const minWidthProperty: CssProperty<
|
||||
Style,
|
||||
dip | LengthDipUnit | LengthPxUnit
|
||||
>;
|
||||
export const minHeightProperty: CssProperty<
|
||||
Style,
|
||||
dip | LengthDipUnit | LengthPxUnit
|
||||
>;
|
||||
export const widthProperty: CssAnimationProperty<Style, PercentLength>;
|
||||
export const heightProperty: CssAnimationProperty<Style, PercentLength>;
|
||||
export const lineHeightProperty: CssProperty<Style, number>;
|
||||
@@ -97,7 +117,10 @@ export const paddingRightProperty: CssProperty<Style, Length>;
|
||||
export const paddingTopProperty: CssProperty<Style, Length>;
|
||||
export const paddingBottomProperty: CssProperty<Style, Length>;
|
||||
|
||||
export const horizontalAlignmentProperty: CssProperty<Style, HorizontalAlignment>;
|
||||
export const horizontalAlignmentProperty: CssProperty<
|
||||
Style,
|
||||
HorizontalAlignment
|
||||
>;
|
||||
export const verticalAlignmentProperty: CssProperty<Style, VerticalAlignment>;
|
||||
|
||||
export const fontSizeProperty: InheritedCssProperty<Style, number>;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
81
nativescript-core/ui/styling/style-scope.d.ts
vendored
81
nativescript-core/ui/styling/style-scope.d.ts
vendored
@@ -1,49 +1,68 @@
|
||||
//@private
|
||||
import { ViewBase } from "../core/view-base";
|
||||
import { SyntaxTree } from "../../css";
|
||||
import { RuleSet, Node, SelectorCore, ChangeMap } from "../styling/css-selector";
|
||||
import {
|
||||
RuleSet,
|
||||
Node,
|
||||
SelectorCore,
|
||||
ChangeMap,
|
||||
} from "../styling/css-selector";
|
||||
import { KeyframeAnimationInfo } from "../animation/keyframe-animation";
|
||||
|
||||
export class CssState {
|
||||
/**
|
||||
* Re-evaluate the selectors and apply any changes to the underlying view.
|
||||
*/
|
||||
public apply(): void;
|
||||
/**
|
||||
* Re-evaluate the selectors and apply any changes to the underlying view.
|
||||
*/
|
||||
public apply(): void;
|
||||
|
||||
/**
|
||||
* Gets the static selectors that match the view and the dynamic selectors that may potentially match the view.
|
||||
*/
|
||||
public changeMap: ChangeMap<ViewBase>;
|
||||
/**
|
||||
* Gets the static selectors that match the view and the dynamic selectors that may potentially match the view.
|
||||
*/
|
||||
public changeMap: ChangeMap<ViewBase>;
|
||||
|
||||
/**
|
||||
* Checks whether style scope and CSS state selectors are in sync.
|
||||
*/
|
||||
public isSelectorsLatestVersionApplied(): boolean
|
||||
/**
|
||||
* Checks whether style scope and CSS state selectors are in sync.
|
||||
*/
|
||||
public isSelectorsLatestVersionApplied(): boolean;
|
||||
}
|
||||
|
||||
export class StyleScope {
|
||||
public css: string;
|
||||
public addCss(cssString: string, cssFileName?: string): void;
|
||||
public addCssFile(cssFileName: string): void;
|
||||
public changeCssFile(cssFileName: string): void;
|
||||
public css: string;
|
||||
public addCss(cssString: string, cssFileName?: string): void;
|
||||
public addCssFile(cssFileName: string): void;
|
||||
public changeCssFile(cssFileName: string): void;
|
||||
|
||||
public static createSelectorsFromCss(css: string, cssFileName: string, keyframes: Object): RuleSet[];
|
||||
public static createSelectorsFromImports(tree: SyntaxTree, keyframes: Object): RuleSet[];
|
||||
public ensureSelectors(): number;
|
||||
public static createSelectorsFromCss(
|
||||
css: string,
|
||||
cssFileName: string,
|
||||
keyframes: Object
|
||||
): RuleSet[];
|
||||
public static createSelectorsFromImports(
|
||||
tree: SyntaxTree,
|
||||
keyframes: Object
|
||||
): RuleSet[];
|
||||
public ensureSelectors(): number;
|
||||
|
||||
/**
|
||||
* Increase the application CSS selector version.
|
||||
*/
|
||||
public _increaseApplicationCssSelectorVersion(): void;
|
||||
public isApplicationCssSelectorsLatestVersionApplied(): boolean;
|
||||
public isLocalCssSelectorsLatestVersionApplied(): boolean;
|
||||
/**
|
||||
* Increase the application CSS selector version.
|
||||
*/
|
||||
public _increaseApplicationCssSelectorVersion(): void;
|
||||
public isApplicationCssSelectorsLatestVersionApplied(): boolean;
|
||||
public isLocalCssSelectorsLatestVersionApplied(): boolean;
|
||||
|
||||
public applySelectors(view: ViewBase): void
|
||||
public query(options: Node): SelectorCore[];
|
||||
public applySelectors(view: ViewBase): void;
|
||||
public query(options: Node): SelectorCore[];
|
||||
|
||||
public getKeyframeAnimationWithName(animationName: string): KeyframeAnimationInfo;
|
||||
public getAnimations(ruleset: RuleSet): KeyframeAnimationInfo[];
|
||||
public getKeyframeAnimationWithName(
|
||||
animationName: string
|
||||
): KeyframeAnimationInfo;
|
||||
public getAnimations(ruleset: RuleSet): KeyframeAnimationInfo[];
|
||||
}
|
||||
|
||||
export function resolveFileNameFromUrl(url: string, appDirectory: string, fileExists: (string) => boolean, importSource?: string): string;
|
||||
export function resolveFileNameFromUrl(
|
||||
url: string,
|
||||
appDirectory: string,
|
||||
fileExists: (string) => boolean,
|
||||
importSource?: string
|
||||
): string;
|
||||
export function applyInlineStyle(view: ViewBase, style: string): void;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,235 +2,253 @@ import { Style as StyleDefinition } from ".";
|
||||
import { Color } from "../../../color";
|
||||
import { Font, FontStyle, FontWeight } from "../font";
|
||||
import { Background } from "../background";
|
||||
import { dip } from "../../core/view";
|
||||
import { ViewBase } from "../../core/view-base";
|
||||
import {
|
||||
dip
|
||||
} from "../../core/view";
|
||||
import {
|
||||
ViewBase
|
||||
} from "../../core/view-base";
|
||||
import {
|
||||
Length, PercentLength,
|
||||
HorizontalAlignment, VerticalAlignment, BackgroundRepeat, Visibility
|
||||
Length,
|
||||
PercentLength,
|
||||
HorizontalAlignment,
|
||||
VerticalAlignment,
|
||||
BackgroundRepeat,
|
||||
Visibility,
|
||||
} from "../../styling/style-properties";
|
||||
import {
|
||||
LinearGradient
|
||||
} from "../../styling/linear-gradient";
|
||||
import { LinearGradient } from "../../styling/linear-gradient";
|
||||
import { Observable } from "../../../data/observable";
|
||||
|
||||
import {
|
||||
FlexDirection, FlexWrap, JustifyContent, AlignItems, AlignContent,
|
||||
Order, FlexGrow, FlexShrink, FlexWrapBefore, AlignSelf
|
||||
FlexDirection,
|
||||
FlexWrap,
|
||||
JustifyContent,
|
||||
AlignItems,
|
||||
AlignContent,
|
||||
Order,
|
||||
FlexGrow,
|
||||
FlexShrink,
|
||||
FlexWrapBefore,
|
||||
AlignSelf,
|
||||
} from "../../layouts/flexbox-layout";
|
||||
import { Trace } from "../../../trace";
|
||||
import {
|
||||
Trace
|
||||
} from "../../../trace";
|
||||
import { TextAlignment, TextDecoration, TextTransform, WhiteSpace } from "../../text-base";
|
||||
TextAlignment,
|
||||
TextDecoration,
|
||||
TextTransform,
|
||||
WhiteSpace,
|
||||
} from "../../text-base";
|
||||
|
||||
export interface CommonLayoutParams {
|
||||
width: number;
|
||||
height: number;
|
||||
width: number;
|
||||
height: number;
|
||||
|
||||
widthPercent: number;
|
||||
heightPercent: number;
|
||||
widthPercent: number;
|
||||
heightPercent: number;
|
||||
|
||||
leftMargin: number;
|
||||
topMargin: number;
|
||||
rightMargin: number;
|
||||
bottomMargin: number;
|
||||
leftMargin: number;
|
||||
topMargin: number;
|
||||
rightMargin: number;
|
||||
bottomMargin: number;
|
||||
|
||||
leftMarginPercent: number;
|
||||
topMarginPercent: number;
|
||||
rightMarginPercent: number;
|
||||
bottomMarginPercent: number;
|
||||
leftMarginPercent: number;
|
||||
topMarginPercent: number;
|
||||
rightMarginPercent: number;
|
||||
bottomMarginPercent: number;
|
||||
|
||||
horizontalAlignment: HorizontalAlignment;
|
||||
verticalAlignment: VerticalAlignment;
|
||||
horizontalAlignment: HorizontalAlignment;
|
||||
verticalAlignment: VerticalAlignment;
|
||||
}
|
||||
|
||||
export class Style extends Observable implements StyleDefinition {
|
||||
private unscopedCssVariables = new Map<string, string>();
|
||||
private scopedCssVariables = new Map<string, string>();
|
||||
private unscopedCssVariables = new Map<string, string>();
|
||||
private scopedCssVariables = new Map<string, string>();
|
||||
|
||||
constructor(ownerView: ViewBase | WeakRef<ViewBase>) {
|
||||
super();
|
||||
constructor(ownerView: ViewBase | WeakRef<ViewBase>) {
|
||||
super();
|
||||
|
||||
// HACK: Could not find better way for cross platform WeakRef type checking.
|
||||
if (ownerView.constructor.toString().indexOf("[native code]") !== -1) {
|
||||
this.viewRef = <WeakRef<ViewBase>>ownerView;
|
||||
} else {
|
||||
this.viewRef = new WeakRef(<ViewBase>ownerView);
|
||||
}
|
||||
}
|
||||
// HACK: Could not find better way for cross platform WeakRef type checking.
|
||||
if (ownerView.constructor.toString().indexOf("[native code]") !== -1) {
|
||||
this.viewRef = <WeakRef<ViewBase>>ownerView;
|
||||
} else {
|
||||
this.viewRef = new WeakRef(<ViewBase>ownerView);
|
||||
}
|
||||
}
|
||||
|
||||
public setScopedCssVariable(varName: string, value: string): void {
|
||||
this.scopedCssVariables.set(varName, value);
|
||||
}
|
||||
public setScopedCssVariable(varName: string, value: string): void {
|
||||
this.scopedCssVariables.set(varName, value);
|
||||
}
|
||||
|
||||
public setUnscopedCssVariable(varName: string, value: string): void {
|
||||
this.unscopedCssVariables.set(varName, value);
|
||||
}
|
||||
public setUnscopedCssVariable(varName: string, value: string): void {
|
||||
this.unscopedCssVariables.set(varName, value);
|
||||
}
|
||||
|
||||
public getCssVariable(varName: string): string | null {
|
||||
const view = this.view;
|
||||
if (!view) {
|
||||
return null;
|
||||
}
|
||||
public getCssVariable(varName: string): string | null {
|
||||
const view = this.view;
|
||||
if (!view) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.unscopedCssVariables.has(varName)) {
|
||||
return this.unscopedCssVariables.get(varName);
|
||||
}
|
||||
if (this.unscopedCssVariables.has(varName)) {
|
||||
return this.unscopedCssVariables.get(varName);
|
||||
}
|
||||
|
||||
if (this.scopedCssVariables.has(varName)) {
|
||||
return this.scopedCssVariables.get(varName);
|
||||
}
|
||||
if (this.scopedCssVariables.has(varName)) {
|
||||
return this.scopedCssVariables.get(varName);
|
||||
}
|
||||
|
||||
if (!view.parent || !view.parent.style) {
|
||||
return null;
|
||||
}
|
||||
if (!view.parent || !view.parent.style) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return view.parent.style.getCssVariable(varName);
|
||||
}
|
||||
return view.parent.style.getCssVariable(varName);
|
||||
}
|
||||
|
||||
public resetScopedCssVariables() {
|
||||
this.scopedCssVariables.clear();
|
||||
}
|
||||
public resetScopedCssVariables() {
|
||||
this.scopedCssVariables.clear();
|
||||
}
|
||||
|
||||
public resetUnscopedCssVariables() {
|
||||
this.unscopedCssVariables.clear();
|
||||
}
|
||||
public resetUnscopedCssVariables() {
|
||||
this.unscopedCssVariables.clear();
|
||||
}
|
||||
|
||||
toString() {
|
||||
const view = this.viewRef.get();
|
||||
if (!view) {
|
||||
Trace.write(`toString() of Style cannot execute correctly because ".viewRef" is cleared`, Trace.categories.Animation, Trace.messageType.warn);
|
||||
toString() {
|
||||
const view = this.viewRef.get();
|
||||
if (!view) {
|
||||
Trace.write(
|
||||
`toString() of Style cannot execute correctly because ".viewRef" is cleared`,
|
||||
Trace.categories.Animation,
|
||||
Trace.messageType.warn
|
||||
);
|
||||
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
return `${view}.style`;
|
||||
}
|
||||
return `${view}.style`;
|
||||
}
|
||||
|
||||
public fontInternal: Font;
|
||||
public backgroundInternal: Background;
|
||||
public fontInternal: Font;
|
||||
public backgroundInternal: Background;
|
||||
|
||||
public rotate: number;
|
||||
public rotateX: number;
|
||||
public rotateY: number;
|
||||
public perspective: number;
|
||||
public rotate: number;
|
||||
public rotateX: number;
|
||||
public rotateY: number;
|
||||
public perspective: number;
|
||||
|
||||
public scaleX: number;
|
||||
public scaleY: number;
|
||||
public translateX: dip;
|
||||
public translateY: dip;
|
||||
public scaleX: number;
|
||||
public scaleY: number;
|
||||
public translateX: dip;
|
||||
public translateY: dip;
|
||||
|
||||
public clipPath: string;
|
||||
public color: Color;
|
||||
public tintColor: Color;
|
||||
public placeholderColor: Color;
|
||||
public clipPath: string;
|
||||
public color: Color;
|
||||
public tintColor: Color;
|
||||
public placeholderColor: Color;
|
||||
|
||||
public background: string;
|
||||
public backgroundColor: Color;
|
||||
public backgroundImage: string | LinearGradient;
|
||||
public backgroundRepeat: BackgroundRepeat;
|
||||
public backgroundSize: string;
|
||||
public backgroundPosition: string;
|
||||
public background: string;
|
||||
public backgroundColor: Color;
|
||||
public backgroundImage: string | LinearGradient;
|
||||
public backgroundRepeat: BackgroundRepeat;
|
||||
public backgroundSize: string;
|
||||
public backgroundPosition: string;
|
||||
|
||||
public borderColor: string | Color;
|
||||
public borderTopColor: Color;
|
||||
public borderRightColor: Color;
|
||||
public borderBottomColor: Color;
|
||||
public borderLeftColor: Color;
|
||||
public borderWidth: string | Length;
|
||||
public borderTopWidth: Length;
|
||||
public borderRightWidth: Length;
|
||||
public borderBottomWidth: Length;
|
||||
public borderLeftWidth: Length;
|
||||
public borderRadius: string | Length;
|
||||
public borderTopLeftRadius: Length;
|
||||
public borderTopRightRadius: Length;
|
||||
public borderBottomRightRadius: Length;
|
||||
public borderBottomLeftRadius: Length;
|
||||
public borderColor: string | Color;
|
||||
public borderTopColor: Color;
|
||||
public borderRightColor: Color;
|
||||
public borderBottomColor: Color;
|
||||
public borderLeftColor: Color;
|
||||
public borderWidth: string | Length;
|
||||
public borderTopWidth: Length;
|
||||
public borderRightWidth: Length;
|
||||
public borderBottomWidth: Length;
|
||||
public borderLeftWidth: Length;
|
||||
public borderRadius: string | Length;
|
||||
public borderTopLeftRadius: Length;
|
||||
public borderTopRightRadius: Length;
|
||||
public borderBottomRightRadius: Length;
|
||||
public borderBottomLeftRadius: Length;
|
||||
|
||||
public fontSize: number;
|
||||
public fontFamily: string;
|
||||
public fontStyle: FontStyle;
|
||||
public fontWeight: FontWeight;
|
||||
public font: string;
|
||||
public fontSize: number;
|
||||
public fontFamily: string;
|
||||
public fontStyle: FontStyle;
|
||||
public fontWeight: FontWeight;
|
||||
public font: string;
|
||||
|
||||
public androidElevation: number;
|
||||
public androidDynamicElevationOffset: number;
|
||||
public zIndex: number;
|
||||
public opacity: number;
|
||||
public visibility: Visibility;
|
||||
public androidElevation: number;
|
||||
public androidDynamicElevationOffset: number;
|
||||
public zIndex: number;
|
||||
public opacity: number;
|
||||
public visibility: Visibility;
|
||||
|
||||
public letterSpacing: number;
|
||||
public lineHeight: number;
|
||||
public textAlignment: TextAlignment;
|
||||
public textDecoration: TextDecoration;
|
||||
public textTransform: TextTransform;
|
||||
public whiteSpace: WhiteSpace;
|
||||
public letterSpacing: number;
|
||||
public lineHeight: number;
|
||||
public textAlignment: TextAlignment;
|
||||
public textDecoration: TextDecoration;
|
||||
public textTransform: TextTransform;
|
||||
public whiteSpace: WhiteSpace;
|
||||
|
||||
public minWidth: Length;
|
||||
public minHeight: Length;
|
||||
public width: PercentLength;
|
||||
public height: PercentLength;
|
||||
public margin: string | PercentLength;
|
||||
public marginLeft: PercentLength;
|
||||
public marginTop: PercentLength;
|
||||
public marginRight: PercentLength;
|
||||
public marginBottom: PercentLength;
|
||||
public padding: string | Length;
|
||||
public paddingLeft: Length;
|
||||
public paddingTop: Length;
|
||||
public paddingRight: Length;
|
||||
public paddingBottom: Length;
|
||||
public horizontalAlignment: HorizontalAlignment;
|
||||
public verticalAlignment: VerticalAlignment;
|
||||
public minWidth: Length;
|
||||
public minHeight: Length;
|
||||
public width: PercentLength;
|
||||
public height: PercentLength;
|
||||
public margin: string | PercentLength;
|
||||
public marginLeft: PercentLength;
|
||||
public marginTop: PercentLength;
|
||||
public marginRight: PercentLength;
|
||||
public marginBottom: PercentLength;
|
||||
public padding: string | Length;
|
||||
public paddingLeft: Length;
|
||||
public paddingTop: Length;
|
||||
public paddingRight: Length;
|
||||
public paddingBottom: Length;
|
||||
public horizontalAlignment: HorizontalAlignment;
|
||||
public verticalAlignment: VerticalAlignment;
|
||||
|
||||
// TabView-specific props
|
||||
public tabTextFontSize: number;
|
||||
public tabTextColor: Color;
|
||||
public tabBackgroundColor: Color;
|
||||
public selectedTabTextColor: Color;
|
||||
public androidSelectedTabHighlightColor: Color;
|
||||
// TabView-specific props
|
||||
public tabTextFontSize: number;
|
||||
public tabTextColor: Color;
|
||||
public tabBackgroundColor: Color;
|
||||
public selectedTabTextColor: Color;
|
||||
public androidSelectedTabHighlightColor: Color;
|
||||
|
||||
// ListView-specific props
|
||||
public separatorColor: Color;
|
||||
// ListView-specific props
|
||||
public separatorColor: Color;
|
||||
|
||||
//SegmentedBar-specific props
|
||||
public selectedBackgroundColor: Color;
|
||||
//SegmentedBar-specific props
|
||||
public selectedBackgroundColor: Color;
|
||||
|
||||
// Page-specific props
|
||||
public statusBarStyle: "light" | "dark";
|
||||
public androidStatusBarBackground: Color;
|
||||
// Page-specific props
|
||||
public statusBarStyle: "light" | "dark";
|
||||
public androidStatusBarBackground: Color;
|
||||
|
||||
// ActionBar-specific props
|
||||
public androidContentInset: string | Length;
|
||||
public androidContentInsetLeft: Length;
|
||||
public androidContentInsetRight: Length;
|
||||
// ActionBar-specific props
|
||||
public androidContentInset: string | Length;
|
||||
public androidContentInsetLeft: Length;
|
||||
public androidContentInsetRight: Length;
|
||||
|
||||
//flexbox layout properties
|
||||
public flexDirection: FlexDirection;
|
||||
public flexWrap: FlexWrap;
|
||||
public justifyContent: JustifyContent;
|
||||
public alignItems: AlignItems;
|
||||
public alignContent: AlignContent;
|
||||
public order: Order;
|
||||
public flexGrow: FlexGrow;
|
||||
public flexShrink: FlexShrink;
|
||||
public flexWrapBefore: FlexWrapBefore;
|
||||
public alignSelf: AlignSelf;
|
||||
//flexbox layout properties
|
||||
public flexDirection: FlexDirection;
|
||||
public flexWrap: FlexWrap;
|
||||
public justifyContent: JustifyContent;
|
||||
public alignItems: AlignItems;
|
||||
public alignContent: AlignContent;
|
||||
public order: Order;
|
||||
public flexGrow: FlexGrow;
|
||||
public flexShrink: FlexShrink;
|
||||
public flexWrapBefore: FlexWrapBefore;
|
||||
public alignSelf: AlignSelf;
|
||||
|
||||
public PropertyBag: { new(): { [property: string]: string }, prototype: { [property: string]: string } };
|
||||
public PropertyBag: {
|
||||
new (): { [property: string]: string };
|
||||
prototype: { [property: string]: string };
|
||||
};
|
||||
|
||||
public viewRef: WeakRef<ViewBase>;
|
||||
public viewRef: WeakRef<ViewBase>;
|
||||
|
||||
public get view(): ViewBase {
|
||||
if (this.viewRef) {
|
||||
return this.viewRef.get();
|
||||
}
|
||||
public get view(): ViewBase {
|
||||
if (this.viewRef) {
|
||||
return this.viewRef.get();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
Style.prototype.PropertyBag = class { [property: string]: string; };
|
||||
Style.prototype.PropertyBag = class {
|
||||
[property: string]: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user