forked from distok/asarfuckery
247 lines
No EOL
10 KiB
JavaScript
247 lines
No EOL
10 KiB
JavaScript
"use strict";
|
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const ipc_renderer_internal_1 = require("@electron/internal/renderer/ipc-renderer-internal");
|
|
// This file implements the following APIs:
|
|
// - window.history.back()
|
|
// - window.history.forward()
|
|
// - window.history.go()
|
|
// - window.history.length
|
|
// - window.open()
|
|
// - window.opener.blur()
|
|
// - window.opener.close()
|
|
// - window.opener.eval()
|
|
// - window.opener.focus()
|
|
// - window.opener.location
|
|
// - window.opener.print()
|
|
// - window.opener.postMessage()
|
|
// - window.prompt()
|
|
// - document.hidden
|
|
// - document.visibilityState
|
|
const { defineProperty } = Object;
|
|
// Helper function to resolve relative url.
|
|
const a = window.document.createElement('a');
|
|
const resolveURL = function (url) {
|
|
a.href = url;
|
|
return a.href;
|
|
};
|
|
// Use this method to ensure values expected as strings in the main process
|
|
// are convertible to strings in the renderer process. This ensures exceptions
|
|
// converting values to strings are thrown in this process.
|
|
const toString = (value) => {
|
|
return value != null ? `${value}` : value;
|
|
};
|
|
const windowProxies = {};
|
|
const getOrCreateProxy = (guestId) => {
|
|
let proxy = windowProxies[guestId];
|
|
if (proxy == null) {
|
|
proxy = new BrowserWindowProxy(guestId);
|
|
windowProxies[guestId] = proxy;
|
|
}
|
|
return proxy;
|
|
};
|
|
const removeProxy = (guestId) => {
|
|
delete windowProxies[guestId];
|
|
};
|
|
class LocationProxy {
|
|
constructor(guestId) {
|
|
// eslint will consider the constructor "useless"
|
|
// unless we assign them in the body. It's fine, that's what
|
|
// TS would do anyway.
|
|
this.guestId = guestId;
|
|
this.getGuestURL = this.getGuestURL.bind(this);
|
|
}
|
|
/**
|
|
* Beware: This decorator will have the _prototype_ as the `target`. It defines properties
|
|
* commonly found in URL on the LocationProxy.
|
|
*/
|
|
static ProxyProperty(target, propertyKey) {
|
|
Object.defineProperty(target, propertyKey, {
|
|
get: function () {
|
|
const guestURL = this.getGuestURL();
|
|
const value = guestURL ? guestURL[propertyKey] : '';
|
|
return value === undefined ? '' : value;
|
|
},
|
|
set: function (newVal) {
|
|
const guestURL = this.getGuestURL();
|
|
if (guestURL) {
|
|
// TypeScript doesn't want us to assign to read-only variables.
|
|
// It's right, that's bad, but we're doing it anway.
|
|
guestURL[propertyKey] = newVal;
|
|
return this.ipcRenderer.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'loadURL', guestURL.toString());
|
|
}
|
|
}
|
|
});
|
|
}
|
|
toString() {
|
|
return this.href;
|
|
}
|
|
getGuestURL() {
|
|
const urlString = ipc_renderer_internal_1.ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'getURL');
|
|
try {
|
|
return new URL(urlString);
|
|
}
|
|
catch (e) {
|
|
console.error('LocationProxy: failed to parse string', urlString, e);
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
__decorate([
|
|
LocationProxy.ProxyProperty
|
|
], LocationProxy.prototype, "hash", void 0);
|
|
__decorate([
|
|
LocationProxy.ProxyProperty
|
|
], LocationProxy.prototype, "href", void 0);
|
|
__decorate([
|
|
LocationProxy.ProxyProperty
|
|
], LocationProxy.prototype, "host", void 0);
|
|
__decorate([
|
|
LocationProxy.ProxyProperty
|
|
], LocationProxy.prototype, "hostname", void 0);
|
|
__decorate([
|
|
LocationProxy.ProxyProperty
|
|
], LocationProxy.prototype, "origin", void 0);
|
|
__decorate([
|
|
LocationProxy.ProxyProperty
|
|
], LocationProxy.prototype, "pathname", void 0);
|
|
__decorate([
|
|
LocationProxy.ProxyProperty
|
|
], LocationProxy.prototype, "port", void 0);
|
|
__decorate([
|
|
LocationProxy.ProxyProperty
|
|
], LocationProxy.prototype, "protocol", void 0);
|
|
__decorate([
|
|
LocationProxy.ProxyProperty
|
|
], LocationProxy.prototype, "search", void 0);
|
|
class BrowserWindowProxy {
|
|
constructor(guestId) {
|
|
this.closed = false;
|
|
this.guestId = guestId;
|
|
this._location = new LocationProxy(guestId);
|
|
ipc_renderer_internal_1.ipcRendererInternal.once(`ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSED_${guestId}`, () => {
|
|
removeProxy(guestId);
|
|
this.closed = true;
|
|
});
|
|
}
|
|
// TypeScript doesn't allow getters/accessors with different types,
|
|
// so for now, we'll have to make do with an "any" in the mix.
|
|
// https://github.com/Microsoft/TypeScript/issues/2521
|
|
get location() {
|
|
return this._location;
|
|
}
|
|
set location(url) {
|
|
url = resolveURL(url);
|
|
ipc_renderer_internal_1.ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD_SYNC', this.guestId, 'loadURL', url);
|
|
}
|
|
close() {
|
|
ipc_renderer_internal_1.ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_CLOSE', this.guestId);
|
|
}
|
|
focus() {
|
|
ipc_renderer_internal_1.ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'focus');
|
|
}
|
|
blur() {
|
|
ipc_renderer_internal_1.ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_METHOD', this.guestId, 'blur');
|
|
}
|
|
print() {
|
|
ipc_renderer_internal_1.ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'print');
|
|
}
|
|
postMessage(message, targetOrigin) {
|
|
ipc_renderer_internal_1.ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_POSTMESSAGE', this.guestId, message, toString(targetOrigin), window.location.origin);
|
|
}
|
|
eval(...args) {
|
|
ipc_renderer_internal_1.ipcRendererInternal.send('ELECTRON_GUEST_WINDOW_MANAGER_WEB_CONTENTS_METHOD', this.guestId, 'executeJavaScript', ...args);
|
|
}
|
|
}
|
|
exports.windowSetup = (guestInstanceId, openerId, isHiddenPage, usesNativeWindowOpen) => {
|
|
if (guestInstanceId == null) {
|
|
// Override default window.close.
|
|
window.close = function () {
|
|
ipc_renderer_internal_1.ipcRendererInternal.sendSync('ELECTRON_BROWSER_WINDOW_CLOSE');
|
|
};
|
|
}
|
|
if (!usesNativeWindowOpen) {
|
|
// Make the browser window or guest view emit "new-window" event.
|
|
window.open = function (url, frameName, features) {
|
|
if (url != null && url !== '') {
|
|
url = resolveURL(url);
|
|
}
|
|
const guestId = ipc_renderer_internal_1.ipcRendererInternal.sendSync('ELECTRON_GUEST_WINDOW_MANAGER_WINDOW_OPEN', url, toString(frameName), toString(features));
|
|
if (guestId != null) {
|
|
return getOrCreateProxy(guestId);
|
|
}
|
|
else {
|
|
return null;
|
|
}
|
|
};
|
|
if (openerId != null) {
|
|
window.opener = getOrCreateProxy(openerId);
|
|
}
|
|
}
|
|
// But we do not support prompt().
|
|
window.prompt = function () {
|
|
throw new Error('prompt() is and will not be supported.');
|
|
};
|
|
ipc_renderer_internal_1.ipcRendererInternal.on('ELECTRON_GUEST_WINDOW_POSTMESSAGE', function (_event, sourceId, message, sourceOrigin) {
|
|
// Manually dispatch event instead of using postMessage because we also need to
|
|
// set event.source.
|
|
//
|
|
// Why any? We can't construct a MessageEvent and we can't
|
|
// use `as MessageEvent` because you're not supposed to override
|
|
// data, origin, and source
|
|
const event = document.createEvent('Event');
|
|
event.initEvent('message', false, false);
|
|
event.data = message;
|
|
event.origin = sourceOrigin;
|
|
event.source = getOrCreateProxy(sourceId);
|
|
window.dispatchEvent(event);
|
|
});
|
|
window.history.back = function () {
|
|
ipc_renderer_internal_1.ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_BACK');
|
|
};
|
|
window.history.forward = function () {
|
|
ipc_renderer_internal_1.ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_FORWARD');
|
|
};
|
|
window.history.go = function (offset) {
|
|
ipc_renderer_internal_1.ipcRendererInternal.send('ELECTRON_NAVIGATION_CONTROLLER_GO_TO_OFFSET', +offset);
|
|
};
|
|
defineProperty(window.history, 'length', {
|
|
get: function () {
|
|
return ipc_renderer_internal_1.ipcRendererInternal.sendSync('ELECTRON_NAVIGATION_CONTROLLER_LENGTH');
|
|
}
|
|
});
|
|
if (guestInstanceId != null) {
|
|
// Webview `document.visibilityState` tracks window visibility (and ignores
|
|
// the actual <webview> element visibility) for backwards compatibility.
|
|
// See discussion in #9178.
|
|
//
|
|
// Note that this results in duplicate visibilitychange events (since
|
|
// Chromium also fires them) and potentially incorrect visibility change.
|
|
// We should reconsider this decision for Electron 2.0.
|
|
let cachedVisibilityState = isHiddenPage ? 'hidden' : 'visible';
|
|
// Subscribe to visibilityState changes.
|
|
ipc_renderer_internal_1.ipcRendererInternal.on('ELECTRON_GUEST_INSTANCE_VISIBILITY_CHANGE', function (_event, visibilityState) {
|
|
if (cachedVisibilityState !== visibilityState) {
|
|
cachedVisibilityState = visibilityState;
|
|
document.dispatchEvent(new Event('visibilitychange'));
|
|
}
|
|
});
|
|
// Make document.hidden and document.visibilityState return the correct value.
|
|
defineProperty(document, 'hidden', {
|
|
get: function () {
|
|
return cachedVisibilityState !== 'visible';
|
|
}
|
|
});
|
|
defineProperty(document, 'visibilityState', {
|
|
get: function () {
|
|
return cachedVisibilityState;
|
|
}
|
|
});
|
|
}
|
|
};
|
|
//# sourceMappingURL=window-setup.js.map
|