refactor: store <webview> attributes as typed Map (#26307)

This commit is contained in:
Milan Burda 2020-11-04 00:02:23 +01:00 committed by GitHub
parent 42aa6b8ea5
commit d25fa7b075
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 35 deletions

View file

@ -18,7 +18,7 @@ interface MutationHandler {
// Attribute objects. // Attribute objects.
// Default implementation of a WebView attribute. // Default implementation of a WebView attribute.
class WebViewAttribute implements MutationHandler { export class WebViewAttribute implements MutationHandler {
public value: any; public value: any;
public ignoreMutation = false; public ignoreMutation = false;
@ -79,7 +79,7 @@ class BooleanAttribute extends WebViewAttribute {
} }
// Attribute representing the state of the storage partition. // Attribute representing the state of the storage partition.
class PartitionAttribute extends WebViewAttribute { export class PartitionAttribute extends WebViewAttribute {
public validPartitionId = true public validPartitionId = true
constructor (public webViewImpl: WebViewImpl) { constructor (public webViewImpl: WebViewImpl) {
@ -103,7 +103,7 @@ class PartitionAttribute extends WebViewAttribute {
} }
// Attribute that handles the location and navigation of the webview. // Attribute that handles the location and navigation of the webview.
class SrcAttribute extends WebViewAttribute { export class SrcAttribute extends WebViewAttribute {
public observer!: MutationObserver; public observer!: MutationObserver;
constructor (public webViewImpl: WebViewImpl) { constructor (public webViewImpl: WebViewImpl) {
@ -169,7 +169,7 @@ class SrcAttribute extends WebViewAttribute {
} }
public parse () { public parse () {
if (!this.webViewImpl.elementAttached || !this.webViewImpl.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION].validPartitionId || !this.getValue()) { if (!this.webViewImpl.elementAttached || !(this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION) as PartitionAttribute).validPartitionId || !this.getValue()) {
return; return;
} }
if (this.webViewImpl.guestInstanceId == null) { if (this.webViewImpl.guestInstanceId == null) {
@ -183,12 +183,12 @@ class SrcAttribute extends WebViewAttribute {
// Navigate to |this.src|. // Navigate to |this.src|.
const opts: Record<string, string> = {}; const opts: Record<string, string> = {};
const httpreferrer = this.webViewImpl.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER].getValue(); const httpreferrer = this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER)!.getValue();
if (httpreferrer) { if (httpreferrer) {
opts.httpReferrer = httpreferrer; opts.httpReferrer = httpreferrer;
} }
const useragent = this.webViewImpl.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT].getValue(); const useragent = this.webViewImpl.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT)!.getValue();
if (useragent) { if (useragent) {
opts.userAgent = useragent; opts.userAgent = useragent;
} }
@ -275,19 +275,18 @@ class EnableRemoteModuleAttribute extends WebViewAttribute {
// Sets up all of the webview attributes. // Sets up all of the webview attributes.
WebViewImpl.prototype.setupWebViewAttributes = function () { WebViewImpl.prototype.setupWebViewAttributes = function () {
this.attributes = {}; this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION, new PartitionAttribute(this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION] = new PartitionAttribute(this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC, new SrcAttribute(this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC] = new SrcAttribute(this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER, new HttpReferrerAttribute(this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER] = new HttpReferrerAttribute(this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT, new UserAgentAttribute(this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT] = new UserAgentAttribute(this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION, this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES, this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS, this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY, this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS] = new BooleanAttribute(WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS, this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_ENABLEREMOTEMODULE, new EnableRemoteModuleAttribute(this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_ENABLEREMOTEMODULE] = new EnableRemoteModuleAttribute(this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD, new PreloadAttribute(this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES, new BlinkFeaturesAttribute(this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES] = new BlinkFeaturesAttribute(this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES, new DisableBlinkFeaturesAttribute(this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES] = new DisableBlinkFeaturesAttribute(this); this.attributes.set(WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES, new WebPreferencesAttribute(this));
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES] = new WebPreferencesAttribute(this);
}; };

View file

@ -16,9 +16,6 @@ export const enum WEB_VIEW_CONSTANTS {
ATTRIBUTE_DISABLEBLINKFEATURES = 'disableblinkfeatures', ATTRIBUTE_DISABLEBLINKFEATURES = 'disableblinkfeatures',
ATTRIBUTE_WEBPREFERENCES = 'webpreferences', ATTRIBUTE_WEBPREFERENCES = 'webpreferences',
// Internal attribute.
ATTRIBUTE_INTERNALINSTANCEID = 'internalinstanceid',
// Error messages. // Error messages.
ERROR_MSG_ALREADY_NAVIGATED = 'The object has already navigated, so its partition cannot be changed.', ERROR_MSG_ALREADY_NAVIGATED = 'The object has already navigated, so its partition cannot be changed.',
ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview> = ' + 'Script cannot be injected into content until the page has loaded.', ERROR_MSG_CANNOT_INJECT_SCRIPT = '<webview> = ' + 'Script cannot be injected into content until the page has loaded.',

View file

@ -10,6 +10,7 @@
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants'; import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
import { WebViewImpl as IWebViewImpl, webViewImplModule } from '@electron/internal/renderer/web-view/web-view-impl'; import { WebViewImpl as IWebViewImpl, webViewImplModule } from '@electron/internal/renderer/web-view/web-view-impl';
import type { SrcAttribute } from '@electron/internal/renderer/web-view/web-view-attributes';
// Return a WebViewElement class that is defined in this context. // Return a WebViewElement class that is defined in this context.
const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof webViewImplModule) => { const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof webViewImplModule) => {
@ -49,7 +50,7 @@ const defineWebViewElement = (v8Util: NodeJS.V8UtilBinding, webViewImpl: typeof
if (!internal.elementAttached) { if (!internal.elementAttached) {
guestViewInternal.registerEvents(internal, internal.viewInstanceId); guestViewInternal.registerEvents(internal, internal.viewInstanceId);
internal.elementAttached = true; internal.elementAttached = true;
internal.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC].parse(); (internal.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC) as SrcAttribute).parse();
} }
} }

View file

@ -5,6 +5,7 @@ import * as ipcRendererUtils from '@electron/internal/renderer/ipc-renderer-inte
import * as guestViewInternal from '@electron/internal/renderer/web-view/guest-view-internal'; import * as guestViewInternal from '@electron/internal/renderer/web-view/guest-view-internal';
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants'; import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
import { syncMethods, asyncMethods, properties } from '@electron/internal/common/web-view-methods'; import { syncMethods, asyncMethods, properties } from '@electron/internal/common/web-view-methods';
import type { WebViewAttribute, PartitionAttribute } from '@electron/internal/renderer/web-view/web-view-attributes';
import { deserialize } from '@electron/internal/common/type-utils'; import { deserialize } from '@electron/internal/common/type-utils';
import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages'; import { IPC_MESSAGES } from '@electron/internal/common/ipc-messages';
const { webFrame } = electron; const { webFrame } = electron;
@ -34,7 +35,7 @@ export class WebViewImpl {
public internalElement: HTMLIFrameElement public internalElement: HTMLIFrameElement
// Replaced in web-view-attributes // Replaced in web-view-attributes
public attributes: Record<string, any> = {} public attributes = new Map<string, WebViewAttribute>();
public setupWebViewAttributes (): void {} public setupWebViewAttributes (): void {}
constructor (public webviewNode: HTMLElement) { constructor (public webviewNode: HTMLElement) {
@ -77,7 +78,7 @@ export class WebViewImpl {
} }
this.beforeFirstNavigation = true; this.beforeFirstNavigation = true;
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION].validPartitionId = true; (this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION) as PartitionAttribute).validPartitionId = true;
// Since attachment swaps a local frame for a remote frame, we need our // Since attachment swaps a local frame for a remote frame, we need our
// internal iframe element to be local again before we can reattach. // internal iframe element to be local again before we can reattach.
@ -96,12 +97,12 @@ export class WebViewImpl {
// attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more // attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more
// details. // details.
handleWebviewAttributeMutation (attributeName: string, oldValue: any, newValue: any) { handleWebviewAttributeMutation (attributeName: string, oldValue: any, newValue: any) {
if (!this.attributes[attributeName] || this.attributes[attributeName].ignoreMutation) { if (!this.attributes.has(attributeName) || this.attributes.get(attributeName)!.ignoreMutation) {
return; return;
} }
// Let the changed attribute handle its own mutation // Let the changed attribute handle its own mutation
this.attributes[attributeName].handleMutation(oldValue, newValue); this.attributes.get(attributeName)!.handleMutation(oldValue, newValue);
} }
onElementResize () { onElementResize () {
@ -150,7 +151,7 @@ export class WebViewImpl {
// Touching the src attribute triggers a navigation. To avoid // Touching the src attribute triggers a navigation. To avoid
// triggering a page reload on every guest-initiated navigation, // triggering a page reload on every guest-initiated navigation,
// we do not handle this mutation. // we do not handle this mutation.
this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC].setValueIgnoreMutation(newValue); this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC)!.setValueIgnoreMutation(newValue);
} }
} }
@ -164,7 +165,7 @@ export class WebViewImpl {
} }
onAttach (storagePartitionId: number) { onAttach (storagePartitionId: number) {
return this.attributes[WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION].setValue(storagePartitionId); return this.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION)!.setValue(storagePartitionId);
} }
buildParams () { buildParams () {
@ -173,10 +174,8 @@ export class WebViewImpl {
userAgentOverride: this.userAgentOverride userAgentOverride: this.userAgentOverride
}; };
for (const attributeName in this.attributes) { for (const [attributeName, attribute] of this.attributes) {
if (Object.prototype.hasOwnProperty.call(this.attributes, attributeName)) { params[attributeName] = attribute.getValue();
params[attributeName] = this.attributes[attributeName].getValue();
}
} }
return params; return params;