diff --git a/src/templates/main.ts.hbs b/src/templates/main.ts.hbs index 526ff26..3b3aa2a 100644 --- a/src/templates/main.ts.hbs +++ b/src/templates/main.ts.hbs @@ -5,7 +5,7 @@ import 'regenerator-runtime/runtime'; // Polyfill for async/await import { ApplicationRef, enableProdMode, NgModuleRef, NgZone } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import { Router } from '@angular/router'; +import { DefaultUrlSerializer, Router } from '@angular/router'; import { environment } from './environments/environment'; @@ -29,6 +29,7 @@ let webCompPage; let router; let zone; let baseHref; +const defaultUrlSerializer = new DefaultUrlSerializer(); {{{mountStyles}}} @@ -57,32 +58,37 @@ function bootstrap(appModuleRef, baseHref) { window.history.replaceState(null, '', `${baseHref}/${pageNameConfigured}`); router.navigate(['/'+ pageNameConfigured]); }else { - const decodedURL = decodeURIComponent(relativePath); - const [path, queryString] = decodedURL.split('?'); - const queryParams: any = {}; - - if (queryString) { - queryString.split('&').forEach(pair => { - const [key, value] = pair.split('='); - queryParams[key] = value; - }); - } - - router.navigate([path], { queryParams }); + const serializedURL = defaultUrlSerializer.serialize(router.parseUrl(relativePath)); + router.navigateByUrl(serializedURL); } - //pushState, replaceState overrided to control routing when user triggered in parent app + /** + * Monkey Patched pushState, replaceSate functions to detect url changes + * when user triggers from parent app this checks if the route + * passed from interceptor, if not it makes a new request + */ function overrideHistoryMethod(methodName: 'pushState' | 'replaceState') { const originalMethod = history[methodName]; history[methodName] = function (state) { + const currRoute = arguments[2]; if (state?.customIntercepted) { + /** + * on removing hashing in route, url will be encoded + * by default angular retuns decoded route, which on compared with browser url + * triggers pushState instead of replaceState + * for this browser url is serialized for comparing with the route + */ + let urlTree = router.parseUrl(window.location.pathname + window.location.search); + let currentURL = defaultUrlSerializer.serialize(urlTree); + + if( currRoute === currentURL ){ + return; + } originalMethod.apply(this, arguments); return; } - const currRoute = arguments[2]; - if (!currRoute.startsWith(baseHref)) { originalMethod.apply(this, arguments); return; @@ -96,19 +102,10 @@ function bootstrap(appModuleRef, baseHref) { const relativePath = currRoute.slice(baseHref.length); if (relativePath) { - const decodedURL = decodeURIComponent(relativePath); - const [path, queryString] = decodedURL.split('?'); - const queryParams: any = {}; - - if (queryString) { - queryString.split('&').forEach(pair => { - const [key, value] = pair.split('='); - queryParams[key] = value; - }); - } + const serializedURL = defaultUrlSerializer.serialize(router.parseUrl(relativePath)); zone.run(() => { - router.navigate([path], { queryParams }); + router.navigateByUrl(serializedURL); }); } else { zone.run(() => { @@ -129,18 +126,8 @@ function bootstrap(appModuleRef, baseHref) { : null; if(relativePath){ - const decodedURL = decodeURIComponent(relativePath); - const [path, queryString] = decodedURL.split('?'); - const queryParams: any = {}; - - if (queryString) { - queryString.split('&').forEach(pair => { - const [key, value] = pair.split('='); - queryParams[decodeURIComponent(key)] = decodeURIComponent(value); - }); - } - - router.navigate([path], { queryParams }); + const serializedURL = defaultUrlSerializer.serialize(router.parseUrl(relativePath)); + router.navigateByUrl(serializedURL); } }); } diff --git a/src/templates/mount.js.hbs b/src/templates/mount.js.hbs index c9aec08..570b289 100644 --- a/src/templates/mount.js.hbs +++ b/src/templates/mount.js.hbs @@ -91,7 +91,10 @@ function initializeApp(appName, retries = 0, maxRetries = 10) { wmAppClassElement.appendChild(appComponentElement); } - // triggered when navigated to webcomponent page from not a webcomponent page + /** + * when user navigates from webcomponent page to non-webcomponent page + * and then returns to webcomponent page, new route request is called + */ if(!webCompPage && hasBootstrapped && {{isWebApp}}){ let pageNameConfigured = appComponentElement.getAttribute("pageName"); pageNameConfigured = pageNameConfigured ? pageNameConfigured : "Main"; @@ -105,17 +108,8 @@ function initializeApp(appName, retries = 0, maxRetries = 10) { window.history.replaceState(null, '', `${baseHref}/${pageNameConfigured}`); router.navigate(['/'+ pageNameConfigured]); }else { - const decodedURL = decodeURIComponent(relativePath); - const [path, queryString] = decodedURL.split('?'); - const queryParams: any = {}; - - if (queryString) { - queryString.split('&').forEach(pair => { - const [key, value] = pair.split('='); - queryParams[key] = value; - }); - } - router.navigate([path], { queryParams }); + const serializedURL = defaultUrlSerializer.serialize(router.parseUrl(relativePath)); + router.navigateByUrl(serializedURL); } webCompPage = true;