diff --git a/.gitignore b/.gitignore
index 610c9ed25..9399b9cd3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,6 +30,7 @@ ng-sample/app/**/*.js
# Webpack configuration files
webpack.config.js
tsconfig.esm.json
+tsconfig.tns.json
# IDEs and editors
/.idea
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3a955ef1f..bba452911 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,18 @@
+## [7.2.4](https://github.com/NativeScript/nativescript-angular/compare/7.2.3...7.2.4) (2019-04-24)
+
+
+### Bug Fixes
+
+* **router:** routing services should be provided in forRoot only ([#1729](https://github.com/NativeScript/nativescript-angular/issues/1729)) ([0f6a975](https://github.com/NativeScript/nativescript-angular/commit/0f6a975))
+* ngOnDestroy not called on Android back button ([#923](https://github.com/NativeScript/nativescript-angular/issues/923))
+
+
+### Features
+
+* **modal:** add ‘ios presentationStyle’ option to ModalDialogParams ([9cfa127](https://github.com/NativeScript/nativescript-angular/commit/9cfa127))
+
+
+
## [7.2.3](https://github.com/NativeScript/nativescript-angular/compare/7.2.2...7.2.3) (2019-03-14)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 13889f11d..b42d49f3b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -81,36 +81,105 @@ If you want to contribute, but you are not sure where to start - look for [issue
## Publishing new versions
-Instructions how to publish a new version for Maintainers.
-1. Execute `npm install` to install dependencies and prepare the package for publishing:
-```bash
-cd nativescript-angular/nativescript-angular
-npm install
+## Releasing new versions
+Instructions how to release a new version for **NativeScript Core Team Members**.
+
+
+
+1. Checkout release branch
+```
+cd nativescript-angular/nativescript-angular && git checkout release && git pull
+```
+#### If we prepare major or minor release, merge master in release branch else **skip this step**.
```
+git merge --ff-only origin/master
+```
+*** Note: If there are commits in release branch which are not merged in master branch '-ff-merge' command will fail.
+In this case the commits should be merge firstly from release in master branch as explained in section 'Merge changes from release into master' and then repeat step 1.
-2. Add the following to your `.npmrc`:
+2. Execute `npm i` to install dependencies:
+```
+cd nativescript-angular && npm i
+```
+3. Execute [`npm version`](https://docs.npmjs.com/cli/version) to bump the version:
+```
+npm --no-git-tag-version version [patch|minor|major] -m "release: cut the %s release"
+```
+or
```
-tag-version-prefix=""
-message="release: cut the %s release"
+npm --no-git-tag-version version [version] --allow-same-version -m "release: cut the %s release"
```
+NOTE: Check the changelog!!!
-3. Create new branch for the release:
-```bash
-git checkout -b username/release-version
+4. Create release-branch with change log
+```
+git checkout -b release-[version]
+```
+5. Add changes
```
+git add changed-files
+git commit -m "release: cut the %s release"
+git push
+```
+NOTE: Make sure the PR is based on release branch
-4. Execute [`npm version`](https://docs.npmjs.com/cli/version) to bump the version in the `package.json` file, tag the release and update the CHANGELOG.md:
-```bash
-npm version [patch|minor|major]
+6. Merge PR into release branch.
+
+7. The merge will produce package with rc tag in npm. If all checks have passed, publish official package. Usually the night builds will be triggered and the package will be ready to be released on the next day.
+
+8. Don't forget to tag the release branch
+```
+git tag [version]
+git push --tags
+```
+Only if needed to Tips to remove tags:
+```
+git push --delete origin [version]
+git tag -d [version]
```
-5. Push all the changes to your branch and create a pull request:
-```bash
-git push --set-upstream origin username/release-version --tags
+## Checkout master branch and bump version usually should be minor or major.
+
+## Merge changes from release into master
+
+## NOTE: Don't use git IDE/WEB
+
+
+
+### Here are steps described in the diagram above.
+
+1. Make sure you are in release branch:
+```
+git checkout release && git pull
+```
+2. Create PR to merge changes back in master and preserve history:
```
+git checkout -b merge-release-in-master-[branch]/[sha]
+git push --set-upstream origin merge-release-in-master-branch-[branch]/[sha]
+git merge origin/master
+```
+3. Resolve conflicts. Choose to keep the version of master branch. If it is needed to revert versions of modules, see at the bottom.
-6. Publish the package to `npm` after the pull request is merged:
-```bash
-npm publish
+4. Add conflicts:
+```
+git add resolved files
+```
+5. Commit changes with default merge message:
+```
+git commit
+git push
+```
+
+6. Create pull request which should be based on master. Replace replace env merge-release-in-master-branch with its value
+```
+curl -d '{"title": "chore: merge release in master","body": "chore: merge release in master","head": "merge-release-in-master","base": "master"}' -X POST https://api.github.com/repos/NativeScript/NativeScript/pulls -H "Authorization: token ${GIT_TOKEN}"
+```
+
+**If needed, to revert file and take it from master:**
+```
+git checkout origin/master nativescript-angular/[some-file]
+git commit --amend
+git push --force-with-lease
```
+This could require to repeat steps from 1 to 4, since we need to keep the branches with the same history
diff --git a/build-docs.sh b/build-docs.sh
new file mode 100755
index 000000000..a0f39ec85
--- /dev/null
+++ b/build-docs.sh
@@ -0,0 +1,9 @@
+set -e
+
+ENV="${ENV:-dev}"
+DIST_DIR="nativescript-angular/bin/dist"
+APIREF_DIR="$DIST_DIR/ng-api-reference"
+rm -rf "$APIREF_DIR"
+cd "nativescript-angular"
+npm install
+npm run typedoc
diff --git a/e2e/config/mocha.opts b/e2e/config/mocha.opts
index ea635b0dc..65bcb91f7 100644
--- a/e2e/config/mocha.opts
+++ b/e2e/config/mocha.opts
@@ -1,4 +1,4 @@
---timeout 140000
+--timeout 60000
--recursive e2e
--reporter mocha-multi
--reporter-options spec=-,mocha-junit-reporter=test-results.xml
\ No newline at end of file
diff --git a/e2e/modal-navigation-ng/app/navigation/basic.navigation.component.ts b/e2e/modal-navigation-ng/app/navigation/basic.navigation.component.ts
index 54c818612..49f7a2567 100644
--- a/e2e/modal-navigation-ng/app/navigation/basic.navigation.component.ts
+++ b/e2e/modal-navigation-ng/app/navigation/basic.navigation.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewContainerRef, Input } from "@angular/core";
+import { Component, ViewContainerRef, Input, ViewChild, ElementRef } from "@angular/core";
import { Router, NavigationEnd } from "@angular/router";
import { ModalDialogService, ModalDialogOptions } from "nativescript-angular/directives/dialogs";
import { ModalComponent } from "../modal/modal.component";
@@ -16,12 +16,14 @@ import { ModalViewComponent } from "~/modal-shared/modal-view.component";
+
`
})
export class BasicsNavigationComponent {
+ @ViewChild("popoverButtonComp") popoverButtonComp: ElementRef;
@Input() col: number;
constructor(
private modal: ModalDialogService,
@@ -29,7 +31,7 @@ export class BasicsNavigationComponent {
private vcf: ViewContainerRef,
private viewContainerRefService: ViewContainerRefService) {
}
-
+
onModalNoFrame() {
const options: ModalDialogOptions = {
context: {
@@ -74,14 +76,28 @@ export class BasicsNavigationComponent {
onRootModalTap(): void {
const options: ModalDialogOptions = {
- viewContainerRef: this.viewContainerRefService.root,
- context: {},
- fullscreen: true
+ viewContainerRef: this.viewContainerRefService.root,
+ context: {},
+ fullscreen: true
};
-
+
this.modal.showModal(ModalViewComponent, options)
- .then((result: string) => {
- console.log(result);
- });
- }
+ .then((result: string) => {
+ console.log(result);
+ });
+ }
+
+ onPopoverModal() {
+ const options: ModalDialogOptions = {
+ viewContainerRef: this.viewContainerRefService.root,
+ context: {},
+ ios: {
+ presentationStyle: UIModalPresentationStyle.Popover
+ },
+ target: this.popoverButtonComp.nativeElement
+ };
+
+ this.modal.showModal(ModalViewComponent, options)
+ .then((result: string) => { console.log(result);});
+ }
}
diff --git a/e2e/modal-navigation-ng/e2e/modal.shared.e2e-spec.ts b/e2e/modal-navigation-ng/e2e/modal.shared.e2e-spec.ts
index fd76f81eb..1ad368ff2 100644
--- a/e2e/modal-navigation-ng/e2e/modal.shared.e2e-spec.ts
+++ b/e2e/modal-navigation-ng/e2e/modal.shared.e2e-spec.ts
@@ -15,7 +15,7 @@ describe("modal-shared:", () => {
});
roots.forEach(root => {
- describe("Shared modal from second and back", () => {
+ describe("Shared modal from home component and back", () => {
before(async () => {
await screen[root]();
@@ -46,6 +46,11 @@ describe("modal-shared:", () => {
await screen.closeModal();
});
+ it("should open/close shared modal with presentation style from home component", async () => {
+ await screen.loadSharedModalWithPresentationStyle(true);
+ await screen.closeModal();
+ });
+
it("should find home component again", async () => {
await screen.loadedHome();
});
diff --git a/e2e/modal-navigation-ng/e2e/screens/screen.ts b/e2e/modal-navigation-ng/e2e/screens/screen.ts
index 107d34b41..690edd0ab 100644
--- a/e2e/modal-navigation-ng/e2e/screens/screen.ts
+++ b/e2e/modal-navigation-ng/e2e/screens/screen.ts
@@ -1,4 +1,4 @@
-import { AppiumDriver } from "nativescript-dev-appium";
+import { AppiumDriver, SearchOptions } from "nativescript-dev-appium";
import { assert } from "chai";
const home = "Home Component"
@@ -165,6 +165,11 @@ export class Screen {
await btnTap.click();
}
+ private showSharedModalPresentationStyle = async () => {
+ const btnTap = await this._driver.findElementByText("popover", SearchOptions.contains);
+ await btnTap.click();
+ }
+
loadedModalPage = async () => {
const btnShowNestedModalPage = await this._driver.findElementByAutomationText(showNestedModalPage);
assert.isTrue(await btnShowNestedModalPage.isDisplayed(), `${showNestedModalPage} is not displayed`);
@@ -212,6 +217,7 @@ export class Screen {
}
loadedModalNoFrame = async () => {
+ await this._driver.wait(2000);
const btnShowDialogConfirm = await this._driver.waitForElement(showDialog);
const btnCloseModal = await this._driver.waitForElement(closeModal);
assert.isTrue(await btnShowDialogConfirm.isDisplayed());
@@ -309,4 +315,13 @@ export class Screen {
const lbl = await this._driver.waitForElement(sharedModalView, 5000);
assert.isTrue(await lbl.isDisplayed());
}
+
+ loadSharedModalWithPresentationStyle = async (loadShowModalPageWithFrame: boolean) => {
+ if (loadShowModalPageWithFrame) {
+ await this.showSharedModalPresentationStyle();
+ }
+
+ const lbl = await this._driver.waitForElement(sharedModalView, 5000);
+ assert.isTrue(await lbl.isDisplayed());
+ }
}
\ No newline at end of file
diff --git a/e2e/modal-navigation-ng/package.json b/e2e/modal-navigation-ng/package.json
index 444d4b4ee..fc6209dc9 100644
--- a/e2e/modal-navigation-ng/package.json
+++ b/e2e/modal-navigation-ng/package.json
@@ -46,6 +46,7 @@
"nativescript-dev-appium": "next",
"nativescript-dev-typescript": "next",
"nativescript-dev-webpack": "next",
+ "tns-platform-declarations": "next",
"typescript": "~3.1.1"
},
"scripts": {
diff --git a/e2e/modal-navigation-ng/references.d.ts b/e2e/modal-navigation-ng/references.d.ts
new file mode 100644
index 000000000..b945d69c5
--- /dev/null
+++ b/e2e/modal-navigation-ng/references.d.ts
@@ -0,0 +1 @@
+///
\ No newline at end of file
diff --git a/merge-guidance-schema.png b/merge-guidance-schema.png
new file mode 100644
index 000000000..dd882471e
Binary files /dev/null and b/merge-guidance-schema.png differ
diff --git a/nativescript-angular/directives/dialogs.ts b/nativescript-angular/directives/dialogs.ts
index 7c8b45739..51363c032 100644
--- a/nativescript-angular/directives/dialogs.ts
+++ b/nativescript-angular/directives/dialogs.ts
@@ -6,7 +6,7 @@ import {
NgModuleRef,
ReflectiveInjector,
Type,
- ViewContainerRef,
+ ViewContainerRef
} from "@angular/core";
import { NSLocationStrategy } from "../router/ns-location-strategy";
@@ -18,14 +18,15 @@ import { DetachedLoader } from "../common/detached-loader";
import { PageFactory, PAGE_FACTORY } from "../platform-providers";
import { once } from "../common/utils";
import { topmost, Frame } from "tns-core-modules/ui/frame";
+import { ShowModalOptions } from "tns-core-modules/ui/core/view";
-export interface ModalDialogOptions {
+export type BaseShowModalOptions = Pick>;
+
+export interface ModalDialogOptions extends BaseShowModalOptions {
context?: any;
- fullscreen?: boolean;
- animated?: boolean;
- stretched?: boolean;
viewContainerRef?: ViewContainerRef;
moduleRef?: NgModuleRef;
+ target?: View;
}
export class ModalDialogParams {
@@ -35,13 +36,10 @@ export class ModalDialogParams {
}
}
-interface ShowDialogOptions {
+interface ShowDialogOptions extends BaseShowModalOptions {
containerRef: ViewContainerRef;
context: any;
doneCallback;
- fullscreen: boolean;
- animated: boolean;
- stretched: boolean;
pageFactory: PageFactory;
parentView: ViewBase;
resolver: ComponentFactoryResolver;
@@ -54,16 +52,20 @@ export class ModalDialogService {
}
public showModal(type: Type,
- { viewContainerRef, moduleRef, context, fullscreen, animated, stretched }: ModalDialogOptions
+ options: ModalDialogOptions
): Promise {
- if (!viewContainerRef) {
+ if (!options.viewContainerRef) {
throw new Error(
"No viewContainerRef: " +
"Make sure you pass viewContainerRef in ModalDialogOptions."
);
}
- let parentView = viewContainerRef.element.nativeElement;
+ let parentView = options.viewContainerRef.element.nativeElement;
+ if (options.target) {
+ parentView = options.target;
+ }
+
if (parentView instanceof AppHostView && parentView.ngAppRoot) {
parentView = parentView.ngAppRoot;
}
@@ -75,11 +77,11 @@ export class ModalDialogService {
parentView = parentView._ngDialogRoot;
}
- const pageFactory: PageFactory = viewContainerRef.injector.get(PAGE_FACTORY);
+ const pageFactory: PageFactory = options.viewContainerRef.injector.get(PAGE_FACTORY);
// resolve from particular module (moduleRef)
// or from same module as parentView (viewContainerRef)
- const componentContainer = moduleRef || viewContainerRef;
+ const componentContainer = options.moduleRef || options.viewContainerRef;
const resolver = componentContainer.injector.get(ComponentFactoryResolver);
let frame = parentView;
@@ -93,16 +95,14 @@ export class ModalDialogService {
setTimeout(() => {
try {
this._showDialog({
- containerRef: viewContainerRef,
- context,
+ ...options,
+ containerRef: options.viewContainerRef,
+ context: options.context,
doneCallback: resolve,
- fullscreen,
- animated,
- stretched,
pageFactory,
parentView,
resolver,
- type,
+ type
});
} catch (err) {
reject(err);
@@ -111,23 +111,12 @@ export class ModalDialogService {
});
}
- private _showDialog({
- containerRef,
- context,
- doneCallback,
- fullscreen,
- animated,
- stretched,
- pageFactory,
- parentView,
- resolver,
- type,
- }: ShowDialogOptions): void {
+ private _showDialog(options: ShowDialogOptions): void {
let componentView: View;
let detachedLoaderRef: ComponentRef;
const closeCallback = once((...args) => {
- doneCallback.apply(undefined, args);
+ options.doneCallback.apply(undefined, args);
if (componentView) {
componentView.closeModal();
this.location._closeModalNavigation();
@@ -136,15 +125,15 @@ export class ModalDialogService {
}
});
- const modalParams = new ModalDialogParams(context, closeCallback);
+ const modalParams = new ModalDialogParams(options.context, closeCallback);
const providers = ReflectiveInjector.resolve([
{ provide: ModalDialogParams, useValue: modalParams },
]);
- const childInjector = ReflectiveInjector.fromResolvedProviders(providers, containerRef.parentInjector);
- const detachedFactory = resolver.resolveComponentFactory(DetachedLoader);
- detachedLoaderRef = containerRef.createComponent(detachedFactory, -1, childInjector, null);
- detachedLoaderRef.instance.loadComponent(type).then((compRef) => {
+ const childInjector = ReflectiveInjector.fromResolvedProviders(providers, options.containerRef.parentInjector);
+ const detachedFactory = options.resolver.resolveComponentFactory(DetachedLoader);
+ detachedLoaderRef = options.containerRef.createComponent(detachedFactory, -1, childInjector, null);
+ detachedLoaderRef.instance.loadComponent(options.type).then((compRef) => {
const detachedProxy = compRef.location.nativeElement;
if (detachedProxy.getChildrenCount() > 1) {
@@ -157,9 +146,7 @@ export class ModalDialogService {
(componentView.parent).removeChild(componentView);
}
- // TODO: remove cast after https://github.com/NativeScript/NativeScript/pull/5734
- // is in a published version of tns-core-modules.
- (parentView).showModal(componentView, context, closeCallback, fullscreen, animated, stretched);
+ options.parentView.showModal(componentView, { ...options, closeCallback });
});
}
}
diff --git a/nativescript-angular/package.json b/nativescript-angular/package.json
index f63220905..b185a77f9 100644
--- a/nativescript-angular/package.json
+++ b/nativescript-angular/package.json
@@ -1,6 +1,6 @@
{
"name": "nativescript-angular",
- "version": "7.2.3",
+ "version": "7.2.4",
"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",
@@ -34,7 +34,8 @@
"tsc-w": "tsc -p tsconfig.json -w",
"ngc": "ngc -p tsconfig.json",
"prepare": "npm run ngc",
- "version": "rm -rf package-lock.json && conventional-changelog -p angular -i ../CHANGELOG.md -s && git add ../CHANGELOG.md"
+ "version": "rm -rf package-lock.json && conventional-changelog -p angular -i ../CHANGELOG.md -s && git add ../CHANGELOG.md",
+ "typedoc": "typedoc --tsconfig \"./tsconfig.typedoc.json\" --out ./bin/dist/ng-api-reference --includeDeclarations --name \"NativeScript Angular\" --theme ./node_modules/nativescript-typedoc-theme --excludeExternals --externalPattern \"**/+(tns-core-modules|module|declarations).d.ts\""
},
"bin": {
"update-app-ng-deps": "./bin/update-app-ng-deps"
@@ -73,6 +74,8 @@
"tns-core-modules": "next",
"tslint": "^5.5.0",
"typescript": "~3.1.1",
- "zone.js": "^0.8.4"
+ "zone.js": "^0.8.4",
+ "nativescript-typedoc-theme": "git://github.com/NativeScript/nativescript-typedoc-theme.git#master",
+ "typedoc": "^0.13.0"
}
}
diff --git a/nativescript-angular/platform-common.ts b/nativescript-angular/platform-common.ts
index 2f7e958cd..d6a4c557f 100644
--- a/nativescript-angular/platform-common.ts
+++ b/nativescript-angular/platform-common.ts
@@ -33,6 +33,8 @@ import {
on,
launchEvent,
LaunchEventData,
+ exitEvent,
+ ApplicationEventData,
} from "tns-core-modules/application";
import { TextView } from "tns-core-modules/ui/text-view";
@@ -255,7 +257,29 @@ export class NativeScriptPlatformRef extends PlatformRef {
args.root = rootContent;
}
);
+ const exitCallback = profile(
+ "nativescript-angular/platform-common.exitCallback", (args: ApplicationEventData) => {
+ const androidActivity = args.android;
+ if (androidActivity && !androidActivity.isFinishing()) {
+ // Exit event was triggered as a part of a restart of the app.
+ return;
+ }
+
+ const lastModuleRef = lastBootstrappedModule ? lastBootstrappedModule.get() : null;
+ if (lastModuleRef) {
+ // Make sure the module is only destroyed once
+ lastBootstrappedModule = null;
+
+ lastModuleRef.destroy();
+ }
+
+ if (!autoCreateFrame) {
+ rootContent = null;
+ }
+ }
+ );
on(launchEvent, launchCallback);
+ on(exitEvent, exitCallback);
applicationRun();
}
diff --git a/nativescript-angular/router/ns-platform-location.ts b/nativescript-angular/router/ns-platform-location.ts
index 311faa5b8..ebd86f067 100644
--- a/nativescript-angular/router/ns-platform-location.ts
+++ b/nativescript-angular/router/ns-platform-location.ts
@@ -6,7 +6,7 @@ import { routerLog, isLogEnabled } from "../trace";
@Injectable()
export class NativescriptPlatformLocation extends PlatformLocation {
- constructor(private locationStartegy: NSLocationStrategy) {
+ constructor(private locationStrategy: NSLocationStrategy) {
super();
if (isLogEnabled()) {
routerLog("NativescriptPlatformLocation.constructor()");
@@ -18,7 +18,7 @@ export class NativescriptPlatformLocation extends PlatformLocation {
}
onPopState(fn: LocationChangeListener): void {
- this.locationStartegy.onPopState(fn);
+ this.locationStrategy.onPopState(fn);
}
onHashChange(_fn: LocationChangeListener): void {
@@ -31,18 +31,18 @@ export class NativescriptPlatformLocation extends PlatformLocation {
return "";
}
get pathname(): string {
- return this.locationStartegy.path();
+ return this.locationStrategy.path();
}
set pathname(_newPath: string) {
throw new Error("NativescriptPlatformLocation set pathname - not implemented");
}
pushState(state: any, title: string, url: string): void {
- this.locationStartegy.pushState(state, title, url, null);
+ this.locationStrategy.pushState(state, title, url, null);
}
replaceState(state: any, title: string, url: string): void {
- this.locationStartegy.replaceState(state, title, url, null);
+ this.locationStrategy.replaceState(state, title, url, null);
}
forward(): void {
@@ -50,6 +50,6 @@ export class NativescriptPlatformLocation extends PlatformLocation {
}
back(): void {
- this.locationStartegy.back();
+ this.locationStrategy.back();
}
}
diff --git a/nativescript-angular/router/page-router-outlet.ts b/nativescript-angular/router/page-router-outlet.ts
index fdcd5e2b1..63f9ea4a8 100644
--- a/nativescript-angular/router/page-router-outlet.ts
+++ b/nativescript-angular/router/page-router-outlet.ts
@@ -352,12 +352,19 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
// Add it to the new page
page.content = componentView;
- page.on(Page.navigatedFromEvent, (global).Zone.current.wrap((args: NavigatedData) => {
+ const navigatedFromCallback = (global).Zone.current.wrap((args: NavigatedData) => {
if (args.isBackNavigation) {
this.locationStrategy._beginBackPageNavigation(this.frame);
this.locationStrategy.back(null, this.frame);
}
- }));
+ });
+ page.on(Page.navigatedFromEvent, navigatedFromCallback);
+ componentRef.onDestroy(() => {
+ if (page) {
+ page.off(Page.navigatedFromEvent, navigatedFromCallback);
+ page = null;
+ }
+ });
const navOptions = this.locationStrategy._beginPageNavigation(this.frame);
@@ -367,14 +374,15 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
if (this.outlet) {
this.routeReuseStrategy.clearCache(this.outlet.outletKeys[0]);
}
- page.off(Page.navigatedToEvent, clearCallback);
});
- page.on(Page.navigatedToEvent, clearCallback);
+ page.once(Page.navigatedToEvent, clearCallback);
}
this.frame.navigate({
- create: () => { return page; },
+ create() {
+ return page;
+ },
clearHistory: navOptions.clearHistory,
animated: navOptions.animated,
transition: navOptions.transition
diff --git a/nativescript-angular/router/router.module.ts b/nativescript-angular/router/router.module.ts
index 385b4fe1f..5246eeea0 100644
--- a/nativescript-angular/router/router.module.ts
+++ b/nativescript-angular/router/router.module.ts
@@ -19,32 +19,39 @@ export { NSEmptyOutletComponent } from "./ns-empty-outlet.component";
export type LocationState = LocationState;
+const ROUTER_DIRECTIVES = [NSRouterLink, NSRouterLinkActive, PageRouterOutlet, NSEmptyOutletComponent];
+
+const NS_ROUTER_PROVIDERS = [
+ {
+ provide: NSLocationStrategy,
+ useFactory: provideLocationStrategy,
+ deps: [[NSLocationStrategy, new Optional(), new SkipSelf()], FrameService],
+ },
+ { provide: LocationStrategy, useExisting: NSLocationStrategy },
+ NativescriptPlatformLocation,
+ { provide: PlatformLocation, useExisting: NativescriptPlatformLocation },
+ RouterExtensions,
+ NSRouteReuseStrategy,
+ { provide: RouteReuseStrategy, useExisting: NSRouteReuseStrategy },
+];
+
@NgModule({
- declarations: [NSRouterLink, NSRouterLinkActive, PageRouterOutlet, NSEmptyOutletComponent],
- providers: [
- {
- provide: NSLocationStrategy,
- useFactory: provideLocationStrategy,
- deps: [[NSLocationStrategy, new Optional(), new SkipSelf()], FrameService],
- },
- { provide: LocationStrategy, useExisting: NSLocationStrategy },
- NativescriptPlatformLocation,
- { provide: PlatformLocation, useClass: NativescriptPlatformLocation },
- RouterExtensions,
- NSRouteReuseStrategy,
- { provide: RouteReuseStrategy, useExisting: NSRouteReuseStrategy },
- ],
+ declarations: ROUTER_DIRECTIVES,
+ entryComponents: [NSEmptyOutletComponent],
imports: [RouterModule, NativeScriptCommonModule],
- exports: [RouterModule, NSRouterLink, NSRouterLinkActive, PageRouterOutlet, NSEmptyOutletComponent],
+ exports: [RouterModule, ...ROUTER_DIRECTIVES],
schemas: [NO_ERRORS_SCHEMA],
})
export class NativeScriptRouterModule {
- static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders {
- return RouterModule.forRoot(routes, config);
+ static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders {
+ return {
+ ngModule: NativeScriptRouterModule,
+ providers: [...RouterModule.forRoot(routes, config).providers, ...NS_ROUTER_PROVIDERS]
+ };
}
- static forChild(routes: Routes): ModuleWithProviders {
- return RouterModule.forChild(routes);
+ static forChild(routes: Routes): ModuleWithProviders {
+ return { ngModule: NativeScriptRouterModule, providers: RouterModule.forChild(routes).providers };
}
}
diff --git a/nativescript-angular/tsconfig.json b/nativescript-angular/tsconfig.json
index e05ddfed9..e8a09f283 100644
--- a/nativescript-angular/tsconfig.json
+++ b/nativescript-angular/tsconfig.json
@@ -16,14 +16,7 @@
"dom",
"es6",
"es2015.iterable"
- ],
- "baseUrl": ".",
- "paths": {
- "*": [
- "./node_modules/tns-core-modules/*",
- "./node_modules/*"
- ]
- }
+ ]
},
"angularCompilerOptions": {
"genDir": ".",
diff --git a/nativescript-angular/tsconfig.typedoc.json b/nativescript-angular/tsconfig.typedoc.json
new file mode 100644
index 000000000..3074c04b8
--- /dev/null
+++ b/nativescript-angular/tsconfig.typedoc.json
@@ -0,0 +1,61 @@
+{"compilerOptions": {
+ "target": "es5",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "sourceMap": true,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "noImplicitUseStrict": true,
+ "noEmitHelpers": true,
+ "declaration": true,
+ "removeComments": false,
+ "noEmitOnError": true,
+ "noImplicitAny": false,
+ "lib": [
+ "dom",
+ "es6",
+ "es2015.iterable"
+ ],
+ "baseUrl": ".",
+ "paths": {
+ "*": [
+ "./node_modules/tns-core-modules/*",
+ "./node_modules/*"
+ ]
+ }
+ },
+ "angularCompilerOptions": {
+ "genDir": ".",
+ "skipMetadataEmit": false,
+ "skipTemplateCodegen": true,
+ "strictMetadataEmit": true
+ },
+"exclude": [
+ "./node_modules",
+ "tns-core-modules/references.d.ts",
+ "tns-core-modules/node_modules",
+ "tns-core-modules/ui/frame/transition-definitions.android.d.ts",
+ "./zone-js",
+ "./index.ts",
+ "./bin",
+ "./index.d.ts",
+ "./testing",
+ "./animations/index.ts",
+ "./animations/utils.ts",
+ "./app-host-view.ts",
+ "./common/utils.ts",
+ "./dom-adapter.ts",
+ "./file-system",
+ "./forms/index.ts",
+ "./forms/value-accessors/index.ts",
+ "./lang-facade.ts",
+ "./polyfills",
+ "./router/private-imports",
+ "./schema-registry.ts",
+ "./http-client/index.ts",
+ "./http/index.ts",
+ "./router/index.ts",
+ ""
+
+ ]
+}
\ No newline at end of file
diff --git a/release-contribution-guide-schema-webpack.png b/release-contribution-guide-schema-webpack.png
new file mode 100644
index 000000000..fa8066082
Binary files /dev/null and b/release-contribution-guide-schema-webpack.png differ
diff --git a/tests/app/tests/router-module-tests.ts b/tests/app/tests/router-module-tests.ts
new file mode 100644
index 000000000..7bce3f7ef
--- /dev/null
+++ b/tests/app/tests/router-module-tests.ts
@@ -0,0 +1,74 @@
+// make sure you import mocha-config before @angular/core
+import { Component, ViewChild } from "@angular/core";
+import { nsTestBedAfterEach, nsTestBedBeforeEach, nsTestBedRender } from "nativescript-angular/testing";
+import { NativeScriptRouterModule, RouterExtensions } from "nativescript-angular/router";
+import { NSRouterLink } from "nativescript-angular/router/ns-router-link";
+import { NSLocationStrategy } from "nativescript-angular/router/ns-location-strategy";
+import { assert } from "~/tests/test-config";
+import { ActivatedRoute, Router, RouteReuseStrategy } from "@angular/router";
+import { LocationStrategy, PlatformLocation } from "@angular/common";
+import { NSRouteReuseStrategy } from "nativescript-angular/router/ns-route-reuse-strategy";
+
+@Component({
+ template: ``
+})
+class RouterTestComponent {
+ @ViewChild(NSRouterLink)
+ nsRouterLink: NSRouterLink;
+}
+
+describe("NativeScriptRouterModule.forRoot", () => {
+ beforeEach(nsTestBedBeforeEach(
+ [RouterTestComponent],
+ [],
+ [NativeScriptRouterModule.forRoot([])],
+ []));
+
+ afterEach(nsTestBedAfterEach());
+
+ it("should provide nativescript routing services", () => {
+ return nsTestBedRender(RouterTestComponent).then((fixture) => {
+ const injector = fixture.componentRef.injector
+
+ assert.instanceOf(injector.get(LocationStrategy, null), NSLocationStrategy);
+ assert.instanceOf(injector.get(RouterExtensions, null), RouterExtensions);
+ assert.instanceOf(injector.get(RouteReuseStrategy, null), NSRouteReuseStrategy);
+ });
+ });
+
+ it("should provide nativescript routing directives", () => {
+ return nsTestBedRender(RouterTestComponent).then((fixture) => {
+ const linkDirective = fixture.componentRef.instance.nsRouterLink;
+ assert.instanceOf(linkDirective, NSRouterLink);
+ });
+ });
+});
+
+describe("NativeScriptRouterModule.forChild", () => {
+ beforeEach(nsTestBedBeforeEach(
+ [RouterTestComponent],
+ [
+ { provide: Router, useValue: {} },
+ { provide: RouterExtensions, useValue: {} },
+ { provide: ActivatedRoute, useValue: {} },
+ ],
+ [NativeScriptRouterModule.forChild([])],
+ []));
+ afterEach(nsTestBedAfterEach());
+
+ it("should not provide nativescript routing services", () => {
+ return nsTestBedRender(RouterTestComponent).then((fixture) => {
+ const injector = fixture.componentRef.injector
+ assert.isNull(injector.get(LocationStrategy, null));
+ assert.isNull(injector.get(RouteReuseStrategy, null));
+ });
+ });
+
+ it("should provide nativescript routing directives", () => {
+ return nsTestBedRender(RouterTestComponent).then((fixture) => {
+ const linkDirective = fixture.componentRef.instance.nsRouterLink;
+ assert.instanceOf(linkDirective, NSRouterLink);
+ });
+ });
+});
+