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 1317
Changed: aslushnikov@gmail.com Wed Jan 26 17:24:09 MST 2022 Changed: pavel.feldman@gmail.com Mon 14 Feb 2022 03:52:34 PM PST

View file

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

View file

@ -73,7 +73,11 @@ class FrameTree {
return this._runtime; return this._runtime;
} }
addScriptToEvaluateOnNewDocument(script, worldName) { setInitScripts(scripts) {
for (const world of this._isolatedWorlds.values())
world._scriptsToEvaluateOnNewDocument = [];
for (let { worldName, script } of scripts) {
worldName = worldName || ''; worldName = worldName || '';
const existing = this._isolatedWorlds.has(worldName); const existing = this._isolatedWorlds.has(worldName);
const world = this._ensureWorld(worldName); const world = this._ensureWorld(worldName);
@ -84,6 +88,7 @@ class FrameTree {
frame._createIsolatedContext(worldName); frame._createIsolatedContext(worldName);
} }
} }
}
_ensureWorld(worldName) { _ensureWorld(worldName) {
worldName = worldName || ''; worldName = worldName || '';

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -73,7 +73,11 @@ class FrameTree {
return this._runtime; return this._runtime;
} }
addScriptToEvaluateOnNewDocument(script, worldName) { setInitScripts(scripts) {
for (const world of this._isolatedWorlds.values())
world._scriptsToEvaluateOnNewDocument = [];
for (let { worldName, script } of scripts) {
worldName = worldName || ''; worldName = worldName || '';
const existing = this._isolatedWorlds.has(worldName); const existing = this._isolatedWorlds.has(worldName);
const world = this._ensureWorld(worldName); const world = this._ensureWorld(worldName);
@ -84,6 +88,7 @@ class FrameTree {
frame._createIsolatedContext(worldName); frame._createIsolatedContext(worldName);
} }
} }
}
_ensureWorld(worldName) { _ensureWorld(worldName) {
worldName = worldName || ''; worldName = worldName || '';

View file

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

View file

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

View file

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

View file

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

View file

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