|
|
@@ -1,4 +1,12 @@
|
|
|
-import { ChangeDetectionStrategy, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
|
|
+import {
|
|
|
+ AfterViewInit,
|
|
|
+ ChangeDetectionStrategy,
|
|
|
+ Component,
|
|
|
+ ElementRef,
|
|
|
+ OnDestroy,
|
|
|
+ OnInit,
|
|
|
+ ViewChild,
|
|
|
+} from '@angular/core';
|
|
|
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
|
|
|
import { ActivatedRoute } from '@angular/router';
|
|
|
|
|
|
@@ -12,9 +20,13 @@ import { ExtensionHostService } from './extension-host.service';
|
|
|
changeDetection: ChangeDetectionStrategy.Default,
|
|
|
providers: [ExtensionHostService],
|
|
|
})
|
|
|
-export class ExtensionHostComponent implements OnInit {
|
|
|
+export class ExtensionHostComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
|
extensionUrl: SafeResourceUrl;
|
|
|
- @ViewChild('extensionFrame', { static: true }) private extensionFrame: ElementRef<HTMLIFrameElement>;
|
|
|
+ openInIframe = true;
|
|
|
+ extensionWindowIsOpen = false;
|
|
|
+ private config: ExtensionHostConfig;
|
|
|
+ private extensionWindow?: Window;
|
|
|
+ @ViewChild('extensionFrame', { static: false }) private extensionFrame: ElementRef<HTMLIFrameElement>;
|
|
|
|
|
|
constructor(
|
|
|
private route: ActivatedRoute,
|
|
|
@@ -29,15 +41,53 @@ export class ExtensionHostComponent implements OnInit {
|
|
|
`Expected an ExtensionHostConfig object, got ${JSON.stringify(data.extensionHostConfig)}`,
|
|
|
);
|
|
|
}
|
|
|
+ this.config = data.extensionHostConfig;
|
|
|
+ this.openInIframe = !this.config.openInNewTab;
|
|
|
this.extensionUrl = this.sanitizer.bypassSecurityTrustResourceUrl(
|
|
|
- data.extensionHostConfig.extensionUrl || 'about:blank',
|
|
|
+ this.config.extensionUrl || 'about:blank',
|
|
|
);
|
|
|
- const { contentWindow } = this.extensionFrame.nativeElement;
|
|
|
- if (contentWindow) {
|
|
|
- this.extensionHostService.init(contentWindow);
|
|
|
+ }
|
|
|
+
|
|
|
+ ngAfterViewInit() {
|
|
|
+ if (this.openInIframe) {
|
|
|
+ const extensionWindow = this.extensionFrame.nativeElement.contentWindow;
|
|
|
+ if (extensionWindow) {
|
|
|
+ this.extensionHostService.init(extensionWindow);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ngOnDestroy(): void {
|
|
|
+ if (this.extensionWindow) {
|
|
|
+ this.extensionWindow.close();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ launchExtensionWindow() {
|
|
|
+ const extensionWindow = window.open(this.config.extensionUrl);
|
|
|
+ if (!extensionWindow) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.extensionHostService.init(extensionWindow);
|
|
|
+ this.extensionWindowIsOpen = true;
|
|
|
+ this.extensionWindow = extensionWindow;
|
|
|
+
|
|
|
+ let timer: number;
|
|
|
+ function pollWindowState(extwindow: Window, onClosed: () => void) {
|
|
|
+ if (extwindow.closed) {
|
|
|
+ window.clearTimeout(timer);
|
|
|
+ onClosed();
|
|
|
+ } else {
|
|
|
+ timer = window.setTimeout(() => pollWindowState(extwindow, onClosed), 250);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pollWindowState(extensionWindow, () => {
|
|
|
+ this.extensionWindowIsOpen = false;
|
|
|
+ this.extensionHostService.destroy();
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
private isExtensionHostConfig(input: any): input is ExtensionHostConfig {
|
|
|
return input.hasOwnProperty('extensionUrl');
|
|
|
}
|