chore: update browser patches as of Dec 13, 2022 (#20297)
This commit is contained in:
Родитель
ba0189f8d7
Коммит
6c5317bd31
|
@ -1,3 +1,3 @@
|
|||
REMOTE_URL="https://github.com/mozilla/gecko-dev"
|
||||
BASE_BRANCH="release"
|
||||
BASE_REVISION="fd854580ffc6fba6a0acdf335c96a1b24b976cb9"
|
||||
BASE_REVISION="e2956def6c181ca7375897992c5c821a5a6c886d"
|
||||
|
|
|
@ -6,6 +6,16 @@ const uuidGen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerat
|
|||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
class Helper {
|
||||
decorateAsEventEmitter(objectToDecorate) {
|
||||
const { EventEmitter } = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
|
||||
const emitter = new EventEmitter();
|
||||
objectToDecorate.on = emitter.on.bind(emitter);
|
||||
objectToDecorate.addEventListener = emitter.on.bind(emitter);
|
||||
objectToDecorate.off = emitter.off.bind(emitter);
|
||||
objectToDecorate.removeEventListener = emitter.off.bind(emitter);
|
||||
objectToDecorate.once = emitter.once.bind(emitter);
|
||||
objectToDecorate.emit = emitter.emit.bind(emitter);
|
||||
}
|
||||
|
||||
addObserver(handler, topic) {
|
||||
Services.obs.addObserver(handler, topic);
|
||||
|
@ -19,7 +29,15 @@ class Helper {
|
|||
|
||||
addEventListener(receiver, eventName, handler) {
|
||||
receiver.addEventListener(eventName, handler);
|
||||
return () => receiver.removeEventListener(eventName, handler);
|
||||
return () => {
|
||||
try {
|
||||
receiver.removeEventListener(eventName, handler);
|
||||
} catch (e) {
|
||||
// This could fail when window has navigated cross-process
|
||||
// and we remove the listener from WindowProxy.
|
||||
dump(`WARNING: removeEventListener throws ${e} at ${new Error().stack}\n`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
awaitEvent(receiver, eventName) {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
"use strict";
|
||||
|
||||
const { TargetRegistry } = ChromeUtils.import('chrome://juggler/content/TargetRegistry.js');
|
||||
const { Helper } = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
|
||||
const helper = new Helper();
|
||||
|
||||
var EXPORTED_SYMBOLS = ['JugglerFrameParent'];
|
||||
|
||||
class JugglerFrameParent extends JSWindowActorParent {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
receiveMessage() { }
|
||||
|
||||
async actorCreated() {
|
||||
// Only interested in main frames for now.
|
||||
if (this.browsingContext.parent)
|
||||
return;
|
||||
|
||||
this._target = TargetRegistry.instance()?.targetForBrowserId(this.browsingContext.browserId);
|
||||
if (!this._target)
|
||||
return;
|
||||
|
||||
this.actorName = `browser::page[${this._target.id()}]/${this.browsingContext.browserId}/${this.browsingContext.id}/${this._target.nextActorSequenceNumber()}`;
|
||||
this._target.setActor(this);
|
||||
}
|
||||
|
||||
didDestroy() {
|
||||
if (!this._target)
|
||||
return;
|
||||
this._target.removeActor(this);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
|
||||
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
|
||||
|
@ -41,7 +40,7 @@ class PageNetwork {
|
|||
}
|
||||
|
||||
constructor(target) {
|
||||
EventEmitter.decorate(this);
|
||||
helper.decorateAsEventEmitter(this);
|
||||
this._target = target;
|
||||
this._extraHTTPHeaders = null;
|
||||
this._responseStorage = new ResponseStorage(MAX_RESPONSE_STORAGE_SIZE, MAX_RESPONSE_STORAGE_SIZE / 10);
|
||||
|
@ -217,8 +216,9 @@ class NetworkRequest {
|
|||
_onInternalRedirect(newChannel) {
|
||||
// Intercepted requests produce "internal redirects" - this is both for our own
|
||||
// interception and service workers.
|
||||
// An internal redirect has the same channelId, inherits notificationCallbacks and
|
||||
// listener, and should be used instead of an old channel.
|
||||
// An internal redirect does not necessarily have the same channelId,
|
||||
// but inherits notificationCallbacks and the listener,
|
||||
// and should be used instead of an old channel.
|
||||
this._networkObserver._channelToRequest.delete(this.httpChannel);
|
||||
this.httpChannel = newChannel;
|
||||
this._networkObserver._channelToRequest.set(this.httpChannel, this);
|
||||
|
@ -363,7 +363,7 @@ class NetworkRequest {
|
|||
}
|
||||
|
||||
const browserContext = pageNetwork._target.browserContext();
|
||||
if (browserContext.settings.onlineOverride === 'offline') {
|
||||
if (browserContext.crossProcessCookie.settings.onlineOverride === 'offline') {
|
||||
// Implement offline.
|
||||
this.abort(Cr.NS_ERROR_OFFLINE);
|
||||
return;
|
||||
|
@ -458,7 +458,7 @@ class NetworkRequest {
|
|||
const browserContext = pageNetwork._target.browserContext();
|
||||
if (browserContext.requestInterceptionEnabled)
|
||||
return true;
|
||||
if (browserContext.settings.onlineOverride === 'offline')
|
||||
if (browserContext.crossProcessCookie.settings.onlineOverride === 'offline')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -581,7 +581,7 @@ class NetworkObserver {
|
|||
}
|
||||
|
||||
constructor(targetRegistry) {
|
||||
EventEmitter.decorate(this);
|
||||
helper.decorateAsEventEmitter(this);
|
||||
NetworkObserver._instance = this;
|
||||
|
||||
this._targetRegistry = targetRegistry;
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
const SIMPLE_CHANNEL_MESSAGE_NAME = 'juggler:simplechannel';
|
||||
|
||||
class SimpleChannel {
|
||||
static createForActor(actor) {
|
||||
const channel = new SimpleChannel('');
|
||||
channel.bindToActor(actor);
|
||||
return channel;
|
||||
}
|
||||
|
||||
static createForMessageManager(name, mm) {
|
||||
const channel = new SimpleChannel(name);
|
||||
|
||||
|
@ -32,15 +38,34 @@ class SimpleChannel {
|
|||
this._pendingMessages = new Map();
|
||||
this._handlers = new Map();
|
||||
this._bufferedIncomingMessages = [];
|
||||
this._bufferedOutgoingMessages = [];
|
||||
this.transport = {
|
||||
sendMessage: null,
|
||||
dispose: null,
|
||||
dispose: () => {},
|
||||
};
|
||||
this._ready = false;
|
||||
this._disposed = false;
|
||||
}
|
||||
|
||||
bindToActor(actor) {
|
||||
this.resetTransport();
|
||||
this._name = actor.actorName;
|
||||
const oldReceiveMessage = actor.receiveMessage;
|
||||
actor.receiveMessage = message => this._onMessage(message.data);
|
||||
this.setTransport({
|
||||
sendMessage: obj => actor.sendAsyncMessage(SIMPLE_CHANNEL_MESSAGE_NAME, obj),
|
||||
dispose: () => actor.receiveMessage = oldReceiveMessage,
|
||||
});
|
||||
}
|
||||
|
||||
resetTransport() {
|
||||
this.transport.dispose();
|
||||
this.transport = {
|
||||
sendMessage: null,
|
||||
dispose: () => {},
|
||||
};
|
||||
this._ready = false;
|
||||
}
|
||||
|
||||
setTransport(transport) {
|
||||
this.transport = transport;
|
||||
// connection handshake:
|
||||
|
@ -59,9 +84,8 @@ class SimpleChannel {
|
|||
if (this._ready)
|
||||
return;
|
||||
this._ready = true;
|
||||
for (const msg of this._bufferedOutgoingMessages)
|
||||
this.transport.sendMessage(msg);
|
||||
this._bufferedOutgoingMessages = [];
|
||||
for (const { message } of this._pendingMessages.values())
|
||||
this.transport.sendMessage(message);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
@ -121,14 +145,12 @@ class SimpleChannel {
|
|||
if (this._disposed)
|
||||
throw new Error(`ERROR: channel ${this._name} is already disposed! Cannot send "${methodName}" to "${namespace}"`);
|
||||
const id = ++this._messageId;
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
this._pendingMessages.set(id, {connectorId, resolve, reject, methodName, namespace});
|
||||
});
|
||||
const message = {requestId: id, methodName, params, namespace};
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
this._pendingMessages.set(id, {connectorId, resolve, reject, methodName, namespace, message});
|
||||
});
|
||||
if (this._ready)
|
||||
this.transport.sendMessage(message);
|
||||
else
|
||||
this._bufferedOutgoingMessages.push(message);
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
@ -143,12 +165,19 @@ class SimpleChannel {
|
|||
return;
|
||||
}
|
||||
if (data.responseId) {
|
||||
const {resolve, reject} = this._pendingMessages.get(data.responseId);
|
||||
const message = this._pendingMessages.get(data.responseId);
|
||||
if (!message) {
|
||||
// During corss-process navigation, we might receive a response for
|
||||
// the message sent by another process.
|
||||
// TODO: consider events that are marked as "no-response" to avoid
|
||||
// unneeded responses altogether.
|
||||
return;
|
||||
}
|
||||
this._pendingMessages.delete(data.responseId);
|
||||
if (data.error)
|
||||
reject(new Error(data.error));
|
||||
message.reject(new Error(data.error));
|
||||
else
|
||||
resolve(data.result);
|
||||
message.resolve(data.result);
|
||||
} else if (data.requestId) {
|
||||
const namespace = data.namespace;
|
||||
const handler = this._handlers.get(namespace);
|
||||
|
@ -169,9 +198,7 @@ class SimpleChannel {
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
dump(`
|
||||
ERROR: unknown message in channel "${this._name}": ${JSON.stringify(data)}
|
||||
`);
|
||||
dump(`WARNING: unknown message in channel "${this._name}": ${JSON.stringify(data)}\n`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
|
||||
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
|
||||
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
@ -38,7 +37,7 @@ class DownloadInterceptor {
|
|||
if (!(request instanceof Ci.nsIChannel))
|
||||
return false;
|
||||
const channel = request.QueryInterface(Ci.nsIChannel);
|
||||
let pageTarget = this._registry._browserBrowsingContextToTarget.get(channel.loadInfo.browsingContext.top);
|
||||
let pageTarget = this._registry._browserIdToTarget.get(channel.loadInfo.browsingContext.top.browserId);
|
||||
if (!pageTarget)
|
||||
return false;
|
||||
|
||||
|
@ -57,7 +56,7 @@ class DownloadInterceptor {
|
|||
try {
|
||||
file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600);
|
||||
} catch (e) {
|
||||
dump(`interceptDownloadRequest failed to create file: ${e}\n`);
|
||||
dump(`WARNING: interceptDownloadRequest failed to create file: ${e}\n`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +67,7 @@ class DownloadInterceptor {
|
|||
uuid,
|
||||
browserContextId: browserContext.browserContextId,
|
||||
pageTargetId: pageTarget.id(),
|
||||
frameId: helper.browsingContextToFrameId(channel.loadInfo.browsingContext),
|
||||
url: request.name,
|
||||
suggestedFileName: externalAppHandler.suggestedFileName,
|
||||
};
|
||||
|
@ -103,13 +103,18 @@ class DownloadInterceptor {
|
|||
const screencastService = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
|
||||
|
||||
class TargetRegistry {
|
||||
static instance() {
|
||||
return TargetRegistry._instance || null;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
EventEmitter.decorate(this);
|
||||
helper.decorateAsEventEmitter(this);
|
||||
TargetRegistry._instance = this;
|
||||
|
||||
this._browserContextIdToBrowserContext = new Map();
|
||||
this._userContextIdToBrowserContext = new Map();
|
||||
this._browserToTarget = new Map();
|
||||
this._browserBrowsingContextToTarget = new Map();
|
||||
this._browserIdToTarget = new Map();
|
||||
|
||||
this._browserProxy = null;
|
||||
|
||||
|
@ -136,20 +141,14 @@ class TargetRegistry {
|
|||
}
|
||||
}, 'oop-frameloader-crashed');
|
||||
|
||||
Services.mm.addMessageListener('juggler:content-ready', {
|
||||
receiveMessage: message => {
|
||||
const linkedBrowser = message.target;
|
||||
const target = this._browserToTarget.get(linkedBrowser);
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
return {
|
||||
initScripts: target.browserContext().initScripts,
|
||||
bindings: target.browserContext().bindings,
|
||||
settings: target.browserContext().settings,
|
||||
};
|
||||
},
|
||||
});
|
||||
helper.addObserver((browsingContext, topic, why) => {
|
||||
if (why === 'replace') {
|
||||
// Top-level browsingContext is replaced on cross-process navigations.
|
||||
const target = this._browserIdToTarget.get(browsingContext.browserId);
|
||||
if (target)
|
||||
target.replaceTopBrowsingContext(browsingContext);
|
||||
}
|
||||
}, 'browsing-context-attached');
|
||||
|
||||
const onTabOpenListener = (appWindow, window, event) => {
|
||||
const tab = event.target;
|
||||
|
@ -161,7 +160,7 @@ class TargetRegistry {
|
|||
if (openerContext) {
|
||||
// Popups usually have opener context. Get top context for the case when opener is
|
||||
// an iframe.
|
||||
openerTarget = this._browserBrowsingContextToTarget.get(openerContext.top);
|
||||
openerTarget = this._browserIdToTarget.get(openerContext.top.browserId);
|
||||
} else if (tab.openerTab) {
|
||||
// Noopener popups from the same window have opener tab instead.
|
||||
openerTarget = this._browserToTarget.get(tab.openerTab.linkedBrowser);
|
||||
|
@ -169,13 +168,7 @@ class TargetRegistry {
|
|||
if (!browserContext)
|
||||
throw new Error(`Internal error: cannot find context for userContextId=${userContextId}`);
|
||||
const target = new PageTarget(this, window, tab, browserContext, openerTarget);
|
||||
target.updateUserAgent();
|
||||
target.updatePlatform();
|
||||
target.updateJavaScriptDisabled();
|
||||
target.updateTouchOverride();
|
||||
target.updateColorSchemeOverride();
|
||||
target.updateReducedMotionOverride();
|
||||
target.updateForcedColorsOverride();
|
||||
target.updateOverridesForBrowsingContext(tab.linkedBrowser.browsingContext);
|
||||
if (!hasExplicitSize)
|
||||
target.updateViewportSize();
|
||||
if (browserContext.videoRecordingOptions)
|
||||
|
@ -329,7 +322,7 @@ class TargetRegistry {
|
|||
target = this._browserToTarget.get(browser);
|
||||
}
|
||||
browser.focus();
|
||||
if (browserContext.settings.timezoneId) {
|
||||
if (browserContext.crossProcessCookie.settings.timezoneId) {
|
||||
if (await target.hasFailedToOverrideTimezone())
|
||||
throw new Error('Failed to override timezone');
|
||||
}
|
||||
|
@ -343,11 +336,15 @@ class TargetRegistry {
|
|||
targetForBrowser(browser) {
|
||||
return this._browserToTarget.get(browser);
|
||||
}
|
||||
|
||||
targetForBrowserId(browserId) {
|
||||
return this._browserIdToTarget.get(browserId);
|
||||
}
|
||||
}
|
||||
|
||||
class PageTarget {
|
||||
constructor(registry, win, tab, browserContext, opener) {
|
||||
EventEmitter.decorate(this);
|
||||
helper.decorateAsEventEmitter(this);
|
||||
|
||||
this._targetId = helper.generateId();
|
||||
this._registry = registry;
|
||||
|
@ -360,12 +357,19 @@ class PageTarget {
|
|||
this._initialDPPX = this._linkedBrowser.browsingContext.overrideDPPX;
|
||||
this._url = 'about:blank';
|
||||
this._openerId = opener ? opener.id() : undefined;
|
||||
this._channel = SimpleChannel.createForMessageManager(`browser::page[${this._targetId}]`, this._linkedBrowser.messageManager);
|
||||
this._actor = undefined;
|
||||
this._actorSequenceNumber = 0;
|
||||
this._channel = new SimpleChannel(`browser::page[${this._targetId}]`);
|
||||
this._videoRecordingInfo = undefined;
|
||||
this._screencastRecordingInfo = undefined;
|
||||
this._dialogs = new Map();
|
||||
this.forcedColors = 'no-override';
|
||||
this._pageInitScripts = [];
|
||||
this.mediumOverride = '';
|
||||
this.crossProcessCookie = {
|
||||
initScripts: [],
|
||||
bindings: [],
|
||||
interceptFileChooserDialog: false,
|
||||
};
|
||||
|
||||
const navigationListener = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
|
||||
|
@ -380,11 +384,38 @@ class PageTarget {
|
|||
this._disposed = false;
|
||||
browserContext.pages.add(this);
|
||||
this._registry._browserToTarget.set(this._linkedBrowser, this);
|
||||
this._registry._browserBrowsingContextToTarget.set(this._linkedBrowser.browsingContext, this);
|
||||
this._registry._browserIdToTarget.set(this._linkedBrowser.browsingContext.browserId, this);
|
||||
|
||||
this._registry.emit(TargetRegistry.Events.TargetCreated, this);
|
||||
}
|
||||
|
||||
nextActorSequenceNumber() {
|
||||
return ++this._actorSequenceNumber;
|
||||
}
|
||||
|
||||
setActor(actor) {
|
||||
this._actor = actor;
|
||||
this._channel.bindToActor(actor);
|
||||
}
|
||||
|
||||
removeActor(actor) {
|
||||
// Note: the order between setActor and removeActor is non-deterministic.
|
||||
// Therefore we check that we are still bound to the actor that is being removed.
|
||||
if (this._actor !== actor)
|
||||
return;
|
||||
this._actor = undefined;
|
||||
this._channel.resetTransport();
|
||||
}
|
||||
|
||||
replaceTopBrowsingContext(browsingContext) {
|
||||
if (this._actor && this._actor.browsingContext !== browsingContext) {
|
||||
// Disconnect early to avoid receiving protocol messages from the old actor.
|
||||
this.removeActor(this._actor);
|
||||
}
|
||||
this.emit(PageTarget.Events.TopBrowsingContextReplaced);
|
||||
this.updateOverridesForBrowsingContext(browsingContext);
|
||||
}
|
||||
|
||||
dialog(dialogId) {
|
||||
return this._dialogs.get(dialogId);
|
||||
}
|
||||
|
@ -405,20 +436,31 @@ class PageTarget {
|
|||
return this._browserContext;
|
||||
}
|
||||
|
||||
updateTouchOverride() {
|
||||
this._linkedBrowser.browsingContext.touchEventsOverride = this._browserContext.touchOverride ? 'enabled' : 'none';
|
||||
updateOverridesForBrowsingContext(browsingContext = undefined) {
|
||||
this.updateTouchOverride(browsingContext);
|
||||
this.updateUserAgent(browsingContext);
|
||||
this.updatePlatform(browsingContext);
|
||||
this.updateDPPXOverride(browsingContext);
|
||||
this.updateEmulatedMedia(browsingContext);
|
||||
this.updateColorSchemeOverride(browsingContext);
|
||||
this.updateReducedMotionOverride(browsingContext);
|
||||
this.updateForcedColorsOverride(browsingContext);
|
||||
}
|
||||
|
||||
updateUserAgent() {
|
||||
this._linkedBrowser.browsingContext.customUserAgent = this._browserContext.defaultUserAgent;
|
||||
updateTouchOverride(browsingContext = undefined) {
|
||||
(browsingContext || this._linkedBrowser.browsingContext).touchEventsOverride = this._browserContext.touchOverride ? 'enabled' : 'none';
|
||||
}
|
||||
|
||||
updatePlatform() {
|
||||
this._linkedBrowser.browsingContext.customPlatform = this._browserContext.defaultPlatform;
|
||||
updateUserAgent(browsingContext = undefined) {
|
||||
(browsingContext || this._linkedBrowser.browsingContext).customUserAgent = this._browserContext.defaultUserAgent;
|
||||
}
|
||||
|
||||
updateJavaScriptDisabled() {
|
||||
this._linkedBrowser.browsingContext.allowJavascript = !this._browserContext.javaScriptDisabled;
|
||||
updatePlatform(browsingContext = undefined) {
|
||||
(browsingContext || this._linkedBrowser.browsingContext).customPlatform = this._browserContext.defaultPlatform;
|
||||
}
|
||||
|
||||
updateDPPXOverride(browsingContext = undefined) {
|
||||
(browsingContext || this._linkedBrowser.browsingContext).overrideDPPX = this._browserContext.deviceScaleFactor || this._initialDPPX;
|
||||
}
|
||||
|
||||
_updateModalDialogs() {
|
||||
|
@ -452,7 +494,7 @@ class PageTarget {
|
|||
// default viewport.
|
||||
const viewportSize = this._viewportSize || this._browserContext.defaultViewportSize;
|
||||
const actualSize = await setViewportSizeForBrowser(viewportSize, this._linkedBrowser, this._window);
|
||||
this._linkedBrowser.browsingContext.overrideDPPX = this._browserContext.deviceScaleFactor || this._initialDPPX;
|
||||
this.updateDPPXOverride();
|
||||
await this._channel.connect('').send('awaitViewportDimensions', {
|
||||
width: actualSize.width,
|
||||
height: actualSize.height,
|
||||
|
@ -461,7 +503,12 @@ class PageTarget {
|
|||
}
|
||||
|
||||
setEmulatedMedia(mediumOverride) {
|
||||
this._linkedBrowser.browsingContext.mediumOverride = mediumOverride || '';
|
||||
this.mediumOverride = mediumOverride || '';
|
||||
this.updateEmulatedMedia();
|
||||
}
|
||||
|
||||
updateEmulatedMedia(browsingContext = undefined) {
|
||||
(browsingContext || this._linkedBrowser.browsingContext).mediumOverride = this.mediumOverride;
|
||||
}
|
||||
|
||||
setColorScheme(colorScheme) {
|
||||
|
@ -469,8 +516,8 @@ class PageTarget {
|
|||
this.updateColorSchemeOverride();
|
||||
}
|
||||
|
||||
updateColorSchemeOverride() {
|
||||
this._linkedBrowser.browsingContext.prefersColorSchemeOverride = this.colorScheme || this._browserContext.colorScheme || 'none';
|
||||
updateColorSchemeOverride(browsingContext = undefined) {
|
||||
(browsingContext || this._linkedBrowser.browsingContext).prefersColorSchemeOverride = this.colorScheme || this._browserContext.colorScheme || 'none';
|
||||
}
|
||||
|
||||
setReducedMotion(reducedMotion) {
|
||||
|
@ -478,8 +525,8 @@ class PageTarget {
|
|||
this.updateReducedMotionOverride();
|
||||
}
|
||||
|
||||
updateReducedMotionOverride() {
|
||||
this._linkedBrowser.browsingContext.prefersReducedMotionOverride = this.reducedMotion || this._browserContext.reducedMotion || 'none';
|
||||
updateReducedMotionOverride(browsingContext = undefined) {
|
||||
(browsingContext || this._linkedBrowser.browsingContext).prefersReducedMotionOverride = this.reducedMotion || this._browserContext.reducedMotion || 'none';
|
||||
}
|
||||
|
||||
setForcedColors(forcedColors) {
|
||||
|
@ -487,8 +534,14 @@ class PageTarget {
|
|||
this.updateForcedColorsOverride();
|
||||
}
|
||||
|
||||
updateForcedColorsOverride() {
|
||||
this._linkedBrowser.browsingContext.forcedColorsOverride = (this.forcedColors !== 'no-override' ? this.forcedColors : this._browserContext.forcedColors) || 'no-override';
|
||||
updateForcedColorsOverride(browsingContext = undefined) {
|
||||
(browsingContext || this._linkedBrowser.browsingContext).forcedColorsOverride = (this.forcedColors !== 'no-override' ? this.forcedColors : this._browserContext.forcedColors) || 'no-override';
|
||||
}
|
||||
|
||||
async setInterceptFileChooserDialog(enabled) {
|
||||
this.crossProcessCookie.interceptFileChooserDialog = enabled;
|
||||
this._updateCrossProcessCookie();
|
||||
await this._channel.connect('').send('setInterceptFileChooserDialog', enabled).catch(e => {});
|
||||
}
|
||||
|
||||
async setViewportSize(viewportSize) {
|
||||
|
@ -524,20 +577,28 @@ class PageTarget {
|
|||
this._browserContext.grantPermissionsToOrigin(this._url);
|
||||
}
|
||||
|
||||
_updateCrossProcessCookie() {
|
||||
Services.ppmm.sharedData.set('juggler:page-cookie-' + this._linkedBrowser.browsingContext.browserId, this.crossProcessCookie);
|
||||
Services.ppmm.sharedData.flush();
|
||||
}
|
||||
|
||||
async ensurePermissions() {
|
||||
await this._channel.connect('').send('ensurePermissions', {}).catch(e => void e);
|
||||
}
|
||||
|
||||
async setInitScripts(scripts) {
|
||||
this._pageInitScripts = scripts;
|
||||
this.crossProcessCookie.initScripts = scripts;
|
||||
this._updateCrossProcessCookie();
|
||||
await this.pushInitScripts();
|
||||
}
|
||||
|
||||
async pushInitScripts() {
|
||||
await this._channel.connect('').send('setInitScripts', [...this._browserContext.initScripts, ...this._pageInitScripts]).catch(e => void e);
|
||||
await this._channel.connect('').send('setInitScripts', [...this._browserContext.crossProcessCookie.initScripts, ...this.crossProcessCookie.initScripts]).catch(e => void e);
|
||||
}
|
||||
|
||||
async addBinding(worldName, name, script) {
|
||||
this.crossProcessCookie.bindings.push({ worldName, name, script });
|
||||
this._updateCrossProcessCookie();
|
||||
await this._channel.connect('').send('addBinding', { worldName, name, script }).catch(e => void e);
|
||||
}
|
||||
|
||||
|
@ -641,7 +702,7 @@ class PageTarget {
|
|||
this.stopScreencast();
|
||||
this._browserContext.pages.delete(this);
|
||||
this._registry._browserToTarget.delete(this._linkedBrowser);
|
||||
this._registry._browserBrowsingContextToTarget.delete(this._linkedBrowser.browsingContext);
|
||||
this._registry._browserIdToTarget.delete(this._linkedBrowser.browsingContext.browserId);
|
||||
try {
|
||||
helper.removeListeners(this._eventListeners);
|
||||
} catch (e) {
|
||||
|
@ -660,6 +721,7 @@ PageTarget.Events = {
|
|||
Crashed: Symbol('PageTarget.Crashed'),
|
||||
DialogOpened: Symbol('PageTarget.DialogOpened'),
|
||||
DialogClosed: Symbol('PageTarget.DialogClosed'),
|
||||
TopBrowsingContextReplaced: Symbol('PageTarget.TopBrowsingContextReplaced'),
|
||||
};
|
||||
|
||||
function fromProtocolColorScheme(colorScheme) {
|
||||
|
@ -712,18 +774,24 @@ class BrowserContext {
|
|||
this.deviceScaleFactor = undefined;
|
||||
this.defaultUserAgent = null;
|
||||
this.defaultPlatform = null;
|
||||
this.javaScriptDisabled = false;
|
||||
this.touchOverride = false;
|
||||
this.colorScheme = 'none';
|
||||
this.forcedColors = 'no-override';
|
||||
this.reducedMotion = 'none';
|
||||
this.videoRecordingOptions = undefined;
|
||||
this.initScripts = [];
|
||||
this.bindings = [];
|
||||
this.settings = {};
|
||||
this.crossProcessCookie = {
|
||||
initScripts: [],
|
||||
bindings: [],
|
||||
settings: {},
|
||||
};
|
||||
this.pages = new Set();
|
||||
}
|
||||
|
||||
_updateCrossProcessCookie() {
|
||||
Services.ppmm.sharedData.set('juggler:context-cookie-' + this.userContextId, this.crossProcessCookie);
|
||||
Services.ppmm.sharedData.flush();
|
||||
}
|
||||
|
||||
setColorScheme(colorScheme) {
|
||||
this.colorScheme = fromProtocolColorScheme(colorScheme);
|
||||
for (const page of this.pages)
|
||||
|
@ -796,12 +864,6 @@ class BrowserContext {
|
|||
page.updatePlatform();
|
||||
}
|
||||
|
||||
setJavaScriptDisabled(javaScriptDisabled) {
|
||||
this.javaScriptDisabled = javaScriptDisabled;
|
||||
for (const page of this.pages)
|
||||
page.updateJavaScriptDisabled();
|
||||
}
|
||||
|
||||
setTouchOverride(touchOverride) {
|
||||
this.touchOverride = touchOverride;
|
||||
for (const page of this.pages)
|
||||
|
@ -815,17 +877,20 @@ class BrowserContext {
|
|||
}
|
||||
|
||||
async setInitScripts(scripts) {
|
||||
this.initScripts = scripts;
|
||||
this.crossProcessCookie.initScripts = scripts;
|
||||
this._updateCrossProcessCookie();
|
||||
await Promise.all(Array.from(this.pages).map(page => page.pushInitScripts()));
|
||||
}
|
||||
|
||||
async addBinding(worldName, name, script) {
|
||||
this.bindings.push({ worldName, name, script });
|
||||
this.crossProcessCookie.bindings.push({ worldName, name, script });
|
||||
this._updateCrossProcessCookie();
|
||||
await Promise.all(Array.from(this.pages).map(page => page.addBinding(worldName, name, script)));
|
||||
}
|
||||
|
||||
async applySetting(name, value) {
|
||||
this.settings[name] = value;
|
||||
this.crossProcessCookie.settings[name] = value;
|
||||
this._updateCrossProcessCookie();
|
||||
await Promise.all(Array.from(this.pages).map(page => page.applyContextSetting(name, value)));
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,34 @@ const {BrowserHandler} = ChromeUtils.import("chrome://juggler/content/protocol/B
|
|||
const {NetworkObserver} = ChromeUtils.import("chrome://juggler/content/NetworkObserver.js");
|
||||
const {TargetRegistry} = ChromeUtils.import("chrome://juggler/content/TargetRegistry.js");
|
||||
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
const {ActorManagerParent} = ChromeUtils.import('resource://gre/modules/ActorManagerParent.jsm');
|
||||
const helper = new Helper();
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
const FRAME_SCRIPT = "chrome://juggler/content/content/main.js";
|
||||
// Register JSWindowActors that will be instantiated for each frame.
|
||||
ActorManagerParent.addJSWindowActors({
|
||||
JugglerFrame: {
|
||||
parent: {
|
||||
moduleURI: 'chrome://juggler/content/JugglerFrameParent.jsm',
|
||||
},
|
||||
child: {
|
||||
moduleURI: 'chrome://juggler/content/content/JugglerFrameChild.jsm',
|
||||
events: {
|
||||
// Normally, we instantiate an actor when a new window is created.
|
||||
DOMWindowCreated: {},
|
||||
// However, for same-origin iframes, the navigation from about:blank
|
||||
// to the URL will share the same window, so we need to also create
|
||||
// an actor for a new document via DOMDocElementInserted.
|
||||
DOMDocElementInserted: {},
|
||||
// Also, listening to DOMContentLoaded.
|
||||
DOMContentLoaded: {},
|
||||
},
|
||||
},
|
||||
allFrames: true,
|
||||
},
|
||||
});
|
||||
|
||||
let browserStartupFinishedCallback;
|
||||
let browserStartupFinishedPromise = new Promise(x => browserStartupFinishedCallback = x);
|
||||
|
@ -72,8 +94,7 @@ class Juggler {
|
|||
const targetRegistry = new TargetRegistry();
|
||||
new NetworkObserver(targetRegistry);
|
||||
|
||||
const loadFrameScript = () => {
|
||||
Services.mm.loadFrameScript(FRAME_SCRIPT, true /* aAllowDelayedLoad */);
|
||||
const loadStyleSheet = () => {
|
||||
if (Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo).isHeadless) {
|
||||
const styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService);
|
||||
const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
|
||||
|
@ -118,7 +139,7 @@ class Juggler {
|
|||
pipeStopped = true;
|
||||
}, () => browserStartupFinishedPromise);
|
||||
dispatcher.rootSession().setHandler(browserHandler);
|
||||
loadFrameScript();
|
||||
loadStyleSheet();
|
||||
dump(`\nJuggler listening to the pipe\n`);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -9,14 +9,13 @@ const Cu = Components.utils;
|
|||
|
||||
const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
|
||||
const {EventEmitter} = ChromeUtils.import('resource://gre/modules/EventEmitter.jsm');
|
||||
const {Runtime} = ChromeUtils.import('chrome://juggler/content/content/Runtime.js');
|
||||
|
||||
const helper = new Helper();
|
||||
|
||||
class FrameTree {
|
||||
constructor(rootDocShell) {
|
||||
EventEmitter.decorate(this);
|
||||
helper.decorateAsEventEmitter(this);
|
||||
|
||||
this._browsingContextGroup = rootDocShell.browsingContext.group;
|
||||
if (!this._browsingContextGroup.__jugglerFrameTrees)
|
||||
|
@ -33,6 +32,7 @@ class FrameTree {
|
|||
this._docShellToFrame = new Map();
|
||||
this._frameIdToFrame = new Map();
|
||||
this._pageReady = false;
|
||||
this._javaScriptDisabled = false;
|
||||
this._mainFrame = this._createFrame(rootDocShell);
|
||||
const webProgress = rootDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
|
@ -128,6 +128,12 @@ class FrameTree {
|
|||
this.scrollbarsHidden = hidden;
|
||||
}
|
||||
|
||||
setJavaScriptDisabled(javaScriptDisabled) {
|
||||
this._javaScriptDisabled = javaScriptDisabled;
|
||||
for (const frame of this.frames())
|
||||
frame._updateJavaScriptDisabled();
|
||||
}
|
||||
|
||||
_onWorkerCreated(workerDebugger) {
|
||||
// Note: we do not interoperate with firefox devtools.
|
||||
if (workerDebugger.isInitialized)
|
||||
|
@ -214,7 +220,7 @@ class FrameTree {
|
|||
const docShell = progress.DOMWindow.docShell;
|
||||
const frame = this._docShellToFrame.get(docShell);
|
||||
if (!frame) {
|
||||
dump(`ERROR: got a state changed event for un-tracked docshell!\n`);
|
||||
dump(`WARNING: got a state changed event for un-tracked docshell!\n`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -227,7 +233,6 @@ class FrameTree {
|
|||
const isStart = flag & Ci.nsIWebProgressListener.STATE_START;
|
||||
const isTransferring = flag & Ci.nsIWebProgressListener.STATE_TRANSFERRING;
|
||||
const isStop = flag & Ci.nsIWebProgressListener.STATE_STOP;
|
||||
const isDocument = flag & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
|
||||
|
||||
if (isStart) {
|
||||
// Starting a new navigation.
|
||||
|
@ -257,9 +262,6 @@ class FrameTree {
|
|||
if (frame === this._mainFrame && status !== Cr.NS_BINDING_ABORTED)
|
||||
this.forcePageReady();
|
||||
}
|
||||
|
||||
if (isStop && isDocument)
|
||||
this.emit(FrameTree.Events.Load, frame);
|
||||
}
|
||||
|
||||
onLocationChange(progress, request, location, flags) {
|
||||
|
@ -287,6 +289,10 @@ class FrameTree {
|
|||
|
||||
_createFrame(docShell) {
|
||||
const parentFrame = this._docShellToFrame.get(docShell.parent) || null;
|
||||
if (!parentFrame && this._mainFrame) {
|
||||
dump(`WARNING: found docShell with the same root, but no parent!\n`);
|
||||
return;
|
||||
}
|
||||
const frame = new Frame(this, this._runtime, docShell, parentFrame);
|
||||
this._docShellToFrame.set(docShell, frame);
|
||||
this._frameIdToFrame.set(frame.id(), frame);
|
||||
|
@ -308,6 +314,11 @@ class FrameTree {
|
|||
// Detach all children first
|
||||
for (const subframe of frame._children)
|
||||
this._detachFrame(subframe);
|
||||
if (frame === this._mainFrame) {
|
||||
// Do not detach main frame (happens during cross-process navigation),
|
||||
// as it confuses the client.
|
||||
return;
|
||||
}
|
||||
this._docShellToFrame.delete(frame._docShell);
|
||||
this._frameIdToFrame.delete(frame.id());
|
||||
if (frame._parentFrame)
|
||||
|
@ -333,7 +344,6 @@ FrameTree.Events = {
|
|||
NavigationAborted: 'navigationaborted',
|
||||
SameDocumentNavigation: 'samedocumentnavigation',
|
||||
PageReady: 'pageready',
|
||||
Load: 'load',
|
||||
};
|
||||
|
||||
class IsolatedWorld {
|
||||
|
@ -518,6 +528,20 @@ class Frame {
|
|||
for (const script of world._scriptsToEvaluateOnNewDocument)
|
||||
executionContext.evaluateScriptSafely(script);
|
||||
}
|
||||
|
||||
const url = this.domWindow().location?.href;
|
||||
if (url === 'about:blank' && !this._url) {
|
||||
// Sometimes FrameTree is created too early, before the location has been set.
|
||||
this._url = url;
|
||||
this._frameTree.emit(FrameTree.Events.NavigationCommitted, this);
|
||||
}
|
||||
|
||||
this._updateJavaScriptDisabled();
|
||||
}
|
||||
|
||||
_updateJavaScriptDisabled() {
|
||||
if (this._docShell.browsingContext.currentWindowContext)
|
||||
this._docShell.browsingContext.currentWindowContext.allowJavascript = !this._frameTree._javaScriptDisabled;
|
||||
}
|
||||
|
||||
mainExecutionContext() {
|
||||
|
@ -592,7 +616,7 @@ class Worker {
|
|||
onMessage: msg => void this._channel._onMessage(JSON.parse(msg)),
|
||||
onClose: () => void this._channel.dispose(),
|
||||
onError: (filename, lineno, message) => {
|
||||
dump(`Error in worker: ${message} @${filename}:${lineno}\n`);
|
||||
dump(`WARNING: Error in worker: ${message} @${filename}:${lineno}\n`);
|
||||
},
|
||||
};
|
||||
workerDebugger.addListener(this._workerDebuggerListener);
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
"use strict";
|
||||
|
||||
const { Helper } = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
const { initialize } = ChromeUtils.import('chrome://juggler/content/content/main.js');
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const helper = new Helper();
|
||||
|
||||
let sameProcessInstanceNumber = 0;
|
||||
|
||||
class JugglerFrameChild extends JSWindowActorChild {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._eventListeners = [];
|
||||
}
|
||||
|
||||
handleEvent(aEvent) {
|
||||
if (this._agents && aEvent.target === this.document)
|
||||
this._agents.pageAgent.onWindowEvent(aEvent);
|
||||
}
|
||||
|
||||
actorCreated() {
|
||||
this.actorName = `content::${this.browsingContext.browserId}/${this.browsingContext.id}/${++sameProcessInstanceNumber}`;
|
||||
|
||||
this._eventListeners.push(helper.addEventListener(this.contentWindow, 'load', event => {
|
||||
this._agents?.pageAgent.onWindowEvent(event);
|
||||
}));
|
||||
|
||||
if (this.document.documentURI.startsWith('moz-extension://'))
|
||||
return;
|
||||
this._agents = initialize(this.browsingContext, this.docShell, this);
|
||||
}
|
||||
|
||||
_dispose() {
|
||||
helper.removeListeners(this._eventListeners);
|
||||
// We do not cleanup since agents are shared for all frames in the process.
|
||||
|
||||
// TODO: restore the cleanup.
|
||||
// Reset transport so that all messages will be pending and will not throw any errors.
|
||||
// this._channel.resetTransport();
|
||||
// this._agents.pageAgent.dispose();
|
||||
// this._agents.frameTree.dispose();
|
||||
// this._agents = undefined;
|
||||
}
|
||||
|
||||
didDestroy() {
|
||||
this._dispose();
|
||||
}
|
||||
|
||||
receiveMessage() { }
|
||||
}
|
||||
|
||||
var EXPORTED_SYMBOLS = ['JugglerFrameChild'];
|
|
@ -50,8 +50,7 @@ class WorkerData {
|
|||
}
|
||||
|
||||
class PageAgent {
|
||||
constructor(messageManager, browserChannel, frameTree) {
|
||||
this._messageManager = messageManager;
|
||||
constructor(browserChannel, frameTree) {
|
||||
this._browserChannel = browserChannel;
|
||||
this._browserPage = browserChannel.connect('page');
|
||||
this._frameTree = frameTree;
|
||||
|
@ -78,6 +77,7 @@ class PageAgent {
|
|||
this._onWorkerCreated(worker);
|
||||
|
||||
// Report execution contexts.
|
||||
this._browserPage.emit('runtimeExecutionContextsCleared', {});
|
||||
for (const context of this._runtime.executionContexts())
|
||||
this._onExecutionContextCreated(context);
|
||||
|
||||
|
@ -99,9 +99,7 @@ class PageAgent {
|
|||
helper.addObserver(this._linkClicked.bind(this, true), 'juggler-link-click-sync'),
|
||||
helper.addObserver(this._onWindowOpenInNewContext.bind(this), 'juggler-window-open-in-new-context'),
|
||||
helper.addObserver(this._filePickerShown.bind(this), 'juggler-file-picker-shown'),
|
||||
helper.addEventListener(this._messageManager, 'DOMContentLoaded', this._onDOMContentLoaded.bind(this)),
|
||||
helper.addObserver(this._onDocumentOpenLoad.bind(this), 'juggler-document-open-loaded'),
|
||||
helper.on(this._frameTree, 'load', this._onLoad.bind(this)),
|
||||
helper.on(this._frameTree, 'frameattached', this._onFrameAttached.bind(this)),
|
||||
helper.on(this._frameTree, 'framedetached', this._onFrameDetached.bind(this)),
|
||||
helper.on(this._frameTree, 'navigationstarted', this._onNavigationStarted.bind(this)),
|
||||
|
@ -133,7 +131,6 @@ class PageAgent {
|
|||
this._runtime.events.onExecutionContextDestroyed(this._onExecutionContextDestroyed.bind(this)),
|
||||
this._runtime.events.onBindingCalled(this._onBindingCalled.bind(this)),
|
||||
browserChannel.register('page', {
|
||||
addBinding: ({ worldName, name, script }) => this._frameTree.addBinding(worldName, name, script),
|
||||
adoptNode: this._adoptNode.bind(this),
|
||||
crash: this._crash.bind(this),
|
||||
describeNode: this._describeNode.bind(this),
|
||||
|
@ -143,15 +140,11 @@ class PageAgent {
|
|||
dispatchTapEvent: this._dispatchTapEvent.bind(this),
|
||||
getContentQuads: this._getContentQuads.bind(this),
|
||||
getFullAXTree: this._getFullAXTree.bind(this),
|
||||
goBack: this._goBack.bind(this),
|
||||
goForward: this._goForward.bind(this),
|
||||
insertText: this._insertText.bind(this),
|
||||
navigate: this._navigate.bind(this),
|
||||
reload: this._reload.bind(this),
|
||||
scrollIntoViewIfNeeded: this._scrollIntoViewIfNeeded.bind(this),
|
||||
setCacheDisabled: this._setCacheDisabled.bind(this),
|
||||
setFileInputFiles: this._setFileInputFiles.bind(this),
|
||||
setInterceptFileChooserDialog: this._setInterceptFileChooserDialog.bind(this),
|
||||
evaluate: this._runtime.evaluate.bind(this._runtime),
|
||||
callFunction: this._runtime.callFunction.bind(this._runtime),
|
||||
getObjectProperties: this._runtime.getObjectProperties.bind(this._runtime),
|
||||
|
@ -224,10 +217,6 @@ class PageAgent {
|
|||
this._emitAllEvents(this._frameTree.mainFrame());
|
||||
}
|
||||
|
||||
_setInterceptFileChooserDialog({enabled}) {
|
||||
this._docShell.fileInputInterceptionEnabled = !!enabled;
|
||||
}
|
||||
|
||||
_linkClicked(sync, anchorElement) {
|
||||
if (anchorElement.ownerGlobal.docShell !== this._docShell)
|
||||
return;
|
||||
|
@ -259,7 +248,9 @@ class PageAgent {
|
|||
});
|
||||
}
|
||||
|
||||
_onDOMContentLoaded(event) {
|
||||
onWindowEvent(event) {
|
||||
if (event.type !== 'DOMContentLoaded' && event.type !== 'load')
|
||||
return;
|
||||
if (!event.target.ownerGlobal)
|
||||
return;
|
||||
const docShell = event.target.ownerGlobal.docShell;
|
||||
|
@ -268,7 +259,7 @@ class PageAgent {
|
|||
return;
|
||||
this._browserPage.emit('pageEventFired', {
|
||||
frameId: frame.id(),
|
||||
name: 'DOMContentLoaded',
|
||||
name: event.type,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -291,13 +282,6 @@ class PageAgent {
|
|||
});
|
||||
}
|
||||
|
||||
_onLoad(frame) {
|
||||
this._browserPage.emit('pageEventFired', {
|
||||
frameId: frame.id(),
|
||||
name: 'load'
|
||||
});
|
||||
}
|
||||
|
||||
_onNavigationStarted(frame) {
|
||||
this._browserPage.emit('pageNavigationStarted', {
|
||||
frameId: frame.id(),
|
||||
|
@ -395,35 +379,16 @@ class PageAgent {
|
|||
return {navigationId: frame.pendingNavigationId(), navigationURL: frame.pendingNavigationURL()};
|
||||
}
|
||||
|
||||
async _reload({frameId, url}) {
|
||||
const frame = this._frameTree.frame(frameId);
|
||||
const docShell = frame.docShell().QueryInterface(Ci.nsIWebNavigation);
|
||||
docShell.reload(Ci.nsIWebNavigation.LOAD_FLAGS_NONE);
|
||||
}
|
||||
|
||||
async _goBack({frameId, url}) {
|
||||
const frame = this._frameTree.frame(frameId);
|
||||
const docShell = frame.docShell();
|
||||
if (!docShell.canGoBack)
|
||||
return {success: false};
|
||||
docShell.goBack();
|
||||
return {success: true};
|
||||
}
|
||||
|
||||
async _goForward({frameId, url}) {
|
||||
const frame = this._frameTree.frame(frameId);
|
||||
const docShell = frame.docShell();
|
||||
if (!docShell.canGoForward)
|
||||
return {success: false};
|
||||
docShell.goForward();
|
||||
return {success: true};
|
||||
}
|
||||
|
||||
async _adoptNode({frameId, objectId, executionContextId}) {
|
||||
const frame = this._frameTree.frame(frameId);
|
||||
if (!frame)
|
||||
throw new Error('Failed to find frame with id = ' + frameId);
|
||||
const unsafeObject = frame.unsafeObject(objectId);
|
||||
let unsafeObject;
|
||||
if (!objectId) {
|
||||
unsafeObject = frame.domWindow().frameElement;
|
||||
} else {
|
||||
unsafeObject = frame.unsafeObject(objectId);
|
||||
}
|
||||
const context = this._runtime.findExecutionContext(executionContextId);
|
||||
const fromPrincipal = unsafeObject.nodePrincipal;
|
||||
const toFrame = this._frameTree.frame(context.auxData().frameId);
|
||||
|
@ -655,30 +620,23 @@ class PageAgent {
|
|||
}
|
||||
|
||||
_simulateDragEvent(type, x, y, modifiers) {
|
||||
const window = this._frameTree.mainFrame().domWindow();
|
||||
const element = window.windowUtils.elementFromPoint(x, y, false, false);
|
||||
const event = window.document.createEvent('DragEvent');
|
||||
|
||||
event.initDragEvent(
|
||||
type,
|
||||
true /* bubble */,
|
||||
true /* cancelable */,
|
||||
window,
|
||||
0 /* clickCount */,
|
||||
window.mozInnerScreenX + x,
|
||||
window.mozInnerScreenY + y,
|
||||
x,
|
||||
y,
|
||||
modifiers & 2 /* ctrlkey */,
|
||||
modifiers & 1 /* altKey */,
|
||||
modifiers & 4 /* shiftKey */,
|
||||
modifiers & 8 /* metaKey */,
|
||||
0 /* button */, // firefox always has the button as 0 on drops, regardless of which was pressed
|
||||
null /* relatedTarget */,
|
||||
null,
|
||||
);
|
||||
if (type !== 'drop' || dragService.dragAction)
|
||||
window.windowUtils.dispatchDOMEventViaPresShellForTesting(element, event);
|
||||
if (type !== 'drop' || dragService.dragAction) {
|
||||
const window = this._frameTree.mainFrame().domWindow();
|
||||
window.windowUtils.sendMouseEvent(
|
||||
type,
|
||||
x,
|
||||
y,
|
||||
0, /*button*/
|
||||
0, /*clickCount*/
|
||||
modifiers,
|
||||
false /*aIgnoreRootScrollFrame*/,
|
||||
undefined /*pressure*/,
|
||||
undefined /*inputSource*/,
|
||||
undefined /*isDOMEventSynthesized*/,
|
||||
undefined /*isWidgetEventSynthesized*/,
|
||||
0, /*buttons*/
|
||||
);
|
||||
}
|
||||
if (type === 'drop')
|
||||
this._cancelDragIfNeeded();
|
||||
}
|
||||
|
|
|
@ -367,7 +367,7 @@ class ExecutionContext {
|
|||
try {
|
||||
this._debuggee.executeInGlobal(script);
|
||||
} catch (e) {
|
||||
dump(`ERROR: ${e.message}\n${e.stack}\n`);
|
||||
dump(`WARNING: ${e.message}\n${e.stack}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,7 +450,7 @@ class ExecutionContext {
|
|||
subtype = 'array';
|
||||
else if (Object.is(rawObj, null))
|
||||
subtype = 'null';
|
||||
else if (this._instanceOf(debuggerObj, rawObj, 'Node'))
|
||||
else if (typeof Node !== 'undefined' && Node.isInstance(rawObj))
|
||||
subtype = 'node';
|
||||
else if (this._instanceOf(debuggerObj, rawObj, 'RegExp'))
|
||||
subtype = 'regexp';
|
||||
|
|
|
@ -8,119 +8,118 @@ const {FrameTree} = ChromeUtils.import('chrome://juggler/content/content/FrameTr
|
|||
const {SimpleChannel} = ChromeUtils.import('chrome://juggler/content/SimpleChannel.js');
|
||||
const {PageAgent} = ChromeUtils.import('chrome://juggler/content/content/PageAgent.js');
|
||||
|
||||
let frameTree;
|
||||
const browsingContextToAgents = new Map();
|
||||
const helper = new Helper();
|
||||
const messageManager = this;
|
||||
|
||||
let pageAgent;
|
||||
function initialize(browsingContext, docShell, actor) {
|
||||
if (browsingContext.parent) {
|
||||
// For child frames, return agents from the main frame.
|
||||
return browsingContextToAgents.get(browsingContext.top);
|
||||
}
|
||||
|
||||
let failedToOverrideTimezone = false;
|
||||
let data = browsingContextToAgents.get(browsingContext);
|
||||
if (data) {
|
||||
// Rebind from one main frame actor to another one.
|
||||
data.channel.bindToActor(actor);
|
||||
return data;
|
||||
}
|
||||
|
||||
const applySetting = {
|
||||
geolocation: (geolocation) => {
|
||||
if (geolocation) {
|
||||
docShell.setGeolocationOverride({
|
||||
coords: {
|
||||
latitude: geolocation.latitude,
|
||||
longitude: geolocation.longitude,
|
||||
accuracy: geolocation.accuracy,
|
||||
altitude: NaN,
|
||||
altitudeAccuracy: NaN,
|
||||
heading: NaN,
|
||||
speed: NaN,
|
||||
},
|
||||
address: null,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
} else {
|
||||
docShell.setGeolocationOverride(null);
|
||||
}
|
||||
},
|
||||
data = { channel: undefined, pageAgent: undefined, frameTree: undefined, failedToOverrideTimezone: false };
|
||||
browsingContextToAgents.set(browsingContext, data);
|
||||
|
||||
onlineOverride: (onlineOverride) => {
|
||||
if (!onlineOverride) {
|
||||
docShell.onlineOverride = Ci.nsIDocShell.ONLINE_OVERRIDE_NONE;
|
||||
return;
|
||||
}
|
||||
docShell.onlineOverride = onlineOverride === 'online' ?
|
||||
Ci.nsIDocShell.ONLINE_OVERRIDE_ONLINE : Ci.nsIDocShell.ONLINE_OVERRIDE_OFFLINE;
|
||||
},
|
||||
const applySetting = {
|
||||
geolocation: (geolocation) => {
|
||||
if (geolocation) {
|
||||
docShell.setGeolocationOverride({
|
||||
coords: {
|
||||
latitude: geolocation.latitude,
|
||||
longitude: geolocation.longitude,
|
||||
accuracy: geolocation.accuracy,
|
||||
altitude: NaN,
|
||||
altitudeAccuracy: NaN,
|
||||
heading: NaN,
|
||||
speed: NaN,
|
||||
},
|
||||
address: null,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
} else {
|
||||
docShell.setGeolocationOverride(null);
|
||||
}
|
||||
},
|
||||
|
||||
bypassCSP: (bypassCSP) => {
|
||||
docShell.bypassCSPEnabled = bypassCSP;
|
||||
},
|
||||
onlineOverride: (onlineOverride) => {
|
||||
if (!onlineOverride) {
|
||||
docShell.onlineOverride = Ci.nsIDocShell.ONLINE_OVERRIDE_NONE;
|
||||
return;
|
||||
}
|
||||
docShell.onlineOverride = onlineOverride === 'online' ?
|
||||
Ci.nsIDocShell.ONLINE_OVERRIDE_ONLINE : Ci.nsIDocShell.ONLINE_OVERRIDE_OFFLINE;
|
||||
},
|
||||
|
||||
timezoneId: (timezoneId) => {
|
||||
failedToOverrideTimezone = !docShell.overrideTimezone(timezoneId);
|
||||
},
|
||||
bypassCSP: (bypassCSP) => {
|
||||
docShell.bypassCSPEnabled = bypassCSP;
|
||||
},
|
||||
|
||||
locale: (locale) => {
|
||||
docShell.languageOverride = locale;
|
||||
},
|
||||
timezoneId: (timezoneId) => {
|
||||
data.failedToOverrideTimezone = !docShell.overrideTimezone(timezoneId);
|
||||
},
|
||||
|
||||
scrollbarsHidden: (hidden) => {
|
||||
frameTree.setScrollbarsHidden(hidden);
|
||||
},
|
||||
locale: (locale) => {
|
||||
docShell.languageOverride = locale;
|
||||
},
|
||||
|
||||
colorScheme: (colorScheme) => {
|
||||
frameTree.setColorScheme(colorScheme);
|
||||
},
|
||||
scrollbarsHidden: (hidden) => {
|
||||
data.frameTree.setScrollbarsHidden(hidden);
|
||||
},
|
||||
|
||||
reducedMotion: (reducedMotion) => {
|
||||
frameTree.setReducedMotion(reducedMotion);
|
||||
},
|
||||
javaScriptDisabled: (javaScriptDisabled) => {
|
||||
data.frameTree.setJavaScriptDisabled(javaScriptDisabled);
|
||||
},
|
||||
};
|
||||
|
||||
forcedColors: (forcedColors) => {
|
||||
frameTree.setForcedColors(forcedColors);
|
||||
},
|
||||
};
|
||||
const contextCrossProcessCookie = Services.cpmm.sharedData.get('juggler:context-cookie-' + browsingContext.originAttributes.userContextId) || { initScripts: [], bindings: [], settings: {} };
|
||||
const pageCrossProcessCookie = Services.cpmm.sharedData.get('juggler:page-cookie-' + browsingContext.browserId) || { initScripts: [], bindings: [], interceptFileChooserDialog: false };
|
||||
|
||||
const channel = SimpleChannel.createForMessageManager('content::page', messageManager);
|
||||
|
||||
function initialize() {
|
||||
const response = sendSyncMessage('juggler:content-ready')[0];
|
||||
// If we didn't get a response, then we don't want to do anything
|
||||
// as a part of this frame script.
|
||||
if (!response)
|
||||
return;
|
||||
const {
|
||||
initScripts = [],
|
||||
bindings = [],
|
||||
settings = {}
|
||||
} = response || {};
|
||||
// Enforce focused state for all top level documents.
|
||||
docShell.overrideHasFocus = true;
|
||||
docShell.forceActiveState = true;
|
||||
frameTree = new FrameTree(docShell);
|
||||
for (const [name, value] of Object.entries(settings)) {
|
||||
docShell.disallowBFCache = true;
|
||||
data.frameTree = new FrameTree(docShell);
|
||||
for (const [name, value] of Object.entries(contextCrossProcessCookie.settings)) {
|
||||
if (value !== undefined)
|
||||
applySetting[name](value);
|
||||
}
|
||||
for (const { worldName, name, script } of bindings)
|
||||
frameTree.addBinding(worldName, name, script);
|
||||
frameTree.setInitScripts(initScripts);
|
||||
for (const { worldName, name, script } of [...contextCrossProcessCookie.bindings, ...pageCrossProcessCookie.bindings])
|
||||
data.frameTree.addBinding(worldName, name, script);
|
||||
data.frameTree.setInitScripts([...contextCrossProcessCookie.initScripts, ...pageCrossProcessCookie.initScripts]);
|
||||
data.channel = SimpleChannel.createForActor(actor);
|
||||
data.pageAgent = new PageAgent(data.channel, data.frameTree);
|
||||
docShell.fileInputInterceptionEnabled = !!pageCrossProcessCookie.interceptFileChooserDialog;
|
||||
|
||||
pageAgent = new PageAgent(messageManager, channel, frameTree);
|
||||
|
||||
channel.register('', {
|
||||
data.channel.register('', {
|
||||
setInitScripts(scripts) {
|
||||
frameTree.setInitScripts(scripts);
|
||||
data.frameTree.setInitScripts(scripts);
|
||||
},
|
||||
|
||||
addBinding({worldName, name, script}) {
|
||||
frameTree.addBinding(worldName, name, script);
|
||||
data.frameTree.addBinding(worldName, name, script);
|
||||
},
|
||||
|
||||
applyContextSetting({name, value}) {
|
||||
applySetting[name](value);
|
||||
},
|
||||
|
||||
setInterceptFileChooserDialog(enabled) {
|
||||
docShell.fileInputInterceptionEnabled = !!enabled;
|
||||
},
|
||||
|
||||
ensurePermissions() {
|
||||
// noop, just a rountrip.
|
||||
},
|
||||
|
||||
hasFailedToOverrideTimezone() {
|
||||
return failedToOverrideTimezone;
|
||||
return data.failedToOverrideTimezone;
|
||||
},
|
||||
|
||||
async awaitViewportDimensions({width, height, deviceSizeIsPageSize}) {
|
||||
|
@ -142,14 +141,8 @@ function initialize() {
|
|||
},
|
||||
});
|
||||
|
||||
const gListeners = [
|
||||
helper.addEventListener(messageManager, 'unload', msg => {
|
||||
helper.removeListeners(gListeners);
|
||||
pageAgent.dispose();
|
||||
frameTree.dispose();
|
||||
channel.dispose();
|
||||
}),
|
||||
];
|
||||
return data;
|
||||
}
|
||||
|
||||
initialize();
|
||||
var EXPORTED_SYMBOLS = ['initialize'];
|
||||
this.initialize = initialize;
|
||||
|
|
|
@ -11,11 +11,13 @@ juggler.jar:
|
|||
content/NetworkObserver.js (NetworkObserver.js)
|
||||
content/TargetRegistry.js (TargetRegistry.js)
|
||||
content/SimpleChannel.js (SimpleChannel.js)
|
||||
content/JugglerFrameParent.jsm (JugglerFrameParent.jsm)
|
||||
content/protocol/PrimitiveTypes.js (protocol/PrimitiveTypes.js)
|
||||
content/protocol/Protocol.js (protocol/Protocol.js)
|
||||
content/protocol/Dispatcher.js (protocol/Dispatcher.js)
|
||||
content/protocol/PageHandler.js (protocol/PageHandler.js)
|
||||
content/protocol/BrowserHandler.js (protocol/BrowserHandler.js)
|
||||
content/content/JugglerFrameChild.jsm (content/JugglerFrameChild.jsm)
|
||||
content/content/main.js (content/main.js)
|
||||
content/content/FrameTree.js (content/FrameTree.js)
|
||||
content/content/PageAgent.js (content/PageAgent.js)
|
||||
|
|
|
@ -214,7 +214,7 @@ class BrowserHandler {
|
|||
}
|
||||
|
||||
async ['Browser.setJavaScriptDisabled']({browserContextId, javaScriptDisabled}) {
|
||||
await this._targetRegistry.browserContextForId(browserContextId).setJavaScriptDisabled(javaScriptDisabled);
|
||||
await this._targetRegistry.browserContextForId(browserContextId).applySetting('javaScriptDisabled', nullToUndefined(javaScriptDisabled));
|
||||
}
|
||||
|
||||
async ['Browser.setLocaleOverride']({browserContextId, locale}) {
|
||||
|
|
|
@ -89,6 +89,11 @@ class PageHandler {
|
|||
// to be ignored by the protocol clients.
|
||||
this._isPageReady = false;
|
||||
|
||||
// Whether the page is about to go cross-process after navigation.
|
||||
this._isTransferringCrossProcessNavigation = false;
|
||||
this._mainFrameId = undefined;
|
||||
this._lastMainFrameNavigationId = undefined;
|
||||
|
||||
if (this._pageTarget.videoRecordingInfo())
|
||||
this._onVideoRecordingStarted();
|
||||
|
||||
|
@ -100,6 +105,7 @@ class PageHandler {
|
|||
}),
|
||||
helper.on(this._pageTarget, PageTarget.Events.ScreencastStarted, this._onVideoRecordingStarted.bind(this)),
|
||||
helper.on(this._pageTarget, PageTarget.Events.ScreencastFrame, this._onScreencastFrame.bind(this)),
|
||||
helper.on(this._pageTarget, PageTarget.Events.TopBrowsingContextReplaced, this._onTopBrowsingContextReplaced.bind(this)),
|
||||
helper.on(this._pageNetwork, PageNetwork.Events.Request, this._handleNetworkEvent.bind(this, 'Network.requestWillBeSent')),
|
||||
helper.on(this._pageNetwork, PageNetwork.Events.Response, this._handleNetworkEvent.bind(this, 'Network.responseReceived')),
|
||||
helper.on(this._pageNetwork, PageNetwork.Events.RequestFinished, this._handleNetworkEvent.bind(this, 'Network.requestFinished')),
|
||||
|
@ -113,9 +119,9 @@ class PageHandler {
|
|||
pageFrameDetached: emitProtocolEvent('Page.frameDetached'),
|
||||
pageLinkClicked: emitProtocolEvent('Page.linkClicked'),
|
||||
pageWillOpenNewWindowAsynchronously: emitProtocolEvent('Page.willOpenNewWindowAsynchronously'),
|
||||
pageNavigationAborted: emitProtocolEvent('Page.navigationAborted'),
|
||||
pageNavigationCommitted: emitProtocolEvent('Page.navigationCommitted'),
|
||||
pageNavigationStarted: emitProtocolEvent('Page.navigationStarted'),
|
||||
pageNavigationAborted: params => this._handleNavigationEvent('Page.navigationAborted', params),
|
||||
pageNavigationCommitted: params => this._handleNavigationEvent('Page.navigationCommitted', params),
|
||||
pageNavigationStarted: params => this._handleNavigationEvent('Page.navigationStarted', params),
|
||||
pageReady: this._onPageReady.bind(this),
|
||||
pageSameDocumentNavigation: emitProtocolEvent('Page.sameDocumentNavigation'),
|
||||
pageUncaughtError: emitProtocolEvent('Page.uncaughtError'),
|
||||
|
@ -129,10 +135,11 @@ class PageHandler {
|
|||
return;
|
||||
}
|
||||
}
|
||||
emitProtocolEvent('Runtime.console')(params);
|
||||
this._session.emitEvent('Runtime.console', params);
|
||||
},
|
||||
runtimeExecutionContextCreated: emitProtocolEvent('Runtime.executionContextCreated'),
|
||||
runtimeExecutionContextDestroyed: emitProtocolEvent('Runtime.executionContextDestroyed'),
|
||||
runtimeExecutionContextsCleared: emitProtocolEvent('Runtime.executionContextsCleared'),
|
||||
|
||||
webSocketCreated: emitProtocolEvent('Page.webSocketCreated'),
|
||||
webSocketOpened: emitProtocolEvent('Page.webSocketOpened'),
|
||||
|
@ -157,6 +164,28 @@ class PageHandler {
|
|||
this._session.emitEvent('Page.screencastFrame', params);
|
||||
}
|
||||
|
||||
_onTopBrowsingContextReplaced() {
|
||||
this._isTransferringCrossProcessNavigation = true;
|
||||
}
|
||||
|
||||
_handleNavigationEvent(event, params) {
|
||||
if (this._isTransferringCrossProcessNavigation && params.frameId === this._mainFrameId) {
|
||||
// During a cross-process navigation, http channel in the new process might not be
|
||||
// the same as the original one in the old process, for example after a redirect/interception.
|
||||
// Therefore, the new proces has a new navigationId.
|
||||
//
|
||||
// To preserve protocol consistency, we replace the new navigationId with
|
||||
// the old navigationId.
|
||||
params.navigationId = this._lastMainFrameNavigationId || params.navigationId;
|
||||
if (event === 'Page.navigationCommitted' || event === 'Page.navigationAborted')
|
||||
this._isTransferringCrossProcessNavigation = false;
|
||||
}
|
||||
|
||||
if (event === 'Page.navigationStarted' && params.frameId === this._mainFrameId)
|
||||
this._lastMainFrameNavigationId = params.navigationId;
|
||||
this._session.emitEvent(event, params);
|
||||
}
|
||||
|
||||
_onPageReady(event) {
|
||||
this._isPageReady = true;
|
||||
this._session.emitEvent('Page.ready');
|
||||
|
@ -210,6 +239,8 @@ class PageHandler {
|
|||
}
|
||||
|
||||
_onFrameAttached({frameId, parentFrameId}) {
|
||||
if (!parentFrameId)
|
||||
this._mainFrameId = frameId;
|
||||
this._session.emitEvent('Page.frameAttached', {frameId, parentFrameId});
|
||||
this._reportedFrameIds.add(frameId);
|
||||
const events = this._networkEventsForUnreportedFrameIds.get(frameId) || [];
|
||||
|
@ -295,8 +326,8 @@ class PageHandler {
|
|||
return await this._contentPage.send('setCacheDisabled', options);
|
||||
}
|
||||
|
||||
async ['Page.addBinding'](options) {
|
||||
return await this._contentPage.send('addBinding', options);
|
||||
async ['Page.addBinding']({ worldName, name, script }) {
|
||||
return await this._pageTarget.addBinding(worldName, name, script);
|
||||
}
|
||||
|
||||
async ['Page.adoptNode'](options) {
|
||||
|
@ -358,16 +389,25 @@ class PageHandler {
|
|||
return await this._contentPage.send('navigate', options);
|
||||
}
|
||||
|
||||
async ['Page.goBack'](options) {
|
||||
return await this._contentPage.send('goBack', options);
|
||||
async ['Page.goBack']({}) {
|
||||
const browsingContext = this._pageTarget.linkedBrowser().browsingContext;
|
||||
if (!browsingContext.embedderElement?.canGoBack)
|
||||
return { success: false };
|
||||
browsingContext.goBack();
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async ['Page.goForward'](options) {
|
||||
return await this._contentPage.send('goForward', options);
|
||||
async ['Page.goForward']({}) {
|
||||
const browsingContext = this._pageTarget.linkedBrowser().browsingContext;
|
||||
if (!browsingContext.embedderElement?.canGoForward)
|
||||
return { success: false };
|
||||
browsingContext.goForward();
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
async ['Page.reload'](options) {
|
||||
return await this._contentPage.send('reload', options);
|
||||
async ['Page.reload']({}) {
|
||||
const browsingContext = this._pageTarget.linkedBrowser().browsingContext;
|
||||
browsingContext.reload(Ci.nsIWebNavigation.LOAD_FLAGS_NONE);
|
||||
}
|
||||
|
||||
async ['Page.describeNode'](options) {
|
||||
|
@ -438,8 +478,8 @@ class PageHandler {
|
|||
dialog.dismiss();
|
||||
}
|
||||
|
||||
async ['Page.setInterceptFileChooserDialog'](options) {
|
||||
return await this._contentPage.send('setInterceptFileChooserDialog', options);
|
||||
async ['Page.setInterceptFileChooserDialog']({ enabled }) {
|
||||
return await this._pageTarget.setInterceptFileChooserDialog(enabled);
|
||||
}
|
||||
|
||||
async ['Page.startScreencast'](options) {
|
||||
|
|
|
@ -227,6 +227,7 @@ const Browser = {
|
|||
uuid: t.String,
|
||||
browserContextId: t.Optional(t.String),
|
||||
pageTargetId: t.String,
|
||||
frameId: t.String,
|
||||
url: t.String,
|
||||
suggestedFileName: t.String,
|
||||
},
|
||||
|
@ -573,6 +574,8 @@ const Runtime = {
|
|||
'executionContextDestroyed': {
|
||||
executionContextId: t.String,
|
||||
},
|
||||
'executionContextsCleared': {
|
||||
},
|
||||
'console': {
|
||||
executionContextId: t.String,
|
||||
args: t.Array(runtimeTypes.RemoteObject),
|
||||
|
@ -847,7 +850,8 @@ const Page = {
|
|||
'adoptNode': {
|
||||
params: {
|
||||
frameId: t.String,
|
||||
objectId: t.String,
|
||||
// Missing objectId adopts frame owner.
|
||||
objectId: t.Optional(t.String),
|
||||
executionContextId: t.String,
|
||||
},
|
||||
returns: {
|
||||
|
|
|
@ -19,7 +19,9 @@ using namespace webrtc;
|
|||
namespace mozilla {
|
||||
|
||||
rtc::scoped_refptr<webrtc::VideoCaptureModuleEx> HeadlessWindowCapturer::Create(HeadlessWidget* headlessWindow) {
|
||||
return new rtc::RefCountedObject<HeadlessWindowCapturer>(headlessWindow);
|
||||
return rtc::scoped_refptr<webrtc::VideoCaptureModuleEx>(
|
||||
new rtc::RefCountedObject<HeadlessWindowCapturer>(headlessWindow)
|
||||
);
|
||||
}
|
||||
|
||||
HeadlessWindowCapturer::HeadlessWindowCapturer(mozilla::widget::HeadlessWidget* window)
|
||||
|
|
|
@ -55,7 +55,7 @@ rtc::scoped_refptr<webrtc::VideoCaptureModuleEx> CreateWindowCapturer(nsIWidget*
|
|||
windowId.AppendPrintf("%" PRIuPTR, rawWindowId);
|
||||
bool captureCursor = false;
|
||||
static int moduleId = 0;
|
||||
return webrtc::DesktopCaptureImpl::Create(++moduleId, windowId.get(), CaptureDeviceType::Window, captureCursor);
|
||||
return rtc::scoped_refptr<webrtc::VideoCaptureModuleEx>(webrtc::DesktopCaptureImpl::Create(++moduleId, windowId.get(), CaptureDeviceType::Window, captureCursor));
|
||||
}
|
||||
|
||||
nsresult generateUid(nsString& uid) {
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -8,24 +8,88 @@ pref("datareporting.policy.dataSubmissionEnabled", false);
|
|||
pref("datareporting.policy.dataSubmissionPolicyAccepted", false);
|
||||
pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);
|
||||
|
||||
// @see https://github.com/microsoft/playwright/issues/4297
|
||||
pref("browser.tabs.remote.useCrossOriginEmbedderPolicy", false);
|
||||
pref("browser.tabs.remote.useCrossOriginOpenerPolicy", false);
|
||||
|
||||
pref("browser.tabs.remote.separatePrivilegedMozillaWebContentProcess", false);
|
||||
|
||||
// Force pdfs into downloads.
|
||||
pref("pdfjs.disabled", true);
|
||||
|
||||
// Disable all kinds of cross-process navigations until we are ready.
|
||||
pref("fission.autostart", false);
|
||||
// Disable cross-process iframes, but not cross-process navigations.
|
||||
pref("fission.webContentIsolationStrategy", 0);
|
||||
|
||||
// Disable BFCache in parent process.
|
||||
// We also separately disable BFCache in content via docSchell property.
|
||||
pref("fission.bfcacheInParent", false);
|
||||
// Avoid about:blank loading cross-process until we are ready.
|
||||
pref("browser.tabs.remote.systemTriggeredAboutBlankAnywhere", true);
|
||||
|
||||
// File url navigations behave differently from http, we are not ready.
|
||||
pref("browser.tabs.remote.separateFileUriProcess", false);
|
||||
|
||||
// Disable first-party-based cookie partitioning.
|
||||
// When it is enabled, we have to retain "thirdPartyCookie^" permissions
|
||||
// in the storageState.
|
||||
pref("network.cookie.cookieBehavior", 4);
|
||||
|
||||
// Increase max number of child web processes so that new pages
|
||||
// get a new process by default and we have a process isolation
|
||||
// between pages from different contexts. If this becomes a performance
|
||||
// issue we can povide custom '@mozilla.org/ipc/processselector;1'
|
||||
pref("dom.ipc.processCount", 60000);
|
||||
|
||||
// Never reuse processes as they may keep previously overridden values
|
||||
// (locale, timezone etc.).
|
||||
pref("dom.ipc.processPrelaunch.enabled", false);
|
||||
|
||||
// Isolate permissions by user context.
|
||||
pref("permissions.isolateBy.userContext", true);
|
||||
|
||||
// We need this to issue Page.navigate from inside the renderer
|
||||
// to cross-process domains, for example file urls.
|
||||
pref("security.sandbox.content.level", 2);
|
||||
|
||||
// Allow creating files in content process - required for
|
||||
// |Page.setFileInputFiles| protocol method.
|
||||
pref("dom.file.createInChild", true);
|
||||
|
||||
// Do not warn when closing all open tabs
|
||||
pref("browser.tabs.warnOnClose", false);
|
||||
|
||||
// Do not warn when closing all other open tabs
|
||||
pref("browser.tabs.warnOnCloseOtherTabs", false);
|
||||
|
||||
// Do not warn when multiple tabs will be opened
|
||||
pref("browser.tabs.warnOnOpen", false);
|
||||
|
||||
// Do not warn on quitting Firefox
|
||||
pref("browser.warnOnQuit", false);
|
||||
|
||||
// Disable popup-blocker
|
||||
pref("dom.disable_open_during_load", false);
|
||||
|
||||
// Disable the ProcessHangMonitor
|
||||
pref("dom.ipc.reportProcessHangs", false);
|
||||
pref("hangmonitor.timeout", 0);
|
||||
|
||||
// Allow the application to have focus even it runs in the background
|
||||
pref("focusmanager.testmode", true);
|
||||
|
||||
// No ICC color correction. We need this for reproducible screenshots.
|
||||
// See https://developer.mozilla.org/en/docs/Mozilla/Firefox/Releases/3.5/ICC_color_correction_in_Firefox.
|
||||
pref("gfx.color_management.mode", 0);
|
||||
pref("gfx.color_management.rendering_intent", 3);
|
||||
|
||||
// Always use network provider for geolocation tests so we bypass the
|
||||
// macOS dialog raised by the corelocation provider
|
||||
pref("geo.provider.testing", true);
|
||||
|
||||
|
||||
|
||||
|
||||
// =================================================================
|
||||
// THESE ARE NICHE PROPERTIES THAT ARE NICE TO HAVE
|
||||
// =================================================================
|
||||
|
||||
// Avoid stalling on shutdown, after "xpcom-will-shutdown" phase.
|
||||
// This at least happens when shutting down soon after launching.
|
||||
// See AppShutdown.cpp for more details on shutdown phases.
|
||||
pref("toolkit.shutdown.fastShutdownStage", 3);
|
||||
|
||||
// @see https://github.com/microsoft/playwright/issues/8178
|
||||
pref("dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled", true);
|
||||
|
||||
|
@ -36,23 +100,9 @@ pref("ui.systemUsesDarkTheme", 0);
|
|||
// support for the new modal UI (see Bug 1686743).
|
||||
pref("prompts.contentPromptSubDialog", false);
|
||||
|
||||
// Increase max number of child web processes so that new pages
|
||||
// get a new process by default and we have a process isolation
|
||||
// between pages from different contexts. If this becomes a performance
|
||||
// issue we can povide custom '@mozilla.org/ipc/processselector;1'
|
||||
//
|
||||
pref("dom.ipc.processCount", 60000);
|
||||
|
||||
// Never reuse processes as they may keep previously overridden values
|
||||
// (locale, timezone etc.).
|
||||
pref("dom.ipc.processPrelaunch.enabled", false);
|
||||
|
||||
// Do not use system colors - they are affected by themes.
|
||||
pref("ui.use_standins_for_native_colors", true);
|
||||
|
||||
// Isolate permissions by user context.
|
||||
pref("permissions.isolateBy.userContext", true);
|
||||
|
||||
pref("dom.push.serverURL", "");
|
||||
// This setting breaks settings loading.
|
||||
pref("services.settings.server", "");
|
||||
|
@ -87,14 +137,10 @@ pref("browser.newtabpage.enabled", false);
|
|||
// Do not redirect user when a milstone upgrade of Firefox is detected
|
||||
pref("browser.startup.homepage_override.mstone", "ignore");
|
||||
|
||||
pref("browser.tabs.remote.separateFileUriProcess", false);
|
||||
pref("security.sandbox.content.level", 2);
|
||||
|
||||
// Disable topstories
|
||||
pref("browser.newtabpage.activity-stream.feeds.section.topstories", false);
|
||||
// DevTools JSONViewer sometimes fails to load dependencies with its require.js.
|
||||
// This doesn't affect Puppeteer operations, but spams console with a lot of
|
||||
// unpleasant errors.
|
||||
// This spams console with a lot of unpleasant errors.
|
||||
// (bug 1424372)
|
||||
pref("devtools.jsonview.enabled", false);
|
||||
|
||||
|
@ -107,10 +153,6 @@ pref("devtools.jsonview.enabled", false);
|
|||
// (bug 1176798, bug 1177018, bug 1210465)
|
||||
pref("apz.content_response_timeout", 60000);
|
||||
|
||||
// Allow creating files in content process - required for
|
||||
// |Page.setFileInputFiles| protocol method.
|
||||
pref("dom.file.createInChild", true);
|
||||
|
||||
// Indicate that the download panel has been shown once so that
|
||||
// whichever download test runs first doesn't show the popup
|
||||
// inconsistently.
|
||||
|
@ -142,15 +184,6 @@ pref("browser.tabs.closeWindowWithLastTab", true);
|
|||
// unloaded
|
||||
pref("browser.tabs.disableBackgroundZombification", false);
|
||||
|
||||
// Do not warn when closing all open tabs
|
||||
pref("browser.tabs.warnOnClose", false);
|
||||
|
||||
// Do not warn when closing all other open tabs
|
||||
pref("browser.tabs.warnOnCloseOtherTabs", false);
|
||||
|
||||
// Do not warn when multiple tabs will be opened
|
||||
pref("browser.tabs.warnOnOpen", false);
|
||||
|
||||
// Disable first run splash page on Windows 10
|
||||
pref("browser.usedOnWindows10.introURL", "");
|
||||
|
||||
|
@ -163,9 +196,6 @@ pref("browser.uitour.enabled", false);
|
|||
// network connections.
|
||||
pref("browser.urlbar.suggest.searches", false);
|
||||
|
||||
// Do not warn on quitting Firefox
|
||||
pref("browser.warnOnQuit", false);
|
||||
|
||||
// Do not show datareporting policy notifications which can
|
||||
// interfere with tests
|
||||
pref("datareporting.healthreport.documentServerURI", "");
|
||||
|
@ -178,13 +208,6 @@ pref("datareporting.healthreport.uploadEnabled", false);
|
|||
// Automatically unload beforeunload alerts
|
||||
pref("dom.disable_beforeunload", false);
|
||||
|
||||
// Disable popup-blocker
|
||||
pref("dom.disable_open_during_load", false);
|
||||
|
||||
// Disable the ProcessHangMonitor
|
||||
pref("dom.ipc.reportProcessHangs", false);
|
||||
pref("hangmonitor.timeout", 0);
|
||||
|
||||
// Disable slow script dialogues
|
||||
pref("dom.max_chrome_script_run_time", 0);
|
||||
pref("dom.max_script_run_time", 0);
|
||||
|
@ -210,21 +233,9 @@ pref("extensions.webservice.discoverURL", "");
|
|||
pref("extensions.screenshots.disabled", true);
|
||||
pref("extensions.screenshots.upload-disabled", true);
|
||||
|
||||
// Allow the application to have focus even it runs in the background
|
||||
pref("focusmanager.testmode", true);
|
||||
|
||||
// Disable useragent updates
|
||||
pref("general.useragent.updates.enabled", false);
|
||||
|
||||
// No ICC color correction.
|
||||
// See https://developer.mozilla.org/en/docs/Mozilla/Firefox/Releases/3.5/ICC_color_correction_in_Firefox.
|
||||
pref("gfx.color_management.mode", 0);
|
||||
pref("gfx.color_management.rendering_intent", 3);
|
||||
|
||||
// Always use network provider for geolocation tests so we bypass the
|
||||
// macOS dialog raised by the corelocation provider
|
||||
pref("geo.provider.testing", true);
|
||||
|
||||
// Do not scan Wifi
|
||||
pref("geo.wifi.scan", false);
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
REMOTE_URL="https://github.com/WebKit/WebKit.git"
|
||||
BASE_BRANCH="main"
|
||||
BASE_REVISION="c888c485b787e204057b56d69536aae567ab8b3a"
|
||||
BASE_REVISION="675d141bdcf7fa6df9bdf505d46e46fdac638452"
|
||||
|
|
|
@ -229,6 +229,7 @@ const NSActivityOptions ActivityOptions =
|
|||
if (!configuration) {
|
||||
configuration = [[WKWebViewConfiguration alloc] init];
|
||||
configuration.websiteDataStore = [self persistentDataStore];
|
||||
configuration._controlledByAutomation = true;
|
||||
configuration.preferences._fullScreenEnabled = YES;
|
||||
configuration.preferences._developerExtrasEnabled = YES;
|
||||
configuration.preferences._mediaDevicesEnabled = YES;
|
||||
|
@ -496,6 +497,12 @@ const NSActivityOptions ActivityOptions =
|
|||
download.delegate = self;
|
||||
}
|
||||
|
||||
// Always automatically accept requestStorageAccess dialog.
|
||||
- (void)_webView:(WKWebView *)webView requestStorageAccessPanelForDomain:(NSString *)requestingDomain underCurrentDomain:(NSString *)currentDomain completionHandler:(void (^)(BOOL result))completionHandler
|
||||
{
|
||||
completionHandler(true);
|
||||
}
|
||||
|
||||
#pragma mark WKDownloadDelegate
|
||||
|
||||
- (void)download:(WKDownload *)download decideDestinationUsingResponse:(NSURLResponse *)response suggestedFilename:(NSString *)suggestedFilename completionHandler:(void (^)(NSURL * _Nullable destination))completionHandler
|
||||
|
|
|
@ -67,10 +67,22 @@ static void* keyValueObservingContext = &keyValueObservingContext;
|
|||
|
||||
- (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen *)screen
|
||||
{
|
||||
// Retain the frame size, but make sure that
|
||||
// the top of the window is always visible.
|
||||
CGFloat yPos = NSHeight(self.screen.frame) - 100 - NSHeight(self.frame);
|
||||
return NSMakeRect(frameRect.origin.x, yPos, frameRect.size.width, frameRect.size.height);
|
||||
float kWindowControlBarHeight = 35;
|
||||
|
||||
CGFloat screenHeight = screen.frame.size.height; // e.g. 1080
|
||||
CGFloat windowHeight = self.frame.size.height; // e.g. 5000
|
||||
CGFloat screenYOffset = screen.frame.origin.y; // screen arrangement offset
|
||||
|
||||
bool exceedsAtTheTop = (NSMaxY(frameRect) - screenYOffset) > screenHeight;
|
||||
bool exceedsAtTheBottom = (frameRect.origin.y + windowHeight + -screenYOffset - kWindowControlBarHeight) < 0;
|
||||
CGFloat newOriginY = frameRect.origin.y;
|
||||
// if it exceeds the height, then we move it to the top of the screen
|
||||
if (screenHeight > 0 && exceedsAtTheTop)
|
||||
newOriginY = screenHeight - windowHeight - kWindowControlBarHeight + screenYOffset;
|
||||
// if it exceeds the bottom, then we move it to the bottom of the screen but make sure that the control bar is still visible
|
||||
else if (screenHeight > 0 && exceedsAtTheBottom)
|
||||
newOriginY = -windowHeight + screenYOffset + kWindowControlBarHeight;
|
||||
return NSMakeRect(frameRect.origin.x, newOriginY, frameRect.size.width, frameRect.size.height);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -670,6 +682,12 @@ static BOOL areEssentiallyEqual(double a, double b)
|
|||
}];
|
||||
}
|
||||
|
||||
// Always automatically accept requestStorageAccess dialog.
|
||||
- (void)_webView:(WKWebView *)webView requestStorageAccessPanelForDomain:(NSString *)requestingDomain underCurrentDomain:(NSString *)currentDomain completionHandler:(void (^)(BOOL result))completionHandler
|
||||
{
|
||||
completionHandler(true);
|
||||
}
|
||||
|
||||
- (WKDragDestinationAction)_webView:(WKWebView *)webView dragDestinationActionMaskForDraggingInfo:(id)draggingInfo
|
||||
{
|
||||
return WKDragDestinationActionAny;
|
||||
|
|
|
@ -1,76 +1,76 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "PlaywrightResource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_PLAYWRIGHT ICON "Playwright.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"PlaywrightResource.\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "PlaywrightResource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_PLAYWRIGHT ICON "Playwright.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"PlaywrightResource.\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
|
|
@ -1,354 +1,354 @@
|
|||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "PlaywrightLibResource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_PLAYWRIGHT ICON "Playwright.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDC_PLAYWRIGHT MENU
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "New Window\tCtrl-N" IDM_NEW_WINDOW
|
||||
MENUITEM "Close\tCtrl-W", IDM_CLOSE_WINDOW
|
||||
END
|
||||
POPUP "&View"
|
||||
BEGIN
|
||||
MENUITEM "Actual Size\tCtrl+0", IDM_ACTUAL_SIZE
|
||||
MENUITEM "Zoom In\tCtrl++", IDM_ZOOM_IN
|
||||
MENUITEM "Zoom Out\tCtrl+-", IDM_ZOOM_OUT
|
||||
MENUITEM "Invert Colors", IDM_INVERT_COLORS
|
||||
END
|
||||
POPUP "&History"
|
||||
BEGIN
|
||||
MENUITEM "Reload\tCtrl-R", IDM_RELOAD
|
||||
MENUITEM "Back", IDM_HISTORY_BACKWARD
|
||||
MENUITEM "Forward", IDM_HISTORY_FORWARD
|
||||
END
|
||||
POPUP "D&evelop"
|
||||
BEGIN
|
||||
MENUITEM "Show Web Inspector", IDM_WEB_INSPECTOR
|
||||
END
|
||||
POPUP "&Help"
|
||||
BEGIN
|
||||
MENUITEM "&About ...", IDM_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDC_PLAYWRIGHT ACCELERATORS
|
||||
BEGIN
|
||||
"/", IDM_ABOUT, ASCII, ALT, NOINVERT
|
||||
"0", IDM_ACTUAL_SIZE, VIRTKEY, CONTROL, NOINVERT
|
||||
"?", IDM_ABOUT, ASCII, ALT, NOINVERT
|
||||
"R", IDM_RELOAD, VIRTKEY, CONTROL, NOINVERT
|
||||
"N", IDM_NEW_WINDOW, VIRTKEY, CONTROL, NOINVERT
|
||||
VK_ADD, IDM_ZOOM_IN, VIRTKEY, CONTROL, NOINVERT
|
||||
VK_OEM_MINUS, IDM_ZOOM_OUT, VIRTKEY, CONTROL, NOINVERT
|
||||
VK_OEM_PLUS, IDM_ZOOM_IN, VIRTKEY, CONTROL, NOINVERT
|
||||
VK_SUBTRACT, IDM_ZOOM_OUT, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
IDR_ACCELERATORS_PRE ACCELERATORS
|
||||
BEGIN
|
||||
"W", IDM_CLOSE_WINDOW, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUTBOX DIALOGEX 22, 17, 230, 41
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
ICON IDI_PLAYWRIGHT,IDC_MYICON,14,9,20,20
|
||||
LTEXT "Playwright Version 1.1",IDC_STATIC,49,10,119,8
|
||||
LTEXT "Copyright (C) 2015-2019",IDC_STATIC,49,20,119,8
|
||||
DEFPUSHBUTTON "OK",IDOK,186,10,30,11,WS_GROUP
|
||||
END
|
||||
|
||||
IDD_CACHES DIALOGEX 0, 0, 401, 456
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,287,435,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,344,435,50,14
|
||||
GROUPBOX "FastMalloc",IDC_STATIC,208,14,186,67
|
||||
GROUPBOX "WebCore Cache",IDC_STATIC,17,83,376,105
|
||||
GROUPBOX "JavaScript Heap",IDC_STATIC,18,193,376,168
|
||||
GROUPBOX "Site Icon Database",IDC_STATIC,18,366,142,65
|
||||
GROUPBOX "Font and Glyph Caches",IDC_STATIC,168,366,226,66
|
||||
GROUPBOX "CFURLCache",IDC_STATIC,7,14,197,67
|
||||
PUSHBUTTON "Empty URLCache",IDC_EMPTY_URL_CACHE,131,63,69,14,WS_DISABLED
|
||||
PUSHBUTTON "Return Free Memory",IDC_RETURN_FREE_MEMORY,308,63,76,14,WS_DISABLED
|
||||
PUSHBUTTON "Empty WebCore Cache",IDC_EMPTY_WEBCORE_CACHE,21,170,83,14,WS_DISABLED
|
||||
CONTROL "Disable WebCore Cache",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,119,172,93,10
|
||||
PUSHBUTTON "Garbage Collect JavaScript Objects",IDC_GC_JSC,253,343,135,14,WS_DISABLED
|
||||
RTEXT "Reserved VM",IDC_STATIC,212,26,67,9
|
||||
RTEXT "0",IDC_RESERVED_VM,290,26,94,8
|
||||
RTEXT "Committed VM",IDC_STATIC,211,39,67,8
|
||||
RTEXT "0",IDC_COMMITTED_VM,290,39,94,8
|
||||
RTEXT "Free List Bytes",IDC_STATIC,211,52,67,8
|
||||
RTEXT "0",IDC_FREE_LIST_BYTES,290,52,94,8
|
||||
RTEXT "Images",IDC_STATIC,37,106,24,8
|
||||
RTEXT "CSS",IDC_STATIC,47,116,14,8
|
||||
RTEXT "XSL",IDC_STATIC,49,126,12,8
|
||||
RTEXT "JavaScript",IDC_STATIC,27,135,34,8
|
||||
RTEXT "Total",IDC_STATIC,43,146,17,8
|
||||
LTEXT "Objects",IDC_STATIC,111,96,26,8
|
||||
LTEXT "Bytes",IDC_STATIC,175,96,19,8
|
||||
LTEXT "Live",IDC_STATIC,232,96,14,8
|
||||
LTEXT "Decoded",IDC_STATIC,284,96,29,8
|
||||
LTEXT "Purgeable",IDC_STATIC,351,96,33,8
|
||||
RTEXT "0",IDC_IMAGES_OBJECT_COUNT,100,106,32,8
|
||||
RTEXT "0",IDC_CSS_OBJECT_COUNT,100,116,32,8
|
||||
RTEXT "0",IDC_XSL_OBJECT_COUNT,100,126,32,8
|
||||
RTEXT "0",IDC_JSC_OBJECT_COUNT,100,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_OBJECT_COUNT,100,146,32,8
|
||||
RTEXT "0",IDC_IMAGES_BYTES,162,106,32,8
|
||||
RTEXT "0",IDC_CSS_BYTES,162,116,32,8
|
||||
RTEXT "0",IDC_XSL_BYTES,162,126,32,8
|
||||
RTEXT "0",IDC_JSC_BYTES,162,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_BYTES,162,146,32,8
|
||||
RTEXT "0",IDC_IMAGES_LIVE_COUNT,221,106,32,8
|
||||
RTEXT "0",IDC_CSS_LIVE_COUNT,221,116,32,8
|
||||
RTEXT "0",IDC_XSL_LIVE_COUNT,221,126,32,8
|
||||
RTEXT "0",IDC_JSC_LIVE_COUNT,221,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_LIVE_COUNT,221,146,32,8
|
||||
RTEXT "0",IDC_IMAGES_DECODED_COUNT,284,106,32,8
|
||||
RTEXT "0",IDC_CSS_DECODED_COUNT,284,116,32,8
|
||||
RTEXT "0",IDC_XSL_DECODED_COUNT,284,126,32,8
|
||||
RTEXT "0",IDC_JSC_DECODED_COUNT,284,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_DECODED,284,146,32,8
|
||||
RTEXT "0",IDC_IMAGES_PURGEABLE_COUNT,354,106,32,8
|
||||
RTEXT "0",IDC_CSS_PURGEABLE_COUNT,354,116,32,8
|
||||
RTEXT "0",IDC_XSL_PURGEABLE_COUNT,354,126,32,8
|
||||
RTEXT "0",IDC_JSC_PURGEABLE_COUNT,354,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_PURGEABLE,354,146,32,8
|
||||
RTEXT "Total Objects",IDC_STATIC,63,207,44,8
|
||||
RTEXT "Global Objects",IDC_STATIC,56,217,51,8
|
||||
RTEXT "Protected Objects",IDC_STATIC,48,227,59,8
|
||||
RTEXT "0",IDC_TOTAL_JSC_HEAP_OBJECTS,127,207,56,8
|
||||
RTEXT "0",IDC_GLOBAL_JSC_HEAP_OBJECTS,127,217,56,8
|
||||
RTEXT "0",IDC_PROTECTED_JSC_HEAP_OBJECTS,127,227,56,8
|
||||
RTEXT "Size",IDC_STATIC56,223,207,14,8
|
||||
RTEXT "Free",IDC_STATIC57,222,217,16,8
|
||||
RTEXT "0",IDC_JSC_HEAP_SIZE,270,207,56,8
|
||||
RTEXT "0",IDC_JSC_HEAP_FREE,270,217,56,8
|
||||
PUSHBUTTON "Purge Inactive Font Data",IDC_BUTTON5,293,415,95,14,WS_DISABLED
|
||||
LTEXT "Total Font Data Objects",IDC_STATIC,208,379,78,8
|
||||
LTEXT "Inactive Font Data Objects",IDC_STATIC,198,390,88,8
|
||||
LTEXT "Glyph Pages",IDC_STATIC,246,402,40,8
|
||||
RTEXT "0",IDC_TOTAL_FONT_OBJECTS,329,379,56,8
|
||||
RTEXT "0",IDC_INACTIVE_FONT_OBJECTS,329,390,56,8
|
||||
RTEXT "0",IDC_GLYPH_PAGES,329,402,56,8
|
||||
LTEXT "Page URL Mappings",IDC_STATIC,33,380,64,8
|
||||
LTEXT "Retained Page URLs",IDC_STATIC,31,390,66,8
|
||||
LTEXT "Site Icon Records",IDC_STATIC,40,400,57,8
|
||||
LTEXT "Site Icons with Data",IDC_STATIC,32,410,65,8
|
||||
RTEXT "0",IDC_PAGE_URL_MAPPINGS,101,380,52,8
|
||||
RTEXT "0",IDC_RETAINED_PAGE_URLS,101,390,52,8
|
||||
RTEXT "0",IDC_SITE_ICON_RECORDS,101,400,52,8
|
||||
RTEXT "0",IDC_SITE_ICONS_WITH_DATA,101,410,52,8
|
||||
END
|
||||
|
||||
IDD_AUTH DIALOGEX 0, 0, 231, 119
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Authentication Required"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Sign In",IDOK,116,98,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,174,98,50,14
|
||||
LTEXT "Realm",IDC_REALM_TEXT,67,21,157,8
|
||||
RTEXT "User Name:",IDC_STATIC,7,41,57,8
|
||||
EDITTEXT IDC_AUTH_USER,67,39,157,14,ES_AUTOHSCROLL
|
||||
RTEXT "Password:",IDC_STATIC,7,66,57,8
|
||||
EDITTEXT IDC_AUTH_PASSWORD,67,64,157,14,ES_PASSWORD | ES_AUTOHSCROLL
|
||||
END
|
||||
|
||||
IDD_PROXY DIALOGEX 0, 0, 310, 176
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Proxy Configuration"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,199,155,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,253,155,50,14
|
||||
CONTROL "Use system default proxy configuration.",IDC_PROXY_DEFAULT,
|
||||
"Button",BS_AUTORADIOBUTTON | WS_GROUP,22,15,226,10
|
||||
CONTROL "Use custom proxy configuration:",IDC_PROXY_CUSTOM,
|
||||
"Button",BS_AUTORADIOBUTTON,22,33,226,10
|
||||
CONTROL "Don't use proxy.",IDC_PROXY_DISABLE,"Button",BS_AUTORADIOBUTTON,22,117,226,10
|
||||
EDITTEXT IDC_PROXY_URL,76,52,193,14,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_PROXY_EXCLUDE,76,85,193,14,ES_AUTOHSCROLL
|
||||
LTEXT "URL:",IDC_STATIC,30,55,43,8,0,WS_EX_RIGHT
|
||||
LTEXT "Excude list:",IDC_STATIC,30,88,43,8,0,WS_EX_RIGHT
|
||||
LTEXT "Example: http://192.168.0.2:8000",IDC_STATIC,80,68,194,8
|
||||
LTEXT "Comma separated hostnames.",IDC_STATIC,80,101,194,8
|
||||
END
|
||||
|
||||
IDD_SERVER_TRUST DIALOGEX 0, 0, 319, 184
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Server Trust Evaluation Request"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Yes",IDOK,197,163,50,14
|
||||
PUSHBUTTON "No",IDCANCEL,262,163,50,14
|
||||
LTEXT "Certificate information",IDC_STATIC,7,7,294,17
|
||||
EDITTEXT IDC_SERVER_TRUST_TEXT,7,24,305,130,ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"PlaywrightLibResource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_ABOUTBOX, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
|
||||
IDD_CACHES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 394
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 449
|
||||
END
|
||||
|
||||
IDD_AUTH, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 224
|
||||
VERTGUIDE, 64
|
||||
VERTGUIDE, 67
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 92
|
||||
HORZGUIDE, 25
|
||||
HORZGUIDE, 50
|
||||
END
|
||||
|
||||
IDD_PROXY, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 303
|
||||
VERTGUIDE, 22
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 169
|
||||
END
|
||||
|
||||
IDD_SERVER_TRUST, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 312
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 177
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitmap
|
||||
//
|
||||
|
||||
IDB_TOOLBAR BITMAP "toolbar.bmp"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_APP_TITLE "Playwright"
|
||||
IDC_PLAYWRIGHT "Playwright"
|
||||
END
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "PlaywrightLibResource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_PLAYWRIGHT ICON "Playwright.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDC_PLAYWRIGHT MENU
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "New Window\tCtrl-N" IDM_NEW_WINDOW
|
||||
MENUITEM "Close\tCtrl-W", IDM_CLOSE_WINDOW
|
||||
END
|
||||
POPUP "&View"
|
||||
BEGIN
|
||||
MENUITEM "Actual Size\tCtrl+0", IDM_ACTUAL_SIZE
|
||||
MENUITEM "Zoom In\tCtrl++", IDM_ZOOM_IN
|
||||
MENUITEM "Zoom Out\tCtrl+-", IDM_ZOOM_OUT
|
||||
MENUITEM "Invert Colors", IDM_INVERT_COLORS
|
||||
END
|
||||
POPUP "&History"
|
||||
BEGIN
|
||||
MENUITEM "Reload\tCtrl-R", IDM_RELOAD
|
||||
MENUITEM "Back", IDM_HISTORY_BACKWARD
|
||||
MENUITEM "Forward", IDM_HISTORY_FORWARD
|
||||
END
|
||||
POPUP "D&evelop"
|
||||
BEGIN
|
||||
MENUITEM "Show Web Inspector", IDM_WEB_INSPECTOR
|
||||
END
|
||||
POPUP "&Help"
|
||||
BEGIN
|
||||
MENUITEM "&About ...", IDM_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDC_PLAYWRIGHT ACCELERATORS
|
||||
BEGIN
|
||||
"/", IDM_ABOUT, ASCII, ALT, NOINVERT
|
||||
"0", IDM_ACTUAL_SIZE, VIRTKEY, CONTROL, NOINVERT
|
||||
"?", IDM_ABOUT, ASCII, ALT, NOINVERT
|
||||
"R", IDM_RELOAD, VIRTKEY, CONTROL, NOINVERT
|
||||
"N", IDM_NEW_WINDOW, VIRTKEY, CONTROL, NOINVERT
|
||||
VK_ADD, IDM_ZOOM_IN, VIRTKEY, CONTROL, NOINVERT
|
||||
VK_OEM_MINUS, IDM_ZOOM_OUT, VIRTKEY, CONTROL, NOINVERT
|
||||
VK_OEM_PLUS, IDM_ZOOM_IN, VIRTKEY, CONTROL, NOINVERT
|
||||
VK_SUBTRACT, IDM_ZOOM_OUT, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
IDR_ACCELERATORS_PRE ACCELERATORS
|
||||
BEGIN
|
||||
"W", IDM_CLOSE_WINDOW, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUTBOX DIALOGEX 22, 17, 230, 41
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
ICON IDI_PLAYWRIGHT,IDC_MYICON,14,9,20,20
|
||||
LTEXT "Playwright Version 1.1",IDC_STATIC,49,10,119,8
|
||||
LTEXT "Copyright (C) 2015-2019",IDC_STATIC,49,20,119,8
|
||||
DEFPUSHBUTTON "OK",IDOK,186,10,30,11,WS_GROUP
|
||||
END
|
||||
|
||||
IDD_CACHES DIALOGEX 0, 0, 401, 456
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,287,435,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,344,435,50,14
|
||||
GROUPBOX "FastMalloc",IDC_STATIC,208,14,186,67
|
||||
GROUPBOX "WebCore Cache",IDC_STATIC,17,83,376,105
|
||||
GROUPBOX "JavaScript Heap",IDC_STATIC,18,193,376,168
|
||||
GROUPBOX "Site Icon Database",IDC_STATIC,18,366,142,65
|
||||
GROUPBOX "Font and Glyph Caches",IDC_STATIC,168,366,226,66
|
||||
GROUPBOX "CFURLCache",IDC_STATIC,7,14,197,67
|
||||
PUSHBUTTON "Empty URLCache",IDC_EMPTY_URL_CACHE,131,63,69,14,WS_DISABLED
|
||||
PUSHBUTTON "Return Free Memory",IDC_RETURN_FREE_MEMORY,308,63,76,14,WS_DISABLED
|
||||
PUSHBUTTON "Empty WebCore Cache",IDC_EMPTY_WEBCORE_CACHE,21,170,83,14,WS_DISABLED
|
||||
CONTROL "Disable WebCore Cache",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,119,172,93,10
|
||||
PUSHBUTTON "Garbage Collect JavaScript Objects",IDC_GC_JSC,253,343,135,14,WS_DISABLED
|
||||
RTEXT "Reserved VM",IDC_STATIC,212,26,67,9
|
||||
RTEXT "0",IDC_RESERVED_VM,290,26,94,8
|
||||
RTEXT "Committed VM",IDC_STATIC,211,39,67,8
|
||||
RTEXT "0",IDC_COMMITTED_VM,290,39,94,8
|
||||
RTEXT "Free List Bytes",IDC_STATIC,211,52,67,8
|
||||
RTEXT "0",IDC_FREE_LIST_BYTES,290,52,94,8
|
||||
RTEXT "Images",IDC_STATIC,37,106,24,8
|
||||
RTEXT "CSS",IDC_STATIC,47,116,14,8
|
||||
RTEXT "XSL",IDC_STATIC,49,126,12,8
|
||||
RTEXT "JavaScript",IDC_STATIC,27,135,34,8
|
||||
RTEXT "Total",IDC_STATIC,43,146,17,8
|
||||
LTEXT "Objects",IDC_STATIC,111,96,26,8
|
||||
LTEXT "Bytes",IDC_STATIC,175,96,19,8
|
||||
LTEXT "Live",IDC_STATIC,232,96,14,8
|
||||
LTEXT "Decoded",IDC_STATIC,284,96,29,8
|
||||
LTEXT "Purgeable",IDC_STATIC,351,96,33,8
|
||||
RTEXT "0",IDC_IMAGES_OBJECT_COUNT,100,106,32,8
|
||||
RTEXT "0",IDC_CSS_OBJECT_COUNT,100,116,32,8
|
||||
RTEXT "0",IDC_XSL_OBJECT_COUNT,100,126,32,8
|
||||
RTEXT "0",IDC_JSC_OBJECT_COUNT,100,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_OBJECT_COUNT,100,146,32,8
|
||||
RTEXT "0",IDC_IMAGES_BYTES,162,106,32,8
|
||||
RTEXT "0",IDC_CSS_BYTES,162,116,32,8
|
||||
RTEXT "0",IDC_XSL_BYTES,162,126,32,8
|
||||
RTEXT "0",IDC_JSC_BYTES,162,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_BYTES,162,146,32,8
|
||||
RTEXT "0",IDC_IMAGES_LIVE_COUNT,221,106,32,8
|
||||
RTEXT "0",IDC_CSS_LIVE_COUNT,221,116,32,8
|
||||
RTEXT "0",IDC_XSL_LIVE_COUNT,221,126,32,8
|
||||
RTEXT "0",IDC_JSC_LIVE_COUNT,221,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_LIVE_COUNT,221,146,32,8
|
||||
RTEXT "0",IDC_IMAGES_DECODED_COUNT,284,106,32,8
|
||||
RTEXT "0",IDC_CSS_DECODED_COUNT,284,116,32,8
|
||||
RTEXT "0",IDC_XSL_DECODED_COUNT,284,126,32,8
|
||||
RTEXT "0",IDC_JSC_DECODED_COUNT,284,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_DECODED,284,146,32,8
|
||||
RTEXT "0",IDC_IMAGES_PURGEABLE_COUNT,354,106,32,8
|
||||
RTEXT "0",IDC_CSS_PURGEABLE_COUNT,354,116,32,8
|
||||
RTEXT "0",IDC_XSL_PURGEABLE_COUNT,354,126,32,8
|
||||
RTEXT "0",IDC_JSC_PURGEABLE_COUNT,354,135,32,8
|
||||
RTEXT "0",IDC_TOTAL_PURGEABLE,354,146,32,8
|
||||
RTEXT "Total Objects",IDC_STATIC,63,207,44,8
|
||||
RTEXT "Global Objects",IDC_STATIC,56,217,51,8
|
||||
RTEXT "Protected Objects",IDC_STATIC,48,227,59,8
|
||||
RTEXT "0",IDC_TOTAL_JSC_HEAP_OBJECTS,127,207,56,8
|
||||
RTEXT "0",IDC_GLOBAL_JSC_HEAP_OBJECTS,127,217,56,8
|
||||
RTEXT "0",IDC_PROTECTED_JSC_HEAP_OBJECTS,127,227,56,8
|
||||
RTEXT "Size",IDC_STATIC56,223,207,14,8
|
||||
RTEXT "Free",IDC_STATIC57,222,217,16,8
|
||||
RTEXT "0",IDC_JSC_HEAP_SIZE,270,207,56,8
|
||||
RTEXT "0",IDC_JSC_HEAP_FREE,270,217,56,8
|
||||
PUSHBUTTON "Purge Inactive Font Data",IDC_BUTTON5,293,415,95,14,WS_DISABLED
|
||||
LTEXT "Total Font Data Objects",IDC_STATIC,208,379,78,8
|
||||
LTEXT "Inactive Font Data Objects",IDC_STATIC,198,390,88,8
|
||||
LTEXT "Glyph Pages",IDC_STATIC,246,402,40,8
|
||||
RTEXT "0",IDC_TOTAL_FONT_OBJECTS,329,379,56,8
|
||||
RTEXT "0",IDC_INACTIVE_FONT_OBJECTS,329,390,56,8
|
||||
RTEXT "0",IDC_GLYPH_PAGES,329,402,56,8
|
||||
LTEXT "Page URL Mappings",IDC_STATIC,33,380,64,8
|
||||
LTEXT "Retained Page URLs",IDC_STATIC,31,390,66,8
|
||||
LTEXT "Site Icon Records",IDC_STATIC,40,400,57,8
|
||||
LTEXT "Site Icons with Data",IDC_STATIC,32,410,65,8
|
||||
RTEXT "0",IDC_PAGE_URL_MAPPINGS,101,380,52,8
|
||||
RTEXT "0",IDC_RETAINED_PAGE_URLS,101,390,52,8
|
||||
RTEXT "0",IDC_SITE_ICON_RECORDS,101,400,52,8
|
||||
RTEXT "0",IDC_SITE_ICONS_WITH_DATA,101,410,52,8
|
||||
END
|
||||
|
||||
IDD_AUTH DIALOGEX 0, 0, 231, 119
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Authentication Required"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Sign In",IDOK,116,98,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,174,98,50,14
|
||||
LTEXT "Realm",IDC_REALM_TEXT,67,21,157,8
|
||||
RTEXT "User Name:",IDC_STATIC,7,41,57,8
|
||||
EDITTEXT IDC_AUTH_USER,67,39,157,14,ES_AUTOHSCROLL
|
||||
RTEXT "Password:",IDC_STATIC,7,66,57,8
|
||||
EDITTEXT IDC_AUTH_PASSWORD,67,64,157,14,ES_PASSWORD | ES_AUTOHSCROLL
|
||||
END
|
||||
|
||||
IDD_PROXY DIALOGEX 0, 0, 310, 176
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Proxy Configuration"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,199,155,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,253,155,50,14
|
||||
CONTROL "Use system default proxy configuration.",IDC_PROXY_DEFAULT,
|
||||
"Button",BS_AUTORADIOBUTTON | WS_GROUP,22,15,226,10
|
||||
CONTROL "Use custom proxy configuration:",IDC_PROXY_CUSTOM,
|
||||
"Button",BS_AUTORADIOBUTTON,22,33,226,10
|
||||
CONTROL "Don't use proxy.",IDC_PROXY_DISABLE,"Button",BS_AUTORADIOBUTTON,22,117,226,10
|
||||
EDITTEXT IDC_PROXY_URL,76,52,193,14,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_PROXY_EXCLUDE,76,85,193,14,ES_AUTOHSCROLL
|
||||
LTEXT "URL:",IDC_STATIC,30,55,43,8,0,WS_EX_RIGHT
|
||||
LTEXT "Excude list:",IDC_STATIC,30,88,43,8,0,WS_EX_RIGHT
|
||||
LTEXT "Example: http://192.168.0.2:8000",IDC_STATIC,80,68,194,8
|
||||
LTEXT "Comma separated hostnames.",IDC_STATIC,80,101,194,8
|
||||
END
|
||||
|
||||
IDD_SERVER_TRUST DIALOGEX 0, 0, 319, 184
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Server Trust Evaluation Request"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Yes",IDOK,197,163,50,14
|
||||
PUSHBUTTON "No",IDCANCEL,262,163,50,14
|
||||
LTEXT "Certificate information",IDC_STATIC,7,7,294,17
|
||||
EDITTEXT IDC_SERVER_TRUST_TEXT,7,24,305,130,ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | NOT WS_TABSTOP
|
||||
END
|
||||
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"PlaywrightLibResource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_ABOUTBOX, DIALOG
|
||||
BEGIN
|
||||
END
|
||||
|
||||
IDD_CACHES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 394
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 449
|
||||
END
|
||||
|
||||
IDD_AUTH, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 224
|
||||
VERTGUIDE, 64
|
||||
VERTGUIDE, 67
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 92
|
||||
HORZGUIDE, 25
|
||||
HORZGUIDE, 50
|
||||
END
|
||||
|
||||
IDD_PROXY, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 303
|
||||
VERTGUIDE, 22
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 169
|
||||
END
|
||||
|
||||
IDD_SERVER_TRUST, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 312
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 177
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitmap
|
||||
//
|
||||
|
||||
IDB_TOOLBAR BITMAP "toolbar.bmp"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_APP_TITLE "Playwright"
|
||||
IDC_PLAYWRIGHT "Playwright"
|
||||
END
|
||||
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <WebKit/WKCredential.h>
|
||||
#include <WebKit/WKFramePolicyListener.h>
|
||||
#include <WebKit/WKInspector.h>
|
||||
#include <WebKit/WKPagePrivate.h>
|
||||
#include <WebKit/WKProtectionSpace.h>
|
||||
#include <WebKit/WKProtectionSpaceCurl.h>
|
||||
#include <WebKit/WKWebsiteDataStoreRef.h>
|
||||
|
@ -102,6 +103,8 @@ WebKitBrowserWindow::WebKitBrowserWindow(BrowserWindowClient& client, HWND mainW
|
|||
policyClient.decidePolicyForResponse_deprecatedForUseWithV0 = decidePolicyForResponse;
|
||||
policyClient.decidePolicyForNavigationAction = decidePolicyForNavigationAction;
|
||||
WKPageSetPagePolicyClient(page, &policyClient.base);
|
||||
|
||||
WKPageSetControlledByAutomation(page, true);
|
||||
resetZoom();
|
||||
}
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче