Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion browser_patches/firefox/UPSTREAM_CONFIG.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
REMOTE_URL="https://github.com/mozilla-firefox/firefox"
BASE_BRANCH="release"
BASE_REVISION="c7fa3c91990bac266ee99a9e31863c202469f369"
BASE_REVISION="d4faced9e237d6431856c0873cb035cbbc25817b"
23 changes: 15 additions & 8 deletions browser_patches/firefox/juggler/NetworkObserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@ class NetworkRequest {
this.httpChannel = httpChannel;

const loadInfo = this.httpChannel.loadInfo;
const browsingContext = loadInfo?.frameBrowsingContext || loadInfo?.workerAssociatedBrowsingContext || loadInfo?.browsingContext;
const browsingContext = loadInfo?.frameBrowsingContext
|| loadInfo?.associatedBrowsingContext
|| loadInfo?.workerAssociatedBrowsingContext
|| loadInfo?.browsingContext;

this._frameId = helper.browsingContextToFrameId(browsingContext);

Expand Down Expand Up @@ -906,13 +909,18 @@ class ResponseStorage {
const encodingHeader = request.httpChannel.getResponseHeader("Content-Encoding");
encodings = encodingHeader.split(/\s*\t*,\s*\t*/);
}
this._responses.set(request.requestId, {body, encodings});
this._responses.set(request.requestId, {
body,
encodings,
httpChannel: encodings.length ? request.httpChannel : null,
});
this._totalSize += body.length;
if (this._totalSize > this._maxTotalSize) {
for (let [requestId, response] of this._responses) {
this._totalSize -= response.body.length;
response.body = '';
response.evicted = true;
response.httpChannel = null;
if (this._totalSize < this._maxTotalSize)
break;
}
Expand All @@ -928,7 +936,7 @@ class ResponseStorage {
let result = response.body;
if (response.encodings && response.encodings.length) {
for (const encoding of response.encodings)
result = convertString(result, encoding, 'uncompressed');
result = convertString(result, encoding, 'uncompressed', response.httpChannel);
}
return {base64body: btoa(result)};
}
Expand Down Expand Up @@ -984,7 +992,7 @@ function setPostData(httpChannel, postData, headers) {
httpChannel.explicitSetUploadStream(synthesized, contentType, -1, httpChannel.requestMethod, false);
}

function convertString(s, source, dest) {
function convertString(s, source, dest, request) {
const is = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
Ci.nsIStringInputStream
);
Expand Down Expand Up @@ -1018,9 +1026,9 @@ function convertString(s, source, dest) {
listener,
null
);
converter.onStartRequest(null, null);
converter.onDataAvailable(null, is, 0, s.length);
converter.onStopRequest(null, null, null);
converter.onStartRequest(request, null);
converter.onDataAvailable(request, is, 0, s.length);
converter.onStopRequest(request, null, null);
return result.join('');
}

Expand All @@ -1047,4 +1055,3 @@ PageNetwork.Events = {
RequestFinished: Symbol('PageNetwork.Events.RequestFinished'),
RequestFailed: Symbol('PageNetwork.Events.RequestFailed'),
};

67 changes: 59 additions & 8 deletions browser_patches/firefox/juggler/TargetRegistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ let globalTabAndWindowActivationChain = Promise.resolve();
let didCreateFirstPage = false;
let globalNewPageChain = Promise.resolve();

let globalContextCloseCounter = 0;

class DownloadInterceptor {
constructor(registry) {
this._registry = registry
Expand Down Expand Up @@ -414,6 +416,8 @@ export class PageTarget {
this._browserContext = browserContext;
this._viewportSize = undefined;
this._deviceScaleFactor = undefined;
this._screenSize = undefined;
this._isMobile = undefined;
this._zoom = 1;
this._initialDPPX = this._linkedBrowser.browsingContext.overrideDPPX;
this._url = 'about:blank';
Expand Down Expand Up @@ -447,6 +451,7 @@ export class PageTarget {
this._registry._browserToTarget.set(this._linkedBrowser, this);

const browserId = this._linkedBrowser.browsingContext.browserId;
this._browserId = browserId;
this._registry._browserIdToTarget.set(browserId, this);
const actor = this._registry._browserIdToActor.get(browserId);
if (actor)
Expand All @@ -456,7 +461,7 @@ export class PageTarget {
}

async activateAndRun(callback = () => {}, { muteNotificationsPopup = false } = {}) {
const ownerWindow = this._tab.linkedBrowser.ownerGlobal;
const ownerWindow = this._tab.linkedBrowser.documentGlobal;
const tabBrowser = ownerWindow.gBrowser;
// Serialize all tab-switching commands per tabbed browser
// to disallow concurrent tab switching.
Expand Down Expand Up @@ -528,6 +533,7 @@ export class PageTarget {
this.updateLanguageOverride(browsingContext);
this.updatePlatform(browsingContext);
this.updateDPPXOverride(browsingContext);
this.updateScreenEmulation(browsingContext);
this.updateZoom(browsingContext);
this.updateEmulatedMedia(browsingContext);
this.updateColorSchemeOverride(browsingContext);
Expand Down Expand Up @@ -568,7 +574,8 @@ export class PageTarget {
}

updateLanguageOverride(browsingContext = undefined) {
(browsingContext || this._linkedBrowser.browsingContext).languageOverride = this._browserContext.languageOverride;
browsingContext ||= this._linkedBrowser.browsingContext;
browsingContext.languageOverride = this._browserContext.languageOverride || '';
}

updatePlatform(browsingContext = undefined) {
Expand All @@ -582,6 +589,32 @@ export class PageTarget {
browsingContext.overrideDPPX = dppx;
}

updateScreenEmulation(browsingContext = undefined) {
browsingContext ||= this._linkedBrowser.browsingContext;
const screenSize = this._screenSize || this._browserContext.screenSize;
const isMobile = this._isMobile ?? this._browserContext.isMobile;

// `isRDMPane` is a "mobile mode": viewport media queries, touch/pointer
// support, viewport media queries.
browsingContext.inRDMPane = !!isMobile;

// Set window.screen.width and window.screen.height
if (screenSize) {
browsingContext.setScreenAreaOverride(screenSize.width, screenSize.height);
} else {
browsingContext.resetScreenAreaOverride();
}

// Derive the orientation from the emulated screen size and keep it in sync
// with the screen area override.
if (screenSize && isMobile) {
const isPortrait = screenSize.height >= screenSize.width;
browsingContext.setOrientationOverride(isPortrait ? 'portrait-primary' : 'landscape-primary', isPortrait ? 0 : 90);
} else {
browsingContext.resetOrientationOverride();
}
}

async updateZoom(browsingContext = undefined) {
browsingContext ||= this._linkedBrowser.browsingContext;
// Update dpr first, and then UI zoom.
Expand Down Expand Up @@ -611,6 +644,7 @@ export class PageTarget {
async updateViewportSize() {
await waitForWindowReady(this._window);
this.updateDPPXOverride();
this.updateScreenEmulation();

// Viewport size is defined by three arguments:
// 1. default size. Could be explicit if set as part of `window.open` call, e.g.
Expand All @@ -630,7 +664,6 @@ export class PageTarget {
this._linkedBrowser.closest('.browserStack').style.setProperty('overflow', 'auto');
this._linkedBrowser.closest('.browserStack').style.setProperty('contain', 'size');
this._linkedBrowser.closest('.browserStack').style.setProperty('scrollbar-width', 'none');
this._linkedBrowser.browsingContext.inRDMPane = true;

const stackRect = this._linkedBrowser.closest('.browserStack').getBoundingClientRect();
const toolbarTop = stackRect.y;
Expand All @@ -644,7 +677,6 @@ export class PageTarget {
this._linkedBrowser.closest('.browserStack').style.removeProperty('overflow');
this._linkedBrowser.closest('.browserStack').style.removeProperty('contain');
this._linkedBrowser.closest('.browserStack').style.removeProperty('scrollbar-width');
this._linkedBrowser.browsingContext.inRDMPane = false;

const actualSize = this._linkedBrowser.getBoundingClientRect();
await this._channel.connect('').send('awaitViewportDimensions', {
Expand Down Expand Up @@ -706,9 +738,11 @@ export class PageTarget {
await this._channel.connect('').send('setInterceptFileChooserDialog', enabled).catch(e => {});
}

async setViewportSize(viewportSize, deviceScaleFactor) {
async setViewportSize(viewportSize, deviceScaleFactor, screenSize, isMobile) {
this._viewportSize = viewportSize;
this._deviceScaleFactor = deviceScaleFactor;
this._screenSize = screenSize;
this._isMobile = isMobile;
await this.updateViewportSize();
}

Expand Down Expand Up @@ -749,7 +783,7 @@ export class PageTarget {
}

_updateCrossProcessCookie() {
Services.ppmm.sharedData.set('juggler:page-cookie-' + this._linkedBrowser.browsingContext.browserId, this.crossProcessCookie);
Services.ppmm.sharedData.set('juggler:page-cookie-' + this._browserId, this.crossProcessCookie);
Services.ppmm.sharedData.flush();
}

Expand Down Expand Up @@ -787,7 +821,7 @@ export class PageTarget {
if (width < 10 || width > 10000 || height < 10 || height > 10000)
throw new Error("Invalid size");

const docShell = this._gBrowser.ownerGlobal.docShell;
const docShell = this._gBrowser.documentGlobal.docShell;
// Exclude address bar and navigation control from the video.
const rect = this.linkedBrowser().getBoundingClientRect();
const devicePixelRatio = this._window.devicePixelRatio;
Expand Down Expand Up @@ -841,7 +875,9 @@ export class PageTarget {
this.stopScreencast();
this._browserContext.pages.delete(this);
this._registry._browserToTarget.delete(this._linkedBrowser);
this._registry._browserIdToTarget.delete(this._linkedBrowser.browsingContext.browserId);
this._registry._browserIdToTarget.delete(this._browserId);
Services.ppmm.sharedData.delete('juggler:page-cookie-' + this._browserId);
Services.ppmm.sharedData.flush();
try {
helper.removeListeners(this._eventListeners);
} catch (e) {
Expand Down Expand Up @@ -917,6 +953,8 @@ class BrowserContext {
this.downloadOptions = undefined;
this.defaultViewportSize = undefined;
this.deviceScaleFactor = undefined;
this.screenSize = undefined;
this.isMobile = undefined;
this.defaultUserAgent = null;
this.timezoneOverride = undefined;
this.languageOverride = undefined;
Expand Down Expand Up @@ -983,7 +1021,18 @@ class BrowserContext {
}
this._registry._browserContextIdToBrowserContext.delete(this.browserContextId);
this._registry._userContextIdToBrowserContext.delete(this.userContextId);
Services.ppmm.sharedData.delete('juggler:context-cookie-' + this.userContextId);
Services.ppmm.sharedData.flush();
this._registry._updateProxiesWithSameAuthCacheAndDifferentCredentials();
// Clean the memory. on every 10'th context closure. On M1 Max, this method
// takes ~150ms, so we spread them out.
if (++globalContextCloseCounter % 10 === 0) {
await new Promise(x => {
Cc["@mozilla.org/memory-reporter-manager;1"]
.getService(Ci.nsIMemoryReporterManager)
.minimizeMemoryUsage(x);
});
}
}

setProxy(proxy) {
Expand Down Expand Up @@ -1056,6 +1105,8 @@ class BrowserContext {
async setDefaultViewport(viewport) {
this.defaultViewportSize = viewport ? viewport.viewportSize : undefined;
this.deviceScaleFactor = viewport ? viewport.deviceScaleFactor : undefined;
this.screenSize = viewport ? viewport.screenSize : undefined;
this.isMobile = viewport ? viewport.isMobile : undefined;
await Promise.all(Array.from(this.pages).map(page => page.updateViewportSize()));
}

Expand Down
Loading
Loading