Merge remote-tracking branch 'origin' into merge-release-in-master

This commit is contained in:
SvetoslavTsenov
2019-09-18 01:08:56 +03:00
11 changed files with 159 additions and 88 deletions

View File

@@ -4,11 +4,12 @@ Development Workflow
## Project Structure
The repository contains several packages and apps:
- `tns-core-modules` - The core NativeScript TypeScript modules used to develop NativeScript apps.
- `apps` - UI app used for manual testing and automation.
- `e2e` - applications and *e2e* tests.
- `tests` - Unit tests app for the `tns-core-modules`.
- `tns-platform-declarations` - TypeScript definitions for Android and iOS native APIs.
- `tns-core-modules` - The core NativeScript TypeScript modules used to develop NativeScript apps
- `tns-core-modules-widgets` - The native widgets (Java and Objective-C) used by the core NativeScript modules
- `e2e/ui-tests-app` - UI app used for manual testing and automation
- `e2e` - applications and *e2e* tests
- `tests` - Unit tests app for the `tns-core-modules`
- `tns-platform-declarations` - TypeScript definitions for Android and iOS native APIs
Working with the repo is organized with npm scripts,
go and read through the `scripts` section in the [package.json](./package.json).
@@ -16,7 +17,7 @@ go and read through the `scripts` section in the [package.json](./package.json).
Managing dependencies:
- `tns-core-modules` depends on:
- `tns-platform-declarations`
- `apps` depends on:
- `e2e/ui-tests-app` depends on:
- `tns-platform-declarations`
- `tns-core-modules`
- `e2e` depends on:
@@ -26,89 +27,60 @@ Managing dependencies:
- `tns-core-modules`
> NOTE: `tns-core-modules` depends on `tns-core-modules-widgets`,
this dependency contains native code and is rarely modified so for now it remains outside this repo.
## Initial Setup
Clone (or fork/clone) the repo:
```bash
``` bash
git clone https://github.com/NativeScript/NativeScript.git
```
Install devDependencies:
Install dependencies:
```bash
``` bash
npm install
```
<!---
## TypeScript
The following commands are commonly used to compile the `tns-core-modules`:
```bash
# Full tsc with type checking ~22.2s.
tsc
# Fast tsc ~11.2s.
tsc --skipLibCheck
# Fast watcher, ~4s. on save
tsc --skipLibCheck -w
```
NOTE: transpile `tns-core-modules` only.
The modules have `typescript` as a devDependency so you should also be able to use the locally installed TypeScript compiler from node_modules:
```bash
./node_modules/.bin/tsc
```
You can compile the TypeScript files in the `tns-core-modules` and `tns-platform-declarations` at once at the root of the repo:
```bash
npm run tsc
```
--->
## Running Unit Tests
```
cd ./tests
tns run android| ios
``` bash
cd tests
tns run android | ios
```
## Running the Test App
## Running the UI Test App
The test app is an ordinary NativeScript app that logs the test results as it go.
The UI test app is an ordinary NativeScript app that logs the test results on the go.
After the [initial setup](#initial-setup) you can run the tests with:
```
# Make sure TypeScript is transpiled
tsc
``` bash
cd e2e/ui-tests-app
# Run the Android app
tns platform add android@next # NOTE: do not commit this change to package.json
tns run android
# Run the iOS app
tns platform add ios@next # NOTE: do not commit this change to package.json
tns run ios
# Run the app
tns run ios --path apps
tns run android --path apps
```
## Running Another App
The [initial setup](#initial-setup) will `npm-link` the `tns-core-modules` globally. You can use it in any local project:
1. Open the app, where you will use the module from the repository in the console.
2. Add the `tns-core-modules` in the application via:
```bash
npm install --save <path to tns-core-modules>
# Example: npm install --save ../NativeScript/tns-core-modules
```
3. Run the app
```bash
# Run once: Link tns-core-modules in your project
npm link tns-core-modules
# Run the app
tns run ios
tns run android
```
> Note: You still have to rebuild the TypeScript if you have made changes in the code of the core-modules.
## Platform declarations
To update the platform declarations (the ios.d.ts-es) you can run:

View File

@@ -54,16 +54,16 @@ Below is a common NativeScript architecture diagram. In more detail, read the [H
The NativeScript framework consists of a number of components, all of which are open source and on GitHub. Here are the major ones:
- **[Cross-platform modules](//github.com/NativeScript/NativeScript/)**
[![npm](https://img.shields.io/npm/dm/tns-core-modules.svg)](https://www.npmjs.com/package/tns-core-modules) [![Waffle.io - NativeScript Modules and Angular](https://badge.waffle.io/NativeScript/NativeScript.svg?columns=In%20Progress)](https://waffle.io/NativeScript/NativeScript)
[![npm](https://img.shields.io/npm/dm/tns-core-modules.svg)](https://www.npmjs.com/package/tns-core-modules)
- This repo contains the [NativeScript cross-platform modules](http://docs.nativescript.org/core-concepts/modules), which abstract iOS and Android APIs into JavaScript APIs—e.g. `camera.takePicture()`. The modules are written in TypeScript.
- **[iOS runtime](//github.com/NativeScript/ios-runtime/)**
[![npm](https://img.shields.io/npm/dm/tns-ios.svg)](https://www.npmjs.com/package/tns-ios) [![Waffle.io - NativeScript iOS Runtime](https://badge.waffle.io/NativeScript/ios-runtime.svg?columns=In%20Progress)](https://waffle.io/NativeScript/ios-runtime)
[![npm](https://img.shields.io/npm/dm/tns-ios.svg)](https://www.npmjs.com/package/tns-ios)
- This repo contains the NativeScript iOS runtime—the code that hosts NativeScript iOS apps, and allows JavaScript code to be executed on iOS devices. The iOS runtime is written in a fun mix of C++, Objective-C, and more.
- **[Android runtime](//github.com/NativeScript/android-runtime)**
[![npm](https://img.shields.io/npm/dm/tns-android.svg)](https://www.npmjs.com/package/tns-android) [![Waffle.io - NativeScript Runtimes and CLI](https://badge.waffle.io/NativeScript/android-runtime.svg?columns=In%20Progress)](https://waffle.io/NativeScript/android-runtime)
[![npm](https://img.shields.io/npm/dm/tns-android.svg)](https://www.npmjs.com/package/tns-android)
- This repo contains the NativeScript Android—the code that hosts NativeScript Android apps, and allows JavaScript code to be executed on Android devices. The Android runtime is written in a fun mix of C++ and Java.
- **[CLI](//github.com/NativeScript/nativescript-cli)**
[![npm](https://img.shields.io/npm/dm/nativescript.svg)](https://www.npmjs.com/package/nativescript) [![Waffle.io - NativeScript CLI](https://badge.waffle.io/NativeScript/nativescript-cli.svg?columns=In%20Progress)](https://waffle.io/NativeScript/nativescript-cli)
[![npm](https://img.shields.io/npm/dm/nativescript.svg)](https://www.npmjs.com/package/nativescript)
- This repo contains the NativeScript command-line interface, which lets you create, build, and run apps using the NativeScript framework. The CLI is written in TypeScript.
- **[Docs](//github.com/NativeScript/docs)**
- This repo contains the NativeScript framework documentation, which is available at <http://docs.nativescript.org/>. The docs are written in Markdown.

View File

@@ -67,7 +67,7 @@
"dev-tsc-tests": "npm run tsc -- -p tests",
"dev-tsc-apps": "npm run tsc -- -p apps",
"dev-tsc-e2e": "npm run tsc -- -p e2e",
"dev-tsc-all": "npm run dev-tsc-tns-platform-declarations && npm run tsc && npm run dev-tsc-tests && npm run dev-tsc-apps && && npm run dev-tsc-e2e",
"dev-tsc-all": "npm run dev-tsc-tns-platform-declarations && npm run tsc && npm run dev-tsc-tests && npm run dev-tsc-apps && npm run dev-tsc-e2e",
"dev-link-tns-core-modules-widgets": "(cd tns-core-modules-widgets/dist/package && npm link) && (cd tns-core-modules && npm i ../tns-core-modules-widgets/dist/package --save)",
"dev-declarations": "rm -rf tns-platform-declarations/ios/objc* && TNS_TYPESCRIPT_DECLARATIONS_PATH=$PWD/tns-platform-declarations/ios/objc tns build ios --path tests",
"test": "npm run test-android && npm run test-ios",

View File

@@ -41,7 +41,7 @@ export function testAndroidApplicationInitialized() {
TKUnit.assert(app.android, "Android application not initialized.");
TKUnit.assert(app.android.context, "Android context not initialized.");
TKUnit.assert(app.android.foregroundActivity, "Android foregroundActivity not initialized.");
TKUnit.assert(app.android.foregroundActivity.isNativeScriptActivity, "Andorid foregroundActivity.isNativeScriptActivity is false.");
TKUnit.assert(app.android.foregroundActivity.isNativeScriptActivity, "Android foregroundActivity.isNativeScriptActivity is false.");
TKUnit.assert(app.android.startActivity, "Android startActivity not initialized.");
TKUnit.assert(app.android.nativeApp, "Android nativeApp not initialized.");
TKUnit.assert(app.android.orientation, "Android orientation not initialized.");

View File

@@ -1,6 +1,6 @@
{
"name": "tns-core-modules-widgets",
"version": "6.1.0",
"version": "6.2.0",
"description": "Native widgets used in the NativeScript framework.",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
@@ -17,8 +17,8 @@
"homepage": "https://github.com/NativeScript/NativeScript/blob/master/tns-core-modules-widgets#readme",
"nativescript": {
"platforms": {
"ios": "5.0.0",
"android": "5.0.0"
"ios": "6.0.0",
"android": "6.0.0"
}
}
}

View File

@@ -85,10 +85,13 @@ export function clear(): void {
}
export function flush(): boolean {
ensureSharedPreferences();
return sharedPreferences.edit().commit();
}
export function getAllKeys(): Array<string> {
ensureSharedPreferences();
const mappedPreferences = sharedPreferences.getAll();
const iterator = mappedPreferences.keySet().iterator();
const result = [];

View File

@@ -1,6 +1,7 @@
import * as definition from ".";
import * as definition from ".";
import * as types from "../utils/types";
import * as knownColors from "./known-colors";
import { convertHSLToRGBColor } from "tns-core-modules/css/parser";
const SHARP = "#";
const HEX_REGEX = /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)|(^#[0-9A-F]{8}$)/i;
@@ -18,6 +19,8 @@ export class Color implements definition.Color {
if (types.isString(arg)) {
if (isRgbOrRgba(arg)) {
this._argb = argbFromRgbOrRgba(arg);
} else if (isHslOrHsla(arg)) {
this._argb = argbFromHslOrHsla(arg);
} else if (knownColors.isKnownName(arg)) {
// The parameter is a known color name
const hex = knownColors.getKnownColor(arg);
@@ -127,7 +130,7 @@ export class Color implements definition.Color {
return true;
}
return HEX_REGEX.test(value) || isRgbOrRgba(value);
return HEX_REGEX.test(value) || isRgbOrRgba(value) || isHslOrHsla(value);
}
private _componentToHex(component: number): string {
@@ -162,33 +165,58 @@ function isRgbOrRgba(value: string): boolean {
return (toLower.indexOf("rgb(") === 0 || toLower.indexOf("rgba(") === 0) && toLower.indexOf(")") === (toLower.length - 1);
}
function argbFromRgbOrRgba(value: string): number {
function isHslOrHsla(value: string): boolean {
const toLower = value.toLowerCase();
const parts = toLower.replace("rgba(", "").replace("rgb(", "").replace(")", "").trim().split(",");
let r = 255;
let g = 255;
let b = 255;
return (toLower.indexOf("hsl(") === 0 || toLower.indexOf("hsla(") === 0) && toLower.indexOf(")") === (toLower.length - 1);
}
function parseColorWithAlpha(value: string): any {
const toLower = value.toLowerCase();
const parts = toLower.replace(/(rgb|hsl)a?\(/, "")
.replace(")", "")
.trim().split(",");
let f = 255;
let s = 255;
let t = 255;
let a = 255;
if (parts[0]) {
r = parseInt(parts[0].trim());
f = parseInt(parts[0].trim());
}
if (parts[1]) {
g = parseInt(parts[1].trim());
s = parseInt(parts[1].trim());
}
if (parts[2]) {
b = parseInt(parts[2].trim());
t = parseInt(parts[2].trim());
}
if (parts[3]) {
a = Math.round(parseFloat(parts[3].trim()) * 255);
}
return { f, s, t, a };
}
function argbFromRgbOrRgba(value: string): number {
const { f: r, s: g, t: b, a } = parseColorWithAlpha(value);
return (a & 0xFF) * 0x01000000
+ (r & 0xFF) * 0x00010000
+ (g & 0xFF) * 0x00000100
+ (b & 0xFF) * 0x00000001;
+ (b & 0xFF);
}
function argbFromHslOrHsla(value: string): number {
const { f: h, s: s, t: l, a } = parseColorWithAlpha(value);
const { r, g, b } = convertHSLToRGBColor(h, s, l);
return (a & 0xFF) * 0x01000000
+ (r & 0xFF) * 0x00010000
+ (g & 0xFF) * 0x00000100
+ (b & 0xFF);
}

View File

@@ -84,7 +84,7 @@ export function parseHexColor(text: string, start: number = 0): Parsed<ARGB> {
function rgbaToArgbNumber(r: number, g: number, b: number, a: number = 1): number | undefined {
if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255 && a >= 0 && a <= 1) {
return (Math.round(a * 0xFF) * 0x01000000) + (r * 0x010000) + (g * 0x000100) + (b * 0x000001);
return (Math.round(a * 0xFF) * 0x01000000) + (r * 0x010000) + (g * 0x000100) + b;
} else {
return null;
}
@@ -116,6 +116,67 @@ export function parseRGBAColor(text: string, start: number = 0): Parsed<ARGB> {
return { start, end, value };
}
export function convertHSLToRGBColor(hue: number, saturation: number, lightness: number): { r: number; g: number; b: number; } {
// Per formula it will be easier if hue is divided to 60° and saturation to 100 beforehand
// https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB
hue /= 60;
lightness /= 100;
let chroma = (1 - Math.abs(2 * lightness - 1)) * saturation / 100,
X = chroma * (1 - Math.abs(hue % 2 - 1)),
// Add lightness match to all RGB components beforehand
{ m: r, m: g, m: b } = { m: lightness - chroma / 2 };
if (0 <= hue && hue < 1) { r += chroma; g += X; }
else if (hue < 2) { r += X; g += chroma; }
else if (hue < 3) { g += chroma; b += X; }
else if (hue < 4) { g += X; b += chroma; }
else if (hue < 5) { r += X; b += chroma; }
else if (hue < 6) { r += chroma; b += X; }
return {
r: Math.round(r * 0xFF),
g: Math.round(g * 0xFF),
b: Math.round(b * 0xFF)
};
}
function hslaToArgbNumber(h: number, s: number, l: number, a: number = 1): number | undefined {
let { r, g, b } = convertHSLToRGBColor(h, s, l);
if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255 && a >= 0 && a <= 1) {
return (Math.round(a * 0xFF) * 0x01000000) + (r * 0x010000) + (g * 0x000100) + b;
} else {
return null;
}
}
const hslColorRegEx = /\s*(hsl\(\s*([\d.]*)\s*,\s*([\d.]*)%\s*,\s*([\d.]*)%\s*\))/gy;
export function parseHSLColor(text: string, start: number = 0): Parsed<ARGB> {
hslColorRegEx.lastIndex = start;
const result = hslColorRegEx.exec(text);
if (!result) {
return null;
}
const end = hslColorRegEx.lastIndex;
const value = result[1] && hslaToArgbNumber(parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4]));
return { start, end, value };
}
const hslaColorRegEx = /\s*(hsla\(\s*([\d.]*)\s*,\s*([\d.]*)%\s*,\s*([\d.]*)%\s*,\s*([01]?\.?\d*)\s*\))/gy;
export function parseHSLAColor(text: string, start: number = 0): Parsed<ARGB> {
hslaColorRegEx.lastIndex = start;
const result = hslaColorRegEx.exec(text);
if (!result) {
return null;
}
const end = hslaColorRegEx.lastIndex;
const value = hslaToArgbNumber(parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4]), parseFloat(result[5]));
return { start, end, value };
}
export enum colors {
transparent = 0x00000000,
aliceblue = 0xFFF0F8FF,
@@ -280,7 +341,12 @@ export function parseColorKeyword(value, start: number, keyword = parseKeyword(v
}
export function parseColor(value: string, start: number = 0, keyword = parseKeyword(value, start)): Parsed<ARGB> {
return parseHexColor(value, start) || parseColorKeyword(value, start, keyword) || parseRGBColor(value, start) || parseRGBAColor(value, start);
return parseHexColor(value, start) ||
parseColorKeyword(value, start, keyword) ||
parseRGBColor(value, start) ||
parseRGBAColor(value, start) ||
parseHSLColor(value, start) ||
parseHSLAColor(value, start);
}
const keywordRegEx = /\s*([a-z][\w\-]*)\s*/giy;

View File

@@ -1,7 +1,7 @@
{
"name": "tns-core-modules",
"description": "Telerik NativeScript Core Modules",
"version": "6.1.1",
"version": "6.2.0",
"homepage": "https://www.nativescript.org",
"repository": {
"type": "git",
@@ -39,8 +39,8 @@
},
"nativescript": {
"platforms": {
"ios": "5.0.0",
"android": "5.0.0"
"ios": "6.0.0",
"android": "6.0.0"
}
},
"snapshot": {

View File

@@ -1,6 +1,6 @@
{
"name": "tns-platform-declarations",
"version": "6.1.1",
"version": "6.2.0",
"description": "Platform-specific TypeScript declarations for NativeScript for accessing native objects",
"main": "",
"scripts": {

View File

@@ -56,6 +56,8 @@ describe("css", () => {
test(parseColor, " #85456789 ", { start: 0, end: 12, value: 0x85456789 });
test(parseColor, " rgb(255, 8, 128) ", { start: 0, end: 18, value: 0xFFFF0880 });
test(parseColor, " rgba(255, 8, 128, 0.5) ", { start: 0, end: 24, value: 0x80FF0880 });
test(parseColor, " hsl(330.9, 100%, 51.6%) ", { start: 0, end: 25, value: 0xFFFF0880 });
test(parseColor, " hsla(330.9, 100%, 51.6%, 0.5) ", { start: 0, end: 31, value: 0x80FF0880 });
test(parseColor, "#FF0000 url(lucky.gif)", 8, null);
test(parseColor, "url(lucky.gif) #FF0000 repeat", 15, { start: 15, end: 23, value: 0xFFFF0000 });
});
@@ -175,11 +177,11 @@ describe("css", () => {
test(parseSelector, `[src ${attributeTest} "val"]`, { start: 0, end: 12 + attributeTest.length, value: [[[{ type: "[]", property: "src", test: attributeTest, value: "val"}], undefined]]});
});
test(parseSelector, "listview > .image", { start: 0, end: 17, value: [
[[{ type: "", identifier: "listview"}], ">"],
[[{ type: "", identifier: "listview"}], ">"],
[[{ type: ".", identifier: "image"}], undefined]
]});
test(parseSelector, "listview .image", { start: 0, end: 16, value: [
[[{ type: "", identifier: "listview"}], " "],
[[{ type: "", identifier: "listview"}], " "],
[[{ type: ".", identifier: "image"}], undefined]
]});
test(parseSelector, "button:hover", { start: 0, end: 12, value: [[[{ type: "", identifier: "button" }, { type: ":", identifier: "hover"}], undefined]]});