diff --git a/CHANGELOG.md b/CHANGELOG.md
index a2472065c..99d09f304 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+
+## [7.2.1](https://github.com/NativeScript/nativescript-angular/compare/7.2.0...7.2.1) (2019-02-10)
+
+
+### Bug Fixes
+
+* **location-strategy:** extend support for nested primary outlets ([566896d](https://github.com/NativeScript/nativescript-angular/commit/566896d))
+* Router tracing does not work with webpack ([e87ef68](https://github.com/NativeScript/nativescript-angular/commit/e87ef68))
+
+
+
# [7.2.0](https://github.com/NativeScript/nativescript-angular/compare/7.1.2...7.2.0) (2019-01-31)
diff --git a/e2e/nested-router-tab-view/app/app.component.html b/e2e/nested-router-tab-view/app/app.component.html
index 1265aa9c8..74b776fc0 100644
--- a/e2e/nested-router-tab-view/app/app.component.html
+++ b/e2e/nested-router-tab-view/app/app.component.html
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/e2e/nested-router-tab-view/app/app.routing.ts b/e2e/nested-router-tab-view/app/app.routing.ts
index 276f26d91..b77942d75 100644
--- a/e2e/nested-router-tab-view/app/app.routing.ts
+++ b/e2e/nested-router-tab-view/app/app.routing.ts
@@ -48,6 +48,10 @@ const routes: Routes = [
path: "home-lazy",
loadChildren: "./home-lazy/home-lazy.module#HomeLazyModule",
},
+ {
+ path: "custom-tabs",
+ loadChildren: "./custom-tabs/custom-tabs.module#CustomTabsModule",
+ },
{
path: "tabs", component: TabsComponent, children: [
{ path: "players", component: PlayerComponent, outlet: "playerTab" },
diff --git a/e2e/nested-router-tab-view/app/custom-tabs/custom-tabs.component.html b/e2e/nested-router-tab-view/app/custom-tabs/custom-tabs.component.html
new file mode 100644
index 000000000..851c8765a
--- /dev/null
+++ b/e2e/nested-router-tab-view/app/custom-tabs/custom-tabs.component.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/e2e/nested-router-tab-view/app/custom-tabs/custom-tabs.component.ts b/e2e/nested-router-tab-view/app/custom-tabs/custom-tabs.component.ts
new file mode 100644
index 000000000..18ca7663b
--- /dev/null
+++ b/e2e/nested-router-tab-view/app/custom-tabs/custom-tabs.component.ts
@@ -0,0 +1,44 @@
+import { Component, OnInit } from '@angular/core';
+import { ModalDialogService, ModalDialogOptions } from "nativescript-angular/directives/dialogs";
+import { RouterExtensions } from "nativescript-angular/router";
+import { ActivatedRoute } from "@angular/router";
+import { confirm } from "tns-core-modules/ui/dialogs";
+import { Page } from 'tns-core-modules/ui/page/page';
+
+@Component({
+ moduleId: module.id,
+ selector: 'custom-tabs',
+ templateUrl: './custom-tabs.component.html'
+})
+export class CustomTabsComponent implements OnInit {
+
+ constructor(
+ private activeRoute: ActivatedRoute,
+ private routerExtension: RouterExtensions,
+ private page: Page) { }
+
+ ngOnInit() {
+ }
+
+ canGoBackParentRoute() {
+ const canGoBackParentRoute = this.routerExtension.canGoBack({ relativeTo: this.activeRoute });
+ const title = "CanGoBack(ParentRoute)";
+ this.onShowDialog(title, title + ` ${canGoBackParentRoute}`);
+ }
+
+ onRootBack() {
+ this.page.frame.goBack();
+ }
+
+ onShowDialog(title: string, result: string) {
+ let options: any = {
+ title: title,
+ message: result,
+ okButtonText: "Ok"
+ }
+
+ confirm(options).then((result: boolean) => {
+ console.log(result);
+ })
+ }
+}
diff --git a/e2e/nested-router-tab-view/app/custom-tabs/custom-tabs.module.ts b/e2e/nested-router-tab-view/app/custom-tabs/custom-tabs.module.ts
new file mode 100644
index 000000000..cd29535d2
--- /dev/null
+++ b/e2e/nested-router-tab-view/app/custom-tabs/custom-tabs.module.ts
@@ -0,0 +1,38 @@
+import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
+import { NativeScriptCommonModule } from 'nativescript-angular/common';
+import { NativeScriptRouterModule } from 'nativescript-angular/router';
+
+import { CustomTabsComponent } from './custom-tabs.component';
+import { PlayerComponent } from "../player/players.component";
+import { PlayerDetailComponent } from "../player/player-detail.component";
+import { TeamsComponent } from "../team/teams.component";
+import { TeamDetailComponent } from "../team/team-detail.component";
+import { Route } from "@angular/router";
+import { SharedModule } from "../shared.module";
+
+const routes: Route[] = [
+ {
+ path: 'tabs',
+ component: CustomTabsComponent,
+ children: [
+ { path: "players", component: PlayerComponent },
+ { path: "player/:id", component: PlayerDetailComponent },
+
+ { path: "teams", component: TeamsComponent },
+ { path: "team/:id", component: TeamDetailComponent },
+ ]
+ },
+];
+
+@NgModule({
+ declarations: [CustomTabsComponent
+ ],
+ imports: [
+ NativeScriptCommonModule,
+ NativeScriptRouterModule,
+ NativeScriptRouterModule.forChild(routes),
+ SharedModule
+ ],
+ schemas: [NO_ERRORS_SCHEMA]
+})
+export class CustomTabsModule { }
diff --git a/e2e/nested-router-tab-view/app/login/login.component.html b/e2e/nested-router-tab-view/app/login/login.component.html
index f022099ed..26e1c80ac 100644
--- a/e2e/nested-router-tab-view/app/login/login.component.html
+++ b/e2e/nested-router-tab-view/app/login/login.component.html
@@ -3,7 +3,7 @@
-
+
\ No newline at end of file
diff --git a/e2e/nested-router-tab-view/app/player/player-detail.component.html b/e2e/nested-router-tab-view/app/player/player-detail.component.html
index b4039955c..ea76ab3cd 100644
--- a/e2e/nested-router-tab-view/app/player/player-detail.component.html
+++ b/e2e/nested-router-tab-view/app/player/player-detail.component.html
@@ -1,4 +1,6 @@
-
+
+
+
diff --git a/e2e/nested-router-tab-view/app/player/players.component.html b/e2e/nested-router-tab-view/app/player/players.component.html
index 780282771..7dc729f6d 100644
--- a/e2e/nested-router-tab-view/app/player/players.component.html
+++ b/e2e/nested-router-tab-view/app/player/players.component.html
@@ -1,11 +1,11 @@
-
+
+
+
-
-
-
+
+
-
+
\ No newline at end of file
diff --git a/e2e/nested-router-tab-view/app/player/players.component.ts b/e2e/nested-router-tab-view/app/player/players.component.ts
index 677168612..b24ef18bd 100644
--- a/e2e/nested-router-tab-view/app/player/players.component.ts
+++ b/e2e/nested-router-tab-view/app/player/players.component.ts
@@ -1,6 +1,5 @@
import { Component, OnInit, ViewContainerRef } from "@angular/core";
import { DataService, DataItem } from "../data.service";
-import { RouterExtensions } from "nativescript-angular/router";
import { ModalDialogService, ModalDialogOptions } from "nativescript-angular/directives/dialogs";
import { ModalRouterComponent } from "../modal/modal-router/modal-router.component";
@@ -12,7 +11,10 @@ import { ModalRouterComponent } from "../modal/modal-router/modal-router.compone
export class PlayerComponent implements OnInit {
items: DataItem[];
- constructor(private modal: ModalDialogService, private itemService: DataService, private router: RouterExtensions, private vcRef: ViewContainerRef, ) { }
+ constructor(
+ private modal: ModalDialogService,
+ private itemService: DataService,
+ private vcRef: ViewContainerRef, ) { }
ngOnInit(): void {
this.items = this.itemService.getPlayers();
diff --git a/e2e/nested-router-tab-view/app/team/team-detail.component.html b/e2e/nested-router-tab-view/app/team/team-detail.component.html
index 13f4b87b7..18086c638 100644
--- a/e2e/nested-router-tab-view/app/team/team-detail.component.html
+++ b/e2e/nested-router-tab-view/app/team/team-detail.component.html
@@ -1,4 +1,6 @@
-
+
+
+
diff --git a/e2e/nested-router-tab-view/app/team/teams.component.html b/e2e/nested-router-tab-view/app/team/teams.component.html
index 4126e1d3b..4af94ca66 100644
--- a/e2e/nested-router-tab-view/app/team/teams.component.html
+++ b/e2e/nested-router-tab-view/app/team/teams.component.html
@@ -1,4 +1,6 @@
-
+
+
+
diff --git a/e2e/nested-router-tab-view/e2e/custom-tabs.e2e-spec.ts b/e2e/nested-router-tab-view/e2e/custom-tabs.e2e-spec.ts
new file mode 100644
index 000000000..e41b858e3
--- /dev/null
+++ b/e2e/nested-router-tab-view/e2e/custom-tabs.e2e-spec.ts
@@ -0,0 +1,72 @@
+import { AppiumDriver, createDriver } from "nativescript-dev-appium";
+import { Screen } from "./screen"
+import {
+ testPlayerNavigated,
+ testTeamNavigated,
+ testPlayerNextNavigated,
+ testTeamNextNavigated,
+} from "./shared.e2e-spec"
+
+describe("custom-tabs:", () => {
+ let driver: AppiumDriver;
+ let screen: Screen;
+
+ before(async () => {
+ driver = await createDriver();
+ screen = new Screen(driver);
+ });
+
+ after(async () => {
+ await driver.quit();
+ console.log("Quit driver!");
+ });
+
+ afterEach(async function () {
+ if (this.currentTest.state === "failed") {
+ await driver.logTestArtifacts(this.currentTest.title);
+ }
+ });
+
+ it("loaded custom tab component and tabs", async () => {
+ await screen.navigateCustomTabsPage();
+ await screen.loadedCustomTabsPage();
+ await screen.loadedPlayersList();
+ await gotoTeamsTab(driver);
+ await screen.loadedTeamList();
+ });
+
+ it("navigate back to login and again to custom tabs", async () => {
+ await backRoot(driver);
+ await screen.loadedLogin();
+ await screen.navigateCustomTabsPage();
+ await screen.loadedCustomTabsPage();
+ await screen.loadedPlayersList();
+ await gotoTeamsTab(driver);
+ await screen.loadedTeamList();
+ });
+
+ it("navigate back to login and again to custom tabs", async () => {
+ await gotoPlayersTab(driver);
+ await testPlayerNavigated(screen, screen.playerOne);
+ await gotoTeamsTab(driver);
+ await screen.loadedTeamList();
+ await testTeamNavigated(screen, screen.teamOne);
+ await backRoot(driver);
+ await screen.loadedLogin();
+ });
+});
+
+async function backRoot(driver: AppiumDriver) {
+ const btnBackRoot = await driver.findElementByAutomationText("Root Back");
+ await btnBackRoot.tap();
+}
+
+async function gotoPlayersTab(driver: AppiumDriver) {
+ const btnTabTeams = await driver.findElementByAutomationText("Players Tab");
+ await btnTabTeams.tap();
+}
+
+async function gotoTeamsTab(driver: AppiumDriver) {
+ const btnTabTeams = await driver.findElementByAutomationText("Teams Tab");
+ await btnTabTeams.tap();
+}
diff --git a/e2e/nested-router-tab-view/e2e/screen.ts b/e2e/nested-router-tab-view/e2e/screen.ts
index 870fdf9bf..f880d33c8 100644
--- a/e2e/nested-router-tab-view/e2e/screen.ts
+++ b/e2e/nested-router-tab-view/e2e/screen.ts
@@ -1,6 +1,7 @@
import { AppiumDriver, SearchOptions } from "nativescript-dev-appium";
import { assert } from "chai";
+const customTabs = "Custom Tabs Component";
const home = "Home Component";
const about = "About Component";
const aboutNested = "Nested About Component";
@@ -18,6 +19,7 @@ const gotoNextTeam = "next team";
const gotoTeams = "teams";
const gotoHomePage = "Go To Home Page";
+const gotoCustomTabPage = "Go To Lazy Custom Tabs";
const gotoAboutPage = "Go To About Page";
const gotoTabsPage = "Go To Tabs Page";
const confirmDialog = "Ok";
@@ -68,6 +70,12 @@ export class Screen {
console.log(home + " loaded!");
}
+ loadedCustomTabsPage= async () => {
+ const lblCustomTabs = await this._driver.findElementByAutomationText(customTabs);
+ assert.isTrue(await lblCustomTabs.isDisplayed());
+ console.log(home + " loaded!");
+ }
+
loadedAbout= async () => {
const lblAbout = await this._driver.findElementByAutomationText(about);
assert.isTrue(await lblAbout.isDisplayed());
@@ -128,6 +136,11 @@ export class Screen {
await btnNavToHomePage.tap();
}
+ navigateCustomTabsPage = async () => {
+ const btnNavToHomePage = await this._driver.findElementByAutomationText(gotoCustomTabPage);
+ await btnNavToHomePage.tap();
+ }
+
navigateToAboutPage = async () => {
const btnNavToAboutPage = await this._driver.findElementByAutomationText(gotoAboutPage);
await btnNavToAboutPage.tap();
diff --git a/nativescript-angular/dom-adapter.ts b/nativescript-angular/dom-adapter.ts
index 7ddffb681..9d47b2fe7 100644
--- a/nativescript-angular/dom-adapter.ts
+++ b/nativescript-angular/dom-adapter.ts
@@ -1,27 +1,15 @@
/* tslint:disable */
import { Type } from "@angular/core";
-import { ɵDomAdapter } from "@angular/platform-browser";
+import { ɵDomAdapter, ɵsetRootDomAdapter } from "@angular/platform-browser";
import { rendererLog, isLogEnabled } from "./trace";
export class NativeScriptDomAdapter implements ɵDomAdapter {
static makeCurrent() {
+ if (isLogEnabled()) {
+ rendererLog("Setting root DOM adapter...");
+ }
- // Don't register when bundling (likely AoT setup).
- if (!global.TNS_WEBPACK) {
- try {
- const privateAPI = global.require("@angular/platform-browser");
- const setRootDomAdapter = privateAPI.ɵsetRootDomAdapter;
-
- if (isLogEnabled()) {
- rendererLog("Setting root DOM adapter...");
- }
- setRootDomAdapter(new NativeScriptDomAdapter());
- } catch (e) {
- if (isLogEnabled()) {
- rendererLog("@angular/platform-browser package not present. NOT setting root DOM adapter...");
- }
- }
- }
+ ɵsetRootDomAdapter(new NativeScriptDomAdapter());
}
hasProperty(_element: any, _name: string) {
@@ -44,8 +32,8 @@ export class NativeScriptDomAdapter implements ɵDomAdapter {
logGroupEnd(): void {
}
- get attrToPropMap(): {[key: string]: string} { throw new Error("Not implemented!"); };
- set attrToPropMap(_value: {[key: string]: string}) { throw new Error("Not implemented!"); };
+ get attrToPropMap(): { [key: string]: string } { throw new Error("Not implemented!"); };
+ set attrToPropMap(_value: { [key: string]: string }) { throw new Error("Not implemented!"); };
public resourceLoaderType: Type = null;
setProperty(_el: Element, _name: string, _value: any): any /** TODO #9100 */ { throw new Error("Not implemented!") }
@@ -58,11 +46,11 @@ export class NativeScriptDomAdapter implements ɵDomAdapter {
querySelector(_el: any /** TODO #9100 */, _selector: string): HTMLElement { throw new Error("Not implemented!") }
querySelectorAll(_el: any /** TODO #9100 */, _selector: string): any[] { throw new Error("Not implemented!") }
on(
- _el: any /** TODO #9100 */, _evt: any /** TODO #9100 */, _listener: any /** TODO #9100 */): any
+ _el: any /** TODO #9100 */, _evt: any /** TODO #9100 */, _listener: any /** TODO #9100 */): any
/** TODO #9100 */ { throw new Error("Not implemented!") }
onAndCancel(
- _el: any /** TODO #9100 */, _evt: any /** TODO #9100 */,
- _listener: any /** TODO #9100 */): Function { throw new Error("Not implemented!") }
+ _el: any /** TODO #9100 */, _evt: any /** TODO #9100 */,
+ _listener: any /** TODO #9100 */): Function { throw new Error("Not implemented!") }
dispatchEvent(_el: any /** TODO #9100 */, _evt: any /** TODO #9100 */): any
/** TODO #9100 */ { throw new Error("Not implemented!") }
createMouseEvent(_eventType: any /** TODO #9100 */): any { throw new Error("Not implemented!") }
@@ -88,8 +76,8 @@ export class NativeScriptDomAdapter implements ɵDomAdapter {
removeChild(_el: any /** TODO #9100 */, _node: any /** TODO #9100 */): any
/** TODO #9100 */ { throw new Error("Not implemented!") }
replaceChild(
- _el: any /** TODO #9100 */, _newNode: any /** TODO #9100 */,
- _oldNode: any /** TODO #9100 */): any /** TODO #9100 */ { throw new Error("Not implemented!") }
+ _el: any /** TODO #9100 */, _newNode: any /** TODO #9100 */,
+ _oldNode: any /** TODO #9100 */): any /** TODO #9100 */ { throw new Error("Not implemented!") }
remove(_el: any /** TODO #9100 */): Node { throw new Error("Not implemented!") }
insertBefore(_el: any /** TODO #9100 */, _node: any /** TODO #9100 */): any
/** TODO #9100 */ { throw new Error("Not implemented!") }
@@ -111,13 +99,13 @@ export class NativeScriptDomAdapter implements ɵDomAdapter {
createElementNS(_ns: string, _tagName: string, _doc?: any /** TODO #9100 */): Element { throw new Error("Not implemented!") }
createTextNode(_text: string, _doc?: any /** TODO #9100 */): Text { throw new Error("Not implemented!") }
createScriptTag(_attrName: string, _attrValue: string, _doc?: any /** TODO #9100 */):
- HTMLElement { throw new Error("Not implemented!") }
+ HTMLElement { throw new Error("Not implemented!") }
createStyleElement(_css: string, _doc?: any /** TODO #9100 */): HTMLStyleElement { throw new Error("Not implemented!") }
createShadowRoot(_el: any /** TODO #9100 */): any { throw new Error("Not implemented!") }
getShadowRoot(_el: any /** TODO #9100 */): any { throw new Error("Not implemented!") }
getHost(_el: any /** TODO #9100 */): any { throw new Error("Not implemented!") }
getDistributedNodes(_el: any /** TODO #9100 */): Node[] { throw new Error("Not implemented!") }
- clone /**/ (_node: Node /*T*/): Node /*T*/ { throw new Error("Not implemented!") }
+ clone /**/(_node: Node /*T*/): Node /*T*/ { throw new Error("Not implemented!") }
getElementsByClassName(_element: any /** TODO #9100 */, _name: string): HTMLElement[] { throw new Error("Not implemented!") }
getElementsByTagName(_element: any /** TODO #9100 */, _name: string): HTMLElement[] { throw new Error("Not implemented!") }
classList(_element: any /** TODO #9100 */): any[] { throw new Error("Not implemented!") }
@@ -129,7 +117,7 @@ export class NativeScriptDomAdapter implements ɵDomAdapter {
removeStyle(_element: any /** TODO #9100 */, _styleName: string): any /** TODO #9100 */ { throw new Error("Not implemented!") }
getStyle(_element: any /** TODO #9100 */, _styleName: string): string { throw new Error("Not implemented!") }
hasStyle(_element: any /** TODO #9100 */, _styleName: string, _styleValue?: string):
- boolean { throw new Error("Not implemented!") }
+ boolean { throw new Error("Not implemented!") }
tagName(_element: any /** TODO #9100 */): string { throw new Error("Not implemented!") }
attributeMap(_element: any /** TODO #9100 */): Map { throw new Error("Not implemented!") }
hasAttribute(_element: any /** TODO #9100 */, _attribute: string): boolean { throw new Error("Not implemented!") }
@@ -139,7 +127,7 @@ export class NativeScriptDomAdapter implements ɵDomAdapter {
setAttribute(_element: any /** TODO #9100 */, _name: string, _value: string): any
/** TODO #9100 */ { throw new Error("Not implemented!") }
setAttributeNS(_element: any /** TODO #9100 */, _ns: string, _name: string, _value: string):
- any /** TODO #9100 */ { throw new Error("Not implemented!") }
+ any /** TODO #9100 */ { throw new Error("Not implemented!") }
removeAttribute(_element: any /** TODO #9100 */, _attribute: string): any
/** TODO #9100 */ { throw new Error("Not implemented!") }
removeAttributeNS(_element: any /** TODO #9100 */, _ns: string, _attribute: string): any
@@ -158,8 +146,8 @@ export class NativeScriptDomAdapter implements ɵDomAdapter {
isElementNode(_node: any /** TODO #9100 */): boolean { throw new Error("Not implemented!") }
hasShadowRoot(_node: any /** TODO #9100 */): boolean { throw new Error("Not implemented!") }
isShadowRoot(_node: any /** TODO #9100 */): boolean { throw new Error("Not implemented!") }
- importIntoDoc /**/ (_node: Node /*T*/): Node /*T*/ { throw new Error("Not implemented!") }
- adoptNode /**/ (_node: Node /*T*/): Node /*T*/ { throw new Error("Not implemented!") }
+ importIntoDoc /**/(_node: Node /*T*/): Node /*T*/ { throw new Error("Not implemented!") }
+ adoptNode /**/(_node: Node /*T*/): Node /*T*/ { throw new Error("Not implemented!") }
getHref(_element: any /** TODO #9100 */): string { throw new Error("Not implemented!") }
getEventKey(_event: any /** TODO #9100 */): string { throw new Error("Not implemented!") }
resolveAndSetHref(_element: any /** TODO #9100 */, _baseUrl: string, _href: string): any
@@ -183,7 +171,7 @@ export class NativeScriptDomAdapter implements ɵDomAdapter {
getTransitionEnd(): string { throw new Error("Not implemented!") }
supportsAnimation(): boolean { throw new Error("Not implemented!") }
- supportsCookies(): boolean { return false; }
+ supportsCookies(): boolean { return false; }
getCookie(_name: string): string { throw new Error("Not implemented!") }
setCookie(_name: string, _value: string): any /** TODO #9100 */ { throw new Error("Not implemented!") }
}
diff --git a/nativescript-angular/platform-common.ts b/nativescript-angular/platform-common.ts
index 505ec91b2..2f7e958cd 100644
--- a/nativescript-angular/platform-common.ts
+++ b/nativescript-angular/platform-common.ts
@@ -6,6 +6,7 @@ import "./zone-js/dist/zone-nativescript";
import "./polyfills/array";
import "./polyfills/console";
import { profile, uptime } from "tns-core-modules/profiling";
+import "./dom-adapter";
import {
Type,
diff --git a/nativescript-angular/platform.ts b/nativescript-angular/platform.ts
index 9194a40a3..8919d34fd 100644
--- a/nativescript-angular/platform.ts
+++ b/nativescript-angular/platform.ts
@@ -40,9 +40,6 @@ if ((global).___TS_UNUSED) {
(() => MissingTranslationStrategy)();
}
-// Register DOM adapter, if possible. Dynamic platform only!
-import "./dom-adapter";
-
import { NativeScriptElementSchemaRegistry } from "./schema-registry";
import { FileSystemResourceLoader } from "./resource-loader";
diff --git a/nativescript-angular/router/ns-location-strategy.ts b/nativescript-angular/router/ns-location-strategy.ts
index fa6b1c488..7ac6331ba 100644
--- a/nativescript-angular/router/ns-location-strategy.ts
+++ b/nativescript-angular/router/ns-location-strategy.ts
@@ -1,6 +1,6 @@
import { Injectable } from "@angular/core";
import { LocationStrategy } from "@angular/common";
-import { DefaultUrlSerializer, UrlSegmentGroup, UrlTree } from "@angular/router";
+import { DefaultUrlSerializer, UrlSegmentGroup, UrlTree, ActivatedRouteSnapshot } from "@angular/router";
import { routerLog, routerError, isLogEnabled } from "../trace";
import { NavigationTransition, Frame } from "tns-core-modules/ui/frame";
import { isPresent } from "../lang-facade";
@@ -88,6 +88,7 @@ export interface LocationState {
segmentGroup: UrlSegmentGroup;
isRootSegmentGroup: boolean;
isPageNavigation: boolean;
+ frame?: Frame;
}
@Injectable()
@@ -162,7 +163,7 @@ export class NSLocationStrategy extends LocationStrategy {
if (!Object.keys(urlTreeRoot.children).length) {
const segmentGroup = this.currentUrlTree && this.currentUrlTree.root;
const outletKey = this.getOutletKey(this.getSegmentGroupFullPath(segmentGroup), "primary");
- const outlet = this.findOutletByKey(outletKey);
+ const outlet = this.findOutlet(outletKey);
if (outlet && this.updateStates(outlet, segmentGroup)) {
this.currentOutlet = outlet; // If states updated
@@ -186,12 +187,12 @@ export class NSLocationStrategy extends LocationStrategy {
const outletPath = this.getSegmentGroupFullPath(currentTree);
let outletKey = this.getOutletKey(outletPath, outletName);
- let outlet = this.findOutletByKey(outletKey);
+ let outlet = this.findOutlet(outletKey);
const parentOutletName = currentTree.outlet || "";
const parentOutletPath = this.getSegmentGroupFullPath(currentTree.parent);
const parentOutletKey = this.getOutletKey(parentOutletPath, parentOutletName);
- const parentOutlet = this.findOutletByKey(parentOutletKey);
+ const parentOutlet = this.findOutlet(parentOutletKey);
const containsLastState = outlet && outlet.containsTopState(currentSegmentGroup.toString());
if (!outlet) {
@@ -237,7 +238,7 @@ export class NSLocationStrategy extends LocationStrategy {
throw new Error("NSLocationStrategy.forward() - not implemented");
}
- back(outlet?: Outlet): void {
+ back(outlet?: Outlet, frame?: Frame): void {
this.currentOutlet = outlet || this.currentOutlet;
if (this.currentOutlet.isPageNavigationBack) {
@@ -247,6 +248,13 @@ export class NSLocationStrategy extends LocationStrategy {
let state = states.pop();
let count = 1;
+ if (frame) {
+ while (state.frame && state.frame !== frame) {
+ state = states.pop();
+ count++;
+ }
+ }
+
while (!state.isPageNavigation) {
state = states.pop();
count++;
@@ -447,7 +455,13 @@ export class NSLocationStrategy extends LocationStrategy {
return this.outlets;
}
- updateOutletFrame(outlet: Outlet, frame: Frame) {
+ updateOutletFrame(outlet: Outlet, frame: Frame, isEmptyOutletFrame: boolean) {
+ const lastState = outlet.peekState();
+
+ if (lastState && !lastState.frame && !isEmptyOutletFrame) {
+ lastState.frame = frame;
+ }
+
if (!outlet.containsFrame(frame)) {
outlet.frames.push(frame);
}
@@ -547,12 +561,17 @@ export class NSLocationStrategy extends LocationStrategy {
});
}
- findOutletByOutletPath(pathByOutlets: string): Outlet {
- return this.outlets.find((outlet) => outlet.pathByOutlets === pathByOutlets);
- }
+ findOutlet(outletKey: string, activatedRouteSnapshot?: ActivatedRouteSnapshot): Outlet {
+ let outlet: Outlet = this.outlets.find((currentOutlet) => currentOutlet.outletKeys.indexOf(outletKey) > -1);
- findOutletByKey(outletKey: string): Outlet {
- return this.outlets.find((outlet) => outlet.outletKeys.indexOf(outletKey) > -1);
+ // No Outlet with the given outletKey could happen when using nested unnamed p-r-o
+ // primary -> primary -> prymary
+ if (!outlet && activatedRouteSnapshot) {
+ const pathByOutlets = this.getPathByOutlets(activatedRouteSnapshot);
+ outlet = this.outlets.find((currentOutlet) => currentOutlet.pathByOutlets === pathByOutlets);
+ }
+
+ return outlet;
}
private getOutletByFrame(frame: Frame): Outlet {
diff --git a/nativescript-angular/router/ns-route-reuse-strategy.ts b/nativescript-angular/router/ns-route-reuse-strategy.ts
index 0fa0f3e03..4de61062d 100644
--- a/nativescript-angular/router/ns-route-reuse-strategy.ts
+++ b/nativescript-angular/router/ns-route-reuse-strategy.ts
@@ -100,7 +100,7 @@ export class NSRouteReuseStrategy implements RouteReuseStrategy {
route = findTopActivatedRouteNodeForOutlet(route);
const outletKey = this.location.getRouteFullPath(route);
- const outlet = this.location.findOutletByKey(outletKey);
+ const outlet = this.location.findOutlet(outletKey, route);
const key = getSnapshotKey(route);
const isPageActivated = route[pageRouterActivatedSymbol];
const isBack = outlet ? outlet.isPageNavigationBack : false;
@@ -125,7 +125,7 @@ export class NSRouteReuseStrategy implements RouteReuseStrategy {
route = findTopActivatedRouteNodeForOutlet(route);
const outletKey = this.location.getRouteFullPath(route);
- const outlet = this.location.findOutletByKey(outletKey);
+ const outlet = this.location.findOutlet(outletKey, route);
const cache = this.cacheByOutlet[outletKey];
if (!cache) {
return false;
@@ -185,7 +185,7 @@ export class NSRouteReuseStrategy implements RouteReuseStrategy {
route = findTopActivatedRouteNodeForOutlet(route);
const outletKey = this.location.getRouteFullPath(route);
- const outlet = this.location.findOutletByKey(outletKey);
+ const outlet = this.location.findOutlet(outletKey, route);
const cache = this.cacheByOutlet[outletKey];
if (!cache) {
return null;
diff --git a/nativescript-angular/router/page-router-outlet.ts b/nativescript-angular/router/page-router-outlet.ts
index cd105c52a..381ff52bd 100644
--- a/nativescript-angular/router/page-router-outlet.ts
+++ b/nativescript-angular/router/page-router-outlet.ts
@@ -287,7 +287,7 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
}
this.outlet.isNSEmptyOutlet = this.isEmptyOutlet;
- this.locationStrategy.updateOutletFrame(this.outlet, this.frame);
+ this.locationStrategy.updateOutletFrame(this.outlet, this.frame, this.isEmptyOutlet);
if (this.outlet && this.outlet.isPageNavigationBack) {
if (isLogEnabled()) {
@@ -355,7 +355,7 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
page.on(Page.navigatedFromEvent, (global).Zone.current.wrap((args: NavigatedData) => {
if (args.isBackNavigation) {
this.locationStrategy._beginBackPageNavigation(this.frame);
- this.locationStrategy.back();
+ this.locationStrategy.back(null, this.frame);
}
}));
@@ -394,14 +394,14 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
queue.push(childRoute);
});
- const nodeToMark = findTopActivatedRouteNodeForOutlet(currentRoute);
- let outletKeyForRoute = this.locationStrategy.getRouteFullPath(nodeToMark);
- let outlet = this.locationStrategy.findOutletByKey(outletKeyForRoute);
+ const topActivatedRoute = findTopActivatedRouteNodeForOutlet(currentRoute);
+ let outletKey = this.locationStrategy.getRouteFullPath(topActivatedRoute);
+ let outlet = this.locationStrategy.findOutlet(outletKey, topActivatedRoute);
if (outlet && outlet.frames.length) {
- nodeToMark[pageRouterActivatedSymbol] = true;
+ topActivatedRoute[pageRouterActivatedSymbol] = true;
if (isLogEnabled()) {
- log("Activated route marked as page: " + routeToString(nodeToMark));
+ log("Activated route marked as page: " + routeToString(topActivatedRoute));
}
}
@@ -429,20 +429,17 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
if (modalNavigation > 0) { // Modal with 'primary' p-r-o
outlet = this.locationStrategy.findOutletByModal(modalNavigation);
} else {
- outlet = this.locationStrategy.findOutletByKey(outletKey);
+ outlet = this.locationStrategy.findOutlet(outletKey, topActivatedRoute);
}
// Named lazy loaded outlet.
if (!outlet && this.isEmptyOutlet) {
const parentOutletKey = this.locationStrategy.getRouteFullPath(topActivatedRoute.parent);
- outlet = this.locationStrategy.findOutletByKey(parentOutletKey);
+ outlet = this.locationStrategy.findOutlet(parentOutletKey, topActivatedRoute.parent);
if (outlet) {
outlet.outletKeys.push(outletKey);
}
- } else if (!outlet) {
- const pathByOutlets = this.locationStrategy.getPathByOutlets(topActivatedRoute);
- outlet = this.locationStrategy.findOutletByOutletPath(pathByOutlets);
}
return outlet;
diff --git a/nativescript-angular/router/router-extensions.ts b/nativescript-angular/router/router-extensions.ts
index 9f2379488..5959e95dc 100644
--- a/nativescript-angular/router/router-extensions.ts
+++ b/nativescript-angular/router/router-extensions.ts
@@ -126,7 +126,7 @@ export class RouterExtensions {
const currentRouteSnapshop = findTopActivatedRouteNodeForOutlet(currentRoute.snapshot);
const outletKey = this.locationStrategy.getRouteFullPath(currentRouteSnapshop);
- outlet = this.locationStrategy.findOutletByKey(outletKey);
+ outlet = this.locationStrategy.findOutlet(outletKey, currentRouteSnapshop);
return outlet;
}
diff --git a/tests/app/tests/ns-location-strategy.ts b/tests/app/tests/ns-location-strategy.ts
index 2f7208903..1c1ee221d 100644
--- a/tests/app/tests/ns-location-strategy.ts
+++ b/tests/app/tests/ns-location-strategy.ts
@@ -142,7 +142,7 @@ function simulatePageNavigation(strategy: NSLocationStrategy, url: string, frame
outletName = outletName || "primary";
strategy.pushState(null, null, url, null);
- const outlet: Outlet = strategy.findOutletByOutletPath(outletName);
+ const outlet: Outlet = strategy.findOutlet(outletName);
outlet.frames.push(frame);
strategy._beginPageNavigation(frame);
}
@@ -281,7 +281,7 @@ describe("NSLocationStrategy", () => {
strategy.pushState(null, null, "/internal", null);
expectedStates.push(createState("/internal", outletName));
- const outlet: Outlet = strategy.findOutletByOutletPath(outletName);
+ const outlet: Outlet = strategy.findOutlet(outletName);
assertStatesEqual(outlet.states, expectedStates);
});
@@ -306,8 +306,8 @@ describe("NSLocationStrategy", () => {
strategy.pushState(null, null, "/(test1:internal//test2:test2)", null);
expectedStatesTest1.push(createState("/(test1:internal//test2:test2)", outletName));
- const outlet: Outlet = strategy.findOutletByOutletPath(outletName);
- const outlet2: Outlet = strategy.findOutletByOutletPath(outletName2);
+ const outlet: Outlet = strategy.findOutlet(outletName);
+ const outlet2: Outlet = strategy.findOutlet(outletName2);
assertStatesEqual(outlet.states, expectedStatesTest1);
assertStatesEqual(outlet2.states, expectedStatesTest2);
@@ -329,7 +329,7 @@ describe("NSLocationStrategy", () => {
});
simulatePageNavigation(strategy, "/page", currentFrame, outletName);
- const outlet: Outlet = strategy.findOutletByOutletPath(outletName);
+ const outlet: Outlet = strategy.findOutlet(outletName);
assert.equal(frameBackCount, 0);
assert.equal(popCount, 0);
@@ -360,8 +360,8 @@ describe("NSLocationStrategy", () => {
const currentFrame = frameService.getFrame();
simulatePageNavigation(strategy, "/(test1:page//test2:test2)", frame, outletName);
simulatePageNavigation(strategy, "/(test1:page//test2:test2)", currentFrame, outletName2);
- const outlet: Outlet = strategy.findOutletByOutletPath(outletName);
- const outlet2: Outlet = strategy.findOutletByOutletPath(outletName2);
+ const outlet: Outlet = strategy.findOutlet(outletName);
+ const outlet2: Outlet = strategy.findOutlet(outletName2);
assert.equal(frameBackCount, 0);
assert.equal(popCount, 0);
@@ -392,7 +392,7 @@ describe("NSLocationStrategy", () => {
});
simulatePageNavigation(strategy, "/page", currentFrame, outletName);
- const outlet: Outlet = strategy.findOutletByOutletPath(outletName);
+ const outlet: Outlet = strategy.findOutlet(outletName);
assert.equal(frameBackCount, 0);
assert.equal(popCount, 0);
@@ -424,8 +424,8 @@ describe("NSLocationStrategy", () => {
simulatePageNavigation(strategy, "/(test1:page//test2:test2)", frame, outletName);
simulatePageNavigation(strategy, "/(test1:page//test2:test2)", frame2, outletName2);
- const outlet: Outlet = strategy.findOutletByOutletPath(outletName);
- const outlet2: Outlet = strategy.findOutletByOutletPath(outletName2);
+ const outlet: Outlet = strategy.findOutlet(outletName);
+ const outlet2: Outlet = strategy.findOutlet(outletName2);
assert.equal(frameBackCount, 0);
assert.equal(popCount, 0);
@@ -449,7 +449,7 @@ describe("NSLocationStrategy", () => {
// Act
strategy._setNavigationOptions({ clearHistory: true });
simulatePageNavigation(strategy, "/cleared", frame, outletName);
- const outlet: Outlet = strategy.findOutletByOutletPath(outletName);
+ const outlet: Outlet = strategy.findOutlet(outletName);
// Assert
assertStatesEqual(outlet.states, [createState("/cleared", outletName, true)]);
});
@@ -472,8 +472,8 @@ describe("NSLocationStrategy", () => {
createState("/(test1:cleared//test2:test2)", outletName2, true)
];
- const outlet: Outlet = strategy.findOutletByOutletPath(outletName);
- const outlet2: Outlet = strategy.findOutletByOutletPath(outletName2);
+ const outlet: Outlet = strategy.findOutlet(outletName);
+ const outlet2: Outlet = strategy.findOutlet(outletName2);
// Assert
assertStatesEqual(outlet.states, expectedStatesTest1);