asarfuckery/electronasar/ptb/renderer/web-view/web-view-element.js

102 lines
4.5 KiB
JavaScript

"use strict";
// When using context isolation, the WebViewElement and the custom element
// methods have to be defined in the main world to be able to be registered.
//
// Note: The hidden values can only be read/set inside the same context, all
// methods that access the "internal" hidden value must be put in this file.
//
// Note: This file could be loaded in the main world of contextIsolation page,
// which runs in browserify environment instead of Node environment, all native
// modules must be passed from outside, all included files must be plain JS.
Object.defineProperty(exports, "__esModule", { value: true });
// Return a WebViewElement class that is defined in this context.
const defineWebViewElement = (v8Util, webViewImpl) => {
const { guestViewInternal, WebViewImpl } = webViewImpl;
return class WebViewElement extends HTMLElement {
static get observedAttributes() {
return [
"partition" /* ATTRIBUTE_PARTITION */,
"src" /* ATTRIBUTE_SRC */,
"httpreferrer" /* ATTRIBUTE_HTTPREFERRER */,
"useragent" /* ATTRIBUTE_USERAGENT */,
"nodeintegration" /* ATTRIBUTE_NODEINTEGRATION */,
"nodeintegrationinsubframes" /* ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES */,
"plugins" /* ATTRIBUTE_PLUGINS */,
"disablewebsecurity" /* ATTRIBUTE_DISABLEWEBSECURITY */,
"allowpopups" /* ATTRIBUTE_ALLOWPOPUPS */,
"enableremotemodule" /* ATTRIBUTE_ENABLEREMOTEMODULE */,
"preload" /* ATTRIBUTE_PRELOAD */,
"blinkfeatures" /* ATTRIBUTE_BLINKFEATURES */,
"disableblinkfeatures" /* ATTRIBUTE_DISABLEBLINKFEATURES */,
"webpreferences" /* ATTRIBUTE_WEBPREFERENCES */
];
}
constructor() {
super();
v8Util.setHiddenValue(this, 'internal', new WebViewImpl(this));
}
connectedCallback() {
const internal = v8Util.getHiddenValue(this, 'internal');
if (!internal) {
return;
}
if (!internal.elementAttached) {
guestViewInternal.registerEvents(internal, internal.viewInstanceId);
internal.elementAttached = true;
internal.attributes["src" /* ATTRIBUTE_SRC */].parse();
}
}
attributeChangedCallback(name, oldValue, newValue) {
const internal = v8Util.getHiddenValue(this, 'internal');
if (internal) {
internal.handleWebviewAttributeMutation(name, oldValue, newValue);
}
}
disconnectedCallback() {
const internal = v8Util.getHiddenValue(this, 'internal');
if (!internal) {
return;
}
guestViewInternal.deregisterEvents(internal.viewInstanceId);
internal.elementAttached = false;
this.internalInstanceId = 0;
internal.reset();
}
};
};
// Register <webview> custom element.
const registerWebViewElement = (v8Util, webViewImpl) => {
// I wish eslint wasn't so stupid, but it is
// eslint-disable-next-line
const WebViewElement = defineWebViewElement(v8Util, webViewImpl);
webViewImpl.setupMethods(WebViewElement);
// The customElements.define has to be called in a special scope.
const webFrame = webViewImpl.webFrame;
webFrame.allowGuestViewElementDefinition(window, () => {
window.customElements.define('webview', WebViewElement);
window.WebView = WebViewElement;
// Delete the callbacks so developers cannot call them and produce unexpected
// behavior.
delete WebViewElement.prototype.connectedCallback;
delete WebViewElement.prototype.disconnectedCallback;
delete WebViewElement.prototype.attributeChangedCallback;
// Now that |observedAttributes| has been retrieved, we can hide it from
// user code as well.
// TypeScript is concerned that we're deleting a read-only attribute
delete WebViewElement.observedAttributes;
});
};
// Prepare to register the <webview> element.
exports.setupWebView = (v8Util, webViewImpl) => {
const useCapture = true;
const listener = (event) => {
if (document.readyState === 'loading') {
return;
}
webViewImpl.setupAttributes();
registerWebViewElement(v8Util, webViewImpl);
window.removeEventListener(event.type, listener, useCapture);
};
window.addEventListener('readystatechange', listener, useCapture);
};