diff --git a/projects/scion/microfrontend-platform/src/lib/client/router-outlet/outlet-router.spec.ts b/projects/scion/microfrontend-platform/src/lib/client/router-outlet/outlet-router.spec.ts index 6837ad34..4be6833f 100644 --- a/projects/scion/microfrontend-platform/src/lib/client/router-outlet/outlet-router.spec.ts +++ b/projects/scion/microfrontend-platform/src/lib/client/router-outlet/outlet-router.spec.ts @@ -11,12 +11,43 @@ import {MicrofrontendPlatform} from '../../microfrontend-platform'; import {MicrofrontendPlatformHost} from '../../host/microfrontend-platform-host'; import {Beans} from '@scion/toolkit/bean-manager'; import {OutletRouter} from './outlet-router'; +import {SciRouterOutletElement} from './router-outlet.element'; +import {fromEvent, lastValueFrom} from 'rxjs'; +import {take} from 'rxjs/operators'; describe('OutletRouter', () => { beforeEach(async () => await MicrofrontendPlatform.destroy()); afterEach(async () => await MicrofrontendPlatform.destroy()); + it('should support navigating to blob URL', async () => { + await MicrofrontendPlatformHost.start({applications: []}); + + // Add element to the DOM. + const sciRouterOutlet = document.body.appendChild(document.createElement('sci-router-outlet') as SciRouterOutletElement); + sciRouterOutlet.name = 'outlet'; + sciRouterOutlet.style.height = '150px'; + sciRouterOutlet.style.width = '300px'; + sciRouterOutlet.style.border = '1px solid black'; + + // Create blob URL. + const content = '
Blob Content
'; + const blobUrl = URL.createObjectURL(new Blob([content], {type: 'text/html'})); + + // Navigate to blob URL. + Beans.get(OutletRouter).navigate(blobUrl, {outlet: 'outlet'}).then(); + + // Wait until loaded the blob page into the iframe. + // Since the iframe is initialized with the "about:blank" page, we expect the blob page load event to fire as the second load event. + await lastValueFrom(fromEvent(sciRouterOutlet.iframe, 'load').pipe(take(2))); + + // Expect the blob page to display. + expect((sciRouterOutlet.iframe.contentWindow!.document.querySelector('main'))!.innerText).toEqual('Blob Content'); + + // Cleanup resources. + URL.revokeObjectURL(blobUrl); + }); + describe('intent-based-routing', () => { it('should reject navigation if passing "relativeTo" navigation option', async () => { await MicrofrontendPlatformHost.start({applications: []}); diff --git a/projects/scion/microfrontend-platform/src/lib/url.util.spec.ts b/projects/scion/microfrontend-platform/src/lib/url.util.spec.ts index 21692450..a55a46d9 100644 --- a/projects/scion/microfrontend-platform/src/lib/url.util.spec.ts +++ b/projects/scion/microfrontend-platform/src/lib/url.util.spec.ts @@ -38,6 +38,10 @@ describe('Urls', () => { it('should evaluate to `true` if given the \'about:blank\' URL', () => { expect(Urls.isAbsoluteUrl('about:blank')).toBeTrue(); }); + + it('should evaluate to `true` if given a blob URL', () => { + expect(Urls.isAbsoluteUrl('blob:https://localhost:4200/bbcc7119-13e2-4f99-95fc-c1872f1e322c')).toBeTrue(); + }); }); describe('Urls.ensureTrailingSlash', () => { diff --git a/projects/scion/microfrontend-platform/src/lib/url.util.ts b/projects/scion/microfrontend-platform/src/lib/url.util.ts index d33e3cf2..1fbc96fa 100644 --- a/projects/scion/microfrontend-platform/src/lib/url.util.ts +++ b/projects/scion/microfrontend-platform/src/lib/url.util.ts @@ -8,7 +8,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -const ABSOLUTE_URL_REGEX = /^http[s]?:\/\//; +const ABSOLUTE_URL_REGEX = /^(https?:\/\/)|(blob:)/; /** * @internal @@ -16,7 +16,7 @@ const ABSOLUTE_URL_REGEX = /^http[s]?:\/\//; export namespace Urls { /** - * Returns `true` if the given URL is an absolute URL or the 'about:blank' page. + * Returns `true` if the given URL is an absolute URL, a blob or the 'about:blank' page. */ export function isAbsoluteUrl(url: string): boolean { return url === 'about:blank' || ABSOLUTE_URL_REGEX.test(url);