browser(firefox): manage scripts to evaluate on load on front-end (#12101)

This commit is contained in:
Pavel Feldman 2022-02-14 20:32:12 -08:00 committed by GitHub
parent e9a135406c
commit 618cc66c8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 90 additions and 68 deletions

View File

@ -1,2 +1,2 @@
1316
Changed: aslushnikov@gmail.com Wed Jan 26 17:24:09 MST 2022
1317
Changed: pavel.feldman@gmail.com Mon 14 Feb 2022 03:52:34 PM PST

View File

@ -144,7 +144,7 @@ class TargetRegistry {
return;
return {
scriptsToEvaluateOnNewDocument: target.browserContext().scriptsToEvaluateOnNewDocument,
initScripts: target.browserContext().initScripts,
bindings: target.browserContext().bindings,
settings: target.browserContext().settings,
};
@ -361,6 +361,7 @@ class PageTarget {
this._screencastRecordingInfo = undefined;
this._dialogs = new Map();
this.forcedColors = 'no-override';
this._pageInitScripts = [];
const navigationListener = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
@ -523,8 +524,13 @@ class PageTarget {
await this._channel.connect('').send('ensurePermissions', {}).catch(e => void e);
}
async addScriptToEvaluateOnNewDocument(script) {
await this._channel.connect('').send('addScriptToEvaluateOnNewDocument', script).catch(e => void e);
async setInitScripts(scripts) {
this._pageInitScripts = scripts;
await this.pushInitScripts();
}
async pushInitScripts() {
await this._channel.connect('').send('setInitScripts', [...this._browserContext.initScripts, ...this._pageInitScripts]).catch(e => void e);
}
async addBinding(worldName, name, script) {
@ -708,7 +714,7 @@ class BrowserContext {
this.forcedColors = 'no-override';
this.reducedMotion = 'none';
this.videoRecordingOptions = undefined;
this.scriptsToEvaluateOnNewDocument = [];
this.initScripts = [];
this.bindings = [];
this.settings = {};
this.pages = new Set();
@ -804,9 +810,9 @@ class BrowserContext {
await Promise.all(Array.from(this.pages).map(page => page.updateViewportSize()));
}
async addScriptToEvaluateOnNewDocument(script) {
this.scriptsToEvaluateOnNewDocument.push(script);
await Promise.all(Array.from(this.pages).map(page => page.addScriptToEvaluateOnNewDocument(script)));
async setInitScripts(scripts) {
this.initScripts = scripts;
await Promise.all(Array.from(this.pages).map(page => page.pushInitScripts()));
}
async addBinding(worldName, name, script) {

View File

@ -73,15 +73,20 @@ class FrameTree {
return this._runtime;
}
addScriptToEvaluateOnNewDocument(script, worldName) {
worldName = worldName || '';
const existing = this._isolatedWorlds.has(worldName);
const world = this._ensureWorld(worldName);
world._scriptsToEvaluateOnNewDocument.push(script);
// FIXME: 'should inherit http credentials from browser context' fails without this
if (worldName && !existing) {
for (const frame of this.frames())
frame._createIsolatedContext(worldName);
setInitScripts(scripts) {
for (const world of this._isolatedWorlds.values())
world._scriptsToEvaluateOnNewDocument = [];
for (let { worldName, script } of scripts) {
worldName = worldName || '';
const existing = this._isolatedWorlds.has(worldName);
const world = this._ensureWorld(worldName);
world._scriptsToEvaluateOnNewDocument.push(script);
// FIXME: 'should inherit http credentials from browser context' fails without this
if (worldName && !existing) {
for (const frame of this.frames())
frame._createIsolatedContext(worldName);
}
}
}

View File

@ -134,7 +134,6 @@ class PageAgent {
this._runtime.events.onBindingCalled(this._onBindingCalled.bind(this)),
browserChannel.register('page', {
addBinding: ({ worldName, name, script }) => this._frameTree.addBinding(worldName, name, script),
addScriptToEvaluateOnNewDocument: ({script, worldName}) => this._frameTree.addScriptToEvaluateOnNewDocument(script, worldName),
adoptNode: this._adoptNode.bind(this),
crash: this._crash.bind(this),
describeNode: this._describeNode.bind(this),

View File

@ -84,11 +84,10 @@ function initialize() {
if (!response)
return;
const {
scriptsToEvaluateOnNewDocument = [],
initScripts = [],
bindings = [],
settings = {}
} = response || {};
// Enforce focused state for all top level documents.
docShell.overrideHasFocus = true;
docShell.forceActiveState = true;
@ -99,14 +98,13 @@ function initialize() {
}
for (const { worldName, name, script } of bindings)
frameTree.addBinding(worldName, name, script);
for (const script of scriptsToEvaluateOnNewDocument)
frameTree.addScriptToEvaluateOnNewDocument(script);
frameTree.setInitScripts(initScripts);
pageAgent = new PageAgent(messageManager, channel, frameTree);
channel.register('', {
addScriptToEvaluateOnNewDocument(script) {
frameTree.addScriptToEvaluateOnNewDocument(script);
setInitScripts(scripts) {
frameTree.setInitScripts(scripts);
},
addBinding({worldName, name, script}) {

View File

@ -253,8 +253,8 @@ class BrowserHandler {
await this._targetRegistry.browserContextForId(browserContextId).applySetting('scrollbarsHidden', nullToUndefined(hidden));
}
async ['Browser.addScriptToEvaluateOnNewDocument']({browserContextId, script}) {
await this._targetRegistry.browserContextForId(browserContextId).addScriptToEvaluateOnNewDocument(script);
async ['Browser.setInitScripts']({browserContextId, scripts}) {
await this._targetRegistry.browserContextForId(browserContextId).setInitScripts(scripts);
}
async ['Browser.addBinding']({browserContextId, worldName, name, script}) {

View File

@ -334,8 +334,8 @@ class PageHandler {
return await this._contentPage.send('scrollIntoViewIfNeeded', options);
}
async ['Page.addScriptToEvaluateOnNewDocument'](options) {
return await this._contentPage.send('addScriptToEvaluateOnNewDocument', options);
async ['Page.setInitScripts']({ scripts }) {
return await this._pageTarget.setInitScripts(scripts);
}
async ['Page.dispatchKeyEvent'](options) {

View File

@ -97,6 +97,10 @@ pageTypes.Clip = {
height: t.Number,
};
pageTypes.InitScript = {
script: t.String,
worldName: t.Optional(t.String),
};
const runtimeTypes = {};
runtimeTypes.RemoteObject = {
@ -381,10 +385,10 @@ const Browser = {
hidden: t.Boolean,
}
},
'addScriptToEvaluateOnNewDocument': {
'setInitScripts': {
params: {
browserContextId: t.Optional(t.String),
script: t.String,
scripts: t.Array(pageTypes.InitScript),
}
},
'addBinding': {
@ -802,10 +806,9 @@ const Page = {
rect: t.Optional(pageTypes.Rect),
},
},
'addScriptToEvaluateOnNewDocument': {
'setInitScripts': {
params: {
script: t.String,
worldName: t.Optional(t.String),
scripts: t.Array(pageTypes.InitScript)
}
},
'navigate': {

View File

@ -1,2 +1,2 @@
1316
Changed: aslushnikov@gmail.com Wed Jan 26 17:24:09 MST 2022
1317
Changed: pavel.feldman@gmail.com Mon 14 Feb 2022 03:52:34 PM PST

View File

@ -144,7 +144,7 @@ class TargetRegistry {
return;
return {
scriptsToEvaluateOnNewDocument: target.browserContext().scriptsToEvaluateOnNewDocument,
initScripts: target.browserContext().initScripts,
bindings: target.browserContext().bindings,
settings: target.browserContext().settings,
};
@ -361,6 +361,7 @@ class PageTarget {
this._screencastRecordingInfo = undefined;
this._dialogs = new Map();
this.forcedColors = 'no-override';
this._pageInitScripts = [];
const navigationListener = {
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference]),
@ -523,8 +524,13 @@ class PageTarget {
await this._channel.connect('').send('ensurePermissions', {}).catch(e => void e);
}
async addScriptToEvaluateOnNewDocument(script) {
await this._channel.connect('').send('addScriptToEvaluateOnNewDocument', script).catch(e => void e);
async setInitScripts(scripts) {
this._pageInitScripts = scripts;
await this.pushInitScripts();
}
async pushInitScripts() {
await this._channel.connect('').send('setInitScripts', [...this._browserContext.initScripts, ...this._pageInitScripts]).catch(e => void e);
}
async addBinding(worldName, name, script) {
@ -708,7 +714,7 @@ class BrowserContext {
this.forcedColors = 'no-override';
this.reducedMotion = 'none';
this.videoRecordingOptions = undefined;
this.scriptsToEvaluateOnNewDocument = [];
this.initScripts = [];
this.bindings = [];
this.settings = {};
this.pages = new Set();
@ -804,9 +810,9 @@ class BrowserContext {
await Promise.all(Array.from(this.pages).map(page => page.updateViewportSize()));
}
async addScriptToEvaluateOnNewDocument(script) {
this.scriptsToEvaluateOnNewDocument.push(script);
await Promise.all(Array.from(this.pages).map(page => page.addScriptToEvaluateOnNewDocument(script)));
async setInitScripts(scripts) {
this.initScripts = scripts;
await Promise.all(Array.from(this.pages).map(page => page.pushInitScripts()));
}
async addBinding(worldName, name, script) {

View File

@ -73,15 +73,20 @@ class FrameTree {
return this._runtime;
}
addScriptToEvaluateOnNewDocument(script, worldName) {
worldName = worldName || '';
const existing = this._isolatedWorlds.has(worldName);
const world = this._ensureWorld(worldName);
world._scriptsToEvaluateOnNewDocument.push(script);
// FIXME: 'should inherit http credentials from browser context' fails without this
if (worldName && !existing) {
for (const frame of this.frames())
frame._createIsolatedContext(worldName);
setInitScripts(scripts) {
for (const world of this._isolatedWorlds.values())
world._scriptsToEvaluateOnNewDocument = [];
for (let { worldName, script } of scripts) {
worldName = worldName || '';
const existing = this._isolatedWorlds.has(worldName);
const world = this._ensureWorld(worldName);
world._scriptsToEvaluateOnNewDocument.push(script);
// FIXME: 'should inherit http credentials from browser context' fails without this
if (worldName && !existing) {
for (const frame of this.frames())
frame._createIsolatedContext(worldName);
}
}
}

View File

@ -134,7 +134,6 @@ class PageAgent {
this._runtime.events.onBindingCalled(this._onBindingCalled.bind(this)),
browserChannel.register('page', {
addBinding: ({ worldName, name, script }) => this._frameTree.addBinding(worldName, name, script),
addScriptToEvaluateOnNewDocument: ({script, worldName}) => this._frameTree.addScriptToEvaluateOnNewDocument(script, worldName),
adoptNode: this._adoptNode.bind(this),
crash: this._crash.bind(this),
describeNode: this._describeNode.bind(this),

View File

@ -84,11 +84,10 @@ function initialize() {
if (!response)
return;
const {
scriptsToEvaluateOnNewDocument = [],
initScripts = [],
bindings = [],
settings = {}
} = response || {};
// Enforce focused state for all top level documents.
docShell.overrideHasFocus = true;
docShell.forceActiveState = true;
@ -99,14 +98,13 @@ function initialize() {
}
for (const { worldName, name, script } of bindings)
frameTree.addBinding(worldName, name, script);
for (const script of scriptsToEvaluateOnNewDocument)
frameTree.addScriptToEvaluateOnNewDocument(script);
frameTree.setInitScripts(initScripts);
pageAgent = new PageAgent(messageManager, channel, frameTree);
channel.register('', {
addScriptToEvaluateOnNewDocument(script) {
frameTree.addScriptToEvaluateOnNewDocument(script);
setInitScripts(scripts) {
frameTree.setInitScripts(scripts);
},
addBinding({worldName, name, script}) {

View File

@ -253,8 +253,8 @@ class BrowserHandler {
await this._targetRegistry.browserContextForId(browserContextId).applySetting('scrollbarsHidden', nullToUndefined(hidden));
}
async ['Browser.addScriptToEvaluateOnNewDocument']({browserContextId, script}) {
await this._targetRegistry.browserContextForId(browserContextId).addScriptToEvaluateOnNewDocument(script);
async ['Browser.setInitScripts']({browserContextId, scripts}) {
await this._targetRegistry.browserContextForId(browserContextId).setInitScripts(scripts);
}
async ['Browser.addBinding']({browserContextId, worldName, name, script}) {

View File

@ -334,8 +334,8 @@ class PageHandler {
return await this._contentPage.send('scrollIntoViewIfNeeded', options);
}
async ['Page.addScriptToEvaluateOnNewDocument'](options) {
return await this._contentPage.send('addScriptToEvaluateOnNewDocument', options);
async ['Page.setInitScripts']({ scripts }) {
return await this._pageTarget.setInitScripts(scripts);
}
async ['Page.dispatchKeyEvent'](options) {

View File

@ -97,6 +97,10 @@ pageTypes.Clip = {
height: t.Number,
};
pageTypes.InitScript = {
script: t.String,
worldName: t.Optional(t.String),
};
const runtimeTypes = {};
runtimeTypes.RemoteObject = {
@ -381,10 +385,10 @@ const Browser = {
hidden: t.Boolean,
}
},
'addScriptToEvaluateOnNewDocument': {
'setInitScripts': {
params: {
browserContextId: t.Optional(t.String),
script: t.String,
scripts: t.Array(pageTypes.InitScript),
}
},
'addBinding': {
@ -802,10 +806,9 @@ const Page = {
rect: t.Optional(pageTypes.Rect),
},
},
'addScriptToEvaluateOnNewDocument': {
'setInitScripts': {
params: {
script: t.String,
worldName: t.Optional(t.String),
scripts: t.Array(pageTypes.InitScript)
}
},
'navigate': {