Skip to content

Commit 0c4bed1

Browse files
authored
chore: update browser patches as of Mar 14, 2023 (microsoft#22603)
Internal commit reference: microsoft/playwright-browsers@e994525
1 parent e6dfaa3 commit 0c4bed1

14 files changed

+1232
-1317
lines changed
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
REMOTE_URL="https://github.com/mozilla/gecko-dev"
22
BASE_BRANCH="release"
3-
BASE_REVISION="fe696abae79ffbfa13037a5d9bd3a2e2b293f2af"
3+
BASE_REVISION="250178df19caa1fb25bfa0e35728426cfbde95f8"

browser_patches/firefox/juggler/JugglerFrameParent.jsm

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ class JugglerFrameParent extends JSWindowActorParent {
1515
receiveMessage() { }
1616

1717
async actorCreated() {
18+
// Actors are registered per the WindowGlobalParent / WindowGlobalChild pair. We are only
19+
// interested in those WindowGlobalParent actors that are matching current browsingContext
20+
// window global.
21+
// See https://github.com/mozilla/gecko-dev/blob/cd2121e7d83af1b421c95e8c923db70e692dab5f/testing/mochitest/BrowserTestUtils/BrowserTestUtilsParent.sys.mjs#L15
22+
if (!this.manager?.isCurrentGlobal)
23+
return;
24+
1825
// Only interested in main frames for now.
1926
if (this.browsingContext.parent)
2027
return;

browser_patches/firefox/juggler/NetworkObserver.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,9 @@ class NetworkRequest {
300300
}
301301
if (!credentials)
302302
return false;
303+
const origin = aChannel.URI.scheme + '://' + aChannel.URI.hostPort;
304+
if (credentials.origin && origin.toLowerCase() !== credentials.origin.toLowerCase())
305+
return false;
303306
authInfo.username = credentials.username;
304307
authInfo.password = credentials.password;
305308
// This will produce a new request with respective auth header set.
@@ -464,9 +467,11 @@ class NetworkRequest {
464467
}
465468

466469
_fallThroughInterceptController() {
467-
if (!this._previousCallbacks || !(this._previousCallbacks instanceof Ci.nsINetworkInterceptController))
470+
try {
471+
return this._previousCallbacks?.getInterface(Ci.nsINetworkInterceptController);
472+
} catch (e) {
468473
return undefined;
469-
return this._previousCallbacks.getInterface(Ci.nsINetworkInterceptController);
474+
}
470475
}
471476

472477
_sendOnRequest(isIntercepted) {

browser_patches/firefox/juggler/TargetRegistry.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ class PageTarget {
386386
const tabBrowser = ownerWindow.gBrowser;
387387
// Serialize all tab-switching commands per tabbed browser
388388
// to disallow concurrent tab switching.
389-
tabBrowser.__serializedChain = (tabBrowser.__serializedChain ?? Promise.resolve()).then(async () => {
389+
const result = (tabBrowser.__serializedChain ?? Promise.resolve()).then(async () => {
390390
this._window.focus();
391391
if (tabBrowser.selectedTab !== this._tab) {
392392
const promise = helper.awaitEvent(ownerWindow, 'TabSwitchDone');
@@ -395,7 +395,8 @@ class PageTarget {
395395
}
396396
await callback();
397397
});
398-
return tabBrowser.__serializedChain;
398+
tabBrowser.__serializedChain = result.catch(error => { /* swallow errors to keep chain running */ });
399+
return result;
399400
}
400401

401402
frameIdToBrowsingContext(frameId) {
@@ -702,7 +703,17 @@ class PageTarget {
702703
screencastService.stopVideoRecording(screencastId);
703704
}
704705

706+
ensureContextMenuClosed() {
707+
// Close context menu, if any, since it might capture mouse events on Linux
708+
// and prevent browser shutdown on MacOS.
709+
const doc = this._linkedBrowser.ownerDocument;
710+
const contextMenu = doc.getElementById("contentAreaContextMenu");
711+
if (contextMenu)
712+
contextMenu.hidePopup();
713+
}
714+
705715
dispose() {
716+
this.ensureContextMenuClosed();
706717
this._disposed = true;
707718
if (this._videoRecordingInfo)
708719
this._stopVideoRecording();

browser_patches/firefox/juggler/content/FrameTree.js

+58-49
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ const {Runtime} = ChromeUtils.import('chrome://juggler/content/content/Runtime.j
1414
const helper = new Helper();
1515

1616
class FrameTree {
17-
constructor(rootDocShell) {
17+
constructor(rootBrowsingContext) {
1818
helper.decorateAsEventEmitter(this);
1919

20-
this._browsingContextGroup = rootDocShell.browsingContext.group;
20+
this._rootBrowsingContext = rootBrowsingContext;
21+
22+
this._browsingContextGroup = rootBrowsingContext.group;
2123
if (!this._browsingContextGroup.__jugglerFrameTrees)
2224
this._browsingContextGroup.__jugglerFrameTrees = new Set();
2325
this._browsingContextGroup.__jugglerFrameTrees.add(this);
@@ -29,12 +31,14 @@ class FrameTree {
2931

3032
this._runtime = new Runtime(false /* isWorker */);
3133
this._workers = new Map();
32-
this._docShellToFrame = new Map();
3334
this._frameIdToFrame = new Map();
3435
this._pageReady = false;
3536
this._javaScriptDisabled = false;
36-
this._mainFrame = this._createFrame(rootDocShell);
37-
const webProgress = rootDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
37+
for (const browsingContext of helper.collectAllBrowsingContexts(rootBrowsingContext))
38+
this._createFrame(browsingContext);
39+
this._mainFrame = this.frameForBrowsingContext(rootBrowsingContext);
40+
41+
const webProgress = rootBrowsingContext.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
3842
.getInterface(Ci.nsIWebProgress);
3943
this.QueryInterface = ChromeUtils.generateQI([
4044
Ci.nsIWebProgressListener,
@@ -58,16 +62,20 @@ class FrameTree {
5862
Ci.nsIWebProgress.NOTIFY_LOCATION;
5963
this._eventListeners = [
6064
helper.addObserver((docShell, topic, loadIdentifier) => {
61-
const frame = this._docShellToFrame.get(docShell);
65+
const frame = this.frameForDocShell(docShell);
6266
if (!frame)
6367
return;
6468
frame._pendingNavigationId = helper.toProtocolNavigationId(loadIdentifier);
6569
this.emit(FrameTree.Events.NavigationStarted, frame);
6670
}, 'juggler-navigation-started-renderer'),
6771
helper.addObserver(this._onDOMWindowCreated.bind(this), 'content-document-global-created'),
6872
helper.addObserver(this._onDOMWindowCreated.bind(this), 'juggler-dom-window-reused'),
69-
helper.addObserver(subject => this._onDocShellCreated(subject.QueryInterface(Ci.nsIDocShell)), 'webnavigation-create'),
70-
helper.addObserver(subject => this._onDocShellDestroyed(subject.QueryInterface(Ci.nsIDocShell)), 'webnavigation-destroy'),
73+
helper.addObserver((browsingContext, topic, why) => {
74+
this._onBrowsingContextAttached(browsingContext);
75+
}, 'browsing-context-attached'),
76+
helper.addObserver((browsingContext, topic, why) => {
77+
this._onBrowsingContextDetached(browsingContext);
78+
}, 'browsing-context-discarded'),
7179
helper.addProgressListener(webProgress, this, flags),
7280
];
7381

@@ -114,8 +122,7 @@ class FrameTree {
114122
return null;
115123
if (!workerDebugger.window)
116124
return null;
117-
const docShell = workerDebugger.window.docShell;
118-
return this._docShellToFrame.get(docShell) || null;
125+
return this.frameForDocShell(workerDebugger.window.docShell);
119126
}
120127

121128
_onDOMWindowCreated(window) {
@@ -127,7 +134,7 @@ class FrameTree {
127134
window.windowUtils.addSheet(sheet, styleSheetService.AGENT_SHEET);
128135
window[this._addedScrollbarsStylesheetSymbol] = true;
129136
}
130-
const frame = this._docShellToFrame.get(window.docShell) || null;
137+
const frame = this.frameForDocShell(window.docShell);
131138
if (!frame)
132139
return;
133140
frame._onGlobalObjectCleared();
@@ -202,8 +209,18 @@ class FrameTree {
202209
frame._addBinding(worldName, name, script);
203210
}
204211

212+
frameForBrowsingContext(browsingContext) {
213+
if (!browsingContext)
214+
return null;
215+
const frameId = helper.browsingContextToFrameId(browsingContext);
216+
return this._frameIdToFrame.get(frameId) ?? null;
217+
}
218+
205219
frameForDocShell(docShell) {
206-
return this._docShellToFrame.get(docShell) || null;
220+
if (!docShell)
221+
return null;
222+
const frameId = helper.browsingContextToFrameId(docShell.browsingContext);
223+
return this._frameIdToFrame.get(frameId) ?? null;
207224
}
208225

209226
frame(frameId) {
@@ -246,9 +263,9 @@ class FrameTree {
246263
return;
247264

248265
const docShell = event.target.ownerGlobal.docShell;
249-
const frame = this._docShellToFrame.get(docShell);
266+
const frame = this.frameForDocShell(docShell);
250267
if (!frame) {
251-
dump(`WARNING: ${event.type} for unknown frame ${docShell.browsingContext.id}\n`);
268+
dump(`WARNING: ${event.type} for unknown frame ${helper.browsingContextToFrameId(docShell.browsingContext)}\n`);
252269
return;
253270
}
254271
if (frame._pendingNavigationId) {
@@ -292,7 +309,7 @@ class FrameTree {
292309
return;
293310
const channel = request.QueryInterface(Ci.nsIChannel);
294311
const docShell = progress.DOMWindow.docShell;
295-
const frame = this._docShellToFrame.get(docShell);
312+
const frame = this.frameForDocShell(docShell);
296313
if (!frame)
297314
return;
298315

@@ -317,38 +334,37 @@ class FrameTree {
317334

318335
onLocationChange(progress, request, location, flags) {
319336
const docShell = progress.DOMWindow.docShell;
320-
const frame = this._docShellToFrame.get(docShell);
337+
const frame = this.frameForDocShell(docShell);
321338
const sameDocumentNavigation = !!(flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT);
322339
if (frame && sameDocumentNavigation) {
323340
frame._url = location.spec;
324341
this.emit(FrameTree.Events.SameDocumentNavigation, frame);
325342
}
326343
}
327344

328-
_onDocShellCreated(docShell) {
329-
// Bug 1142752: sometimes, the docshell appears to be immediately
330-
// destroyed, bailout early to prevent random exceptions.
331-
if (docShell.isBeingDestroyed())
345+
_onBrowsingContextAttached(browsingContext) {
346+
// If this browsing context doesn't belong to our frame tree - do nothing.
347+
if (browsingContext.top !== this._rootBrowsingContext)
332348
return;
333-
// If this docShell doesn't belong to our frame tree - do nothing.
334-
let root = docShell;
335-
while (root.parent)
336-
root = root.parent;
337-
if (root === this._mainFrame._docShell)
338-
this._createFrame(docShell);
349+
this._createFrame(browsingContext);
350+
}
351+
352+
_onBrowsingContextDetached(browsingContext) {
353+
const frame = this.frameForBrowsingContext(browsingContext);
354+
if (frame)
355+
this._detachFrame(frame);
339356
}
340357

341-
_createFrame(docShell) {
342-
const parentFrame = this._docShellToFrame.get(docShell.parent) || null;
358+
_createFrame(browsingContext) {
359+
const parentFrame = this.frameForBrowsingContext(browsingContext.parent);
343360
if (!parentFrame && this._mainFrame) {
344361
dump(`WARNING: found docShell with the same root, but no parent!\n`);
345362
return;
346363
}
347-
const frame = new Frame(this, this._runtime, docShell, parentFrame);
348-
this._docShellToFrame.set(docShell, frame);
364+
const frame = new Frame(this, this._runtime, browsingContext, parentFrame);
349365
this._frameIdToFrame.set(frame.id(), frame);
350-
if (docShell.domWindow && docShell.domWindow.location)
351-
frame._url = docShell.domWindow.location.href;
366+
if (browsingContext.docShell?.domWindow && browsingContext.docShell?.domWindow.location)
367+
frame._url = browsingContext.docShell.domWindow.location.href;
352368
this.emit(FrameTree.Events.FrameAttached, frame);
353369
// Create execution context **after** reporting frame.
354370
// This is our protocol contract.
@@ -357,12 +373,6 @@ class FrameTree {
357373
return frame;
358374
}
359375

360-
_onDocShellDestroyed(docShell) {
361-
const frame = this._docShellToFrame.get(docShell);
362-
if (frame)
363-
this._detachFrame(frame);
364-
}
365-
366376
_detachFrame(frame) {
367377
// Detach all children first
368378
for (const subframe of frame._children)
@@ -372,7 +382,6 @@ class FrameTree {
372382
// as it confuses the client.
373383
return;
374384
}
375-
this._docShellToFrame.delete(frame._docShell);
376385
this._frameIdToFrame.delete(frame.id());
377386
if (frame._parentFrame)
378387
frame._parentFrame._children.delete(frame);
@@ -409,12 +418,12 @@ class IsolatedWorld {
409418
}
410419

411420
class Frame {
412-
constructor(frameTree, runtime, docShell, parentFrame) {
421+
constructor(frameTree, runtime, browsingContext, parentFrame) {
413422
this._frameTree = frameTree;
414423
this._runtime = runtime;
415-
this._docShell = docShell;
424+
this._browsingContext = browsingContext;
416425
this._children = new Set();
417-
this._frameId = helper.browsingContextToFrameId(this._docShell.browsingContext);
426+
this._frameId = helper.browsingContextToFrameId(browsingContext);
418427
this._parentFrame = null;
419428
this._url = '';
420429
if (parentFrame) {
@@ -556,7 +565,7 @@ class Frame {
556565

557566
_onGlobalObjectCleared() {
558567
const webSocketService = this._frameTree._webSocketEventService;
559-
if (this._webSocketListenerInnerWindowId)
568+
if (this._webSocketListenerInnerWindowId && webSocketService.hasListenerFor(this._webSocketListenerInnerWindowId))
560569
webSocketService.removeListener(this._webSocketListenerInnerWindowId, this._webSocketListener);
561570
this._webSocketListenerInnerWindowId = this.domWindow().windowGlobalChild.innerWindowId;
562571
webSocketService.addListener(this._webSocketListenerInnerWindowId, this._webSocketListener);
@@ -591,8 +600,8 @@ class Frame {
591600
}
592601

593602
_updateJavaScriptDisabled() {
594-
if (this._docShell.browsingContext.currentWindowContext)
595-
this._docShell.browsingContext.currentWindowContext.allowJavascript = !this._frameTree._javaScriptDisabled;
603+
if (this._browsingContext.currentWindowContext)
604+
this._browsingContext.currentWindowContext.allowJavascript = !this._frameTree._javaScriptDisabled;
596605
}
597606

598607
mainExecutionContext() {
@@ -603,7 +612,7 @@ class Frame {
603612
if (!this._textInputProcessor) {
604613
this._textInputProcessor = Cc["@mozilla.org/text-input-processor;1"].createInstance(Ci.nsITextInputProcessor);
605614
}
606-
this._textInputProcessor.beginInputTransactionForTests(this._docShell.DOMWindow);
615+
this._textInputProcessor.beginInputTransactionForTests(this.docShell().DOMWindow);
607616
return this._textInputProcessor;
608617
}
609618

@@ -616,15 +625,15 @@ class Frame {
616625
}
617626

618627
docShell() {
619-
return this._docShell;
628+
return this._browsingContext.docShell;
620629
}
621630

622631
domWindow() {
623-
return this._docShell.domWindow;
632+
return this.docShell()?.domWindow;
624633
}
625634

626635
name() {
627-
const frameElement = this._docShell.domWindow.frameElement;
636+
const frameElement = this.domWindow()?.frameElement;
628637
let name = '';
629638
if (frameElement)
630639
name = frameElement.getAttribute('name') || frameElement.getAttribute('id') || '';

browser_patches/firefox/juggler/content/Runtime.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,9 @@ class ExecutionContext {
311311
this._id = generateId();
312312
this._auxData = auxData;
313313
this._jsonStringifyObject = this._debuggee.executeInGlobal(`((stringify, object) => {
314-
const oldToJSON = Date.prototype.toJSON;
315-
Date.prototype.toJSON = undefined;
314+
const oldToJSON = Date.prototype?.toJSON;
315+
if (oldToJSON)
316+
Date.prototype.toJSON = undefined;
316317
const oldArrayToJSON = Array.prototype.toJSON;
317318
const oldArrayHadToJSON = Array.prototype.hasOwnProperty('toJSON');
318319
if (oldArrayHadToJSON)
@@ -325,7 +326,8 @@ class ExecutionContext {
325326
return value;
326327
});
327328
328-
Date.prototype.toJSON = oldToJSON;
329+
if (oldToJSON)
330+
Date.prototype.toJSON = oldToJSON;
329331
if (oldArrayHadToJSON)
330332
Array.prototype.toJSON = oldArrayToJSON;
331333

browser_patches/firefox/juggler/content/main.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function initialize(browsingContext, docShell, actor) {
8585
docShell.overrideHasFocus = true;
8686
docShell.forceActiveState = true;
8787
docShell.disallowBFCache = true;
88-
data.frameTree = new FrameTree(docShell);
88+
data.frameTree = new FrameTree(browsingContext);
8989
for (const [name, value] of Object.entries(contextCrossProcessCookie.settings)) {
9090
if (value !== undefined)
9191
applySetting[name](value);

browser_patches/firefox/juggler/protocol/BrowserHandler.js

+6
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ class BrowserHandler {
152152
this._targetRegistry.browserContextForId(browserContextId).extraHTTPHeaders = headers;
153153
}
154154

155+
['Browser.clearCache']() {
156+
// Clearing only the context cache does not work: https://bugzilla.mozilla.org/show_bug.cgi?id=1819147
157+
Services.cache2.clear();
158+
ChromeUtils.clearStyleSheetCache();
159+
}
160+
155161
['Browser.setHTTPCredentials']({browserContextId, credentials}) {
156162
this._targetRegistry.browserContextForId(browserContextId).httpCredentials = nullToUndefined(credentials);
157163
}

0 commit comments

Comments
 (0)