Webview changed to a normal component, not directive

This commit is contained in:
jliddev
2022-01-07 10:08:03 -06:00
parent d0e6c78e32
commit 7866d9c531
6 changed files with 131 additions and 107 deletions

View File

@@ -0,0 +1 @@
<div #webviewContainer class="webview-container"></div>

View File

@@ -0,0 +1,4 @@
.webview-container {
width: 100%;
height: 100%;
}

View File

@@ -0,0 +1,121 @@
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
ElementRef,
Input,
NgZone,
OnDestroy,
OnInit,
ViewChild,
} from "@angular/core";
import { nanoid } from "nanoid";
import { Subject, takeUntil } from "rxjs";
import { AdPageOptions } from "../../../../common/wowup/models";
import { ElectronService } from "../../../services/electron/electron.service";
import { FileService } from "../../../services/files/file.service";
import { LinkService } from "../../../services/links/link.service";
import { SessionService } from "../../../services/session/session.service";
@Component({
selector: "app-webview",
templateUrl: "./webview.component.html",
styleUrls: ["./webview.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class WebViewComponent implements OnInit, OnDestroy, AfterViewInit {
@Input("options") public options: AdPageOptions;
@ViewChild("webviewContainer", { read: ElementRef }) public webviewContainer!: ElementRef;
private readonly destroy$: Subject<boolean> = new Subject<boolean>();
private _tag: Electron.WebviewTag;
private _id: string = nanoid();
public constructor(
private _electronService: ElectronService,
private _fileService: FileService,
private _linkService: LinkService,
private _sessionService: SessionService,
private _ngZone: NgZone
) {}
ngAfterViewInit(): void {
this.initWebview(this.webviewContainer).catch((e) => console.error(e));
this._electronService.on("webview-new-window", this.onWebviewNewWindow);
}
ngOnInit(): void {}
ngOnDestroy(): void {
this.destroy$.next(true);
this.destroy$.unsubscribe();
this._electronService.off("webview-new-window", this.onWebviewNewWindow);
// Clean up the webview element
if (this._tag) {
if (this._tag.isDevToolsOpened()) {
this._tag.closeDevTools();
}
this._tag = undefined;
}
// this._element.nativeElement.innerHTML = 0;
}
private async initWebview(element: ElementRef) {
const pageReferrer = this.options.referrer ? `httpreferrer="${this.options.referrer}"` : "";
const userAgent = this.options.userAgent ?? "";
const preload = this.options.preloadFilePath
? `preload="${await this._fileService.getAssetFilePath(this.options.preloadFilePath)}"`
: "";
const partition = this.options.partition ?? "memcache";
console.debug("initWebview", this.options);
const placeholder = document.createElement("div");
/* eslint-disable no-irregular-whitespace */
placeholder.innerHTML = `
<webview id="${this._id}"
src="${this.options.pageUrl}"
${pageReferrer}
style="width: 100%; height: 100%;"
nodeintegration="false"
nodeintegrationinsubframes="false"
plugins="false"
allowpopups="false"
partition="${partition}"
${preload}
useragent="${userAgent}">
</webview>`;
/* eslint-enable no-irregular-whitespace */
this._tag = placeholder.firstElementChild as Electron.WebviewTag;
element.nativeElement.appendChild(this._tag);
this._tag.addEventListener("dom-ready", this.onWebviewReady);
}
private onWebviewReady = () => {
console.debug("onWebviewReady", this._tag);
this._sessionService.debugAdFrame$.pipe(takeUntil(this.destroy$)).subscribe(() => {
if (!this._tag.isDevToolsOpened()) {
this._tag?.openDevTools();
}
});
this._tag.removeEventListener("dom-ready", this.onWebviewReady);
// this._tag.openDevTools();
};
private onWebviewNewWindow = (evt, details: Electron.HandlerDetails) => {
console.debug(`webview-new-window`, details);
this._ngZone.run(() => {
this._linkService.confirmLinkNavigation(details.url).subscribe();
});
};
}

View File

@@ -1,104 +0,0 @@
import { Directive, ElementRef, Input, OnDestroy, OnInit } from "@angular/core";
import { nanoid } from "nanoid";
import { Subject, takeUntil } from "rxjs";
import { AdPageOptions } from "../../common/wowup/models";
import { ElectronService } from "../services";
import { FileService } from "../services/files/file.service";
import { LinkService } from "../services/links/link.service";
import { SessionService } from "../services/session/session.service";
@Directive({
selector: "app-webview",
})
export class WebviewComponent implements OnInit, OnDestroy {
@Input("options") public options: AdPageOptions;
private readonly destroy$: Subject<boolean> = new Subject<boolean>();
private _tag: Electron.WebviewTag;
private _id: string = nanoid();
private _element: ElementRef;
public constructor(
el: ElementRef,
private _fileService: FileService,
private _linkService: LinkService,
private _sessionService: SessionService,
private _electronService: ElectronService
) {
this._element = el;
}
public ngOnInit(): void {
this.initWebview(this._element).catch((e) => console.error(e));
this._electronService.on("webview-new-window", this.onWebviewNewWindow);
}
public ngOnDestroy(): void {
this.destroy$.next(true);
this.destroy$.unsubscribe();
this._electronService.off("webview-new-window", this.onWebviewNewWindow);
// Clean up the webview element
if (this._tag) {
if (this._tag.isDevToolsOpened()) {
this._tag.closeDevTools();
}
this._tag = undefined;
}
this._element.nativeElement.innerHTML = 0;
}
private async initWebview(element: ElementRef) {
const pageReferrer = this.options.referrer ? `httpreferrer="${this.options.referrer}"` : "";
const userAgent = this.options.userAgent ?? "";
const preload = this.options.preloadFilePath
? `preload="${await this._fileService.getAssetFilePath(this.options.preloadFilePath)}"`
: "";
const partition = this.options.partition ?? "memcache";
console.debug("initWebview", this.options);
const placeholder = document.createElement("div");
/* eslint-disable no-irregular-whitespace */
placeholder.innerHTML = `
<webview id="${this._id}"
src="${this.options.pageUrl}"
${pageReferrer}
style="width: 100%; height: 100%;"
nodeintegration="false"
nodeintegrationinsubframes="false"
plugins="false"
allowpopups="false"
partition="${partition}"
${preload}
useragent="${userAgent}">
</webview>`;
/* eslint-enable no-irregular-whitespace */
this._tag = placeholder.firstElementChild as Electron.WebviewTag;
element.nativeElement.appendChild(this._tag);
this._tag.addEventListener("dom-ready", this.onWebviewReady);
}
private onWebviewReady = () => {
console.debug("onWebviewReady", this._tag);
this._sessionService.debugAdFrame$.pipe(takeUntil(this.destroy$)).subscribe(() => {
if (!this._tag.isDevToolsOpened()) {
this._tag?.openDevTools();
}
});
this._tag.removeEventListener("dom-ready", this.onWebviewReady);
// this._tag.openDevTools();
};
private onWebviewNewWindow = (evt, details: Electron.HandlerDetails) => {
console.debug(`webview-new-window`, details);
this._linkService.confirmLinkNavigation(details.url).subscribe();
};
}

View File

@@ -14,6 +14,7 @@ import { ExternalUrlConfirmationDialogComponent } from "../components/common/ext
import { PatchNotesDialogComponent } from "../components/common/patch-notes-dialog/patch-notes-dialog.component";
import { ProgressButtonComponent } from "../components/common/progress-button/progress-button.component";
import { TelemetryDialogComponent } from "../components/common/telemetry-dialog/telemetry-dialog.component";
import { WebViewComponent } from "../components/common/webview/webview.component";
import { ProgressSpinnerComponent } from "../components/progress-spinner/progress-spinner.component";
import { MatModule } from "./mat-module";
import { PipesModule } from "./pipes.module";
@@ -33,6 +34,7 @@ import { PipesModule } from "./pipes.module";
CellWrapTextComponent,
CenteredSnackbarComponent,
ClientSelectorComponent,
WebViewComponent,
],
imports: [CommonModule, FormsModule, TranslateModule, MatModule, PipesModule, ReactiveFormsModule],
exports: [
@@ -49,6 +51,7 @@ import { PipesModule } from "./pipes.module";
CellWrapTextComponent,
CenteredSnackbarComponent,
ClientSelectorComponent,
WebViewComponent,
],
})
export class CommonUiModule {}

View File

@@ -1,10 +1,9 @@
import { NgModule } from "@angular/core";
import { WebviewComponent } from "../directives/webview.component";
import { ExternalLinkDirective } from "../directives/external-link.directive";
@NgModule({
declarations: [ExternalLinkDirective, WebviewComponent],
exports: [ExternalLinkDirective, WebviewComponent],
declarations: [ExternalLinkDirective],
exports: [ExternalLinkDirective],
})
export class DirectiveModule {}