chore: update browser patches as of Dec 13, 2022 (#20297)

This commit is contained in:
Andrey Lushnikov 2023-01-23 11:29:48 -08:00 коммит произвёл GitHub
Родитель ba0189f8d7
Коммит 6c5317bd31
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
27 изменённых файлов: 2520 добавлений и 2047 удалений

Просмотреть файл

@ -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();
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу