From 5a88bc2392e66c2afb9eb72d728ded1912d01b98 Mon Sep 17 00:00:00 2001 From: Eduardo Speroni Date: Wed, 9 Feb 2022 16:19:19 -0300 Subject: [PATCH] fix: restrict nested outlet back navigation scope (#54) --- README.md | 4 +- packages/angular/README.md | 2 +- packages/angular/package.json | 2 +- .../lib/legacy/router/ns-location-strategy.ts | 5 ++- .../lib/legacy/router/ns-location-utils.ts | 9 +++++ .../lib/legacy/router/page-router-outlet.ts | 5 ++- .../lib/legacy/router/router-extensions.ts | 37 +++++++++++++------ 7 files changed, 46 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 5538695..ae41151 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# @nativescript/angular 12+ +# @nativescript/angular -For usage with NativeScript for Angular 12+ projects. +For usage with NativeScript for Angular 12+ (13, etc.) projects. Clean and setup workspace: diff --git a/packages/angular/README.md b/packages/angular/README.md index 76c1c58..a90888f 100644 --- a/packages/angular/README.md +++ b/packages/angular/README.md @@ -1,3 +1,3 @@ # @nativescript/angular -NativeScript for Angular v12+ \ No newline at end of file +For usage with NativeScript for Angular 12+ (13, etc.) projects. \ No newline at end of file diff --git a/packages/angular/package.json b/packages/angular/package.json index ebc4889..8579b6a 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/angular", - "version": "13.0.1", + "version": "13.0.2-alpha.0", "homepage": "https://nativescript.org/", "repository": { "type": "git", diff --git a/packages/angular/src/lib/legacy/router/ns-location-strategy.ts b/packages/angular/src/lib/legacy/router/ns-location-strategy.ts index 34ff45c..6e8bd00 100644 --- a/packages/angular/src/lib/legacy/router/ns-location-strategy.ts +++ b/packages/angular/src/lib/legacy/router/ns-location-strategy.ts @@ -266,7 +266,7 @@ export class NSLocationStrategy extends LocationStrategy { } // Methods for syncing with page navigation in PageRouterOutlet - public _beginBackPageNavigation(frame: Frame) { + public _beginBackPageNavigation(frame: Frame, outletKey: string) { const outlet: Outlet = this.getOutletByFrame(frame); if (!outlet || outlet.isPageNavigationBack) { @@ -279,7 +279,8 @@ export class NSLocationStrategy extends LocationStrategy { if (NativeScriptDebug.isLogEnabled()) { NativeScriptDebug.routerLog('NSLocationStrategy.startGoBack()'); } - outlet.isPageNavigationBack = true; + outlet.setOutletKeyNavigatingBack(outletKey); + // outlet.isPageNavigationBack = true; // we find all the children and also set their isPageNavigationBack this.outlets .filter((o) => { diff --git a/packages/angular/src/lib/legacy/router/ns-location-utils.ts b/packages/angular/src/lib/legacy/router/ns-location-utils.ts index 7813ade..95b24ff 100644 --- a/packages/angular/src/lib/legacy/router/ns-location-utils.ts +++ b/packages/angular/src/lib/legacy/router/ns-location-utils.ts @@ -61,6 +61,15 @@ export class Outlet { this.path = path; } + setOutletKeyNavigatingBack(key: string) { + const nests = key.split('/'); + this.outletKeys + .filter((k) => k.split('/').length >= nests.length) + .forEach((k) => { + this._navigatingBackOutlets.add(k); + }); + } + containsFrame(frame: Frame): boolean { return this.frames.indexOf(frame) > -1; } diff --git a/packages/angular/src/lib/legacy/router/page-router-outlet.ts b/packages/angular/src/lib/legacy/router/page-router-outlet.ts index 94e675e..1cab9c7 100644 --- a/packages/angular/src/lib/legacy/router/page-router-outlet.ts +++ b/packages/angular/src/lib/legacy/router/page-router-outlet.ts @@ -327,9 +327,12 @@ export class PageRouterOutlet implements OnDestroy { // Add it to the new page this.viewUtil.appendChild(page, componentView); + const topActivatedRoute = findTopActivatedRouteNodeForOutlet(this._activatedRoute.snapshot); + const outletKey = this.locationStrategy.getRouteFullPath(topActivatedRoute); + const navigatedFromCallback = (global).Zone.current.wrap((args: NavigatedData) => { if (args.isBackNavigation) { - this.locationStrategy._beginBackPageNavigation(this.frame); + this.locationStrategy._beginBackPageNavigation(this.frame, outletKey); this.locationStrategy.back(null, this.frame); } }); diff --git a/packages/angular/src/lib/legacy/router/router-extensions.ts b/packages/angular/src/lib/legacy/router/router-extensions.ts index 5e17c95..27f1f3f 100644 --- a/packages/angular/src/lib/legacy/router/router-extensions.ts +++ b/packages/angular/src/lib/legacy/router/router-extensions.ts @@ -88,7 +88,6 @@ export class RouterExtensions { // tslint:disable-next-line:max-line-length private findOutletsToBack(options?: BackNavigationOptions): { outletsToBack: Array; outlets: Array } { - const outletsToBack: Array = []; const rootRoute: ActivatedRoute = this.router.routerState.root; let outlets = options.outlets; let relativeRoute = options.relativeTo || rootRoute; @@ -102,21 +101,37 @@ export class RouterExtensions { relativeRoute = relativeRoute.parent || relativeRoute; } - const routesToMatch = outlets ? relativeRoute.children : [relativeRoute]; outlets = outlets || [relativeRoute.outlet]; - for (let index = 0; index < routesToMatch.length; index++) { - const currentRoute = routesToMatch[index]; - if (outlets.some((currentOutlet) => currentOutlet === currentRoute.outlet)) { - const outlet = this.findOutletByRoute(currentRoute); + const outletsToBack = this.findOutletsRecursive([...outlets], relativeRoute); - if (outlet) { - outletsToBack.push(outlet); - } + return { outletsToBack: outletsToBack, outlets: outlets }; + } + + // warning, outlets is mutable! + private findOutletsRecursive(outlets: string[], route?: ActivatedRoute) { + if (!route || outlets.length === 0) { + return []; + } + const outletsToBack = []; + if (outlets.some((currentOutlet) => currentOutlet === route.outlet)) { + const outlet = this.findOutletByRoute(route); + if (outlet) { + outlets.splice(outlets.indexOf(route.outlet), 1); + outletsToBack.push(outlet); } } - - return { outletsToBack: outletsToBack, outlets: outlets }; + if (!route.children) { + return outletsToBack; + } + for (let index = 0; index < route.children.length; index++) { + if (outlets.length === 0) { + break; + } + const currentRoute = route.children[index]; + outletsToBack.push(...this.findOutletsRecursive(outlets, currentRoute)); + } + return outletsToBack; } private findOutletByRoute(currentRoute: ActivatedRoute): Outlet {