2019-01-12 01:00:43 +00:00
|
|
|
// 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.
|
|
|
|
|
2020-03-20 20:28:31 +00:00
|
|
|
import { WEB_VIEW_CONSTANTS } from '@electron/internal/renderer/web-view/web-view-constants';
|
2021-05-15 07:42:07 +00:00
|
|
|
import { WebViewImpl, WebViewImplHooks, setupMethods } from '@electron/internal/renderer/web-view/web-view-impl';
|
2020-11-03 23:02:23 +00:00
|
|
|
import type { SrcAttribute } from '@electron/internal/renderer/web-view/web-view-attributes';
|
2019-01-12 01:00:43 +00:00
|
|
|
|
2021-05-15 07:42:07 +00:00
|
|
|
const internals = new WeakMap<HTMLElement, WebViewImpl>();
|
2021-05-06 01:05:01 +00:00
|
|
|
|
2019-01-12 01:00:43 +00:00
|
|
|
// Return a WebViewElement class that is defined in this context.
|
2021-05-15 07:42:07 +00:00
|
|
|
const defineWebViewElement = (hooks: WebViewImplHooks) => {
|
2019-01-12 01:00:43 +00:00
|
|
|
return class WebViewElement extends HTMLElement {
|
|
|
|
static get observedAttributes () {
|
|
|
|
return [
|
2019-03-07 23:26:23 +00:00
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_PARTITION,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_HTTPREFERRER,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_USERAGENT,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATION,
|
2019-03-15 17:39:20 +00:00
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_NODEINTEGRATIONINSUBFRAMES,
|
2019-03-07 23:26:23 +00:00
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_PLUGINS,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEWEBSECURITY,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_ALLOWPOPUPS,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_PRELOAD,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_BLINKFEATURES,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_DISABLEBLINKFEATURES,
|
|
|
|
WEB_VIEW_CONSTANTS.ATTRIBUTE_WEBPREFERENCES
|
2020-03-20 20:28:31 +00:00
|
|
|
];
|
2019-01-12 01:00:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
constructor () {
|
2020-03-20 20:28:31 +00:00
|
|
|
super();
|
2021-05-15 07:42:07 +00:00
|
|
|
internals.set(this, new WebViewImpl(this, hooks));
|
2021-05-08 00:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getWebContentsId () {
|
|
|
|
const internal = internals.get(this);
|
|
|
|
if (!internal || !internal.guestInstanceId) {
|
|
|
|
throw new Error(WEB_VIEW_CONSTANTS.ERROR_MSG_NOT_ATTACHED);
|
|
|
|
}
|
|
|
|
return internal.guestInstanceId;
|
2019-01-12 01:00:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
connectedCallback () {
|
2021-05-08 00:56:22 +00:00
|
|
|
const internal = internals.get(this);
|
2019-01-12 01:00:43 +00:00
|
|
|
if (!internal) {
|
2020-03-20 20:28:31 +00:00
|
|
|
return;
|
2019-01-12 01:00:43 +00:00
|
|
|
}
|
|
|
|
if (!internal.elementAttached) {
|
2021-05-15 07:42:07 +00:00
|
|
|
hooks.guestViewInternal.registerEvents(internal.viewInstanceId, {
|
2022-07-21 09:29:31 +00:00
|
|
|
dispatchEvent: internal.dispatchEvent.bind(internal)
|
2021-05-15 07:42:07 +00:00
|
|
|
});
|
2020-03-20 20:28:31 +00:00
|
|
|
internal.elementAttached = true;
|
2020-11-03 23:02:23 +00:00
|
|
|
(internal.attributes.get(WEB_VIEW_CONSTANTS.ATTRIBUTE_SRC) as SrcAttribute).parse();
|
2019-01-12 01:00:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-07 23:26:23 +00:00
|
|
|
attributeChangedCallback (name: string, oldValue: any, newValue: any) {
|
2021-05-08 00:56:22 +00:00
|
|
|
const internal = internals.get(this);
|
2019-01-12 01:00:43 +00:00
|
|
|
if (internal) {
|
2020-03-20 20:28:31 +00:00
|
|
|
internal.handleWebviewAttributeMutation(name, oldValue, newValue);
|
2019-01-12 01:00:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
disconnectedCallback () {
|
2021-05-08 00:56:22 +00:00
|
|
|
const internal = internals.get(this);
|
2019-01-12 01:00:43 +00:00
|
|
|
if (!internal) {
|
2020-03-20 20:28:31 +00:00
|
|
|
return;
|
2019-01-12 01:00:43 +00:00
|
|
|
}
|
2021-05-15 07:42:07 +00:00
|
|
|
hooks.guestViewInternal.deregisterEvents(internal.viewInstanceId);
|
2020-05-01 04:33:14 +00:00
|
|
|
if (internal.guestInstanceId) {
|
2021-05-15 07:42:07 +00:00
|
|
|
hooks.guestViewInternal.detachGuest(internal.guestInstanceId);
|
2020-05-01 04:33:14 +00:00
|
|
|
}
|
2020-03-20 20:28:31 +00:00
|
|
|
internal.elementAttached = false;
|
|
|
|
internal.reset();
|
2019-01-12 01:00:43 +00:00
|
|
|
}
|
2020-03-20 20:28:31 +00:00
|
|
|
};
|
|
|
|
};
|
2019-01-12 01:00:43 +00:00
|
|
|
|
|
|
|
// Register <webview> custom element.
|
2021-05-15 07:42:07 +00:00
|
|
|
const registerWebViewElement = (hooks: WebViewImplHooks) => {
|
2019-03-07 23:26:23 +00:00
|
|
|
// I wish eslint wasn't so stupid, but it is
|
|
|
|
// eslint-disable-next-line
|
2021-05-15 07:42:07 +00:00
|
|
|
const WebViewElement = defineWebViewElement(hooks) as unknown as typeof ElectronInternal.WebViewElement
|
2019-01-12 01:00:43 +00:00
|
|
|
|
2021-05-15 07:42:07 +00:00
|
|
|
setupMethods(WebViewElement, hooks);
|
2019-01-12 01:00:43 +00:00
|
|
|
|
|
|
|
// The customElements.define has to be called in a special scope.
|
2021-05-15 07:42:07 +00:00
|
|
|
hooks.allowGuestViewElementDefinition(window, () => {
|
2019-03-07 23:26:23 +00:00
|
|
|
window.customElements.define('webview', WebViewElement);
|
2021-01-29 20:41:59 +00:00
|
|
|
window.WebView = WebViewElement;
|
2019-01-12 01:00:43 +00:00
|
|
|
|
|
|
|
// Delete the callbacks so developers cannot call them and produce unexpected
|
|
|
|
// behavior.
|
2020-03-20 20:28:31 +00:00
|
|
|
delete WebViewElement.prototype.connectedCallback;
|
|
|
|
delete WebViewElement.prototype.disconnectedCallback;
|
|
|
|
delete WebViewElement.prototype.attributeChangedCallback;
|
2019-01-12 01:00:43 +00:00
|
|
|
|
|
|
|
// Now that |observedAttributes| has been retrieved, we can hide it from
|
|
|
|
// user code as well.
|
2019-03-07 23:26:23 +00:00
|
|
|
// TypeScript is concerned that we're deleting a read-only attribute
|
2020-03-20 20:28:31 +00:00
|
|
|
delete (WebViewElement as any).observedAttributes;
|
|
|
|
});
|
|
|
|
};
|
2019-01-12 01:00:43 +00:00
|
|
|
|
|
|
|
// Prepare to register the <webview> element.
|
2021-05-15 07:42:07 +00:00
|
|
|
export const setupWebView = (hooks: WebViewImplHooks) => {
|
2020-03-20 20:28:31 +00:00
|
|
|
const useCapture = true;
|
2019-03-07 23:26:23 +00:00
|
|
|
const listener = (event: Event) => {
|
2019-01-12 01:00:43 +00:00
|
|
|
if (document.readyState === 'loading') {
|
2020-03-20 20:28:31 +00:00
|
|
|
return;
|
2019-01-12 01:00:43 +00:00
|
|
|
}
|
2019-03-07 23:26:23 +00:00
|
|
|
|
2021-05-15 07:42:07 +00:00
|
|
|
registerWebViewElement(hooks);
|
2019-03-07 23:26:23 +00:00
|
|
|
|
2020-03-20 20:28:31 +00:00
|
|
|
window.removeEventListener(event.type, listener, useCapture);
|
|
|
|
};
|
2019-01-12 01:00:43 +00:00
|
|
|
|
2020-03-20 20:28:31 +00:00
|
|
|
window.addEventListener('readystatechange', listener, useCapture);
|
|
|
|
};
|