Bug 1450948 - Convert ChromeActor to protocol.js r=ochameau

MozReview-Commit-ID: 1pwYUXGiEdT
* fix types in tab.js

MozReview-Commit-ID: 2PAU8IeEKDV

--HG--
extra : rebase_source : 4003f1c84108aed4f37bca2d3c8cfb32d5ac40e9
This commit is contained in:
yulia 2018-04-24 15:30:38 +02:00
Родитель bcd0977534
Коммит 318a381a6e
7 изменённых файлов: 195 добавлений и 67 удалений

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

@ -10,6 +10,10 @@ const { DebuggerServer } = require("../main");
const { getChildDocShells, TabActor } = require("./tab"); const { getChildDocShells, TabActor } = require("./tab");
const makeDebugger = require("./utils/make-debugger"); const makeDebugger = require("./utils/make-debugger");
const { extend } = require("devtools/shared/extend");
const { ActorClassWithSpec, Actor } = require("devtools/shared/protocol");
const { tabSpec } = require("devtools/shared/specs/tab");
/** /**
* Creates a TabActor for debugging all the chrome content in the * Creates a TabActor for debugging all the chrome content in the
* current process. Most of the implementation is inherited from TabActor. * current process. Most of the implementation is inherited from TabActor.
@ -30,7 +34,17 @@ const makeDebugger = require("./utils/make-debugger");
* @param connection DebuggerServerConnection * @param connection DebuggerServerConnection
* The connection to the client. * The connection to the client.
*/ */
function ChromeActor(connection) {
/**
* Protocol.js expects only the prototype object, and does not maintain the prototype
* chain when it constructs the ActorClass. For this reason we are using `extend` to
* maintain the properties of TabActor.prototype
* */
const chromePrototype = extend({}, TabActor.prototype);
chromePrototype.initialize = function(connection) {
Actor.prototype.initialize.call(this, connection);
TabActor.call(this, connection); TabActor.call(this, connection);
// This creates a Debugger instance for chrome debugging all globals. // This creates a Debugger instance for chrome debugging all globals.
@ -69,20 +83,15 @@ function ChromeActor(connection) {
value: docShell, value: docShell,
configurable: true configurable: true
}); });
} };
exports.ChromeActor = ChromeActor;
ChromeActor.prototype = Object.create(TabActor.prototype); chromePrototype.isRootActor = true;
ChromeActor.prototype.constructor = ChromeActor;
ChromeActor.prototype.isRootActor = true;
/** /**
* Getter for the list of all docshells in this tabActor * Getter for the list of all docshells in this tabActor
* @return {Array} * @return {Array}
*/ */
Object.defineProperty(ChromeActor.prototype, "docShells", { Object.defineProperty(chromePrototype, "docShells", {
get: function() { get: function() {
// Iterate over all top-level windows and all their docshells. // Iterate over all top-level windows and all their docshells.
let docShells = []; let docShells = [];
@ -99,7 +108,7 @@ Object.defineProperty(ChromeActor.prototype, "docShells", {
} }
}); });
ChromeActor.prototype.observe = function(subject, topic, data) { chromePrototype.observe = function(subject, topic, data) {
TabActor.prototype.observe.call(this, subject, topic, data); TabActor.prototype.observe.call(this, subject, topic, data);
if (!this.attached) { if (!this.attached) {
return; return;
@ -114,7 +123,7 @@ ChromeActor.prototype.observe = function(subject, topic, data) {
} }
}; };
ChromeActor.prototype._attach = function() { chromePrototype._attach = function() {
if (this.attached) { if (this.attached) {
return false; return false;
} }
@ -140,7 +149,7 @@ ChromeActor.prototype._attach = function() {
return undefined; return undefined;
}; };
ChromeActor.prototype._detach = function() { chromePrototype._detach = function() {
if (!this.attached) { if (!this.attached) {
return false; return false;
} }
@ -170,7 +179,7 @@ ChromeActor.prototype._detach = function() {
/** /**
* Prepare to enter a nested event loop by disabling debuggee events. * Prepare to enter a nested event loop by disabling debuggee events.
*/ */
ChromeActor.prototype.preNest = function() { chromePrototype.preNest = function() {
// Disable events in all open windows. // Disable events in all open windows.
let e = Services.wm.getEnumerator(null); let e = Services.wm.getEnumerator(null);
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
@ -185,7 +194,7 @@ ChromeActor.prototype.preNest = function() {
/** /**
* Prepare to exit a nested event loop by enabling debuggee events. * Prepare to exit a nested event loop by enabling debuggee events.
*/ */
ChromeActor.prototype.postNest = function(nestData) { chromePrototype.postNest = function(nestData) {
// Enable events in all open windows. // Enable events in all open windows.
let e = Services.wm.getEnumerator(null); let e = Services.wm.getEnumerator(null);
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
@ -196,3 +205,7 @@ ChromeActor.prototype.postNest = function(nestData) {
windowUtils.suppressEventHandling(false); windowUtils.suppressEventHandling(false);
} }
}; };
chromePrototype.typeName = "Chrome";
exports.chromePrototype = chromePrototype;
exports.ChromeActor = ActorClassWithSpec(tabSpec, chromePrototype);

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

@ -611,7 +611,7 @@ TabActor.prototype = {
} }
}, },
onSwitchToFrame(request) { switchToFrame(request) {
let windowId = request.windowId; let windowId = request.windowId;
let win; let win;
@ -633,12 +633,12 @@ TabActor.prototype = {
return {}; return {};
}, },
onListFrames(request) { listFrames(request) {
let windows = this._docShellsToWindows(this.docShells); let windows = this._docShellsToWindows(this.docShells);
return { frames: windows }; return { frames: windows };
}, },
onListWorkers(request) { listWorkers(request) {
if (!this.attached) { if (!this.attached) {
return { error: "wrongState" }; return { error: "wrongState" };
} }
@ -669,7 +669,7 @@ TabActor.prototype = {
}); });
}, },
onLogInPage(request) { logInPage(request) {
let {text, category, flags} = request; let {text, category, flags} = request;
let scriptErrorClass = Cc["@mozilla.org/scripterror;1"]; let scriptErrorClass = Cc["@mozilla.org/scripterror;1"];
let scriptError = scriptErrorClass.createInstance(Ci.nsIScriptError); let scriptError = scriptErrorClass.createInstance(Ci.nsIScriptError);
@ -939,7 +939,7 @@ TabActor.prototype = {
// Protocol Request Handlers // Protocol Request Handlers
onAttach(request) { attach(request) {
if (this.exited) { if (this.exited) {
return { type: "exited" }; return { type: "exited" };
} }
@ -955,7 +955,7 @@ TabActor.prototype = {
}; };
}, },
onDetach(request) { detach(request) {
if (!this._detach()) { if (!this._detach()) {
return { error: "wrongState" }; return { error: "wrongState" };
} }
@ -966,7 +966,7 @@ TabActor.prototype = {
/** /**
* Bring the tab's window to front. * Bring the tab's window to front.
*/ */
onFocus() { focus() {
if (this.window) { if (this.window) {
this.window.focus(); this.window.focus();
} }
@ -976,7 +976,7 @@ TabActor.prototype = {
/** /**
* Reload the page in this tab. * Reload the page in this tab.
*/ */
onReload(request) { reload(request) {
let force = request && request.options && request.options.force; let force = request && request.options && request.options.force;
// Wait a tick so that the response packet can be dispatched before the // Wait a tick so that the response packet can be dispatched before the
// subsequent navigation event packet. // subsequent navigation event packet.
@ -989,26 +989,26 @@ TabActor.prototype = {
this.webNavigation.reload(force ? this.webNavigation.reload(force ?
Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE : Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE :
Ci.nsIWebNavigation.LOAD_FLAGS_NONE); Ci.nsIWebNavigation.LOAD_FLAGS_NONE);
}, "TabActor.prototype.onReload's delayed body")); }, "TabActor.prototype.reload's delayed body"));
return {}; return {};
}, },
/** /**
* Navigate this tab to a new location * Navigate this tab to a new location
*/ */
onNavigateTo(request) { navigateTo(request) {
// Wait a tick so that the response packet can be dispatched before the // Wait a tick so that the response packet can be dispatched before the
// subsequent navigation event packet. // subsequent navigation event packet.
Services.tm.dispatchToMainThread(DevToolsUtils.makeInfallible(() => { Services.tm.dispatchToMainThread(DevToolsUtils.makeInfallible(() => {
this.window.location = request.url; this.window.location = request.url;
}, "TabActor.prototype.onNavigateTo's delayed body")); }, "TabActor.prototype.navigateTo's delayed body"));
return {}; return {};
}, },
/** /**
* Reconfigure options. * Reconfigure options.
*/ */
onReconfigure(request) { reconfigure(request) {
let options = request.options || {}; let options = request.options || {};
if (!this.docShell) { if (!this.docShell) {
@ -1078,7 +1078,7 @@ TabActor.prototype = {
let hasExplicitReloadFlag = "performReload" in options; let hasExplicitReloadFlag = "performReload" in options;
if ((hasExplicitReloadFlag && options.performReload) || if ((hasExplicitReloadFlag && options.performReload) ||
(!hasExplicitReloadFlag && reload)) { (!hasExplicitReloadFlag && reload)) {
this.onReload(); this.reload();
} }
}, },
@ -1464,17 +1464,17 @@ TabActor.prototype = {
* The request types this actor can handle. * The request types this actor can handle.
*/ */
TabActor.prototype.requestTypes = { TabActor.prototype.requestTypes = {
"attach": TabActor.prototype.onAttach, "attach": TabActor.prototype.attach,
"detach": TabActor.prototype.onDetach, "detach": TabActor.prototype.detach,
"focus": TabActor.prototype.onFocus, "focus": TabActor.prototype.focus,
"reload": TabActor.prototype.onReload, "reload": TabActor.prototype.reload,
"navigateTo": TabActor.prototype.onNavigateTo, "navigateTo": TabActor.prototype.navigateTo,
"reconfigure": TabActor.prototype.onReconfigure, "reconfigure": TabActor.prototype.reconfigure,
"ensureCSSErrorReportingEnabled": TabActor.prototype.ensureCSSErrorReportingEnabled, "ensureCSSErrorReportingEnabled": TabActor.prototype.ensureCSSErrorReportingEnabled,
"switchToFrame": TabActor.prototype.onSwitchToFrame, "switchToFrame": TabActor.prototype.switchToFrame,
"listFrames": TabActor.prototype.onListFrames, "listFrames": TabActor.prototype.listFrames,
"listWorkers": TabActor.prototype.onListWorkers, "listWorkers": TabActor.prototype.listWorkers,
"logInPage": TabActor.prototype.onLogInPage, "logInPage": TabActor.prototype.logInPage,
}; };
exports.TabActor = TabActor; exports.TabActor = TabActor;

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

@ -4,15 +4,17 @@
"use strict"; "use strict";
const { extend } = require("devtools/shared/extend");
const { Ci, Cu, Cc } = require("chrome"); const { Ci, Cu, Cc } = require("chrome");
const Services = require("Services"); const Services = require("Services");
const { ChromeActor } = require("./chrome"); const { ChromeActor, chromePrototype } = require("./chrome");
const makeDebugger = require("./utils/make-debugger"); const makeDebugger = require("./utils/make-debugger");
const { ActorClassWithSpec } = require("devtools/shared/protocol");
const { tabSpec } = require("devtools/shared/specs/tab");
loader.lazyRequireGetter(this, "unwrapDebuggerObjectGlobal", "devtools/server/actors/thread", true); loader.lazyRequireGetter(this, "unwrapDebuggerObjectGlobal", "devtools/server/actors/thread", true);
loader.lazyRequireGetter(this, "ChromeUtils"); loader.lazyRequireGetter(this, "ChromeUtils");
const FALLBACK_DOC_MESSAGE = "Your addon does not have any document opened yet."; const FALLBACK_DOC_MESSAGE = "Your addon does not have any document opened yet.";
/** /**
@ -52,9 +54,11 @@ const FALLBACK_DOC_MESSAGE = "Your addon does not have any document opened yet."
* @param {string} addonId * @param {string} addonId
* the addonId of the target WebExtension. * the addonId of the target WebExtension.
*/ */
function WebExtensionChildActor(conn, chromeGlobal, prefix, addonId) {
ChromeActor.call(this, conn);
const webExtensionChildPrototype = extend({}, chromePrototype);
webExtensionChildPrototype.initialize = function(conn, chromeGlobal, prefix, addonId) {
chromePrototype.initialize.call(this, conn);
this._chromeGlobal = chromeGlobal; this._chromeGlobal = chromeGlobal;
this._prefix = prefix; this._prefix = prefix;
this.id = addonId; this.id = addonId;
@ -102,23 +106,19 @@ function WebExtensionChildActor(conn, chromeGlobal, prefix, addonId) {
if (extensionWindow) { if (extensionWindow) {
this._setWindow(extensionWindow); this._setWindow(extensionWindow);
} }
} };
exports.WebExtensionChildActor = WebExtensionChildActor;
WebExtensionChildActor.prototype = Object.create(ChromeActor.prototype); webExtensionChildPrototype.typeName = "webExtension";
WebExtensionChildActor.prototype.actorPrefix = "webExtension";
WebExtensionChildActor.prototype.constructor = WebExtensionChildActor;
// NOTE: This is needed to catch in the webextension webconsole all the // NOTE: This is needed to catch in the webextension webconsole all the
// errors raised by the WebExtension internals that are not currently // errors raised by the WebExtension internals that are not currently
// associated with any window. // associated with any window.
WebExtensionChildActor.prototype.isRootActor = true; webExtensionChildPrototype.isRootActor = true;
/** /**
* Called when the actor is removed from the connection. * Called when the actor is removed from the connection.
*/ */
WebExtensionChildActor.prototype.exit = function() { webExtensionChildPrototype.exit = function() {
if (this._chromeGlobal) { if (this._chromeGlobal) {
let chromeGlobal = this._chromeGlobal; let chromeGlobal = this._chromeGlobal;
this._chromeGlobal = null; this._chromeGlobal = null;
@ -138,7 +138,7 @@ WebExtensionChildActor.prototype.exit = function() {
// Private helpers. // Private helpers.
WebExtensionChildActor.prototype._createFallbackWindow = function() { webExtensionChildPrototype._createFallbackWindow = function() {
if (this.fallbackWindow) { if (this.fallbackWindow) {
// Skip if there is already an existent fallback window. // Skip if there is already an existent fallback window.
return; return;
@ -157,7 +157,7 @@ WebExtensionChildActor.prototype._createFallbackWindow = function() {
this.fallbackWindow.document.body.innerText = FALLBACK_DOC_MESSAGE; this.fallbackWindow.document.body.innerText = FALLBACK_DOC_MESSAGE;
}; };
WebExtensionChildActor.prototype._destroyFallbackWindow = function() { webExtensionChildPrototype._destroyFallbackWindow = function() {
if (this.fallbackWebNav) { if (this.fallbackWebNav) {
// Explicitly close the fallback windowless browser to prevent it to leak // Explicitly close the fallback windowless browser to prevent it to leak
// (and to prevent it to freeze devtools xpcshell tests). // (and to prevent it to freeze devtools xpcshell tests).
@ -173,7 +173,7 @@ WebExtensionChildActor.prototype._destroyFallbackWindow = function() {
// NOTE: This currently fail to discovery an extension page running in a // NOTE: This currently fail to discovery an extension page running in a
// windowless browser when running in non-oop mode, and the background page // windowless browser when running in non-oop mode, and the background page
// is set later using _onNewExtensionWindow. // is set later using _onNewExtensionWindow.
WebExtensionChildActor.prototype._searchForExtensionWindow = function() { webExtensionChildPrototype._searchForExtensionWindow = function() {
let e = Services.ww.getWindowEnumerator(null); let e = Services.ww.getWindowEnumerator(null);
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
let window = e.getNext(); let window = e.getNext();
@ -188,7 +188,7 @@ WebExtensionChildActor.prototype._searchForExtensionWindow = function() {
// Customized ChromeActor/TabActor hooks. // Customized ChromeActor/TabActor hooks.
WebExtensionChildActor.prototype._onDocShellDestroy = function(docShell) { webExtensionChildPrototype._onDocShellDestroy = function(docShell) {
// Stop watching this docshell (the unwatch() method will check if we // Stop watching this docshell (the unwatch() method will check if we
// started watching it before). // started watching it before).
this._unwatchDocShell(docShell); this._unwatchDocShell(docShell);
@ -207,13 +207,13 @@ WebExtensionChildActor.prototype._onDocShellDestroy = function(docShell) {
} }
}; };
WebExtensionChildActor.prototype._onNewExtensionWindow = function(window) { webExtensionChildPrototype._onNewExtensionWindow = function(window) {
if (!this.window || this.window === this.fallbackWindow) { if (!this.window || this.window === this.fallbackWindow) {
this._changeTopLevelDocument(window); this._changeTopLevelDocument(window);
} }
}; };
WebExtensionChildActor.prototype._attach = function() { webExtensionChildPrototype._attach = function() {
// NOTE: we need to be sure that `this.window` can return a // NOTE: we need to be sure that `this.window` can return a
// window before calling the ChromeActor.onAttach, or the TabActor // window before calling the ChromeActor.onAttach, or the TabActor
// will not be subscribed to the child doc shell updates. // will not be subscribed to the child doc shell updates.
@ -234,7 +234,7 @@ WebExtensionChildActor.prototype._attach = function() {
ChromeActor.prototype._attach.apply(this); ChromeActor.prototype._attach.apply(this);
}; };
WebExtensionChildActor.prototype._detach = function() { webExtensionChildPrototype._detach = function() {
// Call ChromeActor's _detach to unsubscribe new/destroyed chrome docshell listeners. // Call ChromeActor's _detach to unsubscribe new/destroyed chrome docshell listeners.
ChromeActor.prototype._detach.apply(this); ChromeActor.prototype._detach.apply(this);
@ -245,7 +245,7 @@ WebExtensionChildActor.prototype._detach = function() {
/** /**
* Return the json details related to a docShell. * Return the json details related to a docShell.
*/ */
WebExtensionChildActor.prototype._docShellToWindow = function(docShell) { webExtensionChildPrototype._docShellToWindow = function(docShell) {
const baseWindowDetails = ChromeActor.prototype._docShellToWindow.call(this, docShell); const baseWindowDetails = ChromeActor.prototype._docShellToWindow.call(this, docShell);
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor) let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
@ -270,7 +270,7 @@ WebExtensionChildActor.prototype._docShellToWindow = function(docShell) {
/** /**
* Return an array of the json details related to an array/iterator of docShells. * Return an array of the json details related to an array/iterator of docShells.
*/ */
WebExtensionChildActor.prototype._docShellsToWindows = function(docshells) { webExtensionChildPrototype._docShellsToWindows = function(docshells) {
return ChromeActor.prototype._docShellsToWindows.call(this, docshells) return ChromeActor.prototype._docShellsToWindows.call(this, docshells)
.filter(windowDetails => { .filter(windowDetails => {
// Filter the docShells based on the addon id of the window or // Filter the docShells based on the addon id of the window or
@ -280,11 +280,11 @@ WebExtensionChildActor.prototype._docShellsToWindows = function(docshells) {
}); });
}; };
WebExtensionChildActor.prototype.isExtensionWindow = function(window) { webExtensionChildPrototype.isExtensionWindow = function(window) {
return window.document.nodePrincipal.addonId == this.id; return window.document.nodePrincipal.addonId == this.id;
}; };
WebExtensionChildActor.prototype.isExtensionWindowDescendent = function(window) { webExtensionChildPrototype.isExtensionWindowDescendent = function(window) {
// Check if the source is coming from a descendant docShell of an extension window. // Check if the source is coming from a descendant docShell of an extension window.
let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor) let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell); .getInterface(Ci.nsIDocShell);
@ -297,7 +297,7 @@ WebExtensionChildActor.prototype.isExtensionWindowDescendent = function(window)
* Return true if the given source is associated with this addon and should be * Return true if the given source is associated with this addon and should be
* added to the visible sources (retrieved and used by the webbrowser actor module). * added to the visible sources (retrieved and used by the webbrowser actor module).
*/ */
WebExtensionChildActor.prototype._allowSource = function(source) { webExtensionChildPrototype._allowSource = function(source) {
// Use the source.element to detect the allowed source, if any. // Use the source.element to detect the allowed source, if any.
if (source.element) { if (source.element) {
let domEl = unwrapDebuggerObjectGlobal(source.element); let domEl = unwrapDebuggerObjectGlobal(source.element);
@ -344,7 +344,7 @@ WebExtensionChildActor.prototype._allowSource = function(source) {
* Return true if the given global is associated with this addon and should be * Return true if the given global is associated with this addon and should be
* added as a debuggee, false otherwise. * added as a debuggee, false otherwise.
*/ */
WebExtensionChildActor.prototype._shouldAddNewGlobalAsDebuggee = function(newGlobal) { webExtensionChildPrototype._shouldAddNewGlobalAsDebuggee = function(newGlobal) {
const global = unwrapDebuggerObjectGlobal(newGlobal); const global = unwrapDebuggerObjectGlobal(newGlobal);
if (global instanceof Ci.nsIDOMWindow) { if (global instanceof Ci.nsIDOMWindow) {
@ -387,10 +387,12 @@ WebExtensionChildActor.prototype._shouldAddNewGlobalAsDebuggee = function(newGlo
// Handlers for the messages received from the parent actor. // Handlers for the messages received from the parent actor.
WebExtensionChildActor.prototype._onParentExit = function(msg) { webExtensionChildPrototype._onParentExit = function(msg) {
if (msg.json.actor !== this.actorID) { if (msg.json.actor !== this.actorID) {
return; return;
} }
this.exit(); this.exit();
}; };
exports.WebExtensionChildActor = ActorClassWithSpec(tabSpec, webExtensionChildPrototype);

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

@ -1110,10 +1110,6 @@ exports.generateActorSpec = generateActorSpec;
* the given actor prototype. Returns the actor prototype. * the given actor prototype. Returns the actor prototype.
*/ */
var generateRequestHandlers = function(actorSpec, actorProto) { var generateRequestHandlers = function(actorSpec, actorProto) {
if (actorProto._actorSpec) {
throw new Error("actorProto called twice on the same actor prototype!");
}
actorProto.typeName = actorSpec.typeName; actorProto.typeName = actorSpec.typeName;
// Generate request handlers for each method definition // Generate request handlers for each method definition

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

@ -204,6 +204,11 @@ const Types = exports.__TypesForTests = [
spec: "devtools/shared/specs/symbol-iterator", spec: "devtools/shared/specs/symbol-iterator",
front: null, front: null,
}, },
{
types: ["tab"],
spec: "devtools/shared/specs/tab",
front: null,
},
{ {
types: ["timeline"], types: ["timeline"],
spec: "devtools/shared/specs/timeline", spec: "devtools/shared/specs/timeline",

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

@ -41,6 +41,7 @@ DevToolsModules(
'styles.js', 'styles.js',
'stylesheets.js', 'stylesheets.js',
'symbol-iterator.js', 'symbol-iterator.js',
'tab.js',
'timeline.js', 'timeline.js',
'webaudio.js', 'webaudio.js',
'webextension-inspected-window.js', 'webextension-inspected-window.js',

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

@ -0,0 +1,111 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
"use strict";
const {types, generateActorSpec, RetVal, Option} = require("devtools/shared/protocol");
types.addDictType("tab.attach", {
type: "string",
threadActor: "number",
cacheDisabled: "boolean",
javascriptEnabled: "boolean",
traits: "json"
});
types.addDictType("tab.detach", {
error: "nullable:string",
type: "nullable:string"
});
types.addDictType("tab.switchtoframe", {
error: "nullable:string",
message: "nullable:string"
});
types.addDictType("tab.listframes", {
frames: "array:tab.window"
});
types.addDictType("tab.window", {
id: "string",
parentID: "nullable:string",
url: "string",
title: "string"
});
types.addDictType("tab.workers", {
error: "nullable:string"
});
types.addDictType("tab.reload", {
force: "boolean"
});
types.addDictType("tab.reconfigure", {
javascriptEnabled: "nullable:boolean",
cacheDisabled: "nullable:boolean",
serviceWorkersTestingEnabled: "nullable:boolean",
performReload: "nullable:boolean"
});
const tabSpec = generateActorSpec({
typeName: "tab",
methods: {
attach: {
request: {},
response: RetVal("tab.attach")
},
detach: {
request: {},
response: RetVal("tab.detach")
},
focus: {
request: {},
response: {}
},
reload: {
request: {
options: Option(0, "tab.reload"),
},
response: {}
},
navigateTo: {
request: {
url: Option(0, "string"),
},
response: {}
},
reconfigure: {
request: {
options: Option(0, "tab.reconfigure")
},
response: {}
},
switchToFrame: {
request: {
windowId: Option(0, "string")
},
response: RetVal("tab.switchtoframe")
},
listFrames: {
request: {},
response: RetVal("tab.listframes")
},
listWorkers: {
request: {},
response: RetVal("tab.workers")
},
logInPage: {
request: {
text: Option(0, "string"),
category: Option(0, "string"),
flags: Option(0, "string")
},
response: {}
}
},
});
exports.tabSpec = tabSpec;