diff --git a/.travis.yml b/.travis.yml
index 09ea3d370..fc289f2cc 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,14 +1,12 @@
env:
global:
- NODE_VERSION=6.9.1
- - DATE=$(date +%Y-%m-%d)
- - PACKAGE_VERSION=$DATE-$TRAVIS_BUILD_NUMBER
- EMULATOR_API_LEVEL=19
- ANDROID_VERSION=23
- ANDROID_BUILD_TOOLS_VERSION=23.0.1
- ANDROID_ABI=armeabi-v7a
- ANDROID_TAG=google_apis
- - APPIUM_VERSION=1.6.3
+ - APPIUM_VERSION=1.6.5
language: android
jdk:
- oraclejdk8
@@ -38,27 +36,12 @@ install:
- npm run tslint
- cd ../tests
- npm install
+- npm i appium@$APPIUM_VERSION
before_script:
- echo no | android create avd --force -n test -t android-$EMULATOR_API_LEVEL --abi $ANDROID_ABI
- emulator -memory 1024 -avd test -no-audio -no-window &
- android-wait-for-emulator
script:
--
--
- tns build android
- android-wait-for-emulator
-- npm run run-appium-android
-before_deploy:
-- cd ../nativescript-angular
-- npm install -g nativescript --ignore-scripts
-- tns usage-reporting disable
-- tns error-reporting disable
-- node ../build/travis-scripts/add-publishConfig.js next $PACKAGE_VERSION
-deploy:
- provider: npm
- email: nativescript@telerik.com
- skip_cleanup: true
- api_key:
- secure: J88MqLAoZStZZ77AAf+wgaoZp+8zG3fOUHRneSe4x/yEzyUShS9SlGuq0TSkm9sJVX94iHJl1BQ4yjLshOPV9dkOg1+BB4PbsDTKPCAhPCZgpW7WKz6iImmuWHArchLIRtI1fp+UYi1+V6c7gLALQPY7qR2QJcDJdq1tdgORAyGySMis95ttVhnn6DWTBbs/ocu+IzgOyBSkIiZR0mGk7q/pmVQPy+XL5PQoyUOhD4MmvAAIeVr+XoZ5I8pAUwhi1/bZijXrzWe7LbXh8pTDlEWvYduzYYjJZqUrHiE/e1e8/DIPXGaBUQBj7LRxSqqO8AJXGeCg4DF1R9j4CSG5c0pAwQ/U6vOGu8duPEGaoKG5+HlrTav7gI/YbwFA5HKyh1uzQ5trZDJ4mMKUoB1+8/eL2cjLudtyBB2Kg28wH6f78A9mQC1EJcP7Jz3qJTSUyhczIvwSF8/EkD8xmeaoTi2e+4TNgf7pys1cp6c7m7zKZbvVy25lfyAfG1rCF5+rzKj+GnE9mtLaY6VvlKWjyxklh8hfRBC94TZ8K7PH0tmdgk2Jal+OCdm9FDdmNrBSC1G/gPS8PchtffIRprPhNAUfcVpdg0rlQ4dckbGRbB5UBgwHkpoKasaSTx/nO85AiK6USIYOIod19loXUBvN3QyHUX76w265UhmTnb8iojo=
- on:
- branch: master
\ No newline at end of file
+- npm run appium --runtype=android19 --appium=$APPIUM_VERSION
diff --git a/CHANGELOG.md b/CHANGELOG.md
index aa037c81d..2ce916fb8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,33 @@
+
+## [3.1.1](https://github.com/NativeScript/nativescript-angular/compare/3.1.0...3.1.1) (2017-06-29)
+
+
+### Bug Fixes
+
+* **forms:** add directives for formControl ([#861](https://github.com/NativeScript/nativescript-angular/issues/861)) ([#864](https://github.com/NativeScript/nativescript-angular/issues/864)) ([d29c8e1](https://github.com/NativeScript/nativescript-angular/commit/d29c8e1))
+
+
+
+
+# [3.1.0](https://github.com/NativeScript/nativescript-angular/compare/3.0.0...3.1.0) (2017-06-19)
+
+
+### Bug Fixes
+
+* **animations:** use parsers from core modules ([#844](https://github.com/NativeScript/nativescript-angular/issues/844)) ([1abebb6](https://github.com/NativeScript/nativescript-angular/commit/1abebb6)), closes [#738](https://github.com/NativeScript/nativescript-angular/issues/738)
+* **dom-adapter:** add fake implementation for getUserAgent ([#835](https://github.com/NativeScript/nativescript-angular/issues/835)) ([743131c](https://github.com/NativeScript/nativescript-angular/commit/743131c)), closes [#831](https://github.com/NativeScript/nativescript-angular/issues/831)
+* **forms:** add (touch) event and [disabled] property for controls ([#836](https://github.com/NativeScript/nativescript-angular/issues/836)) ([c8a6404](https://github.com/NativeScript/nativescript-angular/commit/c8a6404)), closes [#804](https://github.com/NativeScript/nativescript-angular/issues/804)
+* **ns-router-link:** convert clearHistory string to boolean ([#834](https://github.com/NativeScript/nativescript-angular/issues/834)) ([ff99984](https://github.com/NativeScript/nativescript-angular/commit/ff99984)), closes [#832](https://github.com/NativeScript/nativescript-angular/issues/832)
+* **renderer:** add styles when ViewEncapsulation is None ([#812](https://github.com/NativeScript/nativescript-angular/issues/812)) ([8d013e2](https://github.com/NativeScript/nativescript-angular/commit/8d013e2)), closes [#794](https://github.com/NativeScript/nativescript-angular/issues/794)
+* **renderer:** set templateParent to comment and text nodes ([#785](https://github.com/NativeScript/nativescript-angular/issues/785)) ([b127ba7](https://github.com/NativeScript/nativescript-angular/commit/b127ba7)), closes [#777](https://github.com/NativeScript/nativescript-angular/issues/777) [#787](https://github.com/NativeScript/nativescript-angular/issues/787)
+* **renderer:** stop performing value conversions ([#806](https://github.com/NativeScript/nativescript-angular/issues/806)) ([354074d](https://github.com/NativeScript/nativescript-angular/commit/354074d)), closes [#799](https://github.com/NativeScript/nativescript-angular/issues/799)
+
+### Features
+
+* **Modal:** allow modal to be lazily loaded from a module on demand ([#772](https://github.com/NativeScript/nativescript-angular/issues/772)) ([6a1f6a9](https://github.com/NativeScript/nativescript-angular/commit/6a1f6a9))
+
-# [3.0.0](https://github.com/NativeScript/nativescript-angular/compare/v1.5.2..v3.0.0) (2017-05-03)
+# [3.0.0](https://github.com/NativeScript/nativescript-angular/compare/v1.5.2..3.0.0) (2017-05-03)
### Bug Fixes
diff --git a/build/generate-value-accessor-selector.js b/build/generate-value-accessor-selector.js
deleted file mode 100644
index ffa189806..000000000
--- a/build/generate-value-accessor-selector.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Usage:
-// node generate-value-accessor-selector TextField TextView
-
-function generateValueAccessorSelector(tagNames) {
- const tags = [];
- tagNames.forEach(tagName => {
- tags.push(tagName); // regular tag
- tags.push(tagName.charAt(0).toLowerCase() + tagName.slice(1)); // lowercase first char
- tags.push(tagName.split(/(?=[A-Z])/).join("-").toLowerCase()); // kebab case
- });
-
- const selectors = [];
- for (const tag of tags) {
- for (const directive of ["ngModel", "formControlName"]) {
- selectors.push(`${tag}[${directive}]`);
- }
- }
- return selectors.join(", ");
-}
-
-process.argv.shift();
-process.argv.shift();
-console.log(generateValueAccessorSelector(process.argv));
diff --git a/build/prepublish-next.js b/build/prepublish-next.js
new file mode 100644
index 000000000..e320c99f8
--- /dev/null
+++ b/build/prepublish-next.js
@@ -0,0 +1,33 @@
+#!/usr/bin/env node
+const fs = require("fs");
+const path = require("path");
+
+const getPackageJson = projectDir => {
+ const packageJsonPath = getPackageJsonPath(projectDir);
+ return JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
+};
+
+const writePackageJson = (content, projectDir) => {
+ const packageJsonPath = getPackageJsonPath(projectDir);
+ fs.writeFileSync(packageJsonPath, JSON.stringify(content, null, 2))
+}
+
+const getPackageJsonPath = projectDir => path.resolve(projectDir, "package.json");
+
+const tag = "next";
+const projectDir = "nativescript-angular";
+const packageJson = getPackageJson(projectDir);
+const [, , packageVersion = new Date() ] = process.argv;
+
+packageJson.publishConfig = Object.assign(
+ packageJson.publishConfig || {},
+ { tag }
+);
+
+delete packageJson.private;
+
+const currentVersion = packageJson.version;
+const nextVersion = `${currentVersion}-${packageVersion}`;
+const newPackageJson = Object.assign(packageJson, { version: nextVersion });
+
+writePackageJson(newPackageJson, projectDir);
diff --git a/build/travis-scripts/add-publishConfig.js b/build/travis-scripts/add-publishConfig.js
deleted file mode 100644
index 224c66165..000000000
--- a/build/travis-scripts/add-publishConfig.js
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env node
-
-var fsModule = require('fs');
-
-//Adds a publishConfig section to the package.json file
-// and sets a tag to it
-
-var path = './package.json';
-var fileOptions = {encoding: "utf-8"};
-var content = fsModule.readFileSync(path, fileOptions);
-
-var tag = process.argv[2];
-if (!tag) {
- console.log('Please pass the tag name as an argument!');
- process.exit(1);
-}
-
-var packageDef = JSON.parse(content);
-if (!packageDef.publishConfig) {
- packageDef.publishConfig = {};
-}
-packageDef.publishConfig.tag = tag;
-
-if (packageDef.private) {
- delete packageDef.private;
-}
-
-// adding date and travis build number (2016-07-18-765) to version in order to get unique version for @next build
-var package_version = process.argv[3];
-packageDef.version += '-' + package_version;
-
-var newContent = JSON.stringify(packageDef, null, ' ');
-fsModule.writeFileSync(path, newContent, fileOptions);
diff --git a/nativescript-angular/CHANGELOG.md b/nativescript-angular/CHANGELOG.md
new file mode 100644
index 000000000..873d9cfda
--- /dev/null
+++ b/nativescript-angular/CHANGELOG.md
@@ -0,0 +1,25 @@
+
+## [3.1.2](https://github.com/NativeScript/nativescript-angular/compare/3.0.0...3.1.2) (2017-07-12)
+
+
+### Bug Fixes
+
+* **animations:** use parsers from core modules ([#844](https://github.com/NativeScript/nativescript-angular/issues/844)) ([1abebb6](https://github.com/NativeScript/nativescript-angular/commit/1abebb6)), closes [#738](https://github.com/NativeScript/nativescript-angular/issues/738)
+* **dom-adapter:** add fake implementation for getUserAgent ([#835](https://github.com/NativeScript/nativescript-angular/issues/835)) ([743131c](https://github.com/NativeScript/nativescript-angular/commit/743131c)), closes [#831](https://github.com/NativeScript/nativescript-angular/issues/831)
+* **forms:** add (touch) event and [disabled] property for controls ([#836](https://github.com/NativeScript/nativescript-angular/issues/836)) ([c8a6404](https://github.com/NativeScript/nativescript-angular/commit/c8a6404)), closes [#804](https://github.com/NativeScript/nativescript-angular/issues/804)
+* **forms:** add directives for formControl ([#861](https://github.com/NativeScript/nativescript-angular/issues/861)) ([bd38745](https://github.com/NativeScript/nativescript-angular/commit/bd38745))
+* **ns-router-link:** convert clearHistory string to boolean ([#834](https://github.com/NativeScript/nativescript-angular/issues/834)) ([ff99984](https://github.com/NativeScript/nativescript-angular/commit/ff99984)), closes [#832](https://github.com/NativeScript/nativescript-angular/issues/832)
+* **renderer:** add styles when ViewEncapsulation is None ([#812](https://github.com/NativeScript/nativescript-angular/issues/812)) ([8d013e2](https://github.com/NativeScript/nativescript-angular/commit/8d013e2)), closes [#794](https://github.com/NativeScript/nativescript-angular/issues/794)
+* **renderer:** attach `CommentNode`s to visual tree ([#888](https://github.com/NativeScript/nativescript-angular/issues/888)) ([65359fa](https://github.com/NativeScript/nativescript-angular/commit/65359fa)), closes [#872](https://github.com/NativeScript/nativescript-angular/issues/872)
+* **renderer:** set templateParent to comment and text nodes ([#785](https://github.com/NativeScript/nativescript-angular/issues/785)) ([b127ba7](https://github.com/NativeScript/nativescript-angular/commit/b127ba7)), closes [#777](https://github.com/NativeScript/nativescript-angular/issues/777) [#787](https://github.com/NativeScript/nativescript-angular/issues/787)
+* **renderer:** stop performing value conversions ([#806](https://github.com/NativeScript/nativescript-angular/issues/806)) ([354074d](https://github.com/NativeScript/nativescript-angular/commit/354074d)), closes [#799](https://github.com/NativeScript/nativescript-angular/issues/799)
+* **time-value-accessor:** typo onTouch -> onTouched ([#843](https://github.com/NativeScript/nativescript-angular/issues/843)) ([6168ddb](https://github.com/NativeScript/nativescript-angular/commit/6168ddb))
+* export NgView and NgElement from element-registry ([#823](https://github.com/NativeScript/nativescript-angular/issues/823)) ([4521c7c](https://github.com/NativeScript/nativescript-angular/commit/4521c7c))
+
+
+### Features
+
+* **Modal:** allow modal to be lazily loaded from a module on demand ([#772](https://github.com/NativeScript/nativescript-angular/issues/772)) ([6a1f6a9](https://github.com/NativeScript/nativescript-angular/commit/6a1f6a9))
+
+
+
diff --git a/nativescript-angular/animations/animation-engine.ts b/nativescript-angular/animations/animation-engine.ts
index 0dcbd51ff..b5e0911dc 100644
--- a/nativescript-angular/animations/animation-engine.ts
+++ b/nativescript-angular/animations/animation-engine.ts
@@ -1,3 +1,4 @@
+/* tslint:disable */
import { ɵDomAnimationEngine as DomAnimationEngine } from "@angular/animations/browser";
import { AnimationEvent, AnimationPlayer } from "@angular/animations";
diff --git a/nativescript-angular/directives/list-view-comp.ts b/nativescript-angular/directives/list-view-comp.ts
index cbf9aa46f..f2237df90 100644
--- a/nativescript-angular/directives/list-view-comp.ts
+++ b/nativescript-angular/directives/list-view-comp.ts
@@ -21,11 +21,11 @@ import {
} from "@angular/core";
import { ListView, ItemEventData } from "tns-core-modules/ui/list-view";
import { View, KeyedTemplate } from "tns-core-modules/ui/core/view";
-import { ObservableArray } from "tns-core-modules/data/observable-array";
import { LayoutBase } from "tns-core-modules/ui/layouts/layout-base";
+import { ObservableArray } from "tns-core-modules/data/observable-array";
import { profile } from "tns-core-modules/profiling";
-import { CommentNode } from "../element-registry";
+import { getSingleViewRecursive } from "../element-registry";
import { isListLikeIterable } from "../collection-facade";
import { listViewLog, listViewError } from "../trace";
@@ -216,30 +216,6 @@ export class ListViewComponent implements DoCheck, OnDestroy, AfterContentInit {
}
}
-function getSingleViewRecursive(nodes: Array, nestLevel: number): View {
- const actualNodes = nodes.filter(node => !(node instanceof CommentNode));
-
- if (actualNodes.length === 0) {
- throw new Error(`No suitable views found in list template! ` +
- `Nesting level: ${nestLevel}`);
- } else if (actualNodes.length > 1) {
- throw new Error(`More than one view found in list template!` +
- `Nesting level: ${nestLevel}`);
- }
-
- const rootLayout = actualNodes[0];
- if (!rootLayout) {
- return getSingleViewRecursive(rootLayout.children, nestLevel + 1);
- }
-
- let parentLayout = rootLayout.parent;
- if (parentLayout instanceof LayoutBase) {
- parentLayout.removeChild(rootLayout);
- }
-
- return rootLayout;
-}
-
export interface ComponentView {
rootNodes: Array;
destroy(): void;
diff --git a/nativescript-angular/directives/tab-view.ts b/nativescript-angular/directives/tab-view.ts
index 3b578be54..a945531f9 100644
--- a/nativescript-angular/directives/tab-view.ts
+++ b/nativescript-angular/directives/tab-view.ts
@@ -9,7 +9,7 @@ import {
} from "@angular/core";
import { TabView, TabViewItem } from "tns-core-modules/ui/tab-view";
-import { CommentNode } from "../element-registry";
+import { InvisibleNode } from "../element-registry";
import { rendererLog } from "../trace";
import { isBlank } from "../lang-facade";
@@ -105,7 +105,7 @@ export class TabViewItemDirective implements OnInit {
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
// Filter out text nodes and comments
const realViews = viewRef.rootNodes.filter(node =>
- !(node instanceof CommentNode));
+ !(node instanceof InvisibleNode));
if (realViews.length > 0) {
this.item.view = realViews[0];
diff --git a/nativescript-angular/element-registry.ts b/nativescript-angular/element-registry.ts
index 6cf0c6cf0..9a0f044aa 100644
--- a/nativescript-angular/element-registry.ts
+++ b/nativescript-angular/element-registry.ts
@@ -1,7 +1,8 @@
import { View } from "tns-core-modules/ui/core/view";
+import { LayoutBase } from "tns-core-modules/ui/layouts/layout-base";
export type NgView = (View & ViewExtensions);
-export type NgElement = NgView | CommentNode;
+export type NgElement = NgView | InvisibleNode;
export interface ViewExtensions {
nodeType: number;
@@ -15,12 +16,55 @@ export interface ViewClass {
new (): View;
}
-// used for creating comments and text nodes in the renderer
-export class CommentNode {
- meta: { skipAddToDom: true };
+export abstract class InvisibleNode extends View implements ViewExtensions {
+ meta: { skipAddToDom: boolean };
templateParent: NgView;
+ nodeType: number;
+ nodeName: string;
+ ngCssClasses: Map;
+
+ constructor() {
+ super();
+
+ this.nodeType = 1;
+ this.nodeName = getClassName(this);
+ }
+
+ toString() {
+ return `${this.nodeName}(${this.id})`;
+ }
+}
+
+export class CommentNode extends InvisibleNode {
+ protected static id = 0;
+
+ constructor() {
+ super();
+
+ this.meta = {
+ skipAddToDom: false,
+ };
+ this.id = CommentNode.id.toString();
+ CommentNode.id += 1;
+ }
+}
+
+export class TextNode extends InvisibleNode {
+ protected static id = 0;
+
+ constructor() {
+ super();
+
+ this.meta = {
+ skipAddToDom: true,
+ };
+ this.id = TextNode.id.toString();
+ TextNode.id += 1;
+ }
}
+const getClassName = instance => instance.constructor.name;
+
export interface ViewClassMeta {
skipAddToDom?: boolean;
insertChild?: (parent: NgView, child: NgView, atIndex: number) => void;
@@ -76,6 +120,30 @@ export function isKnownView(elementName: string): boolean {
elementMap.has(elementName.toLowerCase());
}
+export function getSingleViewRecursive(nodes: Array, nestLevel: number): View {
+ const actualNodes = nodes.filter(node => !(node instanceof InvisibleNode));
+
+ if (actualNodes.length === 0) {
+ throw new Error(`No suitable views found in list template! ` +
+ `Nesting level: ${nestLevel}`);
+ } else if (actualNodes.length > 1) {
+ throw new Error(`More than one view found in list template!` +
+ `Nesting level: ${nestLevel}`);
+ }
+
+ const rootLayout = actualNodes[0];
+ if (!rootLayout) {
+ return getSingleViewRecursive(rootLayout.children, nestLevel + 1);
+ }
+
+ const parentLayout = rootLayout.parent;
+ if (parentLayout instanceof LayoutBase) {
+ parentLayout.removeChild(rootLayout);
+ }
+
+ return rootLayout;
+}
+
// Register default NativeScript components
// Note: ActionBar related components are registerd together with action-bar directives.
registerElement("AbsoluteLayout", () => require("tns-core-modules/ui/layouts/absolute-layout").AbsoluteLayout);
diff --git a/nativescript-angular/package.json b/nativescript-angular/package.json
index f08150dcb..0ec2d8c69 100644
--- a/nativescript-angular/package.json
+++ b/nativescript-angular/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "nativescript-angular",
- "version": "3.1.0",
+ "version": "3.1.2",
"description": "An Angular renderer that lets you build mobile apps with NativeScript.",
"homepage": "https://www.nativescript.org/",
"bugs": "https://github.com/NativeScript/nativescript-angular/issues",
@@ -51,7 +51,7 @@
"@angular/platform-browser": "~4.0.0 || ~4.1.0",
"@angular/router": "~4.0.0 || ~4.1.0",
"rxjs": "^5.0.1",
- "tns-core-modules": "^3.0.0",
+ "tns-core-modules": "^3.1.0 || >3.2.0-",
"zone.js": "^0.8.4"
},
"devDependencies": {
@@ -64,11 +64,11 @@
"@angular/http": "~4.0.0 || ~4.1.0",
"@angular/platform-browser": "~4.0.0 || ~4.1.0",
"@angular/router": "~4.0.0 || ~4.1.0",
- "codelyzer": "^3.0.1",
- "rxjs": "^5.0.1",
+ "codelyzer": "^3.1.2",
+ "rxjs": "^5.4.2",
"tns-core-modules": "next",
"tslint": "^5.1.0",
- "typescript": "^2.3.2",
+ "typescript": "^2.4.0",
"zone.js": "^0.8.4"
}
}
diff --git a/nativescript-angular/renderer.ts b/nativescript-angular/renderer.ts
index b95318bc3..8f3826e2d 100644
--- a/nativescript-angular/renderer.ts
+++ b/nativescript-angular/renderer.ts
@@ -13,7 +13,7 @@ import { profile } from "tns-core-modules/profiling";
import { APP_ROOT_VIEW, DEVICE, getRootPage } from "./platform-providers";
import { isBlank } from "./lang-facade";
import { ViewUtil } from "./view-util";
-import { NgView, CommentNode } from "./element-registry";
+import { NgView, InvisibleNode } from "./element-registry";
import { rendererLog as traceLog } from "./trace";
// CONTENT_ATTR not exported from NativeScript_renderer - we need it for styles application.
@@ -120,7 +120,7 @@ export class NativeScriptRenderer extends Renderer2 {
}
@profile
- createComment(_value: any): CommentNode {
+ createComment(_value: any): InvisibleNode {
traceLog(`NativeScriptRenderer.createComment ${_value}`);
return this.viewUtil.createComment();
}
@@ -132,7 +132,7 @@ export class NativeScriptRenderer extends Renderer2 {
}
@profile
- createText(_value: string): CommentNode {
+ createText(_value: string): InvisibleNode {
traceLog(`NativeScriptRenderer.createText ${_value}`);
return this.viewUtil.createText();
}
@@ -284,6 +284,7 @@ class EmulatedRenderer extends NativeScriptRenderer {
}
}
+// tslint:disable-next-line
const addStyleToCss = profile('"renderer".addStyleToCss', function addStyleToCss(style: string): void {
addCss(style);
});
diff --git a/nativescript-angular/router/ns-module-factory-loader.ts b/nativescript-angular/router/ns-module-factory-loader.ts
index a64868808..052669d87 100644
--- a/nativescript-angular/router/ns-module-factory-loader.ts
+++ b/nativescript-angular/router/ns-module-factory-loader.ts
@@ -6,7 +6,10 @@ import {
SystemJsNgModuleLoader,
Type,
} from "@angular/core";
-import { path, knownFolders } from "tns-core-modules/file-system";
+import {
+ path as fileSystemPath,
+ knownFolders
+} from "tns-core-modules/file-system";
const SEPARATOR = "#";
@@ -51,9 +54,9 @@ function splitPath(path: string): {modulePath: string, exportName: string} {
function getAbsolutePath(relativePath: string) {
const projectPath = knownFolders.currentApp().path;
- const absolutePath = path.join(projectPath, relativePath);
+ const absolutePath = fileSystemPath.join(projectPath, relativePath);
- return path.normalize(absolutePath);
+ return fileSystemPath.normalize(absolutePath);
}
function checkNotEmpty(value: any, modulePath: string, exportName: string): void {
diff --git a/nativescript-angular/router/ns-router-link.ts b/nativescript-angular/router/ns-router-link.ts
index 1881f43e3..0a5bfed50 100644
--- a/nativescript-angular/router/ns-router-link.ts
+++ b/nativescript-angular/router/ns-router-link.ts
@@ -107,7 +107,7 @@ export class NSRouterLink implements OnChanges { // tslint:disable-line:directiv
} else {
return {
animated: true,
- transition: this.pageTransition
+ transition: this.pageTransition
};
}
}
diff --git a/nativescript-angular/tsconfig.json b/nativescript-angular/tsconfig.json
index 641cfd5e2..e05ddfed9 100644
--- a/nativescript-angular/tsconfig.json
+++ b/nativescript-angular/tsconfig.json
@@ -11,8 +11,6 @@
"declaration": true,
"removeComments": false,
"noEmitOnError": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
"noImplicitAny": false,
"lib": [
"dom",
diff --git a/nativescript-angular/tslint.json b/nativescript-angular/tslint.json
index 4a49adfe4..b9630d813 100644
--- a/nativescript-angular/tslint.json
+++ b/nativescript-angular/tslint.json
@@ -61,6 +61,7 @@
"no-string-literal": false,
"no-switch-case-fall-through": true,
"no-unused-expression": true,
+ "no-unused-variable": true,
"no-var-keyword": true,
"radix": false,
"switch-default": true,
diff --git a/nativescript-angular/value-accessors/base-value-accessor.ts b/nativescript-angular/value-accessors/base-value-accessor.ts
index d7b180c56..25ac8aa7a 100644
--- a/nativescript-angular/value-accessors/base-value-accessor.ts
+++ b/nativescript-angular/value-accessors/base-value-accessor.ts
@@ -2,7 +2,7 @@ import { ControlValueAccessor } from "@angular/forms";
import { View } from "tns-core-modules/ui/core/view";
export class BaseValueAccessor implements ControlValueAccessor {
- private pendingChangeNotification: number = 0;
+ private pendingChangeNotification: any = 0;
onChange = (_) => { };
onTouched = () => {};
diff --git a/nativescript-angular/value-accessors/checked-value-accessor.ts b/nativescript-angular/value-accessors/checked-value-accessor.ts
index 85d8a1a2c..af1a22289 100644
--- a/nativescript-angular/value-accessors/checked-value-accessor.ts
+++ b/nativescript-angular/value-accessors/checked-value-accessor.ts
@@ -20,8 +20,8 @@ const CHECKED_VALUE_ACCESSOR = {
*/
@Directive({
selector:
- "Switch[ngModel],Switch[formControlName]," +
- "switch[ngModel],switch[formControlName]",
+ "Switch[ngModel],Switch[formControlName],Switch[formControl]," +
+ "switch[ngModel],switch[formControlName],switch[formControl]",
providers: [CHECKED_VALUE_ACCESSOR],
host: {
"(touch)": "onTouched()",
diff --git a/nativescript-angular/value-accessors/date-value-accessor.ts b/nativescript-angular/value-accessors/date-value-accessor.ts
index 4541f9bb9..9e66bbc92 100644
--- a/nativescript-angular/value-accessors/date-value-accessor.ts
+++ b/nativescript-angular/value-accessors/date-value-accessor.ts
@@ -19,10 +19,10 @@ const DATE_VALUE_ACCESSOR = {
* ```
*/
@Directive({
- selector: "DatePicker[ngModel],DatePicker[formControlName]," +
- "datepicker[ngModel],datepicker[formControlName]," +
- "datePicker[ngModel],datePicker[formControlName]," +
- "date-picker[ngModel],date-picker[formControlName]",
+ selector: "DatePicker[ngModel],DatePicker[formControlName],DatePicker[formControl]," +
+ "datepicker[ngModel],datepicker[formControlName],datepicker[formControl]," +
+ "datePicker[ngModel],datePicker[formControlName],datePicker[formControl]," +
+ "date-picker[ngModel],date-picker[formControlName],date-picker[formControl]",
providers: [DATE_VALUE_ACCESSOR],
host: {
"(touch)": "onTouched()",
diff --git a/nativescript-angular/value-accessors/number-value-accessor.ts b/nativescript-angular/value-accessors/number-value-accessor.ts
index 224a9790a..44451f96e 100644
--- a/nativescript-angular/value-accessors/number-value-accessor.ts
+++ b/nativescript-angular/value-accessors/number-value-accessor.ts
@@ -20,8 +20,8 @@ const NUMBER_VALUE_ACCESSOR = {
*/
@Directive({
selector:
- "Slider[ngModel],Slider[formControlName]," +
- "slider[ngModel],slider[formControlName]",
+ "Slider[ngModel],Slider[formControlName],Slider[formControl]," +
+ "slider[ngModel],slider[formControlName],slider[formControl]",
providers: [NUMBER_VALUE_ACCESSOR],
host: {
"(touch)": "onTouched()",
diff --git a/nativescript-angular/value-accessors/selectedIndex-value-accessor.ts b/nativescript-angular/value-accessors/selectedIndex-value-accessor.ts
index 462d294dc..005a40f98 100644
--- a/nativescript-angular/value-accessors/selectedIndex-value-accessor.ts
+++ b/nativescript-angular/value-accessors/selectedIndex-value-accessor.ts
@@ -22,20 +22,20 @@ export type SelectableView = {selectedIndex: number} & View;
*/
@Directive({
selector:
- "SegmentedBar[ngModel],SegmentedBar[formControlName]," +
- "segmentedBar[ngModel],segmentedBar[formControlName]," +
- "segmentedbar[ngModel],segmentedbar[formControlName]," +
- "segmented-bar[ngModel],segmented-bar[formControlName]," +
+ "SegmentedBar[ngModel],SegmentedBar[formControlName],SegmentedBar[formControl]," +
+ "segmentedBar[ngModel],segmentedBar[formControlName],segmentedBar[formControl]," +
+ "segmentedbar[ngModel],segmentedbar[formControlName],segmentedbar[formControl]," +
+ "segmented-bar[ngModel],segmented-bar[formControlName],segmented-bar[formControl]," +
- "ListPicker[ngModel],ListPicker[formControlName]," +
- "listPicker[ngModel],listPicker[formControlName]," +
- "listpicker[ngModel],listpicker[formControlName]," +
- "list-picker[ngModel],list-picker[formControlName]," +
+ "ListPicker[ngModel],ListPicker[formControlName],ListPicker[formControl]," +
+ "listPicker[ngModel],listPicker[formControlName],listPicker[formControl]," +
+ "listpicker[ngModel],listpicker[formControlName],listpicker[formControl]," +
+ "list-picker[ngModel],list-picker[formControlName],list-picker[formControl]," +
- "TabView[ngModel],TabView[formControlName]," +
- "tabView[ngModel],tabView[formControlName]," +
- "tabview[ngModel],tabview[formControlName]," +
- "tab-view[ngModel],tab-view[formControlName]",
+ "TabView[ngModel],TabView[formControlName],TabView[formControl]," +
+ "tabView[ngModel],tabView[formControlName],tabView[formControl]," +
+ "tabview[ngModel],tabview[formControlName],tabview[formControl]," +
+ "tab-view[ngModel],tab-view[formControlName],tab-view[formControl]",
providers: [SELECTED_INDEX_VALUE_ACCESSOR],
host: {
"(touch)": "onTouched()",
diff --git a/nativescript-angular/value-accessors/text-value-accessor.ts b/nativescript-angular/value-accessors/text-value-accessor.ts
index 03688b27e..b578cf6a3 100644
--- a/nativescript-angular/value-accessors/text-value-accessor.ts
+++ b/nativescript-angular/value-accessors/text-value-accessor.ts
@@ -22,20 +22,20 @@ export type TextView = {text: string} & View;
*/
@Directive({
selector:
- "TextField[ngModel],TextField[formControlName]," +
- "textField[ngModel],textField[formControlName]," +
- "textfield[ngModel],textfield[formControlName]," +
- "text-field[ngModel],text-field[formControlName]," +
+ "TextField[ngModel],TextField[formControlName],TextField[formControl]," +
+ "textField[ngModel],textField[formControlName],textField[formControl]," +
+ "textfield[ngModel],textfield[formControlName],textfield[formControl]," +
+ "text-field[ngModel],text-field[formControlName],text-field[formControl]," +
- "TextView[ngModel],TextView[formControlName]," +
- "textView[ngModel],textView[formControlName]," +
- "textview[ngModel],textview[formControlName]," +
- "text-view[ngModel],text-view[formControlName]," +
+ "TextView[ngModel],TextView[formControlName],TextView[formControl]," +
+ "textView[ngModel],textView[formControlName],textView[formControl]," +
+ "textview[ngModel],textview[formControlName],textview[formControl]," +
+ "text-view[ngModel],text-view[formControlName],text-view[formControl]," +
- "SearchBar[ngModel],SearchBar[formControlName]," +
- "searchBar[ngModel],searchBar[formControlName]," +
- "searchbar[ngModel],searchbar[formControlName]," +
- "search-bar[ngModel], search-bar[formControlName]",
+ "SearchBar[ngModel],SearchBar[formControlName],SearchBar[formControl]," +
+ "searchBar[ngModel],searchBar[formControlName],searchBar[formControl]," +
+ "searchbar[ngModel],searchbar[formControlName],searchbar[formControl]," +
+ "search-bar[ngModel], search-bar[formControlName],search-bar[formControl]",
providers: [TEXT_VALUE_ACCESSOR],
host: {
"(touch)": "onTouched()",
diff --git a/nativescript-angular/value-accessors/time-value-accessor.ts b/nativescript-angular/value-accessors/time-value-accessor.ts
index 4112de8f0..d62b170e7 100644
--- a/nativescript-angular/value-accessors/time-value-accessor.ts
+++ b/nativescript-angular/value-accessors/time-value-accessor.ts
@@ -20,10 +20,10 @@ const TIME_VALUE_ACCESSOR = {
*/
@Directive({
selector:
- "TimePicker[ngModel],TimePicker[formControlName]," +
- "timepicker[ngModel],timepicker[formControlName]," +
- "timePicker[ngModel],timePicker[formControlName]," +
- "time-picker[ngModel], time-picker[formControlName]",
+ "TimePicker[ngModel],TimePicker[formControlName],TimePicker[formControl]," +
+ "timepicker[ngModel],timepicker[formControlName],timepicker[formControl]," +
+ "timePicker[ngModel],timePicker[formControlName],timePicker[formControl]," +
+ "time-picker[ngModel],time-picker[formControlName],time-picker[formControl]",
providers: [TIME_VALUE_ACCESSOR],
host: {
"(touch)": "onTouched()",
diff --git a/nativescript-angular/view-util.ts b/nativescript-angular/view-util.ts
index 6349c203f..99b196197 100644
--- a/nativescript-angular/view-util.ts
+++ b/nativescript-angular/view-util.ts
@@ -5,8 +5,10 @@ import { ContentView } from "tns-core-modules/ui/content-view";
import { LayoutBase } from "tns-core-modules/ui/layouts/layout-base";
import {
CommentNode,
+ InvisibleNode,
NgElement,
NgView,
+ TextNode,
ViewExtensions,
getViewClass,
getViewMeta,
@@ -52,9 +54,8 @@ export class ViewUtil {
}
public insertChild(parent: any, child: NgElement, atIndex: number = -1) {
- if (child instanceof CommentNode) {
+ if (child instanceof InvisibleNode) {
child.templateParent = parent;
- return;
}
if (!parent || isDetachedElement(child)) {
@@ -79,16 +80,11 @@ export class ViewUtil {
parent.content = child;
} else if (parent && parent._addChildFromBuilder) {
parent._addChildFromBuilder(child.nodeName, child);
- } else {
- // throw new Error("Parent can"t contain children: " + parent.nodeName + ", " + parent);
}
}
public removeChild(parent: any, child: NgElement) {
- if (!parent ||
- child instanceof CommentNode ||
- isDetachedElement(child)) {
-
+ if (!parent || isDetachedElement(child)) {
return;
}
@@ -102,8 +98,6 @@ export class ViewUtil {
}
} else if (isView(parent)) {
parent._removeView(child);
- } else {
- // throw new Error("Unknown parent type: " + parent);
}
}
@@ -112,17 +106,15 @@ export class ViewUtil {
return parent.getChildIndex(child);
} else if (isContentView(parent)) {
return child === parent.content ? 0 : -1;
- } else {
- // throw new Error("Parent can"t contain children: " + parent);
}
}
- public createComment(): CommentNode {
+ public createComment(): InvisibleNode {
return new CommentNode();
}
- public createText(): CommentNode {
- return new CommentNode();
+ public createText(): InvisibleNode {
+ return new TextNode();
}
public createView(name: string): NgView {
diff --git a/tests/app/App_Resources/Android/app.gradle b/tests/app/App_Resources/Android/app.gradle
new file mode 100644
index 000000000..5a83b0360
--- /dev/null
+++ b/tests/app/App_Resources/Android/app.gradle
@@ -0,0 +1,23 @@
+// Add your native dependencies here:
+
+// Uncomment to add recyclerview-v7 dependency
+//dependencies {
+// compile 'com.android.support:recyclerview-v7:+'
+//}
+
+android {
+ defaultConfig {
+ generatedDensities = []
+ applicationId = "org.nativescript.tests"
+
+ //override supported platforms
+ // ndk {
+ // abiFilters.clear()
+ // abiFilters "armeabi-v7a"
+ // }
+
+ }
+ aaptOptions {
+ additionalParameters "--no-version-vectors"
+ }
+}
diff --git a/tests/app/tests/renderer-tests.ts b/tests/app/tests/renderer-tests.ts
index fecbaf982..6efc463c8 100644
--- a/tests/app/tests/renderer-tests.ts
+++ b/tests/app/tests/renderer-tests.ts
@@ -94,6 +94,39 @@ export class NgIfLabel {
}
}
+@Component({
+ selector: "ng-if-two-elements",
+ template: `
+
+
+
+
+ `
+})
+export class NgIfTwoElements {
+ public show: boolean = false;
+ constructor(public elementRef: ElementRef) {
+ }
+}
+
+@Component({
+ selector: "ng-if-multiple",
+ template: `
+
+
+
+
+
+
+
+ `
+})
+export class NgIfMultiple {
+ public show: boolean = false;
+ constructor(public elementRef: ElementRef) {
+ }
+}
+
@Component({
selector: "ng-if-else",
template: `
@@ -154,7 +187,9 @@ describe("Renderer E2E", () => {
LayoutWithLabel, LabelCmp, LabelContainer,
ProjectableCmp, ProjectionContainer,
StyledLabelCmp, StyledLabelCmp2,
- NgIfLabel, NgIfElseComponent, NgIfThenElseComponent,
+ NgIfLabel, NgIfThenElseComponent, NgIfMultiple,
+ NgIfTwoElements, NgIfMultiple,
+ NgIfElseComponent, NgIfThenElseComponent,
NgForLabel,
]).then((app) => {
testApp = app;
@@ -256,7 +291,7 @@ describe("Renderer E2E", () => {
it("ngIf hides component when false", () => {
return testApp.loadComponent(NgIfLabel).then((componentRef) => {
const componentRoot = componentRef.instance.elementRef.nativeElement;
- assert.equal("(ProxyViewContainer)", dumpView(componentRoot));
+ assert.equal("(ProxyViewContainer (CommentNode))", dumpView(componentRoot));
});
});
@@ -267,7 +302,43 @@ describe("Renderer E2E", () => {
component.show = true;
testApp.appRef.tick();
- assert.equal("(ProxyViewContainer (Label))", dumpView(componentRoot));
+ assert.equal("(ProxyViewContainer (CommentNode), (Label))", dumpView(componentRoot));
+ });
+ });
+
+ it("ngIf shows elements in correct order when two are rendered", () => {
+ return testApp.loadComponent(NgIfTwoElements).then((componentRef) => {
+ const component = componentRef.instance;
+ const componentRoot = component.elementRef.nativeElement;
+
+ component.show = true;
+ testApp.appRef.tick();
+ assert.equal(
+ "(ProxyViewContainer (StackLayout (CommentNode), (Label), (Button)))",
+ dumpView(componentRoot));
+ });
+ });
+
+
+ it("ngIf shows elements in correct order when multiple are rendered and there's *ngIf", () => {
+ return testApp.loadComponent(NgIfMultiple).then((componentRef) => {
+ const component = componentRef.instance;
+ const componentRoot = component.elementRef.nativeElement;
+
+ component.show = true;
+ testApp.appRef.tick();
+ assert.equal(
+ "(ProxyViewContainer " +
+ "(StackLayout " +
+ "(Label[text=1]), " +
+ "(Label[text=2]), " +
+ "(Label[text=3]), " +
+ "(CommentNode), " + // ng-reflect comment
+ "(Label[text=4]), " + // the content to be displayed and its anchor
+ "(Label[text=5])" +
+ ")" +
+ ")",
+ dumpView(componentRoot, true));
});
});
@@ -280,7 +351,8 @@ describe("Renderer E2E", () => {
assert.equal(
"(ProxyViewContainer " +
"(StackLayout " +
- "(Label[text=If])))", // the content to be displayed
+ "(CommentNode), " + // ng-reflect comment
+ "(Label[text=If]), (CommentNode)))", // the content to be displayed and its anchor
dumpView(componentRoot, true));
});
@@ -296,7 +368,8 @@ describe("Renderer E2E", () => {
assert.equal(
"(ProxyViewContainer " +
"(StackLayout " +
- "(Label[text=Else])))", // the content to be displayed
+ "(CommentNode), " + // ng-reflect comment
+ "(Label[text=Else]), (CommentNode)))", // the content to be displayed and its anchor
dumpView(componentRoot, true));
});
@@ -311,7 +384,10 @@ describe("Renderer E2E", () => {
assert.equal(
"(ProxyViewContainer " +
"(StackLayout " +
- "(Label[text=Then])))", // the content to be displayed
+ "(CommentNode), " + // ng-reflect comment
+ "(Label[text=Then]), (CommentNode), " + // the content to be displayed and its anchor
+ "(CommentNode)))", // the anchor for the else template
+
dumpView(componentRoot, true));
});
});
@@ -327,7 +403,9 @@ describe("Renderer E2E", () => {
assert.equal(
"(ProxyViewContainer " +
"(StackLayout " +
- "(Label[text=Else])))", // the content to be displayed
+ "(CommentNode), " + // the content to be displayed
+ "(Label[text=Else]), (CommentNode), " + // the content to be displayed
+ "(CommentNode)))", // the content to be displayed
dumpView(componentRoot, true));
});
@@ -337,7 +415,7 @@ describe("Renderer E2E", () => {
return testApp.loadComponent(NgForLabel).then((componentRef) => {
const componentRoot = componentRef.instance.elementRef.nativeElement;
assert.equal(
- "(ProxyViewContainer (Label[text=one]), (Label[text=two]), (Label[text=three]))",
+ "(ProxyViewContainer (CommentNode), (Label[text=one]), (Label[text=two]), (Label[text=three]))",
dumpView(componentRoot, true));
});
});
@@ -351,7 +429,7 @@ describe("Renderer E2E", () => {
testApp.appRef.tick();
assert.equal(
- "(ProxyViewContainer (Label[text=one]), (Label[text=three]))",
+ "(ProxyViewContainer (CommentNode), (Label[text=one]), (Label[text=three]))",
dumpView(componentRoot, true));
});
});
@@ -365,7 +443,7 @@ describe("Renderer E2E", () => {
testApp.appRef.tick();
assert.equal(
- "(ProxyViewContainer " +
+ "(ProxyViewContainer (CommentNode), " +
"(Label[text=one]), (Label[text=new]), (Label[text=two]), (Label[text=three]))",
dumpView(componentRoot, true));
});
@@ -464,19 +542,5 @@ describe("Renderer attach/detach", () => {
assert.equal(parent.getChildrenCount(), 0);
assert.isUndefined(button.parent);
});
-
- it("attaching and detaching comment anchor to content view does not affect its content", () => {
- const parent = renderer.createElement("ContentView");
- const button =