Merge branch 'frame_nav_events' of github.com:Akylas/NativeScript

# Conflicts:
#	apps/automated/src/test-runner.ts
#	packages/core/css/parser.ts
#	packages/core/global-types.d.ts
#	packages/core/ui/bottom-navigation/index.android.ts
#	packages/core/ui/styling/style-scope.ts
#	packages/core/ui/tabs/index.android.ts
#	packages/core/ui/tabs/index.ios.ts
This commit is contained in:
Martin Guillon
2020-11-12 10:02:51 +01:00
174 changed files with 1979 additions and 1723 deletions

View File

@ -17,14 +17,14 @@ export class Background implements BackgroundDefinition {
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 borderTopWidth = 0;
public borderRightWidth = 0;
public borderBottomWidth = 0;
public borderLeftWidth = 0;
public borderTopLeftRadius = 0;
public borderTopRightRadius = 0;
public borderBottomLeftRadius = 0;
public borderBottomRightRadius = 0;
public clipPath: string;
private clone(): Background {

View File

@ -14,7 +14,7 @@ interface AndroidView {
// TODO: Change this implementation to use
// We are using "ad" here to avoid namespace collision with the global android object
export module ad {
export namespace ad {
let SDK: number;
function getSDK() {
if (!SDK) {
@ -121,7 +121,7 @@ function fromGradient(gradient: LinearGradient): org.nativescript.widgets.Linear
return new org.nativescript.widgets.LinearGradientDefinition(startX, startY, endX, endY, colors, hasStops ? stops : null);
}
const pattern: RegExp = /url\(('|")(.*?)\1\)/;
const pattern = /url\(('|")(.*?)\1\)/;
function refreshBorderDrawable(this: void, view: View, borderDrawable: org.nativescript.widgets.BorderDrawable) {
const nativeView = <android.view.View>view.nativeViewProtected;
const context = nativeView.getContext();
@ -220,7 +220,7 @@ export enum CacheMode {
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 {
export function initImageCache(context: android.content.Context, mode = CacheMode.diskAndMemory, memoryCacheSize = 0.25, diskCacheSize: number = 10 * 1024 * 1024): void {
if (currentCacheMode === mode) {
return;
}

View File

@ -65,10 +65,10 @@ export declare class Background {
public getUniformBorderRadius(): number;
}
export module ios {
export namespace ios {
export function createBackgroundUIColor(view: View, callback: (uiColor: any /* UIColor */) => void, flip?: boolean): void;
}
export module ad {
export namespace ad {
export function onBackgroundOrBorderPropertyChanged(v: View);
}

View File

@ -40,7 +40,7 @@ export enum CacheMode {
none,
}
export module ios {
export namespace ios {
export function createBackgroundUIColor(view: View, callback: (uiColor: UIColor) => void, flip?: boolean): void {
const background = view.style.backgroundInternal;
const nativeView = <NativeView>view.nativeViewProtected;
@ -159,7 +159,7 @@ function clearNonUniformBorders(nativeView: NativeView): void {
}
}
const pattern: RegExp = /url\(('|")(.*?)\1\)/;
const pattern = /url\(('|")(.*?)\1\)/;
function setUIColorFromImage(view: View, nativeView: UIView, callback: (uiColor: UIColor) => void, flip?: boolean): void {
const frame = nativeView.frame;
const boundsWidth = view.scaleX ? frame.size.width / view.scaleX : frame.size.width;

View File

@ -36,7 +36,7 @@ function parseCubicBezierCurve(value: string) {
}
function stringToBezieCoords(value: string): number {
let result = parseFloat(value);
const result = parseFloat(value);
if (result < 0) {
return 0;
} else if (result > 1) {

View File

@ -21,7 +21,7 @@ export class CssAnimationParser {
return undefined;
}
let animations = new Array<KeyframeAnimationInfo>();
const animations = new Array<KeyframeAnimationInfo>();
let animationInfo: KeyframeAnimationInfo = undefined;
declarations.forEach(({ property, value }) => {
@ -43,9 +43,9 @@ export class CssAnimationParser {
}
public static keyframesArrayFromCSS(keyframes: UnparsedKeyframe[]): KeyframeInfo[] {
let parsedKeyframes = new Array<KeyframeInfo>();
for (let keyframe of keyframes) {
let declarations = parseKeyframeDeclarations(keyframe.declarations);
const parsedKeyframes = new Array<KeyframeInfo>();
for (const keyframe of keyframes) {
const declarations = parseKeyframeDeclarations(keyframe.declarations);
for (let time of keyframe.values) {
if (time === 'from') {
time = 0;
@ -66,7 +66,7 @@ export class CssAnimationParser {
current.duration = time;
parsedKeyframes[time] = current;
}
for (let declaration of keyframe.declarations) {
for (const declaration of keyframe.declarations) {
if (declaration.property === 'animation-timing-function') {
current.curve = animationTimingFunctionConverter(declaration.value);
}
@ -74,8 +74,8 @@ export class CssAnimationParser {
current.declarations = declarations;
}
}
let array = new Array();
for (let parsedKeyframe in parsedKeyframes) {
const array = [];
for (const parsedKeyframe in parsedKeyframes) {
array.push(parsedKeyframes[parsedKeyframe]);
}
array.sort(function (a, b) {
@ -88,10 +88,10 @@ export class CssAnimationParser {
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(/[ ]+/);
const values = value.split(/[,]+/);
for (const parsedValue of values) {
const animationInfo = new KeyframeAnimationInfo();
const arr = (<string>parsedValue).trim().split(/[ ]+/);
if (arr.length > 0) {
animationInfo.name = arr[0];

View File

@ -84,7 +84,7 @@ function getNodeDirectSibling(node): null | Node {
return node.parent.getChildAt(nodeIndex - 1);
}
function SelectorProperties(specificity: Specificity, rarity: Rarity, dynamic: boolean = false): ClassDecorator {
function SelectorProperties(specificity: Specificity, rarity: Rarity, dynamic = false): ClassDecorator {
return (cls) => {
cls.prototype.specificity = specificity;
cls.prototype.rarity = rarity;
@ -340,7 +340,7 @@ export class Selector extends SelectorCore {
const supportedCombinator = [undefined, ' ', '>', '+'];
let siblingGroup: SimpleSelector[];
let lastGroup: SimpleSelector[][];
let groups: SimpleSelector[][][] = [];
const groups: SimpleSelector[][][] = [];
this.specificity = 0;
this.dynamic = false;
@ -403,10 +403,10 @@ export class Selector extends SelectorCore {
return this.match(node);
}
let bounds: Selector.Bound[] = [];
let mayMatch = this.groups.every((group, i) => {
const bounds: Selector.Bound[] = [];
const mayMatch = this.groups.every((group, i) => {
if (i === 0) {
let nextNode = group.mayMatch(node);
const nextNode = group.mayMatch(node);
bounds.push({ left: node, right: node });
node = nextNode;
@ -414,7 +414,7 @@ export class Selector extends SelectorCore {
} else {
let ancestor = node;
while ((ancestor = ancestor.parent)) {
let nextNode = group.mayMatch(ancestor);
const nextNode = group.mayMatch(ancestor);
if (nextNode) {
bounds.push({ left: ancestor, right: null });
node = nextNode;
@ -437,11 +437,11 @@ export class Selector extends SelectorCore {
}
for (let i = 0; i < this.groups.length; i++) {
let group = this.groups[i];
const group = this.groups[i];
if (!group.dynamic) {
continue;
}
let bound = bounds[i];
const bound = bounds[i];
let node = bound.left;
do {
if (group.mayMatch(node)) {
@ -500,7 +500,7 @@ export namespace Selector {
}
export class RuleSet {
tag: string | Number;
tag: string | number;
constructor(public selectors: SelectorCore[], public declarations: Declaration[]) {
this.selectors.forEach((sel) => (sel.ruleset = this));
}
@ -514,8 +514,8 @@ export class RuleSet {
export function fromAstNodes(astRules: cssParser.Node[]): RuleSet[] {
return (<cssParser.Rule[]>astRules.filter(isRule)).map((rule) => {
let declarations = rule.declarations.filter(isDeclaration).map(createDeclaration);
let selectors = rule.selectors.map(createSelector);
const declarations = rule.declarations.filter(isDeclaration).map(createDeclaration);
const selectors = rule.selectors.map(createSelector);
return new RuleSet(selectors, declarations);
});
@ -567,7 +567,7 @@ function createSelectorFromAst(ast: parser.Selector): SimpleSelector | SimpleSel
} else if (ast.length === 1) {
return createSimpleSelectorSequenceFromAst(ast[0][0]);
} else {
let simpleSelectorSequences = [];
const simpleSelectorSequences = [];
let simpleSelectorSequence: SimpleSelectorSequence | SimpleSelector;
let combinator: parser.Combinator;
for (let i = 0; i < ast.length; i++) {
@ -585,7 +585,7 @@ function createSelectorFromAst(ast: parser.Selector): SimpleSelector | SimpleSel
export function createSelector(sel: string): SimpleSelector | SimpleSelectorSequence | Selector {
try {
let parsedSelector = parser.parseSelector(sel);
const parsedSelector = parser.parseSelector(sel);
if (!parsedSelector) {
return new InvalidSelector(new Error('Empty selector'));
}
@ -672,7 +672,7 @@ export class SelectorsMatch<T extends Node> implements ChangeAccumulator {
public selectors;
public addAttribute(node: T, attribute: string): void {
let deps: Changes = this.properties(node);
const deps: Changes = this.properties(node);
if (!deps.attributes) {
deps.attributes = new Set();
}
@ -680,7 +680,7 @@ export class SelectorsMatch<T extends Node> implements ChangeAccumulator {
}
public addPseudoClass(node: T, pseudoClass: string): void {
let deps: Changes = this.properties(node);
const deps: Changes = this.properties(node);
if (!deps.pseudoClasses) {
deps.pseudoClasses = new Set();
}

View File

@ -41,23 +41,23 @@ export abstract class Font implements FontDefinition {
export type FontStyle = 'normal' | 'italic';
export namespace FontStyle {
export const NORMAL: 'normal' = 'normal';
export const ITALIC: 'italic' = 'italic';
export const NORMAL = 'normal';
export const 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 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 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 const isValid = makeValidator<FontWeight>(THIN, EXTRA_LIGHT, LIGHT, NORMAL, '400', MEDIUM, SEMI_BOLD, BOLD, '700', EXTRA_BOLD, BLACK);
export const parse = makeParser<FontStyle>(isValid);
}
@ -70,7 +70,7 @@ export function parseFontFamily(value: string): Array<string> {
const split = value.split(',');
for (let i = 0; i < split.length; i++) {
let str = split[i].trim().replace(/['"]+/g, '');
const str = split[i].trim().replace(/['"]+/g, '');
if (str) {
result.push(str);
}
@ -79,7 +79,7 @@ export function parseFontFamily(value: string): Array<string> {
return result;
}
export module genericFontFamilies {
export namespace genericFontFamilies {
export const serif = 'serif';
export const sansSerif = 'sans-serif';
export const monospace = 'monospace';
@ -105,7 +105,7 @@ 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].forEach((val, i, a) => weights.add(val));
export function parseFont(fontValue: string): ParsedFont {
let result: ParsedFont = {
const result: ParsedFont = {
fontStyle: 'normal',
fontVariant: 'normal',
fontWeight: 'normal',
@ -124,7 +124,7 @@ export function parseFont(fontValue: string): ParsedFont {
} else if (weights.has(part)) {
result.fontWeight = <any>part;
} else if (!result.fontSize) {
let sizes = part.split('/');
const sizes = part.split('/');
result.fontSize = sizes[0];
result.lineHeight = sizes.length > 1 ? sizes[1] : undefined;
} else {

View File

@ -56,6 +56,6 @@ export interface ParsedFont {
export function parseFont(fontValue: string): ParsedFont;
export module ios {
export namespace ios {
export function registerFont(fontFile: string);
}

View File

@ -101,7 +101,7 @@ function getNativeFontWeight(fontWeight: FontWeight): number {
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);
const descriptor = result.fontDescriptor.fontDescriptorWithSymbolicTraits(symbolicTraits);
result = UIFont.fontWithDescriptorSize(descriptor, size);
}
@ -114,7 +114,7 @@ function createUIFont(font: Font, defaultFont: UIFont): UIFont {
const nativeWeight = getNativeFontWeight(font.fontWeight);
const fontFamilies = parseFontFamily(font.fontFamily);
let symbolicTraits: number = 0;
let symbolicTraits = 0;
if (font.isBold) {
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitBold;
}
@ -122,7 +122,7 @@ function createUIFont(font: Font, defaultFont: UIFont): UIFont {
symbolicTraits |= UIFontDescriptorSymbolicTraits.TraitItalic;
}
let fontDescriptorTraits = {
const fontDescriptorTraits = {
[UIFontSymbolicTrait]: symbolicTraits,
};
@ -147,7 +147,7 @@ function createUIFont(font: Font, defaultFont: UIFont): UIFont {
let descriptor = UIFontDescriptor.fontDescriptorWithFontAttributes(<any>fontAttributes);
result = UIFont.fontWithDescriptorSize(descriptor, size);
let actualItalic = result.fontDescriptor.symbolicTraits & UIFontDescriptorSymbolicTraits.TraitItalic;
const 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);
@ -172,7 +172,7 @@ function createUIFont(font: Font, defaultFont: UIFont): UIFont {
return result;
}
export module ios {
export namespace ios {
export function registerFont(fontFile: string) {
let filePath = fs.path.join(fs.knownFolders.currentApp().path, 'fonts', fontFile);
if (!fs.File.exists(filePath)) {

View File

@ -106,7 +106,7 @@ export namespace PercentLength {
}
if (typeof fromValue === 'string') {
let stringValue = fromValue.trim();
let percentIndex = stringValue.indexOf('%');
const percentIndex = stringValue.indexOf('%');
if (percentIndex !== -1) {
let value: percent;
// if only % or % is not last we treat it as invalid value.
@ -124,14 +124,14 @@ export namespace PercentLength {
return { unit: '%', value };
} else if (stringValue.indexOf('px') !== -1) {
stringValue = stringValue.replace('px', '').trim();
let value: px = parseFloat(stringValue);
const value: px = parseFloat(stringValue);
if (isNaN(value) || !isFinite(value)) {
throw new Error(`Invalid value: ${fromValue}`);
}
return { unit: 'px', value };
} else {
let value: dip = parseFloat(stringValue);
const value: dip = parseFloat(stringValue);
if (isNaN(value) || !isFinite(value)) {
throw new Error(`Invalid value: ${fromValue}`);
}
@ -164,14 +164,14 @@ export namespace Length {
let stringValue = fromValue.trim();
if (stringValue.indexOf('px') !== -1) {
stringValue = stringValue.replace('px', '').trim();
let value: px = parseFloat(stringValue);
const value: px = parseFloat(stringValue);
if (isNaN(value) || !isFinite(value)) {
throw new Error(`Invalid value: ${stringValue}`);
}
return { unit: 'px', value };
} else {
let value: dip = parseFloat(stringValue);
const value: dip = parseFloat(stringValue);
if (isNaN(value) || !isFinite(value)) {
throw new Error(`Invalid value: ${stringValue}`);
}
@ -409,10 +409,10 @@ paddingBottomProperty.register(Style);
export type HorizontalAlignment = 'left' | 'center' | 'right' | 'stretch';
export namespace HorizontalAlignment {
export const LEFT: 'left' = 'left';
export const CENTER: 'center' = 'center';
export const RIGHT: 'right' = 'right';
export const STRETCH: 'stretch' = 'stretch';
export const LEFT = 'left';
export const CENTER = 'center';
export const RIGHT = 'right';
export const STRETCH = 'stretch';
export const isValid = makeValidator<HorizontalAlignment>(LEFT, CENTER, RIGHT, STRETCH);
export const parse = makeParser<HorizontalAlignment>(isValid);
}
@ -428,15 +428,15 @@ horizontalAlignmentProperty.register(Style);
export type VerticalAlignment = 'top' | 'middle' | 'bottom' | 'stretch' | 'text-top' | 'text-bottom' | 'super' | 'sub' | 'baseline';
export namespace VerticalAlignment {
export const TOP: 'top' = 'top';
export const MIDDLE: 'middle' = 'middle';
export const BOTTOM: 'bottom' = 'bottom';
export const STRETCH: 'stretch' = 'stretch';
export const TEXTTOP: 'text-top' = 'text-top';
export const TEXTBOTTOM: 'text-bottom' = 'text-bottom';
export const SUPER: 'super' = 'super';
export const SUB: 'sub' = 'sub';
export const BASELINE: 'baseline' = 'baseline';
export const TOP = 'top';
export const MIDDLE = 'middle';
export const BOTTOM = 'bottom';
export const STRETCH = 'stretch';
export const TEXTTOP = 'text-top';
export const TEXTBOTTOM = 'text-bottom';
export const SUPER = 'super';
export const SUB = 'sub';
export const BASELINE = 'baseline';
export const isValid = makeValidator<VerticalAlignment>(TOP, MIDDLE, BOTTOM, STRETCH, TEXTTOP, TEXTBOTTOM, SUPER, SUB, BASELINE);
export const parse = (value: string) => (value.toLowerCase() === 'center' ? MIDDLE : parseStrict(value));
const parseStrict = makeParser<VerticalAlignment>(isValid);
@ -460,7 +460,7 @@ interface Thickness {
function parseThickness(value: string): Thickness {
if (typeof value === 'string') {
let arr = value.split(/[ ,]+/);
const arr = value.split(/[ ,]+/);
let top: string;
let right: string;
@ -504,7 +504,7 @@ function parseThickness(value: string): Thickness {
function convertToMargins(this: void, value: string | PercentLength): [CssProperty<any, any>, any][] {
if (typeof value === 'string' && value !== 'auto') {
let thickness = parseThickness(value);
const thickness = parseThickness(value);
return [
[marginTopProperty, PercentLength.parse(thickness.top)],
@ -524,7 +524,7 @@ function convertToMargins(this: void, value: string | PercentLength): [CssProper
function convertToPaddings(this: void, value: string | Length): [CssProperty<any, any>, any][] {
if (typeof value === 'string' && value !== 'auto') {
let thickness = parseThickness(value);
const thickness = parseThickness(value);
return [
[paddingTopProperty, Length.parse(thickness.top)],
@ -618,13 +618,13 @@ const transformProperty = new ShorthandProperty<Style, string>({
name: 'transform',
cssName: 'transform',
getter: function (this: Style) {
let scaleX = this.scaleX;
let scaleY = this.scaleY;
let translateX = this.translateX;
let translateY = this.translateY;
let rotate = this.rotate;
let rotateX = this.rotateX;
let rotateY = this.rotateY;
const scaleX = this.scaleX;
const scaleY = this.scaleY;
const translateX = this.translateX;
const translateY = this.translateY;
const rotate = this.rotate;
const rotateX = this.rotateX;
const rotateY = this.rotateY;
let result = '';
if (translateX !== 0 || translateY !== 0) {
result += `translate(${translateX}, ${translateY}) `;
@ -749,7 +749,7 @@ export function transformConverter(text: string): TransformFunctionsInfo {
// properties is faster than using more specific regex
// https://jsperf.com/cssparse
function parseTransformString(text: string): Transformation[] {
let matches: Transformation[] = [];
const matches: Transformation[] = [];
let match;
while ((match = TRANSFORM_SPLITTER.exec(text)) !== null) {
@ -839,10 +839,10 @@ backgroundColorProperty.register(Style);
export type BackgroundRepeat = 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat';
export namespace BackgroundRepeat {
export const REPEAT: 'repeat' = 'repeat';
export const REPEAT_X: 'repeat-x' = 'repeat-x';
export const REPEAT_Y: 'repeat-y' = 'repeat-y';
export const NO_REPEAT: 'no-repeat' = 'no-repeat';
export const REPEAT = 'repeat';
export const REPEAT_X = 'repeat-x';
export const REPEAT_Y = 'repeat-y';
export const NO_REPEAT = 'no-repeat';
export const isValid = makeValidator<BackgroundRepeat>(REPEAT, REPEAT_X, REPEAT_Y, NO_REPEAT);
export const parse = makeParser<BackgroundRepeat>(isValid);
}
@ -910,7 +910,7 @@ function convertToBackgrounds(this: void, value: string): [CssProperty<any, any>
}
function parseBorderColor(value: string): { top: Color; right: Color; bottom: Color; left: Color } {
let result: { top: Color; right: Color; bottom: Color; left: Color } = {
const result: { top: Color; right: Color; bottom: Color; left: Color } = {
top: undefined,
right: undefined,
bottom: undefined,
@ -922,33 +922,33 @@ function parseBorderColor(value: string): { top: Color; right: Color; bottom: Co
return result;
}
let arr = value.split(/[ ,]+/);
const arr = value.split(/[ ,]+/);
if (arr.length === 1) {
let arr0 = new Color(arr[0]);
const arr0 = new Color(arr[0]);
result.top = arr0;
result.right = arr0;
result.bottom = arr0;
result.left = arr0;
} else if (arr.length === 2) {
let arr0 = new Color(arr[0]);
let arr1 = new Color(arr[1]);
const arr0 = new Color(arr[0]);
const arr1 = new Color(arr[1]);
result.top = arr0;
result.right = arr1;
result.bottom = arr0;
result.left = arr1;
} else if (arr.length === 3) {
let arr0 = new Color(arr[0]);
let arr1 = new Color(arr[1]);
let arr2 = new Color(arr[2]);
const arr0 = new Color(arr[0]);
const arr1 = new Color(arr[1]);
const arr2 = new Color(arr[2]);
result.top = arr0;
result.right = arr1;
result.bottom = arr2;
result.left = arr1;
} else if (arr.length === 4) {
let arr0 = new Color(arr[0]);
let arr1 = new Color(arr[1]);
let arr2 = new Color(arr[2]);
let arr3 = new Color(arr[3]);
const arr0 = new Color(arr[0]);
const arr1 = new Color(arr[1]);
const arr2 = new Color(arr[2]);
const arr3 = new Color(arr[3]);
result.top = arr0;
result.right = arr1;
result.bottom = arr2;
@ -973,7 +973,7 @@ const borderColorProperty = new ShorthandProperty<Style, string | Color>({
},
converter: function (value) {
if (typeof value === 'string') {
let fourColors = parseBorderColor(value);
const fourColors = parseBorderColor(value);
return [
[borderTopColorProperty, fourColors.top],
@ -1054,7 +1054,7 @@ const borderWidthProperty = new ShorthandProperty<Style, string | Length>({
},
converter: function (value) {
if (typeof value === 'string' && value !== 'auto') {
let borderWidths = parseThickness(value);
const borderWidths = parseThickness(value);
return [
[borderTopWidthProperty, borderWidths.top],
@ -1081,7 +1081,7 @@ export const borderTopWidthProperty = new CssProperty<Style, Length>({
affectsLayout: global.isIOS,
equalityComparer: Length.equals,
valueChanged: (target, oldValue, newValue) => {
let value = Length.toDevicePixels(newValue, 0);
const value = Length.toDevicePixels(newValue, 0);
if (!isNonNegativeFiniteNumber(value)) {
throw new Error(`border-top-width should be Non-Negative Finite number. Value: ${value}`);
}
@ -1106,7 +1106,7 @@ export const borderRightWidthProperty = new CssProperty<Style, Length>({
affectsLayout: global.isIOS,
equalityComparer: Length.equals,
valueChanged: (target, oldValue, newValue) => {
let value = Length.toDevicePixels(newValue, 0);
const value = Length.toDevicePixels(newValue, 0);
if (!isNonNegativeFiniteNumber(value)) {
throw new Error(`border-right-width should be Non-Negative Finite number. Value: ${value}`);
}
@ -1131,7 +1131,7 @@ export const borderBottomWidthProperty = new CssProperty<Style, Length>({
affectsLayout: global.isIOS,
equalityComparer: Length.equals,
valueChanged: (target, oldValue, newValue) => {
let value = Length.toDevicePixels(newValue, 0);
const value = Length.toDevicePixels(newValue, 0);
if (!isNonNegativeFiniteNumber(value)) {
throw new Error(`border-bottom-width should be Non-Negative Finite number. Value: ${value}`);
}
@ -1156,7 +1156,7 @@ export const borderLeftWidthProperty = new CssProperty<Style, Length>({
affectsLayout: global.isIOS,
equalityComparer: Length.equals,
valueChanged: (target, oldValue, newValue) => {
let value = Length.toDevicePixels(newValue, 0);
const value = Length.toDevicePixels(newValue, 0);
if (!isNonNegativeFiniteNumber(value)) {
throw new Error(`border-left-width should be Non-Negative Finite number. Value: ${value}`);
}
@ -1187,7 +1187,7 @@ const borderRadiusProperty = new ShorthandProperty<Style, string | Length>({
},
converter: function (value) {
if (typeof value === 'string') {
let borderRadius = parseThickness(value);
const borderRadius = parseThickness(value);
return [
[borderTopLeftRadiusProperty, borderRadius.top],
@ -1213,7 +1213,7 @@ export const borderTopLeftRadiusProperty = new CssProperty<Style, Length>({
defaultValue: 0,
affectsLayout: global.isIOS,
valueChanged: (target, oldValue, newValue) => {
let value = Length.toDevicePixels(newValue, 0);
const value = Length.toDevicePixels(newValue, 0);
if (!isNonNegativeFiniteNumber(value)) {
throw new Error(`border-top-left-radius should be Non-Negative Finite number. Value: ${value}`);
}
@ -1230,7 +1230,7 @@ export const borderTopRightRadiusProperty = new CssProperty<Style, Length>({
defaultValue: 0,
affectsLayout: global.isIOS,
valueChanged: (target, oldValue, newValue) => {
let value = Length.toDevicePixels(newValue, 0);
const value = Length.toDevicePixels(newValue, 0);
if (!isNonNegativeFiniteNumber(value)) {
throw new Error(`border-top-right-radius should be Non-Negative Finite number. Value: ${value}`);
}
@ -1247,7 +1247,7 @@ export const borderBottomRightRadiusProperty = new CssProperty<Style, Length>({
defaultValue: 0,
affectsLayout: global.isIOS,
valueChanged: (target, oldValue, newValue) => {
let value = Length.toDevicePixels(newValue, 0);
const value = Length.toDevicePixels(newValue, 0);
if (!isNonNegativeFiniteNumber(value)) {
throw new Error(`border-bottom-right-radius should be Non-Negative Finite number. Value: ${value}`);
}
@ -1264,7 +1264,7 @@ export const borderBottomLeftRadiusProperty = new CssProperty<Style, Length>({
defaultValue: 0,
affectsLayout: global.isIOS,
valueChanged: (target, oldValue, newValue) => {
let value = Length.toDevicePixels(newValue, 0);
const value = Length.toDevicePixels(newValue, 0);
if (!isNonNegativeFiniteNumber(value)) {
throw new Error(`border-bottom-left-radius should be Non-Negative Finite number. Value: ${value}`);
}
@ -1279,12 +1279,12 @@ function isNonNegativeFiniteNumber(value: number): boolean {
return isFinite(value) && !isNaN(value) && value >= 0;
}
let supportedPaths = ['rect', 'circle', 'ellipse', 'polygon', 'inset'];
const supportedPaths = ['rect', 'circle', 'ellipse', 'polygon', 'inset'];
function isClipPathValid(value: string): boolean {
if (!value) {
return true;
}
let functionName = value.substring(0, value.indexOf('(')).trim();
const functionName = value.substring(0, value.indexOf('(')).trim();
return supportedPaths.indexOf(functionName) !== -1;
}
@ -1304,7 +1304,7 @@ export const clipPathProperty = new CssProperty<Style, string>({
clipPathProperty.register(Style);
function isFloatValueConverter(value: string): number {
let newValue = parseFloat(value);
const newValue = parseFloat(value);
if (isNaN(newValue)) {
throw new Error(`Invalid value: ${newValue}`);
}
@ -1320,7 +1320,7 @@ export const zIndexProperty = new CssProperty<Style, number>({
zIndexProperty.register(Style);
function opacityConverter(value: any): number {
let newValue = parseFloat(value);
const newValue = parseFloat(value);
if (!isNaN(newValue) && 0 <= newValue && newValue <= 1) {
return newValue;
}
@ -1355,7 +1355,7 @@ export const fontFamilyProperty = new InheritedCssProperty<Style, string>({
cssName: 'font-family',
affectsLayout: global.isIOS,
valueChanged: (target, oldValue, newValue) => {
let currentFont = target.fontInternal || Font.default;
const currentFont = target.fontInternal || Font.default;
if (currentFont.fontFamily !== newValue) {
const newFont = currentFont.withFontFamily(newValue);
target.fontInternal = Font.equals(Font.default, newFont) ? unsetValue : newFont;
@ -1372,7 +1372,7 @@ export const fontSizeProperty = new InheritedCssProperty<Style, number>({
if (target.viewRef['handleFontSize'] === true) {
return;
}
let currentFont = target.fontInternal || Font.default;
const currentFont = target.fontInternal || Font.default;
if (currentFont.fontSize !== newValue) {
const newFont = currentFont.withFontSize(newValue);
target.fontInternal = Font.equals(Font.default, newFont) ? unsetValue : newFont;
@ -1389,7 +1389,7 @@ export const fontStyleProperty = new InheritedCssProperty<Style, FontStyle>({
defaultValue: FontStyle.NORMAL,
valueConverter: FontStyle.parse,
valueChanged: (target, oldValue, newValue) => {
let currentFont = target.fontInternal || Font.default;
const currentFont = target.fontInternal || Font.default;
if (currentFont.fontStyle !== newValue) {
const newFont = currentFont.withFontStyle(newValue);
target.fontInternal = Font.equals(Font.default, newFont) ? unsetValue : newFont;
@ -1405,7 +1405,7 @@ export const fontWeightProperty = new InheritedCssProperty<Style, FontWeight>({
defaultValue: FontWeight.NORMAL,
valueConverter: FontWeight.parse,
valueChanged: (target, oldValue, newValue) => {
let currentFont = target.fontInternal || Font.default;
const currentFont = target.fontInternal || Font.default;
if (currentFont.fontWeight !== newValue) {
const newFont = currentFont.withFontWeight(newValue);
target.fontInternal = Font.equals(Font.default, newFont) ? unsetValue : newFont;
@ -1445,9 +1445,9 @@ fontProperty.register(Style);
export type Visibility = 'visible' | 'hidden' | 'collapse';
export namespace Visibility {
export const VISIBLE: 'visible' = 'visible';
export const HIDDEN: 'hidden' = 'hidden';
export const COLLAPSE: 'collapse' = 'collapse';
export const VISIBLE = 'visible';
export const HIDDEN = 'hidden';
export const COLLAPSE = 'collapse';
export const isValid = makeValidator<Visibility>(VISIBLE, HIDDEN, COLLAPSE);
export const parse = (value: string) => (value.toLowerCase() === 'collapsed' ? COLLAPSE : parseStrict(value));
const parseStrict = makeParser<Visibility>(isValid);

View File

@ -1,5 +1,4 @@
//@private
import { ViewBase } from '../core/view-base';
import { ViewBase } from '../core/view-base';
import { SyntaxTree } from '../../css';
import { RuleSet, Node, SelectorCore, ChangeMap } from '../styling/css-selector';
import { KeyframeAnimationInfo } from '../animation/keyframe-animation';

View File

@ -31,6 +31,7 @@ function ensureCssAnimationParserModule() {
let parser: 'rework' | 'nativescript' | 'css-tree' = 'css-tree';
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const appConfig = require('~/package.json');
if (appConfig) {
if (appConfig.cssParser === 'rework') {
@ -67,17 +68,17 @@ function evaluateCssExpressions(view: ViewBase, property: string, value: string)
export function mergeCssSelectors(): void {
applicationCssSelectors = applicationSelectors.slice();
applicationCssSelectors.push.apply(applicationCssSelectors, applicationAdditionalSelectors);
applicationCssSelectors.push(...applicationAdditionalSelectors);
applicationCssSelectorVersion++;
}
let applicationCssSelectors: RuleSet[] = [];
let applicationCssSelectorVersion: number = 0;
let applicationCssSelectorVersion = 0;
let applicationSelectors: RuleSet[] = [];
const applicationAdditionalSelectors: RuleSet[] = [];
const applicationKeyframes: any = {};
const animationsSymbol: symbol = Symbol('animations');
const pattern: RegExp = /('|")(.*?)\1/;
const animationsSymbol = Symbol('animations');
const pattern = /('|")(.*?)\1/;
class CSSSource {
private _selectors: RuleSet[] = [];
@ -136,7 +137,7 @@ class CSSSource {
public static fromFile(url: string, keyframes: KeyframesMap): CSSSource {
// .scss, .sass, etc. css files in vanilla app are usually compiled to .css so we will try to load a compiled file first.
let cssFileUrl = url.replace(/\..\w+$/, '.css');
const cssFileUrl = url.replace(/\..\w+$/, '.css');
if (cssFileUrl !== url) {
const cssFile = CSSSource.resolveCSSPathFromURL(cssFileUrl);
if (cssFile) {
@ -224,6 +225,7 @@ class CSSSource {
this._ast = cssNS.parseStylesheet(stylesheet);
return;
}
case 'rework':
const parseCss = require('../../css').parse;
this._ast = parseCss(this._source, { source: this._file });
@ -290,7 +292,7 @@ class CSSSource {
}
}
export function removeTaggedAdditionalCSS(tag: String | Number): Boolean {
export function removeTaggedAdditionalCSS(tag: string | number): boolean {
let changed = false;
for (let i = 0; i < applicationAdditionalSelectors.length; i++) {
if (applicationAdditionalSelectors[i].tag === tag) {
@ -306,7 +308,7 @@ export function removeTaggedAdditionalCSS(tag: String | Number): Boolean {
return changed;
}
export function addTaggedAdditionalCSS(cssText: string, tag?: string | Number): Boolean {
export function addTaggedAdditionalCSS(cssText: string, tag?: string | number): boolean {
const parsed: RuleSet[] = CSSSource.fromDetect(cssText, applicationKeyframes, undefined).selectors;
let changed = false;
if (parsed && parsed.length) {
@ -316,7 +318,7 @@ export function addTaggedAdditionalCSS(cssText: string, tag?: string | Number):
parsed[i].tag = tag;
}
}
applicationAdditionalSelectors.push.apply(applicationAdditionalSelectors, parsed);
applicationAdditionalSelectors.push(...parsed);
mergeCssSelectors();
}
@ -327,7 +329,7 @@ const onCssChanged = profile('"style-scope".onCssChanged', (args: application.Cs
if (args.cssText) {
const parsed = CSSSource.fromSource(args.cssText, applicationKeyframes, args.cssFile).selectors;
if (parsed) {
applicationAdditionalSelectors.push.apply(applicationAdditionalSelectors, parsed);
applicationAdditionalSelectors.push(...parsed);
mergeCssSelectors();
}
} else if (args.cssFile) {
@ -380,12 +382,12 @@ if (application.hasLaunched()) {
null
);
} else {
global.NativeScriptGlobals.events.on('loadAppCss', <any>loadAppCSS);
global.NativeScriptGlobals.events.on('loadAppCss', loadAppCSS);
}
export class CssState {
static emptyChangeMap: Readonly<ChangeMap<ViewBase>> = Object.freeze(new Map());
static emptyPropertyBag: Readonly<{}> = Object.freeze({});
static emptyPropertyBag: Readonly<Record<string, unknown>> = Object.freeze({});
static emptyAnimationArray: ReadonlyArray<kam.KeyframeAnimation> = Object.freeze([]);
static emptyMatch: Readonly<SelectorsMatch<ViewBase>> = {
selectors: [],
@ -397,7 +399,7 @@ export class CssState {
_onDynamicStateChangeHandler: () => void;
_appliedChangeMap: Readonly<ChangeMap<ViewBase>>;
_appliedPropertyValues: Readonly<{}>;
_appliedPropertyValues: Readonly<Record<string, unknown>>;
_appliedAnimations: ReadonlyArray<kam.KeyframeAnimation>;
_appliedSelectorsVersion: number;
@ -482,11 +484,11 @@ export class CssState {
const animations: kam.KeyframeAnimation[] = [];
matchingSelectors.forEach((selector) => {
let ruleAnimations: kam.KeyframeAnimationInfo[] = selector.ruleset[animationsSymbol];
const ruleAnimations: kam.KeyframeAnimationInfo[] = selector.ruleset[animationsSymbol];
if (ruleAnimations) {
ensureKeyframeAnimationModule();
for (let animationInfo of ruleAnimations) {
let animation = keyframeAnimationModule.KeyframeAnimation.keyframeAnimationFromInfo(animationInfo);
for (const animationInfo of ruleAnimations) {
const animation = keyframeAnimationModule.KeyframeAnimation.keyframeAnimationFromInfo(animationInfo);
if (animation) {
animations.push(animation);
}
@ -632,7 +634,7 @@ export class CssState {
}
if (changes.pseudoClasses) {
changes.pseudoClasses.forEach((pseudoClass) => {
let eventName = ':' + pseudoClass;
const eventName = ':' + pseudoClass;
view.addEventListener(':' + pseudoClass, this._onDynamicStateChangeHandler);
if (view[eventName]) {
view[eventName](+1);
@ -652,7 +654,7 @@ export class CssState {
}
if (changes.pseudoClasses) {
changes.pseudoClasses.forEach((pseudoClass) => {
let eventName = ':' + pseudoClass;
const eventName = ':' + pseudoClass;
view.removeEventListener(eventName, this._onDynamicStateChangeHandler);
if (view[eventName]) {
view[eventName](-1);
@ -681,12 +683,12 @@ CssState.prototype._matchInvalid = true;
export class StyleScope {
private _selectors: SelectorsMap<any>;
private _css: string = '';
private _css = '';
private _mergedCssSelectors: RuleSet[];
private _localCssSelectors: RuleSet[] = [];
private _localCssSelectorVersion: number = 0;
private _localCssSelectorsAppliedVersion: number = 0;
private _applicationCssSelectorsAppliedVersion: number = 0;
private _localCssSelectorVersion = 0;
private _localCssSelectorsAppliedVersion = 0;
private _applicationCssSelectorsAppliedVersion = 0;
private _keyframes = new Map<string, Keyframes>();
get css(): string {
@ -733,9 +735,9 @@ export class StyleScope {
return;
}
let parsedCssSelectors = cssString ? CSSSource.fromSource(cssString, this._keyframes, cssFileName) : CSSSource.fromURI(cssFileName, this._keyframes);
const parsedCssSelectors = cssString ? CSSSource.fromSource(cssString, this._keyframes, cssFileName) : CSSSource.fromURI(cssFileName, this._keyframes);
this._css = this._css + parsedCssSelectors.source;
this._localCssSelectors.push.apply(this._localCssSelectors, parsedCssSelectors.selectors);
this._localCssSelectors.push(...parsedCssSelectors.selectors);
this._localCssSelectorVersion++;
this.ensureSelectors();
}
@ -776,12 +778,12 @@ export class StyleScope {
@profile
private _createSelectors() {
let toMerge: RuleSet[][] = [];
const toMerge: RuleSet[][] = [];
toMerge.push(applicationCssSelectors);
this._applicationCssSelectorsAppliedVersion = applicationCssSelectorVersion;
toMerge.push(this._localCssSelectors);
this._localCssSelectorsAppliedVersion = this._localCssSelectorVersion;
for (let keyframe in applicationKeyframes) {
for (const keyframe in applicationKeyframes) {
this._keyframes[keyframe] = applicationKeyframes[keyframe];
}
@ -795,7 +797,7 @@ export class StyleScope {
// HACK: This @profile decorator creates a circular dependency
// HACK: because the function parameter type is evaluated with 'typeof'
@profile
public matchSelectors(view: any): SelectorsMatch<ViewBase> {
public matchSelectors(view): SelectorsMatch<ViewBase> {
// should be (view: ViewBase): SelectorsMatch<ViewBase>
this.ensureSelectors();
@ -816,11 +818,11 @@ export class StyleScope {
private _applyKeyframesOnSelectors() {
for (let i = this._mergedCssSelectors.length - 1; i >= 0; i--) {
let ruleset = this._mergedCssSelectors[i];
let animations: kam.KeyframeAnimationInfo[] = ruleset[animationsSymbol];
const ruleset = this._mergedCssSelectors[i];
const animations: kam.KeyframeAnimationInfo[] = ruleset[animationsSymbol];
if (animations !== undefined && animations.length) {
ensureCssAnimationParserModule();
for (let animation of animations) {
for (const animation of animations) {
const cssKeyframe = this._keyframes[animation.name];
if (cssKeyframe !== undefined) {
animation.keyframes = cssAnimationParserModule.CssAnimationParser.keyframesArrayFromCSS(cssKeyframe.keyframes);
@ -886,8 +888,8 @@ function resolveFilePathFromImport(importSource: string, fileName: string): stri
}
export const applyInlineStyle = profile(function applyInlineStyle(view: ViewBase, styleStr: string) {
let localStyle = `local { ${styleStr} }`;
let inlineRuleSet = CSSSource.fromSource(localStyle, new Map()).selectors;
const localStyle = `local { ${styleStr} }`;
const inlineRuleSet = CSSSource.fromSource(localStyle, new Map()).selectors;
// Reset unscoped css-variables
view.style.resetUnscopedCssVariables();
@ -895,7 +897,7 @@ export const applyInlineStyle = profile(function applyInlineStyle(view: ViewBase
// Set all the css-variables first, so we can be sure they are up-to-date
inlineRuleSet[0].declarations.forEach((d) => {
// Use the actual property name so that a local value is set.
let property = d.property;
const property = d.property;
if (isCssVariable(property)) {
view.style.setUnscopedCssVariable(property, d.value);
}
@ -903,7 +905,7 @@ export const applyInlineStyle = profile(function applyInlineStyle(view: ViewBase
inlineRuleSet[0].declarations.forEach((d) => {
// Use the actual property name so that a local value is set.
let property = d.property;
const property = d.property;
try {
if (isCssVariable(property)) {
// Skip css-variables, they have been handled