summaryrefslogtreecommitdiffstats
path: root/devtools/shared/specs
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/specs')
-rw-r--r--devtools/shared/specs/accessibility.js299
-rw-r--r--devtools/shared/specs/addon/addons.js33
-rw-r--r--devtools/shared/specs/addon/moz.build10
-rw-r--r--devtools/shared/specs/addon/webextension-inspected-window.js119
-rw-r--r--devtools/shared/specs/animation.js110
-rw-r--r--devtools/shared/specs/array-buffer.js24
-rw-r--r--devtools/shared/specs/blackboxing.js42
-rw-r--r--devtools/shared/specs/breakpoint-list.js54
-rw-r--r--devtools/shared/specs/changes.js40
-rw-r--r--devtools/shared/specs/compatibility.js69
-rw-r--r--devtools/shared/specs/css-properties.js23
-rw-r--r--devtools/shared/specs/descriptors/moz.build12
-rw-r--r--devtools/shared/specs/descriptors/process.js41
-rw-r--r--devtools/shared/specs/descriptors/tab.js50
-rw-r--r--devtools/shared/specs/descriptors/webextension.js58
-rw-r--r--devtools/shared/specs/descriptors/worker.js32
-rw-r--r--devtools/shared/specs/device.js18
-rw-r--r--devtools/shared/specs/environment.js14
-rw-r--r--devtools/shared/specs/frame.js21
-rw-r--r--devtools/shared/specs/heap-snapshot-file.js23
-rw-r--r--devtools/shared/specs/highlighters.js44
-rw-r--r--devtools/shared/specs/index.js404
-rw-r--r--devtools/shared/specs/inspector.js79
-rw-r--r--devtools/shared/specs/layout.js75
-rw-r--r--devtools/shared/specs/manifest.js21
-rw-r--r--devtools/shared/specs/memory.js124
-rw-r--r--devtools/shared/specs/moz.build63
-rw-r--r--devtools/shared/specs/network-content.js32
-rw-r--r--devtools/shared/specs/network-event.js220
-rw-r--r--devtools/shared/specs/network-parent.js82
-rw-r--r--devtools/shared/specs/node.js160
-rw-r--r--devtools/shared/specs/object.js214
-rw-r--r--devtools/shared/specs/page-style.js126
-rw-r--r--devtools/shared/specs/perf.js90
-rw-r--r--devtools/shared/specs/preference.js55
-rw-r--r--devtools/shared/specs/private-properties-iterator.js42
-rw-r--r--devtools/shared/specs/property-iterator.js45
-rw-r--r--devtools/shared/specs/reflow.js36
-rw-r--r--devtools/shared/specs/responsive.js40
-rw-r--r--devtools/shared/specs/root.js139
-rw-r--r--devtools/shared/specs/screenshot-content.js34
-rw-r--r--devtools/shared/specs/screenshot.js37
-rw-r--r--devtools/shared/specs/source.js87
-rw-r--r--devtools/shared/specs/storage.js308
-rw-r--r--devtools/shared/specs/string.js85
-rw-r--r--devtools/shared/specs/style-rule.js73
-rw-r--r--devtools/shared/specs/style-sheets.js49
-rw-r--r--devtools/shared/specs/style/moz.build9
-rw-r--r--devtools/shared/specs/style/style-types.js78
-rw-r--r--devtools/shared/specs/symbol-iterator.js42
-rw-r--r--devtools/shared/specs/symbol.js20
-rw-r--r--devtools/shared/specs/target-configuration.js50
-rw-r--r--devtools/shared/specs/targets/content-process.js55
-rw-r--r--devtools/shared/specs/targets/moz.build13
-rw-r--r--devtools/shared/specs/targets/parent-process.js24
-rw-r--r--devtools/shared/specs/targets/webextension.js18
-rw-r--r--devtools/shared/specs/targets/window-global.js156
-rw-r--r--devtools/shared/specs/targets/worker.js30
-rw-r--r--devtools/shared/specs/thread-configuration.js31
-rw-r--r--devtools/shared/specs/thread.js189
-rw-r--r--devtools/shared/specs/tracer.js27
-rw-r--r--devtools/shared/specs/walker.js389
-rw-r--r--devtools/shared/specs/watcher.js123
-rw-r--r--devtools/shared/specs/webconsole.js201
-rw-r--r--devtools/shared/specs/worker/moz.build11
-rw-r--r--devtools/shared/specs/worker/push-subscription.js12
-rw-r--r--devtools/shared/specs/worker/service-worker-registration.js48
-rw-r--r--devtools/shared/specs/worker/service-worker.js12
68 files changed, 5394 insertions, 0 deletions
diff --git a/devtools/shared/specs/accessibility.js b/devtools/shared/specs/accessibility.js
new file mode 100644
index 0000000000..acfd7db068
--- /dev/null
+++ b/devtools/shared/specs/accessibility.js
@@ -0,0 +1,299 @@
+/* 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 protocol = require("resource://devtools/shared/protocol.js");
+const { Arg, generateActorSpec, RetVal, types } = protocol;
+
+types.addActorType("accessible");
+
+/**
+ * Accessible with children listed in the ancestry structure calculated by the
+ * walker.
+ */
+types.addDictType("accessibleWithChildren", {
+ // Accessible
+ accessible: "accessible",
+ // Accessible's children
+ children: "array:accessible",
+});
+
+/**
+ * Data passed via "audit-event" to the client. It may include type, a list of
+ * ancestries for accessible actors that have failing accessibility checks or
+ * a progress information.
+ */
+types.addDictType("auditEventData", {
+ type: "string",
+ // List of ancestries (array:accessibleWithChildren)
+ ancestries: "nullable:array:array:accessibleWithChildren",
+ // Audit progress information
+ progress: "nullable:json",
+});
+
+/**
+ * Accessible relation object described by its type that also includes relation targets.
+ */
+types.addDictType("accessibleRelation", {
+ // Accessible relation type
+ type: "string",
+ // Accessible relation's targets
+ targets: "array:accessible",
+});
+
+const accessibleSpec = generateActorSpec({
+ typeName: "accessible",
+
+ events: {
+ "actions-change": {
+ type: "actionsChange",
+ actions: Arg(0, "array:string"),
+ },
+ "name-change": {
+ type: "nameChange",
+ name: Arg(0, "string"),
+ parent: Arg(1, "nullable:accessible"),
+ },
+ "value-change": {
+ type: "valueChange",
+ value: Arg(0, "string"),
+ },
+ "description-change": {
+ type: "descriptionChange",
+ description: Arg(0, "string"),
+ },
+ "states-change": {
+ type: "statesChange",
+ states: Arg(0, "array:string"),
+ },
+ "attributes-change": {
+ type: "attributesChange",
+ attributes: Arg(0, "json"),
+ },
+ "shortcut-change": {
+ type: "shortcutChange",
+ shortcut: Arg(0, "string"),
+ },
+ reorder: {
+ type: "reorder",
+ childCount: Arg(0, "number"),
+ },
+ "text-change": {
+ type: "textChange",
+ },
+ "index-in-parent-change": {
+ type: "indexInParentChange",
+ indexInParent: Arg(0, "number"),
+ },
+ audited: {
+ type: "audited",
+ audit: Arg(0, "nullable:json"),
+ },
+ },
+
+ methods: {
+ audit: {
+ request: { options: Arg(0, "nullable:json") },
+ response: {
+ audit: RetVal("nullable:json"),
+ },
+ },
+ children: {
+ request: {},
+ response: {
+ children: RetVal("array:accessible"),
+ },
+ },
+ getRelations: {
+ request: {},
+ response: {
+ relations: RetVal("array:accessibleRelation"),
+ },
+ },
+ hydrate: {
+ request: {},
+ response: {
+ properties: RetVal("json"),
+ },
+ },
+ snapshot: {
+ request: {},
+ response: {
+ snapshot: RetVal("json"),
+ },
+ },
+ },
+});
+
+const accessibleWalkerSpec = generateActorSpec({
+ typeName: "accessiblewalker",
+
+ events: {
+ "document-ready": {
+ type: "documentReady",
+ },
+ "picker-accessible-picked": {
+ type: "pickerAccessiblePicked",
+ accessible: Arg(0, "nullable:accessible"),
+ },
+ "picker-accessible-previewed": {
+ type: "pickerAccessiblePreviewed",
+ accessible: Arg(0, "nullable:accessible"),
+ },
+ "picker-accessible-hovered": {
+ type: "pickerAccessibleHovered",
+ accessible: Arg(0, "nullable:accessible"),
+ },
+ "picker-accessible-canceled": {
+ type: "pickerAccessibleCanceled",
+ },
+ "highlighter-event": {
+ type: "highlighter-event",
+ data: Arg(0, "json"),
+ },
+ "audit-event": {
+ type: "audit-event",
+ audit: Arg(0, "auditEventData"),
+ },
+ },
+
+ methods: {
+ children: {
+ request: {},
+ response: {
+ children: RetVal("array:accessible"),
+ },
+ },
+ getAccessibleFor: {
+ request: { node: Arg(0, "domnode") },
+ response: {
+ accessible: RetVal("nullable:accessible"),
+ },
+ },
+ getAncestry: {
+ request: { accessible: Arg(0, "accessible") },
+ response: {
+ ancestry: RetVal("array:accessibleWithChildren"),
+ },
+ },
+ startAudit: {
+ request: { options: Arg(0, "nullable:json") },
+ },
+ highlightAccessible: {
+ request: {
+ accessible: Arg(0, "accessible"),
+ options: Arg(1, "nullable:json"),
+ },
+ response: {
+ value: RetVal("nullable:boolean"),
+ },
+ },
+ unhighlight: {
+ request: {},
+ },
+ pick: {},
+ pickAndFocus: {},
+ cancelPick: {},
+ showTabbingOrder: {
+ request: {
+ elm: Arg(0, "domnode"),
+ index: Arg(1, "number"),
+ },
+ response: {
+ tabbingOrderInfo: RetVal("json"),
+ },
+ },
+ hideTabbingOrder() {},
+ },
+});
+
+const simulatorSpec = generateActorSpec({
+ typeName: "simulator",
+
+ methods: {
+ simulate: {
+ request: { options: Arg(0, "nullable:json") },
+ response: {
+ value: RetVal("boolean"),
+ },
+ },
+ },
+});
+
+const accessibilitySpec = generateActorSpec({
+ typeName: "accessibility",
+
+ events: {
+ init: {
+ type: "init",
+ },
+ shutdown: {
+ type: "shutdown",
+ },
+ },
+
+ methods: {
+ getTraits: {
+ request: {},
+ response: { traits: RetVal("json") },
+ },
+ bootstrap: {
+ request: {},
+ response: {
+ state: RetVal("json"),
+ },
+ },
+ getWalker: {
+ request: {},
+ response: {
+ walker: RetVal("accessiblewalker"),
+ },
+ },
+ getSimulator: {
+ request: {},
+ response: {
+ simulator: RetVal("nullable:simulator"),
+ },
+ },
+ },
+});
+
+const parentAccessibilitySpec = generateActorSpec({
+ typeName: "parentaccessibility",
+
+ events: {
+ "can-be-disabled-change": {
+ type: "canBeDisabledChange",
+ canBeDisabled: Arg(0, "boolean"),
+ },
+ "can-be-enabled-change": {
+ type: "canBeEnabledChange",
+ canBeEnabled: Arg(0, "boolean"),
+ },
+ },
+
+ methods: {
+ bootstrap: {
+ request: {},
+ response: {
+ state: RetVal("json"),
+ },
+ },
+ enable: {
+ request: {},
+ response: {},
+ },
+ disable: {
+ request: {},
+ response: {},
+ },
+ },
+});
+
+exports.accessibleSpec = accessibleSpec;
+exports.accessibleWalkerSpec = accessibleWalkerSpec;
+exports.accessibilitySpec = accessibilitySpec;
+exports.parentAccessibilitySpec = parentAccessibilitySpec;
+exports.simulatorSpec = simulatorSpec;
diff --git a/devtools/shared/specs/addon/addons.js b/devtools/shared/specs/addon/addons.js
new file mode 100644
index 0000000000..309a7acdf5
--- /dev/null
+++ b/devtools/shared/specs/addon/addons.js
@@ -0,0 +1,33 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const addonsSpec = generateActorSpec({
+ typeName: "addons",
+
+ methods: {
+ installTemporaryAddon: {
+ request: {
+ addonPath: Arg(0, "string"),
+ openDevTools: Arg(1, "nullable:boolean"),
+ },
+ response: { addon: RetVal("json") },
+ },
+
+ uninstallAddon: {
+ request: {
+ addonId: Arg(0, "string"),
+ },
+ response: {},
+ },
+ },
+});
+
+exports.addonsSpec = addonsSpec;
diff --git a/devtools/shared/specs/addon/moz.build b/devtools/shared/specs/addon/moz.build
new file mode 100644
index 0000000000..e382173641
--- /dev/null
+++ b/devtools/shared/specs/addon/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DevToolsModules(
+ "addons.js",
+ "webextension-inspected-window.js",
+)
diff --git a/devtools/shared/specs/addon/webextension-inspected-window.js b/devtools/shared/specs/addon/webextension-inspected-window.js
new file mode 100644
index 0000000000..3a0cf166ed
--- /dev/null
+++ b/devtools/shared/specs/addon/webextension-inspected-window.js
@@ -0,0 +1,119 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+/**
+ * Sent with the eval and reload requests, used to inform the
+ * webExtensionInspectedWindowActor about the caller information
+ * to be able to evaluate code as being executed from the caller
+ * WebExtension sources, or log errors with information that can
+ * help the addon developer to more easily identify the affected
+ * lines in his own addon code.
+ */
+types.addDictType("webExtensionCallerInfo", {
+ // Information related to the line of code that has originated
+ // the request.
+ url: "string",
+ lineNumber: "nullable:number",
+
+ // The called addonId.
+ addonId: "string",
+});
+
+/**
+ * RDP type related to the inspectedWindow.eval method request.
+ */
+types.addDictType("webExtensionEvalOptions", {
+ frameURL: "nullable:string",
+ contextSecurityOrigin: "nullable:string",
+ useContentScriptContext: "nullable:boolean",
+
+ // Return the evalResult as a grip (used by the WebExtensions
+ // devtools inspector's sidebar.setExpression API method).
+ evalResultAsGrip: "nullable:boolean",
+
+ // The actor ID of the node selected in the inspector if any,
+ // used to provide the '$0' binding.
+ toolboxSelectedNodeActorID: "nullable:string",
+
+ // The actor ID of the console actor,
+ // used to provide the 'inspect' binding.
+ toolboxConsoleActorID: "nullable:string",
+});
+
+/**
+ * RDP type related to the inspectedWindow.eval method result errors.
+ *
+ * This type has been modelled on the same data format
+ * used in the corresponding chrome API method.
+ */
+types.addDictType("webExtensionEvalExceptionInfo", {
+ // The following properties are set if the error has not occurred
+ // in the evaluated JS code.
+ isError: "nullable:boolean",
+ code: "nullable:string",
+ description: "nullable:string",
+ details: "nullable:array:json",
+
+ // The following properties are set if the error has occurred
+ // in the evaluated JS code.
+ isException: "nullable:string",
+ value: "nullable:string",
+});
+
+/**
+ * RDP type related to the inspectedWindow.eval method result.
+ */
+types.addDictType("webExtensionEvalResult", {
+ // The following properties are set if the evaluation has been
+ // completed successfully.
+ value: "nullable:json",
+ valueGrip: "nullable:json",
+ // The following properties are set if the evalutation has been
+ // completed with errors.
+ exceptionInfo: "nullable:webExtensionEvalExceptionInfo",
+});
+
+/**
+ * RDP type related to the inspectedWindow.reload method request.
+ */
+types.addDictType("webExtensionReloadOptions", {
+ ignoreCache: "nullable:boolean",
+ userAgent: "nullable:string",
+ injectedScript: "nullable:string",
+});
+
+const webExtensionInspectedWindowSpec = generateActorSpec({
+ typeName: "webExtensionInspectedWindow",
+
+ methods: {
+ reload: {
+ request: {
+ webExtensionCallerInfo: Arg(0, "webExtensionCallerInfo"),
+ options: Arg(1, "webExtensionReloadOptions"),
+ },
+ },
+ eval: {
+ request: {
+ webExtensionCallerInfo: Arg(0, "webExtensionCallerInfo"),
+ expression: Arg(1, "string"),
+ options: Arg(2, "webExtensionEvalOptions"),
+ },
+
+ response: {
+ evalResult: RetVal("webExtensionEvalResult"),
+ },
+ },
+ },
+});
+
+exports.webExtensionInspectedWindowSpec = webExtensionInspectedWindowSpec;
diff --git a/devtools/shared/specs/animation.js b/devtools/shared/specs/animation.js
new file mode 100644
index 0000000000..95acd606b5
--- /dev/null
+++ b/devtools/shared/specs/animation.js
@@ -0,0 +1,110 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+/**
+ * Sent with the 'mutations' event as part of an array of changes, used to
+ * inform fronts of the type of change that occured.
+ */
+types.addDictType("animationMutationChange", {
+ // The type of change ("added" or "removed").
+ type: "string",
+ // The changed AnimationPlayerActor.
+ player: "animationplayer",
+});
+
+const animationPlayerSpec = generateActorSpec({
+ typeName: "animationplayer",
+
+ events: {
+ changed: {
+ type: "changed",
+ state: Arg(0, "json"),
+ },
+ },
+
+ methods: {
+ release: { release: true },
+ getCurrentState: {
+ request: {},
+ response: {
+ data: RetVal("json"),
+ },
+ },
+ getAnimationTypes: {
+ request: {
+ propertyNames: Arg(0, "array:string"),
+ },
+ response: {
+ animationTypes: RetVal("json"),
+ },
+ },
+ },
+});
+
+exports.animationPlayerSpec = animationPlayerSpec;
+
+const animationsSpec = generateActorSpec({
+ typeName: "animations",
+
+ events: {
+ mutations: {
+ type: "mutations",
+ changes: Arg(0, "array:animationMutationChange"),
+ },
+ },
+
+ methods: {
+ setWalkerActor: {
+ request: {
+ walker: Arg(0, "domwalker"),
+ },
+ response: {},
+ },
+ getAnimationPlayersForNode: {
+ request: {
+ actorID: Arg(0, "domnode"),
+ },
+ response: {
+ players: RetVal("array:animationplayer"),
+ },
+ },
+ pauseSome: {
+ request: {
+ players: Arg(0, "array:animationplayer"),
+ },
+ response: {},
+ },
+ playSome: {
+ request: {
+ players: Arg(0, "array:animationplayer"),
+ },
+ response: {},
+ },
+ setCurrentTimes: {
+ request: {
+ players: Arg(0, "array:animationplayer"),
+ time: Arg(1, "number"),
+ shouldPause: Arg(2, "boolean"),
+ },
+ response: {},
+ },
+ setPlaybackRates: {
+ request: {
+ players: Arg(0, "array:animationplayer"),
+ rate: Arg(1, "number"),
+ },
+ response: {},
+ },
+ },
+});
+
+exports.animationsSpec = animationsSpec;
diff --git a/devtools/shared/specs/array-buffer.js b/devtools/shared/specs/array-buffer.js
new file mode 100644
index 0000000000..ba7650ff61
--- /dev/null
+++ b/devtools/shared/specs/array-buffer.js
@@ -0,0 +1,24 @@
+/* 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 protocol = require("resource://devtools/shared/protocol.js");
+const { Arg, RetVal, generateActorSpec } = protocol;
+
+const arrayBufferSpec = generateActorSpec({
+ typeName: "arraybuffer",
+
+ methods: {
+ slice: {
+ request: {
+ start: Arg(0),
+ count: Arg(1),
+ },
+ response: RetVal("json"),
+ },
+ release: { release: true },
+ },
+});
+
+exports.arrayBufferSpec = arrayBufferSpec;
diff --git a/devtools/shared/specs/blackboxing.js b/devtools/shared/specs/blackboxing.js
new file mode 100644
index 0000000000..baf773f77f
--- /dev/null
+++ b/devtools/shared/specs/blackboxing.js
@@ -0,0 +1,42 @@
+/* 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 {
+ generateActorSpec,
+ Arg,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("blackboxing.position", {
+ line: "number",
+ column: "number",
+});
+
+types.addDictType("blackboxing.range", {
+ start: "blackboxing.position",
+ end: "blackboxing.position",
+});
+
+const blackboxingSpec = generateActorSpec({
+ typeName: "blackboxing",
+
+ methods: {
+ blackbox: {
+ request: {
+ url: Arg(0, "string"),
+ range: Arg(1, "array:blackboxing.range"),
+ },
+ },
+ unblackbox: {
+ request: {
+ url: Arg(0, "string"),
+ range: Arg(1, "array:blackboxing.range"),
+ },
+ },
+ },
+});
+
+exports.blackboxingSpec = blackboxingSpec;
diff --git a/devtools/shared/specs/breakpoint-list.js b/devtools/shared/specs/breakpoint-list.js
new file mode 100644
index 0000000000..3e4e0eff00
--- /dev/null
+++ b/devtools/shared/specs/breakpoint-list.js
@@ -0,0 +1,54 @@
+/* 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 {
+ generateActorSpec,
+ Arg,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("breakpoint-list.breakpoint-options", {
+ condition: "nullable:string",
+ logValue: "nullable:string",
+});
+
+const breakpointListSpec = generateActorSpec({
+ typeName: "breakpoint-list",
+
+ methods: {
+ setBreakpoint: {
+ request: {
+ location: Arg(0, "json"),
+ options: Arg(1, "breakpoint-list.breakpoint-options"),
+ },
+ },
+ removeBreakpoint: {
+ request: {
+ location: Arg(0, "json"),
+ },
+ },
+
+ setXHRBreakpoint: {
+ request: {
+ path: Arg(0, "string"),
+ method: Arg(1, "string"),
+ },
+ },
+ removeXHRBreakpoint: {
+ request: {
+ path: Arg(0, "string"),
+ method: Arg(1, "string"),
+ },
+ },
+ setActiveEventBreakpoints: {
+ request: {
+ ids: Arg(0, "array:string"),
+ },
+ },
+ },
+});
+
+exports.breakpointListSpec = breakpointListSpec;
diff --git a/devtools/shared/specs/changes.js b/devtools/shared/specs/changes.js
new file mode 100644
index 0000000000..ba8f2fd042
--- /dev/null
+++ b/devtools/shared/specs/changes.js
@@ -0,0 +1,40 @@
+/* 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 {
+ Arg,
+ generateActorSpec,
+ RetVal,
+} = require("resource://devtools/shared/protocol.js");
+
+const changesSpec = generateActorSpec({
+ typeName: "changes",
+
+ events: {
+ "add-change": {
+ type: "addChange",
+ change: Arg(0, "json"),
+ },
+ "remove-change": {
+ type: "removeChange",
+ change: Arg(0, "json"),
+ },
+ "clear-changes": {
+ type: "clearChanges",
+ },
+ },
+
+ methods: {
+ allChanges: {
+ response: {
+ changes: RetVal("array:json"),
+ },
+ },
+ start: {}, // no arguments, no response
+ },
+});
+
+exports.changesSpec = changesSpec;
diff --git a/devtools/shared/specs/compatibility.js b/devtools/shared/specs/compatibility.js
new file mode 100644
index 0000000000..0af211860a
--- /dev/null
+++ b/devtools/shared/specs/compatibility.js
@@ -0,0 +1,69 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("browsertype", {
+ id: "string",
+ name: "string",
+ version: "string",
+ status: "string",
+});
+
+types.addDictType("compatibilityissues", {
+ type: "string",
+ property: "string",
+ aliases: "nullable:array:string",
+ url: "nullable:string",
+ specUrl: "nullable:string",
+ deprecated: "boolean",
+ experimental: "boolean",
+ unsupportedBrowsers: "array:browsertype",
+});
+
+types.addDictType("declaration", {
+ name: "string",
+ value: "string",
+});
+
+const compatibilitySpec = generateActorSpec({
+ typeName: "compatibility",
+
+ methods: {
+ // While not being used on the client at the moment, keep this method in case
+ // we need traits again to support backwards compatibility for the Compatibility
+ // actor.
+ getTraits: {
+ request: {},
+ response: { traits: RetVal("json") },
+ },
+ getCSSDeclarationBlockIssues: {
+ request: {
+ domRulesDeclarations: Arg(0, "array:array:declaration"),
+ targetBrowsers: Arg(1, "array:browsertype"),
+ },
+ response: {
+ compatibilityIssues: RetVal("array:array:compatibilityissues"),
+ },
+ },
+ getNodeCssIssues: {
+ request: {
+ node: Arg(0, "domnode"),
+ targetBrowsers: Arg(1, "array:browsertype"),
+ },
+ response: {
+ compatibilityIssues: RetVal("array:compatibilityissues"),
+ },
+ },
+ },
+});
+
+exports.compatibilitySpec = compatibilitySpec;
diff --git a/devtools/shared/specs/css-properties.js b/devtools/shared/specs/css-properties.js
new file mode 100644
index 0000000000..04aadd22c6
--- /dev/null
+++ b/devtools/shared/specs/css-properties.js
@@ -0,0 +1,23 @@
+/* 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 {
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const cssPropertiesSpec = generateActorSpec({
+ typeName: "cssProperties",
+
+ methods: {
+ getCSSDatabase: {
+ request: {},
+
+ response: RetVal("json"),
+ },
+ },
+});
+
+exports.cssPropertiesSpec = cssPropertiesSpec;
diff --git a/devtools/shared/specs/descriptors/moz.build b/devtools/shared/specs/descriptors/moz.build
new file mode 100644
index 0000000000..bf297b3dcb
--- /dev/null
+++ b/devtools/shared/specs/descriptors/moz.build
@@ -0,0 +1,12 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DevToolsModules(
+ "process.js",
+ "tab.js",
+ "webextension.js",
+ "worker.js",
+)
diff --git a/devtools/shared/specs/descriptors/process.js b/devtools/shared/specs/descriptors/process.js
new file mode 100644
index 0000000000..f9cb1d4ce6
--- /dev/null
+++ b/devtools/shared/specs/descriptors/process.js
@@ -0,0 +1,41 @@
+/* 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 {
+ generateActorSpec,
+ RetVal,
+ Option,
+} = require("resource://devtools/shared/protocol.js");
+
+const processDescriptorSpec = generateActorSpec({
+ typeName: "processDescriptor",
+
+ methods: {
+ getTarget: {
+ request: {},
+ response: {
+ process: RetVal("json"),
+ },
+ },
+ getWatcher: {
+ request: {},
+ response: RetVal("watcher"),
+ },
+ reloadDescriptor: {
+ request: {
+ bypassCache: Option(0, "boolean"),
+ },
+ response: {},
+ },
+ },
+
+ events: {
+ "descriptor-destroyed": {
+ type: "descriptor-destroyed",
+ },
+ },
+});
+
+exports.processDescriptorSpec = processDescriptorSpec;
diff --git a/devtools/shared/specs/descriptors/tab.js b/devtools/shared/specs/descriptors/tab.js
new file mode 100644
index 0000000000..c2c0f69431
--- /dev/null
+++ b/devtools/shared/specs/descriptors/tab.js
@@ -0,0 +1,50 @@
+/* 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 {
+ generateActorSpec,
+ Option,
+ RetVal,
+} = require("resource://devtools/shared/protocol.js");
+
+const tabDescriptorSpec = generateActorSpec({
+ typeName: "tabDescriptor",
+
+ methods: {
+ getTarget: {
+ request: {},
+ response: {
+ frame: RetVal("json"),
+ },
+ },
+ getFavicon: {
+ request: {},
+ response: {
+ favicon: RetVal("string"),
+ },
+ },
+ getWatcher: {
+ request: {
+ isServerTargetSwitchingEnabled: Option(0, "boolean"),
+ isPopupDebuggingEnabled: Option(0, "boolean"),
+ },
+ response: RetVal("watcher"),
+ },
+ reloadDescriptor: {
+ request: {
+ bypassCache: Option(0, "boolean"),
+ },
+ response: {},
+ },
+ },
+
+ events: {
+ "descriptor-destroyed": {
+ type: "descriptor-destroyed",
+ },
+ },
+});
+
+exports.tabDescriptorSpec = tabDescriptorSpec;
diff --git a/devtools/shared/specs/descriptors/webextension.js b/devtools/shared/specs/descriptors/webextension.js
new file mode 100644
index 0000000000..692896fc0a
--- /dev/null
+++ b/devtools/shared/specs/descriptors/webextension.js
@@ -0,0 +1,58 @@
+/* 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 {
+ RetVal,
+ generateActorSpec,
+ Option,
+} = require("resource://devtools/shared/protocol.js");
+
+const webExtensionDescriptorSpec = generateActorSpec({
+ typeName: "webExtensionDescriptor",
+
+ methods: {
+ reload: {
+ request: {},
+ response: { addon: RetVal("json") },
+ },
+
+ terminateBackgroundScript: {
+ request: {},
+ response: {},
+ },
+
+ // @backward-compat { version 70 } The method is now called getTarget
+ connect: {
+ request: {},
+ response: { form: RetVal("json") },
+ },
+
+ getTarget: {
+ request: {},
+ response: { form: RetVal("json") },
+ },
+
+ reloadDescriptor: {
+ request: {
+ bypassCache: Option(0, "boolean"),
+ },
+ response: {},
+ },
+ getWatcher: {
+ request: {
+ isServerTargetSwitchingEnabled: Option(0, "boolean"),
+ },
+ response: RetVal("watcher"),
+ },
+ },
+
+ events: {
+ "descriptor-destroyed": {
+ type: "descriptor-destroyed",
+ },
+ },
+});
+
+exports.webExtensionDescriptorSpec = webExtensionDescriptorSpec;
diff --git a/devtools/shared/specs/descriptors/worker.js b/devtools/shared/specs/descriptors/worker.js
new file mode 100644
index 0000000000..1bf21bcc0a
--- /dev/null
+++ b/devtools/shared/specs/descriptors/worker.js
@@ -0,0 +1,32 @@
+/* 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 {
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const workerDescriptorSpec = generateActorSpec({
+ typeName: "workerDescriptor",
+
+ methods: {
+ detach: {
+ request: {},
+ response: {},
+ },
+ getTarget: {
+ request: {},
+ response: RetVal("json"),
+ },
+ },
+
+ events: {
+ "descriptor-destroyed": {
+ type: "descriptor-destroyed",
+ },
+ },
+});
+
+exports.workerDescriptorSpec = workerDescriptorSpec;
diff --git a/devtools/shared/specs/device.js b/devtools/shared/specs/device.js
new file mode 100644
index 0000000000..cfe392950d
--- /dev/null
+++ b/devtools/shared/specs/device.js
@@ -0,0 +1,18 @@
+/* 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 {
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+const deviceSpec = generateActorSpec({
+ typeName: "device",
+
+ methods: {
+ getDescription: { request: {}, response: { value: RetVal("json") } },
+ },
+});
+
+exports.deviceSpec = deviceSpec;
diff --git a/devtools/shared/specs/environment.js b/devtools/shared/specs/environment.js
new file mode 100644
index 0000000000..e98d906838
--- /dev/null
+++ b/devtools/shared/specs/environment.js
@@ -0,0 +1,14 @@
+/* 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 { generateActorSpec } = require("resource://devtools/shared/protocol.js");
+
+const environmentSpec = generateActorSpec({
+ typeName: "environment",
+
+ methods: {},
+});
+
+exports.environmentSpec = environmentSpec;
diff --git a/devtools/shared/specs/frame.js b/devtools/shared/specs/frame.js
new file mode 100644
index 0000000000..03127e1d9f
--- /dev/null
+++ b/devtools/shared/specs/frame.js
@@ -0,0 +1,21 @@
+/* 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 {
+ generateActorSpec,
+ RetVal,
+} = require("resource://devtools/shared/protocol.js");
+
+const frameSpec = generateActorSpec({
+ typeName: "frame",
+
+ methods: {
+ getEnvironment: {
+ response: RetVal("json"),
+ },
+ },
+});
+
+exports.frameSpec = frameSpec;
diff --git a/devtools/shared/specs/heap-snapshot-file.js b/devtools/shared/specs/heap-snapshot-file.js
new file mode 100644
index 0000000000..9153fce005
--- /dev/null
+++ b/devtools/shared/specs/heap-snapshot-file.js
@@ -0,0 +1,23 @@
+/* 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 {
+ Arg,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const heapSnapshotFileSpec = generateActorSpec({
+ typeName: "heapSnapshotFile",
+
+ methods: {
+ transferHeapSnapshot: {
+ request: {
+ snapshotId: Arg(0, "string"),
+ },
+ },
+ },
+});
+
+exports.heapSnapshotFileSpec = heapSnapshotFileSpec;
diff --git a/devtools/shared/specs/highlighters.js b/devtools/shared/specs/highlighters.js
new file mode 100644
index 0000000000..94d437f797
--- /dev/null
+++ b/devtools/shared/specs/highlighters.js
@@ -0,0 +1,44 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const customHighlighterSpec = generateActorSpec({
+ typeName: "customhighlighter",
+
+ events: {
+ "highlighter-event": {
+ type: "highlighter-event",
+ data: Arg(0, "json"),
+ },
+ },
+
+ methods: {
+ release: {
+ release: true,
+ },
+ show: {
+ request: {
+ node: Arg(0, "nullable:domnode"),
+ options: Arg(1, "nullable:json"),
+ },
+ response: {
+ value: RetVal("nullable:boolean"),
+ },
+ },
+ hide: {
+ request: {},
+ },
+ finalize: {
+ oneway: true,
+ },
+ },
+});
+
+exports.customHighlighterSpec = customHighlighterSpec;
diff --git a/devtools/shared/specs/index.js b/devtools/shared/specs/index.js
new file mode 100644
index 0000000000..29f04c4b2f
--- /dev/null
+++ b/devtools/shared/specs/index.js
@@ -0,0 +1,404 @@
+/* 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";
+
+// Registry indexing all specs and front modules
+//
+// All spec and front modules should be listed here
+// in order to be referenced by any other spec or front module.
+
+// Declare in which spec module and front module a set of types are defined.
+// This array should be sorted by `spec` attribute, and this is verified in the
+// test devtools/shared/protocol/tests/xpcshell/test_protocol_index.js
+const Types = (exports.__TypesForTests = [
+ {
+ types: [
+ "accessible",
+ "accessiblewalker",
+ "accessibility",
+ "parentaccessibility",
+ ],
+ spec: "devtools/shared/specs/accessibility",
+ front: "devtools/client/fronts/accessibility",
+ },
+ {
+ types: ["addons"],
+ spec: "devtools/shared/specs/addon/addons",
+ front: "devtools/client/fronts/addon/addons",
+ },
+ {
+ types: ["webExtensionInspectedWindow"],
+ spec: "devtools/shared/specs/addon/webextension-inspected-window",
+ front: "devtools/client/fronts/addon/webextension-inspected-window",
+ },
+ {
+ types: ["animationplayer", "animations"],
+ spec: "devtools/shared/specs/animation",
+ front: "devtools/client/fronts/animation",
+ },
+ {
+ types: ["arraybuffer"],
+ spec: "devtools/shared/specs/array-buffer",
+ front: "devtools/client/fronts/array-buffer",
+ },
+ {
+ types: ["blackboxing"],
+ spec: "devtools/shared/specs/blackboxing",
+ front: "devtools/client/fronts/blackboxing",
+ },
+ {
+ types: ["breakpoint-list"],
+ spec: "devtools/shared/specs/breakpoint-list",
+ front: "devtools/client/fronts/breakpoint-list",
+ },
+ {
+ types: ["changes"],
+ spec: "devtools/shared/specs/changes",
+ front: "devtools/client/fronts/changes",
+ },
+ {
+ types: ["compatibility"],
+ spec: "devtools/shared/specs/compatibility",
+ front: "devtools/client/fronts/compatibility",
+ },
+ {
+ types: ["cssProperties"],
+ spec: "devtools/shared/specs/css-properties",
+ front: "devtools/client/fronts/css-properties",
+ },
+ {
+ types: ["processDescriptor"],
+ spec: "devtools/shared/specs/descriptors/process",
+ front: "devtools/client/fronts/descriptors/process",
+ },
+ {
+ types: ["tabDescriptor"],
+ spec: "devtools/shared/specs/descriptors/tab",
+ front: "devtools/client/fronts/descriptors/tab",
+ },
+ {
+ types: ["webExtensionDescriptor"],
+ spec: "devtools/shared/specs/descriptors/webextension",
+ front: "devtools/client/fronts/descriptors/webextension",
+ },
+ {
+ types: ["workerDescriptor"],
+ spec: "devtools/shared/specs/descriptors/worker",
+ front: "devtools/client/fronts/descriptors/worker",
+ },
+ {
+ types: ["device"],
+ spec: "devtools/shared/specs/device",
+ front: "devtools/client/fronts/device",
+ },
+ {
+ types: ["environment"],
+ spec: "devtools/shared/specs/environment",
+ front: null,
+ },
+ {
+ types: ["frame"],
+ spec: "devtools/shared/specs/frame",
+ front: "devtools/client/fronts/frame",
+ },
+ /* heap snapshot has old fashion client and no front */
+ {
+ types: ["heapSnapshotFile"],
+ spec: "devtools/shared/specs/heap-snapshot-file",
+ front: null,
+ },
+ {
+ types: ["customhighlighter"],
+ spec: "devtools/shared/specs/highlighters",
+ front: "devtools/client/fronts/highlighters",
+ },
+ {
+ types: ["inspector"],
+ spec: "devtools/shared/specs/inspector",
+ front: "devtools/client/fronts/inspector",
+ },
+ {
+ types: ["flexbox", "grid", "layout"],
+ spec: "devtools/shared/specs/layout",
+ front: "devtools/client/fronts/layout",
+ },
+ {
+ types: ["manifest"],
+ spec: "devtools/shared/specs/manifest",
+ front: "devtools/client/fronts/manifest",
+ },
+ {
+ types: ["memory"],
+ spec: "devtools/shared/specs/memory",
+ front: "devtools/client/fronts/memory",
+ },
+ {
+ types: ["networkContent"],
+ spec: "devtools/shared/specs/network-content",
+ front: "devtools/client/fronts/network-content",
+ },
+ {
+ types: ["netEvent"],
+ spec: "devtools/shared/specs/network-event",
+ front: null,
+ },
+ {
+ types: ["networkParent"],
+ spec: "devtools/shared/specs/network-parent",
+ front: "devtools/client/fronts/network-parent",
+ },
+ /* imageData isn't an actor but just a DictType */
+ {
+ types: ["imageData", "disconnectedNode", "disconnectedNodeArray"],
+ spec: "devtools/shared/specs/node",
+ front: null,
+ },
+ {
+ types: ["domnode", "domnodelist"],
+ spec: "devtools/shared/specs/node",
+ front: "devtools/client/fronts/node",
+ },
+ {
+ types: ["obj", "object.descriptor"],
+ spec: "devtools/shared/specs/object",
+ front: null,
+ },
+ {
+ types: ["pagestyle"],
+ spec: "devtools/shared/specs/page-style",
+ front: "devtools/client/fronts/page-style",
+ },
+ {
+ types: ["perf"],
+ spec: "devtools/shared/specs/perf",
+ front: "devtools/client/fronts/perf",
+ },
+ {
+ types: ["preference"],
+ spec: "devtools/shared/specs/preference",
+ front: "devtools/client/fronts/preference",
+ },
+ {
+ types: ["privatePropertiesIterator"],
+ spec: "devtools/shared/specs/private-properties-iterator",
+ front: "devtools/client/fronts/private-properties-iterator",
+ },
+ {
+ types: ["propertyIterator"],
+ spec: "devtools/shared/specs/property-iterator",
+ front: "devtools/client/fronts/property-iterator",
+ },
+ {
+ types: ["reflow"],
+ spec: "devtools/shared/specs/reflow",
+ front: "devtools/client/fronts/reflow",
+ },
+ {
+ types: ["responsive"],
+ spec: "devtools/shared/specs/responsive",
+ front: "devtools/client/fronts/responsive",
+ },
+ {
+ types: ["root"],
+ spec: "devtools/shared/specs/root",
+ front: "devtools/client/fronts/root",
+ },
+ {
+ types: ["screenshot"],
+ spec: "devtools/shared/specs/screenshot",
+ front: "devtools/client/fronts/screenshot",
+ },
+ {
+ types: ["screenshot-content"],
+ spec: "devtools/shared/specs/screenshot-content",
+ front: "devtools/client/fronts/screenshot-content",
+ },
+ {
+ types: ["source"],
+ spec: "devtools/shared/specs/source",
+ front: "devtools/client/fronts/source",
+ },
+ {
+ types: [
+ "Cache",
+ "cookies",
+ "localStorage",
+ "extensionStorage",
+ "indexedDB",
+ "sessionStorage",
+ ],
+ spec: "devtools/shared/specs/storage",
+ front: "devtools/client/fronts/storage",
+ },
+ /* longstring is special, it has a wrapper type. See its spec module */
+ {
+ types: ["longstring"],
+ spec: "devtools/shared/specs/string",
+ front: null,
+ },
+ {
+ types: ["longstractor"],
+ spec: "devtools/shared/specs/string",
+ front: "devtools/client/fronts/string",
+ },
+ {
+ types: ["domstylerule"],
+ spec: "devtools/shared/specs/style-rule",
+ front: "devtools/client/fronts/style-rule",
+ },
+ {
+ types: ["stylesheets"],
+ spec: "devtools/shared/specs/style-sheets",
+ front: "devtools/client/fronts/style-sheets",
+ },
+ {
+ types: ["symbol"],
+ spec: "devtools/shared/specs/symbol",
+ front: null,
+ },
+ {
+ types: ["symbolIterator"],
+ spec: "devtools/shared/specs/symbol-iterator",
+ front: "devtools/client/fronts/symbol-iterator",
+ },
+ {
+ types: ["target-configuration"],
+ spec: "devtools/shared/specs/target-configuration",
+ front: "devtools/client/fronts/target-configuration",
+ },
+ {
+ types: ["contentProcessTarget"],
+ spec: "devtools/shared/specs/targets/content-process",
+ front: null,
+ },
+ {
+ types: ["parentProcessTarget"],
+ spec: "devtools/shared/specs/targets/parent-process",
+ front: null,
+ },
+ {
+ types: ["webExtensionTarget"],
+ spec: "devtools/shared/specs/targets/webextension",
+ front: null,
+ },
+ {
+ types: ["windowGlobalTarget"],
+ spec: "devtools/shared/specs/targets/window-global",
+ front: "devtools/client/fronts/targets/window-global",
+ },
+ {
+ types: ["workerTarget"],
+ spec: "devtools/shared/specs/targets/worker",
+ front: "devtools/client/fronts/targets/worker",
+ },
+ {
+ types: ["thread"],
+ spec: "devtools/shared/specs/thread",
+ front: "devtools/client/fronts/thread",
+ },
+ {
+ types: ["thread-configuration"],
+ spec: "devtools/shared/specs/thread-configuration",
+ front: "devtools/client/fronts/thread-configuration",
+ },
+ {
+ types: ["tracer"],
+ spec: "devtools/shared/specs/tracer",
+ front: "devtools/client/fronts/tracer",
+ },
+ {
+ types: ["domwalker"],
+ spec: "devtools/shared/specs/walker",
+ front: "devtools/client/fronts/walker",
+ },
+ {
+ types: ["watcher"],
+ spec: "devtools/shared/specs/watcher",
+ front: "devtools/client/fronts/watcher",
+ },
+ {
+ types: ["console"],
+ spec: "devtools/shared/specs/webconsole",
+ front: "devtools/client/fronts/webconsole",
+ },
+ {
+ types: ["pushSubscription"],
+ spec: "devtools/shared/specs/worker/push-subscription",
+ front: "devtools/client/fronts/worker/push-subscription",
+ },
+ {
+ types: ["serviceWorker"],
+ spec: "devtools/shared/specs/worker/service-worker",
+ front: "devtools/client/fronts/worker/service-worker",
+ },
+ {
+ types: ["serviceWorkerRegistration"],
+ spec: "devtools/shared/specs/worker/service-worker-registration",
+ front: "devtools/client/fronts/worker/service-worker-registration",
+ },
+]);
+
+const lazySpecs = new Map();
+const lazyFronts = new Map();
+
+// Convert the human readable `Types` list into efficient maps
+Types.forEach(item => {
+ item.types.forEach(type => {
+ lazySpecs.set(type, item.spec);
+ lazyFronts.set(type, item.front);
+ });
+});
+
+/**
+ * Try lazy loading spec module for the given type.
+ *
+ * @param [string] type
+ * Type name
+ *
+ * @returns true, if it matched a lazy loaded type and tried to load it.
+ */
+function lazyLoadSpec(type) {
+ const modulePath = lazySpecs.get(type);
+ if (modulePath) {
+ try {
+ require(modulePath);
+ } catch (e) {
+ throw new Error(
+ `Unable to load lazy spec module '${modulePath}' for type '${type}'.
+ Error: ${e}`
+ );
+ }
+ lazySpecs.delete(type);
+ return true;
+ }
+ return false;
+}
+exports.lazyLoadSpec = lazyLoadSpec;
+
+/**
+ * Try lazy loading front module for the given type.
+ *
+ * @param [string] type
+ * Type name
+ *
+ * @returns true, if it matched a lazy loaded type and tried to load it.
+ */
+function lazyLoadFront(type) {
+ const modulePath = lazyFronts.get(type);
+ if (modulePath) {
+ try {
+ require(modulePath);
+ } catch (e) {
+ throw new Error(
+ `Unable to load lazy front module '${modulePath}' for type '${type}'.
+ Error: ${e}`
+ );
+ }
+ lazyFronts.delete(type);
+ return true;
+ }
+ return false;
+}
+exports.lazyLoadFront = lazyLoadFront;
diff --git a/devtools/shared/specs/inspector.js b/devtools/shared/specs/inspector.js
new file mode 100644
index 0000000000..949532f9c4
--- /dev/null
+++ b/devtools/shared/specs/inspector.js
@@ -0,0 +1,79 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const inspectorSpec = generateActorSpec({
+ typeName: "inspector",
+
+ events: {
+ "color-picked": {
+ type: "colorPicked",
+ color: Arg(0, "string"),
+ },
+ "color-pick-canceled": {
+ type: "colorPickCanceled",
+ },
+ },
+
+ methods: {
+ getWalker: {
+ request: {
+ options: Arg(0, "nullable:json"),
+ },
+ response: {
+ walker: RetVal("domwalker"),
+ },
+ },
+ getPageStyle: {
+ request: {},
+ response: {
+ pageStyle: RetVal("pagestyle"),
+ },
+ },
+ getCompatibility: {
+ request: {},
+ response: {
+ compatibility: RetVal("compatibility"),
+ },
+ },
+ getHighlighterByType: {
+ request: {
+ typeName: Arg(0),
+ },
+ response: {
+ highlighter: RetVal("nullable:customhighlighter"),
+ },
+ },
+ getImageDataFromURL: {
+ request: { url: Arg(0), maxDim: Arg(1, "nullable:number") },
+ response: RetVal("imageData"),
+ },
+ resolveRelativeURL: {
+ request: { url: Arg(0, "string"), node: Arg(1, "nullable:domnode") },
+ response: { value: RetVal("string") },
+ },
+ pickColorFromPage: {
+ request: { options: Arg(0, "nullable:json") },
+ response: {},
+ },
+ cancelPickColorFromPage: {
+ request: {},
+ response: {},
+ },
+ supportsHighlighters: {
+ request: {},
+ response: {
+ value: RetVal("boolean"),
+ },
+ },
+ },
+});
+
+exports.inspectorSpec = inspectorSpec;
diff --git a/devtools/shared/specs/layout.js b/devtools/shared/specs/layout.js
new file mode 100644
index 0000000000..69371cd023
--- /dev/null
+++ b/devtools/shared/specs/layout.js
@@ -0,0 +1,75 @@
+/* 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 {
+ Arg,
+ generateActorSpec,
+ RetVal,
+} = require("resource://devtools/shared/protocol.js");
+
+const flexboxSpec = generateActorSpec({
+ typeName: "flexbox",
+
+ methods: {
+ getFlexItems: {
+ request: {},
+ response: {
+ flexitems: RetVal("array:flexitem"),
+ },
+ },
+ },
+});
+
+const flexItemSpec = generateActorSpec({
+ typeName: "flexitem",
+
+ methods: {},
+});
+
+const gridSpec = generateActorSpec({
+ typeName: "grid",
+
+ methods: {},
+});
+
+const layoutSpec = generateActorSpec({
+ typeName: "layout",
+
+ methods: {
+ getCurrentFlexbox: {
+ request: {
+ node: Arg(0, "domnode"),
+ onlyLookAtParents: Arg(1, "nullable:boolean"),
+ },
+ response: {
+ flexbox: RetVal("nullable:flexbox"),
+ },
+ },
+
+ getCurrentGrid: {
+ request: {
+ node: Arg(0, "domnode"),
+ },
+ response: {
+ grid: RetVal("nullable:grid"),
+ },
+ },
+
+ getGrids: {
+ request: {
+ rootNode: Arg(0, "domnode"),
+ },
+ response: {
+ grids: RetVal("array:grid"),
+ },
+ },
+ },
+});
+
+exports.flexboxSpec = flexboxSpec;
+exports.flexItemSpec = flexItemSpec;
+exports.gridSpec = gridSpec;
+exports.layoutSpec = layoutSpec;
diff --git a/devtools/shared/specs/manifest.js b/devtools/shared/specs/manifest.js
new file mode 100644
index 0000000000..ecddacca33
--- /dev/null
+++ b/devtools/shared/specs/manifest.js
@@ -0,0 +1,21 @@
+/* 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 {
+ generateActorSpec,
+ RetVal,
+} = require("resource://devtools/shared/protocol.js");
+
+const manifestSpec = generateActorSpec({
+ typeName: "manifest",
+ methods: {
+ fetchCanonicalManifest: {
+ request: {},
+ response: RetVal("json"),
+ },
+ },
+});
+
+exports.manifestSpec = manifestSpec;
diff --git a/devtools/shared/specs/memory.js b/devtools/shared/specs/memory.js
new file mode 100644
index 0000000000..b70999c9f1
--- /dev/null
+++ b/devtools/shared/specs/memory.js
@@ -0,0 +1,124 @@
+/* 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 {
+ Arg,
+ RetVal,
+ types,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("AllocationsRecordingOptions", {
+ // The probability we sample any given allocation when recording
+ // allocations. Must be between 0.0 and 1.0. Defaults to 1.0, or sampling
+ // every allocation.
+ probability: "number",
+
+ // The maximum number of of allocation events to keep in the allocations
+ // log. If new allocations arrive, when we are already at capacity, the oldest
+ // allocation event is lost. This number must fit in a 32 bit signed integer.
+ maxLogLength: "number",
+});
+
+const memorySpec = generateActorSpec({
+ typeName: "memory",
+
+ /**
+ * The set of unsolicited events the MemoryActor emits that will be sent over
+ * the RDP (by protocol.js).
+ */
+ events: {
+ // Same format as the data passed to the
+ // `Debugger.Memory.prototype.onGarbageCollection` hook. See
+ // `js/src/doc/Debugger/Debugger.Memory.md` for documentation.
+ "garbage-collection": {
+ type: "garbage-collection",
+ data: Arg(0, "json"),
+ },
+
+ // Same data as the data from `getAllocations` -- only fired if
+ // `autoDrain` set during `startRecordingAllocations`.
+ allocations: {
+ type: "allocations",
+ data: Arg(0, "json"),
+ },
+ },
+
+ methods: {
+ attach: {
+ request: {},
+ response: {
+ type: RetVal("string"),
+ },
+ },
+ detach: {
+ request: {},
+ response: {
+ type: RetVal("string"),
+ },
+ },
+ getState: {
+ response: {
+ state: RetVal(0, "string"),
+ },
+ },
+ takeCensus: {
+ request: {},
+ response: RetVal("json"),
+ },
+ startRecordingAllocations: {
+ request: {
+ options: Arg(0, "nullable:AllocationsRecordingOptions"),
+ },
+ response: {
+ // Accept `nullable` in the case of server Gecko <= 37, handled on the front
+ value: RetVal(0, "nullable:number"),
+ },
+ },
+ stopRecordingAllocations: {
+ request: {},
+ response: {
+ // Accept `nullable` in the case of server Gecko <= 37, handled on the front
+ value: RetVal(0, "nullable:number"),
+ },
+ },
+ getAllocationsSettings: {
+ request: {},
+ response: {
+ options: RetVal(0, "json"),
+ },
+ },
+ getAllocations: {
+ request: {},
+ response: RetVal("json"),
+ },
+ forceGarbageCollection: {
+ request: {},
+ response: {},
+ },
+ forceCycleCollection: {
+ request: {},
+ response: {},
+ },
+ measure: {
+ request: {},
+ response: RetVal("json"),
+ },
+ residentUnique: {
+ request: {},
+ response: { value: RetVal("number") },
+ },
+ saveHeapSnapshot: {
+ request: {
+ boundaries: Arg(0, "nullable:json"),
+ },
+ response: {
+ snapshotId: RetVal("string"),
+ },
+ },
+ },
+});
+
+exports.memorySpec = memorySpec;
diff --git a/devtools/shared/specs/moz.build b/devtools/shared/specs/moz.build
new file mode 100644
index 0000000000..dd917465ad
--- /dev/null
+++ b/devtools/shared/specs/moz.build
@@ -0,0 +1,63 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DIRS += [
+ "addon",
+ "descriptors",
+ "style",
+ "targets",
+ "worker",
+]
+
+DevToolsModules(
+ "accessibility.js",
+ "animation.js",
+ "array-buffer.js",
+ "blackboxing.js",
+ "breakpoint-list.js",
+ "changes.js",
+ "compatibility.js",
+ "css-properties.js",
+ "device.js",
+ "environment.js",
+ "frame.js",
+ "heap-snapshot-file.js",
+ "highlighters.js",
+ "index.js",
+ "inspector.js",
+ "layout.js",
+ "manifest.js",
+ "memory.js",
+ "network-content.js",
+ "network-event.js",
+ "network-parent.js",
+ "node.js",
+ "object.js",
+ "page-style.js",
+ "perf.js",
+ "preference.js",
+ "private-properties-iterator.js",
+ "property-iterator.js",
+ "reflow.js",
+ "responsive.js",
+ "root.js",
+ "screenshot-content.js",
+ "screenshot.js",
+ "source.js",
+ "storage.js",
+ "string.js",
+ "style-rule.js",
+ "style-sheets.js",
+ "symbol-iterator.js",
+ "symbol.js",
+ "target-configuration.js",
+ "thread-configuration.js",
+ "thread.js",
+ "tracer.js",
+ "walker.js",
+ "watcher.js",
+ "webconsole.js",
+)
diff --git a/devtools/shared/specs/network-content.js b/devtools/shared/specs/network-content.js
new file mode 100644
index 0000000000..4c262ea59b
--- /dev/null
+++ b/devtools/shared/specs/network-content.js
@@ -0,0 +1,32 @@
+/* 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 {
+ generateActorSpec,
+ RetVal,
+ Arg,
+} = require("resource://devtools/shared/protocol.js");
+
+const networkContentSpec = generateActorSpec({
+ typeName: "networkContent",
+ methods: {
+ sendHTTPRequest: {
+ request: {
+ request: Arg(0, "json"),
+ },
+ response: RetVal("number"),
+ },
+ getStackTrace: {
+ request: { resourceId: Arg(0) },
+ response: {
+ // stacktrace is an "array:string", but not always.
+ stacktrace: RetVal("json"),
+ },
+ },
+ },
+});
+
+exports.networkContentSpec = networkContentSpec;
diff --git a/devtools/shared/specs/network-event.js b/devtools/shared/specs/network-event.js
new file mode 100644
index 0000000000..3f1cfe8538
--- /dev/null
+++ b/devtools/shared/specs/network-event.js
@@ -0,0 +1,220 @@
+/* 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 {
+ Arg,
+ Option,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("netevent.headers-cookies", {
+ name: "string",
+ value: "longstring",
+});
+
+types.addDictType("netevent.headers", {
+ headers: "array:netevent.headers-cookies",
+ headersSize: "number",
+ rawHeaders: "nullable:longstring",
+});
+
+types.addDictType("netevent.cookies", {
+ cookies: "array:netevent.headers-cookies",
+});
+
+types.addDictType("netevent.postdata.text", {
+ text: "longstring",
+});
+
+types.addDictType("netevent.postdata", {
+ postData: "netevent.postdata.text",
+ postDataDiscarded: "boolean",
+});
+
+types.addDictType("netevent.cache", {
+ content: "json",
+});
+
+types.addDictType("netevent.content.content", {
+ text: "longstring",
+});
+
+types.addDictType("netevent.content", {
+ content: "netevent.content.content",
+ contentDiscarded: "boolean",
+});
+
+types.addDictType("netevent.timings.data", {
+ blocked: "number",
+ dns: "number",
+ ssl: "number",
+ connect: "number",
+ send: "number",
+ wait: "number",
+ receive: "number",
+});
+
+types.addDictType("netevent.timings", {
+ timings: "netevent.timings.data",
+ totalTime: "number",
+ offsets: "netevent.timings.data",
+ serverTimings: "array:netevent.timings.serverTiming",
+});
+
+types.addDictType("netevent.timings.serverTiming", {
+ name: "string",
+ description: "string",
+ duration: "number",
+});
+
+// See NetworkHelper.parseCertificateInfo for more details
+types.addDictType("netevent.cert", {
+ subject: "json",
+ issuer: "json",
+ validity: "json",
+ fingerprint: "json",
+});
+
+types.addDictType("netevent.secinfo", {
+ state: "string",
+ weaknessReasons: "array:string",
+ cipherSuite: "string",
+ keaGroupName: "string",
+ signatureSchemeName: "string",
+ protocolVersion: "string",
+ cert: "nullable:netevent.cert",
+ certificateTransparency: "number",
+ hsts: "boolean",
+ hpkp: "boolean",
+ errorMessage: "nullable:string",
+ usedEch: "boolean",
+ usedDelegatedCredentials: "boolean",
+ usedOcsp: "boolean",
+ usedPrivateDns: "boolean",
+});
+
+const networkEventSpec = generateActorSpec({
+ typeName: "netEvent",
+
+ events: {
+ // All these events end up emitting a `networkEventUpdate` RDP message
+ // `updateType` attribute allows to identify which kind of event is emitted.
+ // We use individual event at protocol.js level to workaround performance issue
+ // with `Option` types. (See bug 1449162)
+ "network-event-update:headers": {
+ type: "networkEventUpdate",
+ updateType: Arg(0, "string"),
+
+ headers: Option(1, "number"),
+ headersSize: Option(1, "number"),
+ },
+
+ "network-event-update:cookies": {
+ type: "networkEventUpdate",
+ updateType: Arg(0, "string"),
+
+ cookies: Option(1, "number"),
+ },
+
+ "network-event-update:post-data": {
+ type: "networkEventUpdate",
+ updateType: Arg(0, "string"),
+
+ dataSize: Option(1, "number"),
+ },
+
+ "network-event-update:response-start": {
+ type: "networkEventUpdate",
+ updateType: Arg(0, "string"),
+
+ response: Option(1, "json"),
+ },
+
+ "network-event-update:security-info": {
+ type: "networkEventUpdate",
+ updateType: Arg(0, "string"),
+
+ state: Option(1, "string"),
+ isRacing: Option(1, "boolean"),
+ },
+
+ "network-event-update:response-content": {
+ type: "networkEventUpdate",
+ updateType: Arg(0, "string"),
+
+ mimeType: Option(1, "string"),
+ contentSize: Option(1, "number"),
+ encoding: Option(1, "string"),
+ transferredSize: Option(1, "number"),
+ blockedReason: Option(1, "number"),
+ blockingExtension: Option(1, "string"),
+ },
+
+ "network-event-update:event-timings": {
+ type: "networkEventUpdate",
+ updateType: Arg(0, "string"),
+
+ totalTime: Option(1, "number"),
+ },
+
+ "network-event-update:response-cache": {
+ type: "networkEventUpdate",
+ updateType: Arg(0, "string"),
+ },
+ },
+
+ methods: {
+ release: {
+ // This makes protocol.js call destroy method
+ release: true,
+ },
+ getRequestHeaders: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getRequestCookies: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getRequestPostData: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getResponseHeaders: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getResponseCookies: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getResponseCache: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getResponseContent: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getEventTimings: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getSecurityInfo: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getStackTrace: {
+ request: {},
+ // stacktrace is an "array:string", but not always.
+ response: RetVal("json"),
+ },
+ },
+});
+
+exports.networkEventSpec = networkEventSpec;
diff --git a/devtools/shared/specs/network-parent.js b/devtools/shared/specs/network-parent.js
new file mode 100644
index 0000000000..7438081eea
--- /dev/null
+++ b/devtools/shared/specs/network-parent.js
@@ -0,0 +1,82 @@
+/* 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 {
+ generateActorSpec,
+ Arg,
+ RetVal,
+} = require("resource://devtools/shared/protocol.js");
+
+const networkParentSpec = generateActorSpec({
+ typeName: "networkParent",
+
+ methods: {
+ setPersist: {
+ request: {
+ options: Arg(0, "boolean"),
+ },
+ response: {},
+ },
+ setNetworkThrottling: {
+ request: {
+ options: Arg(0, "json"),
+ },
+ response: {},
+ },
+ getNetworkThrottling: {
+ request: {},
+ response: {
+ state: RetVal("json"),
+ },
+ },
+ clearNetworkThrottling: {
+ request: {},
+ response: {},
+ },
+ setSaveRequestAndResponseBodies: {
+ request: {
+ save: Arg(0, "boolean"),
+ },
+ response: {},
+ },
+ setBlockedUrls: {
+ request: {
+ urls: Arg(0, "array:string"),
+ },
+ },
+ getBlockedUrls: {
+ request: {},
+ response: {
+ urls: RetVal("array:string"),
+ },
+ },
+ blockRequest: {
+ request: {
+ filters: Arg(0, "json"),
+ },
+ response: {},
+ },
+ unblockRequest: {
+ request: {
+ filters: Arg(0, "json"),
+ },
+ response: {},
+ },
+ override: {
+ request: {
+ url: Arg(0, "string"),
+ path: Arg(1, "string"),
+ },
+ },
+ removeOverride: {
+ request: {
+ url: Arg(0, "string"),
+ },
+ },
+ },
+});
+
+exports.networkParentSpec = networkParentSpec;
diff --git a/devtools/shared/specs/node.js b/devtools/shared/specs/node.js
new file mode 100644
index 0000000000..1daeb48a33
--- /dev/null
+++ b/devtools/shared/specs/node.js
@@ -0,0 +1,160 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("imageData", {
+ // The image data
+ data: "nullable:longstring",
+ // The original image dimensions
+ size: "json",
+});
+
+types.addDictType("windowDimensions", {
+ // The window innerWidth
+ innerWidth: "nullable:number",
+ // The window innerHeight
+ innerHeight: "nullable:number",
+});
+
+/**
+ * Returned from any call that might return a node that isn't connected to root
+ * by nodes the child has seen, such as querySelector.
+ */
+types.addDictType("disconnectedNode", {
+ // The actual node to return
+ node: "domnode",
+
+ // Nodes that are needed to connect the node to a node the client has already
+ // seen
+ newParents: "array:domnode",
+});
+
+types.addDictType("disconnectedNodeArray", {
+ // The actual node list to return
+ nodes: "array:domnode",
+
+ // Nodes that are needed to connect those nodes to the root.
+ newParents: "array:domnode",
+});
+
+const nodeListSpec = generateActorSpec({
+ typeName: "domnodelist",
+
+ methods: {
+ item: {
+ request: { item: Arg(0) },
+ response: RetVal("disconnectedNode"),
+ },
+ items: {
+ request: {
+ start: Arg(0, "nullable:number"),
+ end: Arg(1, "nullable:number"),
+ },
+ response: RetVal("disconnectedNodeArray"),
+ },
+ release: {
+ release: true,
+ },
+ },
+});
+
+exports.nodeListSpec = nodeListSpec;
+
+const nodeSpec = generateActorSpec({
+ typeName: "domnode",
+
+ methods: {
+ getNodeValue: {
+ request: {},
+ response: {
+ value: RetVal("longstring"),
+ },
+ },
+ setNodeValue: {
+ request: { value: Arg(0) },
+ response: {},
+ },
+ getUniqueSelector: {
+ request: {},
+ response: {
+ value: RetVal("string"),
+ },
+ },
+ getCssPath: {
+ request: {},
+ response: {
+ value: RetVal("string"),
+ },
+ },
+ getXPath: {
+ request: {},
+ response: {
+ value: RetVal("string"),
+ },
+ },
+ scrollIntoView: {
+ request: {},
+ response: {},
+ },
+ getImageData: {
+ request: { maxDim: Arg(0, "nullable:number") },
+ response: RetVal("imageData"),
+ },
+ getEventListenerInfo: {
+ request: {},
+ response: {
+ events: RetVal("json"),
+ },
+ },
+ enableEventListener: {
+ request: {
+ eventListenerInfoId: Arg(0),
+ },
+ response: {},
+ },
+ disableEventListener: {
+ request: {
+ eventListenerInfoId: Arg(0),
+ },
+ response: {},
+ },
+ modifyAttributes: {
+ request: {
+ modifications: Arg(0, "array:json"),
+ },
+ response: {},
+ },
+ getFontFamilyDataURL: {
+ request: { font: Arg(0, "string"), fillStyle: Arg(1, "nullable:string") },
+ response: RetVal("imageData"),
+ },
+ getClosestBackgroundColor: {
+ request: {},
+ response: {
+ value: RetVal("string"),
+ },
+ },
+ getBackgroundColor: {
+ request: {},
+ response: RetVal("json"),
+ },
+ getOwnerGlobalDimensions: {
+ request: {},
+ response: RetVal("windowDimensions"),
+ },
+ waitForFrameLoad: {
+ request: {},
+ response: {},
+ },
+ },
+});
+
+exports.nodeSpec = nodeSpec;
diff --git a/devtools/shared/specs/object.js b/devtools/shared/specs/object.js
new file mode 100644
index 0000000000..7af82cc419
--- /dev/null
+++ b/devtools/shared/specs/object.js
@@ -0,0 +1,214 @@
+/* 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 {
+ generateActorSpec,
+ Arg,
+ RetVal,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("object.descriptor", {
+ configurable: "boolean",
+ enumerable: "boolean",
+ // Can be null if there is a getter for the property.
+ value: "nullable:json",
+ // Only set `value` exists.
+ writable: "nullable:boolean",
+ // Only set when `value` does not exist and there is a getter for the property.
+ get: "nullable:json",
+ // Only set when `value` does not exist and there is a setter for the property.
+ set: "nullable:json",
+});
+
+types.addDictType("object.completion", {
+ return: "nullable:json",
+ throw: "nullable:json",
+});
+
+types.addDictType("object.prototypeproperties", {
+ prototype: "object.descriptor",
+ ownProperties: "nullable:json",
+ ownSymbols: "nullable:array:object.descriptor",
+ safeGetterValues: "nullable:json",
+});
+
+types.addDictType("object.prototype", {
+ prototype: "object.descriptor",
+});
+
+types.addDictType("object.property", {
+ descriptor: "nullable:object.descriptor",
+});
+
+types.addDictType("object.propertyValue", {
+ value: "nullable:object.completion",
+});
+
+types.addDictType("object.apply", {
+ value: "nullable:object.completion",
+});
+
+types.addDictType("object.bindings", {
+ arguments: "array:json",
+ variables: "json",
+});
+
+types.addDictType("object.enumProperties.Options", {
+ enumEntries: "nullable:boolean",
+ ignoreNonIndexedProperties: "nullable:boolean",
+ ignoreIndexedProperties: "nullable:boolean",
+ query: "nullable:string",
+ sort: "nullable:boolean",
+});
+
+types.addDictType("object.dependentPromises", {
+ promises: "array:object.descriptor",
+});
+
+types.addDictType("object.originalSourceLocation", {
+ source: "source",
+ line: "number",
+ column: "number",
+ functionDisplayName: "string",
+});
+
+types.addDictType("object.promiseState", {
+ state: "string",
+ value: "nullable:object.descriptor",
+ reason: "nullable:object.descriptor",
+ creationTimestamp: "number",
+ timeToSettle: "nullable:number",
+});
+
+types.addDictType("object.proxySlots", {
+ proxyTarget: "object.descriptor",
+ proxyHandler: "object.descriptor",
+});
+
+types.addDictType("object.customFormatterBody", {
+ customFormatterBody: "json",
+});
+
+const objectSpec = generateActorSpec({
+ typeName: "obj",
+ methods: {
+ allocationStack: {
+ request: {},
+ response: {
+ allocationStack: RetVal("array:object.originalSourceLocation"),
+ },
+ },
+ dependentPromises: {
+ request: {},
+ response: RetVal("object.dependentPromises"),
+ },
+ enumEntries: {
+ request: {},
+ response: {
+ iterator: RetVal("propertyIterator"),
+ },
+ },
+ enumProperties: {
+ request: {
+ options: Arg(0, "nullable:object.enumProperties.Options"),
+ },
+ response: {
+ iterator: RetVal("propertyIterator"),
+ },
+ },
+ enumPrivateProperties: {
+ request: {},
+ response: {
+ iterator: RetVal("privatePropertiesIterator"),
+ },
+ },
+ enumSymbols: {
+ request: {},
+ response: {
+ iterator: RetVal("symbolIterator"),
+ },
+ },
+ fulfillmentStack: {
+ request: {},
+ response: {
+ fulfillmentStack: RetVal("array:object.originalSourceLocation"),
+ },
+ },
+ prototypeAndProperties: {
+ request: {},
+ response: RetVal("object.prototypeproperties"),
+ },
+ prototype: {
+ request: {},
+ response: RetVal("object.prototype"),
+ },
+ property: {
+ request: {
+ name: Arg(0, "string"),
+ },
+ response: RetVal("object.property"),
+ },
+ propertyValue: {
+ request: {
+ name: Arg(0, "string"),
+ receiverId: Arg(1, "nullable:string"),
+ },
+ response: RetVal("object.propertyValue"),
+ },
+ apply: {
+ request: {
+ context: Arg(0, "nullable:json"),
+ arguments: Arg(1, "nullable:array:json"),
+ },
+ response: RetVal("object.apply"),
+ },
+ rejectionStack: {
+ request: {},
+ response: {
+ rejectionStack: RetVal("array:object.originalSourceLocation"),
+ },
+ },
+ promiseState: {
+ request: {},
+ response: RetVal("object.promiseState"),
+ },
+ proxySlots: {
+ request: {},
+ response: RetVal("object.proxySlots"),
+ },
+ customFormatterBody: {
+ request: {},
+ response: RetVal("object.customFormatterBody"),
+ },
+ addWatchpoint: {
+ request: {
+ property: Arg(0, "string"),
+ label: Arg(1, "string"),
+ watchpointType: Arg(2, "string"),
+ },
+ oneway: true,
+ },
+ removeWatchpoint: {
+ request: {
+ property: Arg(0, "string"),
+ },
+ oneway: true,
+ },
+ removeWatchpoints: {
+ request: {},
+ oneway: true,
+ },
+ release: { release: true },
+ // Needed for the PauseScopedObjectActor which extends the ObjectActor.
+ threadGrip: {
+ request: {},
+ response: {},
+ },
+ },
+});
+
+exports.objectSpec = objectSpec;
diff --git a/devtools/shared/specs/page-style.js b/devtools/shared/specs/page-style.js
new file mode 100644
index 0000000000..ffdec07611
--- /dev/null
+++ b/devtools/shared/specs/page-style.js
@@ -0,0 +1,126 @@
+/* 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 {
+ Arg,
+ Option,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+// Load the shared types for style actors
+require("resource://devtools/shared/specs/style/style-types.js");
+
+const pageStyleSpec = generateActorSpec({
+ typeName: "pagestyle",
+
+ events: {
+ "stylesheet-updated": {
+ type: "styleSheetUpdated",
+ },
+ },
+
+ methods: {
+ getComputed: {
+ request: {
+ node: Arg(0, "domnode"),
+ markMatched: Option(1, "boolean"),
+ onlyMatched: Option(1, "boolean"),
+ filter: Option(1, "string"),
+ filterProperties: Option(1, "nullable:array:string"),
+ },
+ response: {
+ computed: RetVal("json"),
+ },
+ },
+ getAllUsedFontFaces: {
+ request: {
+ includePreviews: Option(0, "boolean"),
+ includeVariations: Option(1, "boolean"),
+ previewText: Option(0, "string"),
+ previewFontSize: Option(0, "string"),
+ previewFillStyle: Option(0, "string"),
+ },
+ response: {
+ fontFaces: RetVal("array:fontface"),
+ },
+ },
+ getUsedFontFaces: {
+ request: {
+ node: Arg(0, "domnode"),
+ includePreviews: Option(1, "boolean"),
+ includeVariations: Option(1, "boolean"),
+ previewText: Option(1, "string"),
+ previewFontSize: Option(1, "string"),
+ previewFillStyle: Option(1, "string"),
+ },
+ response: {
+ fontFaces: RetVal("array:fontface"),
+ },
+ },
+ getMatchedSelectors: {
+ request: {
+ node: Arg(0, "domnode"),
+ property: Arg(1, "string"),
+ filter: Option(2, "string"),
+ },
+ response: RetVal(
+ types.addDictType("matchedselectorresponse", {
+ rules: "array:domstylerule",
+ matched: "array:matchedselector",
+ })
+ ),
+ },
+ getRule: {
+ request: {
+ ruleId: Arg(0, "string"),
+ },
+ response: {
+ rule: RetVal("nullable:domstylerule"),
+ },
+ },
+ getApplied: {
+ request: {
+ node: Arg(0, "domnode"),
+ inherited: Option(1, "boolean"),
+ matchedSelectors: Option(1, "boolean"),
+ skipPseudo: Option(1, "boolean"),
+ filter: Option(1, "string"),
+ },
+ response: RetVal("appliedStylesReturn"),
+ },
+ isPositionEditable: {
+ request: { node: Arg(0, "domnode") },
+ response: { value: RetVal("boolean") },
+ },
+ getLayout: {
+ request: {
+ node: Arg(0, "domnode"),
+ autoMargins: Option(1, "boolean"),
+ },
+ response: RetVal("json"),
+ },
+ addNewRule: {
+ request: {
+ node: Arg(0, "domnode"),
+ pseudoClasses: Arg(1, "nullable:array:string"),
+ },
+ response: RetVal("appliedStylesReturn"),
+ },
+ getAttributesInOwnerDocument: {
+ request: {
+ search: Arg(0, "string"),
+ attributeType: Arg(1, "string"),
+ node: Arg(2, "nullable:domnode"),
+ },
+ response: {
+ attributes: RetVal("array:string"),
+ },
+ },
+ },
+});
+
+exports.pageStyleSpec = pageStyleSpec;
diff --git a/devtools/shared/specs/perf.js b/devtools/shared/specs/perf.js
new file mode 100644
index 0000000000..de8f9ffb21
--- /dev/null
+++ b/devtools/shared/specs/perf.js
@@ -0,0 +1,90 @@
+/* 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 {
+ Arg,
+ Option,
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const perfDescription = {
+ typeName: "perf",
+
+ events: {
+ "profiler-started": {
+ type: "profiler-started",
+ entries: Arg(0, "number"),
+ interval: Arg(1, "number"),
+ features: Arg(2, "number"),
+ duration: Arg(3, "nullable:number"),
+ // The `activeTabID` option passed to `profiler_start` is used to
+ // determine the active tab when user starts the profiler.
+ // This is a parameter that is generated on the
+ // server, that's why we don't need to pass anything on `startProfiler`
+ // actor method. But we return this in "profiler-started" event because
+ // client may want to use that value.
+ activeTabID: Arg(4, "number"),
+ },
+ "profiler-stopped": {
+ type: "profiler-stopped",
+ },
+ },
+
+ methods: {
+ startProfiler: {
+ request: {
+ entries: Option(0, "number"),
+ duration: Option(0, "nullable:number"),
+ interval: Option(0, "number"),
+ features: Option(0, "array:string"),
+ threads: Option(0, "array:string"),
+ },
+ response: { value: RetVal("boolean") },
+ },
+
+ /**
+ * Returns null when unable to return the profile.
+ */
+ getProfileAndStopProfiler: {
+ request: {},
+ response: RetVal("nullable:json"),
+ },
+
+ stopProfilerAndDiscardProfile: {
+ request: {},
+ response: {},
+ },
+
+ getSymbolTable: {
+ request: {
+ debugPath: Arg(0, "string"),
+ breakpadId: Arg(1, "string"),
+ },
+ response: { value: RetVal("array:array:number") },
+ },
+
+ isActive: {
+ request: {},
+ response: { value: RetVal("boolean") },
+ },
+
+ isSupportedPlatform: {
+ request: {},
+ response: { value: RetVal("boolean") },
+ },
+
+ getSupportedFeatures: {
+ request: {},
+ response: { value: RetVal("array:string") },
+ },
+ },
+};
+
+exports.perfDescription = perfDescription;
+
+const perfSpec = generateActorSpec(perfDescription);
+
+exports.perfSpec = perfSpec;
diff --git a/devtools/shared/specs/preference.js b/devtools/shared/specs/preference.js
new file mode 100644
index 0000000000..b8d33261d4
--- /dev/null
+++ b/devtools/shared/specs/preference.js
@@ -0,0 +1,55 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const preferenceSpec = generateActorSpec({
+ typeName: "preference",
+
+ methods: {
+ getTraits: {
+ request: {},
+ response: { traits: RetVal("json") },
+ },
+ getBoolPref: {
+ request: { value: Arg(0) },
+ response: { value: RetVal("boolean") },
+ },
+ getCharPref: {
+ request: { value: Arg(0) },
+ response: { value: RetVal("string") },
+ },
+ getIntPref: {
+ request: { value: Arg(0) },
+ response: { value: RetVal("number") },
+ },
+ getAllPrefs: {
+ request: {},
+ response: { value: RetVal("json") },
+ },
+ setBoolPref: {
+ request: { name: Arg(0), value: Arg(1) },
+ response: {},
+ },
+ setCharPref: {
+ request: { name: Arg(0), value: Arg(1) },
+ response: {},
+ },
+ setIntPref: {
+ request: { name: Arg(0), value: Arg(1) },
+ response: {},
+ },
+ clearUserPref: {
+ request: { name: Arg(0) },
+ response: {},
+ },
+ },
+});
+
+exports.preferenceSpec = preferenceSpec;
diff --git a/devtools/shared/specs/private-properties-iterator.js b/devtools/shared/specs/private-properties-iterator.js
new file mode 100644
index 0000000000..ef967d0698
--- /dev/null
+++ b/devtools/shared/specs/private-properties-iterator.js
@@ -0,0 +1,42 @@
+/* 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 {
+ generateActorSpec,
+ Option,
+ RetVal,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("privatepropertiesiterator.data", {
+ privateProperties: "array:privatepropertiesiterator.privateProperties",
+});
+
+types.addDictType("privatepropertiesiterator.privateProperties", {
+ name: "string",
+ descriptor: "nullable:object.descriptor",
+});
+
+const privatePropertiesIteratorSpec = generateActorSpec({
+ typeName: "privatePropertiesIterator",
+
+ methods: {
+ slice: {
+ request: {
+ start: Option(0, "number"),
+ count: Option(0, "number"),
+ },
+ response: RetVal("privatepropertiesiterator.data"),
+ },
+ all: {
+ request: {},
+ response: RetVal("privatepropertiesiterator.data"),
+ },
+ release: { release: true },
+ },
+});
+
+exports.privatePropertiesIteratorSpec = privatePropertiesIteratorSpec;
diff --git a/devtools/shared/specs/property-iterator.js b/devtools/shared/specs/property-iterator.js
new file mode 100644
index 0000000000..991a8cede1
--- /dev/null
+++ b/devtools/shared/specs/property-iterator.js
@@ -0,0 +1,45 @@
+/* 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 {
+ generateActorSpec,
+ Option,
+ RetVal,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("propertyiterator.data", {
+ ownProperties: "nullable:json",
+});
+
+const propertyIteratorSpec = generateActorSpec({
+ typeName: "propertyIterator",
+
+ methods: {
+ names: {
+ request: {
+ indexes: Option(0, "array:number"),
+ },
+ response: {
+ names: RetVal("array:string"),
+ },
+ },
+ slice: {
+ request: {
+ start: Option(0, "number"),
+ count: Option(0, "number"),
+ },
+ response: RetVal("propertyiterator.data"),
+ },
+ all: {
+ request: {},
+ response: RetVal("propertyiterator.data"),
+ },
+ release: { release: true },
+ },
+});
+
+exports.propertyIteratorSpec = propertyIteratorSpec;
diff --git a/devtools/shared/specs/reflow.js b/devtools/shared/specs/reflow.js
new file mode 100644
index 0000000000..9a6993ecbb
--- /dev/null
+++ b/devtools/shared/specs/reflow.js
@@ -0,0 +1,36 @@
+/* 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 {
+ Arg,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const reflowSpec = generateActorSpec({
+ typeName: "reflow",
+
+ events: {
+ /**
+ * The reflows event is emitted when reflows have been detected. The event
+ * is sent with an array of reflows that occured. Each item has the
+ * following properties:
+ * - start {Number}
+ * - end {Number}
+ * - isInterruptible {Boolean}
+ */
+ reflows: {
+ type: "reflows",
+ reflows: Arg(0, "array:json"),
+ },
+ },
+
+ methods: {
+ start: { oneway: true },
+ stop: { oneway: true },
+ },
+});
+
+exports.reflowSpec = reflowSpec;
diff --git a/devtools/shared/specs/responsive.js b/devtools/shared/specs/responsive.js
new file mode 100644
index 0000000000..49b04f7391
--- /dev/null
+++ b/devtools/shared/specs/responsive.js
@@ -0,0 +1,40 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const responsiveSpec = generateActorSpec({
+ typeName: "responsive",
+
+ methods: {
+ toggleTouchSimulator: {
+ request: {
+ options: Arg(0, "json"),
+ },
+ response: {
+ valueChanged: RetVal("boolean"),
+ },
+ },
+
+ setElementPickerState: {
+ request: {
+ state: Arg(0, "boolean"),
+ pickerType: Arg(1, "string"),
+ },
+ response: {},
+ },
+
+ dispatchOrientationChangeEvent: {
+ request: {},
+ response: {},
+ },
+ },
+});
+
+exports.responsiveSpec = responsiveSpec;
diff --git a/devtools/shared/specs/root.js b/devtools/shared/specs/root.js
new file mode 100644
index 0000000000..f48f3b6262
--- /dev/null
+++ b/devtools/shared/specs/root.js
@@ -0,0 +1,139 @@
+/* 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,
+ Arg,
+ Option,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("root.listWorkers", {
+ workers: "array:workerDescriptor",
+});
+types.addDictType("root.listServiceWorkerRegistrations", {
+ registrations: "array:serviceWorkerRegistration",
+});
+
+const rootSpecPrototype = {
+ typeName: "root",
+
+ methods: {
+ getRoot: {
+ request: {},
+ response: RetVal("json"),
+ },
+
+ listTabs: {
+ request: {},
+ response: {
+ tabs: RetVal("array:tabDescriptor"),
+ },
+ },
+
+ getTab: {
+ request: {
+ browserId: Option(0, "number"),
+ },
+ response: {
+ tab: RetVal("tabDescriptor"),
+ },
+ },
+
+ listAddons: {
+ request: {
+ iconDataURL: Option(0, "boolean"),
+ },
+ response: {
+ addons: RetVal("array:webExtensionDescriptor"),
+ },
+ },
+
+ listWorkers: {
+ request: {},
+ response: RetVal("root.listWorkers"),
+ },
+
+ listServiceWorkerRegistrations: {
+ request: {},
+ response: RetVal("root.listServiceWorkerRegistrations"),
+ },
+
+ listProcesses: {
+ request: {},
+ response: {
+ processes: RetVal("array:processDescriptor"),
+ },
+ },
+
+ getProcess: {
+ request: {
+ id: Arg(0, "number"),
+ },
+ response: {
+ processDescriptor: RetVal("processDescriptor"),
+ },
+ },
+
+ watchResources: {
+ request: {
+ resourceTypes: Arg(0, "array:string"),
+ },
+ response: {},
+ },
+
+ unwatchResources: {
+ request: {
+ resourceTypes: Arg(0, "array:string"),
+ },
+ oneway: true,
+ },
+
+ clearResources: {
+ request: {
+ resourceTypes: Arg(0, "array:string"),
+ },
+ oneway: true,
+ },
+
+ requestTypes: {
+ request: {},
+ response: RetVal("json"),
+ },
+ },
+
+ events: {
+ tabListChanged: {
+ type: "tabListChanged",
+ },
+ workerListChanged: {
+ type: "workerListChanged",
+ },
+ addonListChanged: {
+ type: "addonListChanged",
+ },
+ serviceWorkerRegistrationListChanged: {
+ type: "serviceWorkerRegistrationListChanged",
+ },
+ processListChanged: {
+ type: "processListChanged",
+ },
+
+ "resource-available-form": {
+ type: "resource-available-form",
+ resources: Arg(0, "array:json"),
+ },
+ "resource-destroyed-form": {
+ type: "resource-destroyed-form",
+ resources: Arg(0, "array:json"),
+ },
+ },
+};
+
+const rootSpec = generateActorSpec(rootSpecPrototype);
+
+exports.rootSpecPrototype = rootSpecPrototype;
+exports.rootSpec = rootSpec;
diff --git a/devtools/shared/specs/screenshot-content.js b/devtools/shared/specs/screenshot-content.js
new file mode 100644
index 0000000000..c5205fe5a4
--- /dev/null
+++ b/devtools/shared/specs/screenshot-content.js
@@ -0,0 +1,34 @@
+/* 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 {
+ RetVal,
+ Arg,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("screenshot-content.args", {
+ fullpage: "nullable:boolean",
+ selector: "nullable:string",
+ nodeActorID: "nullable:number",
+});
+
+const screenshotContentSpec = generateActorSpec({
+ typeName: "screenshot-content",
+
+ methods: {
+ prepareCapture: {
+ request: {
+ args: Arg(0, "screenshot-content.args"),
+ },
+ response: {
+ value: RetVal("json"),
+ },
+ },
+ },
+});
+
+exports.screenshotContentSpec = screenshotContentSpec;
diff --git a/devtools/shared/specs/screenshot.js b/devtools/shared/specs/screenshot.js
new file mode 100644
index 0000000000..3aa4a7035f
--- /dev/null
+++ b/devtools/shared/specs/screenshot.js
@@ -0,0 +1,37 @@
+/* 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 {
+ RetVal,
+ Arg,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("screenshot.args", {
+ fullpage: "nullable:boolean",
+ file: "nullable:boolean",
+ clipboard: "nullable:boolean",
+ selector: "nullable:string",
+ dpr: "nullable:string",
+ delay: "nullable:string",
+});
+
+const screenshotSpec = generateActorSpec({
+ typeName: "screenshot",
+
+ methods: {
+ capture: {
+ request: {
+ args: Arg(0, "screenshot.args"),
+ },
+ response: {
+ value: RetVal("json"),
+ },
+ },
+ },
+});
+
+exports.screenshotSpec = screenshotSpec;
diff --git a/devtools/shared/specs/source.js b/devtools/shared/specs/source.js
new file mode 100644
index 0000000000..b2cd2d977a
--- /dev/null
+++ b/devtools/shared/specs/source.js
@@ -0,0 +1,87 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+const longstringType = types.getType("longstring");
+const arraybufferType = types.getType("arraybuffer");
+// The sourcedata type needs some custom marshalling, because it is sometimes
+// returned as an arraybuffer and sometimes as a longstring.
+types.addType("sourcedata", {
+ write: (value, context, detail) => {
+ if (value.typeName === "arraybuffer") {
+ return arraybufferType.write(value, context, detail);
+ }
+ return longstringType.write(value, context, detail);
+ },
+ read: (value, context, detail) => {
+ if (value.typeName === "arraybuffer") {
+ return arraybufferType.read(value, context, detail);
+ }
+ return longstringType.read(value, context, detail);
+ },
+});
+
+types.addDictType("sourceposition", {
+ line: "number",
+ column: "number",
+});
+types.addDictType("nullablesourceposition", {
+ line: "nullable:number",
+ column: "nullable:number",
+});
+types.addDictType("breakpointquery", {
+ start: "nullable:nullablesourceposition",
+ end: "nullable:nullablesourceposition",
+});
+
+types.addDictType("source.onsource", {
+ contentType: "nullable:string",
+ source: "nullable:sourcedata",
+});
+
+const sourceSpec = generateActorSpec({
+ typeName: "source",
+
+ methods: {
+ getBreakpointPositionsCompressed: {
+ request: {
+ query: Arg(0, "nullable:breakpointquery"),
+ },
+ response: {
+ positions: RetVal("json"),
+ },
+ },
+ getBreakableLines: {
+ request: {},
+ response: {
+ lines: RetVal("json"),
+ },
+ },
+ source: {
+ request: {},
+ response: RetVal("source.onsource"),
+ },
+ setPausePoints: {
+ request: {
+ pausePoints: Arg(0, "json"),
+ },
+ },
+ blackbox: {
+ request: { range: Arg(0, "nullable:json") },
+ response: { pausedInSource: RetVal("boolean") },
+ },
+ unblackbox: {
+ request: { range: Arg(0, "nullable:json") },
+ },
+ },
+});
+
+exports.sourceSpec = sourceSpec;
diff --git a/devtools/shared/specs/storage.js b/devtools/shared/specs/storage.js
new file mode 100644
index 0000000000..51ee69fd04
--- /dev/null
+++ b/devtools/shared/specs/storage.js
@@ -0,0 +1,308 @@
+/* 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 protocol = require("resource://devtools/shared/protocol.js");
+const { Arg, RetVal, types } = protocol;
+
+const childSpecs = {};
+
+function createStorageSpec(options) {
+ // common methods for all storage types
+ const methods = {
+ getStoreObjects: {
+ request: {
+ host: Arg(0),
+ names: Arg(1, "nullable:array:string"),
+ options: Arg(2, "nullable:json"),
+ },
+ response: RetVal(options.storeObjectType),
+ },
+ getFields: {
+ request: {
+ subType: Arg(0, "nullable:string"),
+ },
+ response: {
+ value: RetVal("json"),
+ },
+ },
+ };
+
+ // extra methods specific for storage type
+ Object.assign(methods, options.methods);
+
+ childSpecs[options.typeName] = protocol.generateActorSpec({
+ typeName: options.typeName,
+ methods,
+ events: {
+ "single-store-update": {
+ type: "storesUpdate",
+ data: Arg(0, "storeUpdateObject"),
+ },
+ "single-store-cleared": {
+ type: "storesCleared",
+ data: Arg(0, "json"),
+ },
+ },
+ });
+}
+
+// Cookies store object
+types.addDictType("cookieobject", {
+ uniqueKey: "string",
+ name: "string",
+ value: "longstring",
+ path: "nullable:string",
+ host: "string",
+ hostOnly: "boolean",
+ isSecure: "boolean",
+ isHttpOnly: "boolean",
+ creationTime: "number",
+ lastAccessed: "number",
+ expires: "number",
+});
+
+// Array of cookie store objects
+types.addDictType("cookiestoreobject", {
+ total: "number",
+ offset: "number",
+ data: "array:nullable:cookieobject",
+});
+
+// Common methods for edit/remove
+const editRemoveMethods = {
+ getFields: {
+ request: {},
+ response: {
+ value: RetVal("json"),
+ },
+ },
+ editItem: {
+ request: {
+ data: Arg(0, "json"),
+ },
+ response: {},
+ },
+ removeItem: {
+ request: {
+ host: Arg(0, "string"),
+ name: Arg(1, "string"),
+ },
+ response: {},
+ },
+};
+
+// Cookies actor spec
+createStorageSpec({
+ typeName: "cookies",
+ storeObjectType: "cookiestoreobject",
+ methods: Object.assign(
+ {},
+ editRemoveMethods,
+ {
+ addItem: {
+ request: {
+ guid: Arg(0, "string"),
+ host: Arg(1, "nullable:string"),
+ },
+ response: {},
+ },
+ },
+ {
+ removeAll: {
+ request: {
+ host: Arg(0, "string"),
+ domain: Arg(1, "nullable:string"),
+ },
+ response: {},
+ },
+ },
+ {
+ removeAllSessionCookies: {
+ request: {
+ host: Arg(0, "string"),
+ domain: Arg(1, "nullable:string"),
+ },
+ response: {},
+ },
+ }
+ ),
+});
+
+// Local Storage / Session Storage store object
+types.addDictType("storageobject", {
+ name: "string",
+ value: "longstring",
+});
+
+// Common methods for local/session storage
+const storageMethods = Object.assign(
+ {},
+ editRemoveMethods,
+ {
+ addItem: {
+ request: {
+ guid: Arg(0, "string"),
+ host: Arg(1, "nullable:string"),
+ },
+ response: {},
+ },
+ },
+ {
+ removeAll: {
+ request: {
+ host: Arg(0, "string"),
+ },
+ response: {},
+ },
+ }
+);
+
+// Array of Local Storage / Session Storage store objects
+types.addDictType("storagestoreobject", {
+ total: "number",
+ offset: "number",
+ data: "array:nullable:storageobject",
+});
+
+createStorageSpec({
+ typeName: "localStorage",
+ storeObjectType: "storagestoreobject",
+ methods: storageMethods,
+});
+
+createStorageSpec({
+ typeName: "sessionStorage",
+ storeObjectType: "storagestoreobject",
+ methods: storageMethods,
+});
+
+types.addDictType("extensionobject", {
+ name: "nullable:string",
+ value: "nullable:longstring",
+ area: "string",
+ isValueEditable: "boolean",
+});
+
+types.addDictType("extensionstoreobject", {
+ total: "number",
+ offset: "number",
+ data: "array:nullable:extensionobject",
+});
+
+createStorageSpec({
+ typeName: "extensionStorage",
+ storeObjectType: "extensionstoreobject",
+ // Same as storageMethods except for addItem
+ methods: Object.assign({}, editRemoveMethods, {
+ removeAll: {
+ request: {
+ host: Arg(0, "string"),
+ },
+ response: {},
+ },
+ }),
+});
+
+types.addDictType("cacheobject", {
+ url: "string",
+ status: "string",
+});
+
+// Array of Cache store objects
+types.addDictType("cachestoreobject", {
+ total: "number",
+ offset: "number",
+ data: "array:nullable:cacheobject",
+});
+
+// Cache storage spec
+createStorageSpec({
+ typeName: "Cache",
+ storeObjectType: "cachestoreobject",
+ methods: {
+ removeAll: {
+ request: {
+ host: Arg(0, "string"),
+ name: Arg(1, "string"),
+ },
+ response: {},
+ },
+ removeItem: {
+ request: {
+ host: Arg(0, "string"),
+ name: Arg(1, "string"),
+ },
+ response: {},
+ },
+ },
+});
+
+// Indexed DB store object
+// This is a union on idb object, db metadata object and object store metadata
+// object
+types.addDictType("idbobject", {
+ uniqueKey: "string",
+ name: "nullable:string",
+ db: "nullable:string",
+ objectStore: "nullable:string",
+ origin: "nullable:string",
+ version: "nullable:number",
+ storage: "nullable:string",
+ objectStores: "nullable:number",
+ keyPath: "nullable:string",
+ autoIncrement: "nullable:boolean",
+ indexes: "nullable:string",
+ value: "nullable:longstring",
+});
+
+// Array of Indexed DB store objects
+types.addDictType("idbstoreobject", {
+ total: "number",
+ offset: "number",
+ data: "array:nullable:idbobject",
+});
+
+// Result of Indexed DB delete operation: can block or throw error
+types.addDictType("idbdeleteresult", {
+ blocked: "nullable:boolean",
+ error: "nullable:string",
+});
+
+createStorageSpec({
+ typeName: "indexedDB",
+ storeObjectType: "idbstoreobject",
+ methods: {
+ removeDatabase: {
+ request: {
+ host: Arg(0, "string"),
+ name: Arg(1, "string"),
+ },
+ response: RetVal("idbdeleteresult"),
+ },
+ removeAll: {
+ request: {
+ host: Arg(0, "string"),
+ name: Arg(1, "string"),
+ },
+ response: {},
+ },
+ removeItem: {
+ request: {
+ host: Arg(0, "string"),
+ name: Arg(1, "string"),
+ },
+ response: {},
+ },
+ },
+});
+
+// Update notification object
+types.addDictType("storeUpdateObject", {
+ changed: "nullable:json",
+ deleted: "nullable:json",
+ added: "nullable:json",
+});
+
+exports.childSpecs = childSpecs;
diff --git a/devtools/shared/specs/string.js b/devtools/shared/specs/string.js
new file mode 100644
index 0000000000..89b53c0a95
--- /dev/null
+++ b/devtools/shared/specs/string.js
@@ -0,0 +1,85 @@
+/* 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 protocol = require("resource://devtools/shared/protocol.js");
+const { Arg, RetVal, generateActorSpec } = protocol;
+
+const longStringSpec = generateActorSpec({
+ typeName: "longstractor",
+
+ methods: {
+ substring: {
+ request: {
+ start: Arg(0),
+ end: Arg(1),
+ },
+ response: { substring: RetVal() },
+ },
+ release: { release: true },
+ },
+});
+
+exports.longStringSpec = longStringSpec;
+
+/**
+ * When a caller is expecting a LongString actor but the string is already available on
+ * client, the SimpleStringFront can be used as it shares the same API as a
+ * LongStringFront but will not make unnecessary trips to the server.
+ */
+class SimpleStringFront {
+ constructor(str) {
+ this.str = str;
+ }
+
+ get length() {
+ return this.str.length;
+ }
+
+ get initial() {
+ return this.str;
+ }
+
+ string() {
+ return Promise.resolve(this.str);
+ }
+
+ substring(start, end) {
+ return Promise.resolve(this.str.substring(start, end));
+ }
+
+ release() {
+ this.str = null;
+ return Promise.resolve(undefined);
+ }
+}
+
+exports.SimpleStringFront = SimpleStringFront;
+
+// The long string actor needs some custom marshalling, because it is sometimes
+// returned as a primitive rather than a complete form.
+
+var stringActorType = protocol.types.getType("longstractor");
+protocol.types.addType("longstring", {
+ _actor: true,
+ write: (value, context, detail) => {
+ if (!(context instanceof protocol.Actor)) {
+ throw Error("Passing a longstring as an argument isn't supported.");
+ }
+
+ if (value.short) {
+ return value.str;
+ }
+ return stringActorType.write(value, context, detail);
+ },
+ read: (value, context, detail) => {
+ if (context instanceof protocol.Actor) {
+ throw Error("Passing a longstring as an argument isn't supported.");
+ }
+ if (typeof value === "string") {
+ return new SimpleStringFront(value);
+ }
+ return stringActorType.read(value, context, detail);
+ },
+});
diff --git a/devtools/shared/specs/style-rule.js b/devtools/shared/specs/style-rule.js
new file mode 100644
index 0000000000..cb06a578b9
--- /dev/null
+++ b/devtools/shared/specs/style-rule.js
@@ -0,0 +1,73 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+// Load the shared types for style actors
+require("resource://devtools/shared/specs/style/style-types.js");
+
+types.addDictType("domstylerule.queryContainerForNodeReturn", {
+ node: "nullable:domnode",
+ containerType: "nullable:string",
+ blockSize: "nullable:string",
+ inlineSize: "nullable:string",
+});
+
+const styleRuleSpec = generateActorSpec({
+ typeName: "domstylerule",
+
+ events: {
+ "location-changed": {
+ type: "locationChanged",
+ line: Arg(0, "number"),
+ column: Arg(1, "number"),
+ },
+ "rule-updated": {
+ type: "ruleUpdated",
+ rule: Arg(0, "domstylerule"),
+ },
+ },
+
+ methods: {
+ getRuleText: {
+ response: {
+ text: RetVal("string"),
+ },
+ },
+ setRuleText: {
+ request: {
+ newText: Arg(0, "string"),
+ modifications: Arg(1, "array:json"),
+ },
+ response: { rule: RetVal("domstylerule") },
+ },
+ modifyProperties: {
+ request: { modifications: Arg(0, "array:json") },
+ response: { rule: RetVal("domstylerule") },
+ },
+ modifySelector: {
+ request: {
+ node: Arg(0, "domnode"),
+ value: Arg(1, "string"),
+ editAuthored: Arg(2, "boolean"),
+ },
+ response: RetVal("modifiedStylesReturn"),
+ },
+ getQueryContainerForNode: {
+ request: {
+ ancestorRuleIndex: Arg(0, "number"),
+ node: Arg(1, "domnode"),
+ },
+ response: RetVal("domstylerule.queryContainerForNodeReturn"),
+ },
+ },
+});
+
+exports.styleRuleSpec = styleRuleSpec;
diff --git a/devtools/shared/specs/style-sheets.js b/devtools/shared/specs/style-sheets.js
new file mode 100644
index 0000000000..94d3e72f5f
--- /dev/null
+++ b/devtools/shared/specs/style-sheets.js
@@ -0,0 +1,49 @@
+/* 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 {
+ Arg,
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const styleSheetsSpec = generateActorSpec({
+ typeName: "stylesheets",
+
+ events: {},
+
+ methods: {
+ getTraits: {
+ request: {},
+ response: { traits: RetVal("json") },
+ },
+ addStyleSheet: {
+ request: {
+ text: Arg(0, "string"),
+ fileName: Arg(1, "nullable:string"),
+ },
+ response: {},
+ },
+ toggleDisabled: {
+ request: { resourceId: Arg(0, "string") },
+ response: { disabled: RetVal("boolean") },
+ },
+ getText: {
+ request: { resourceId: Arg(0, "string") },
+ response: { text: RetVal("longstring") },
+ },
+ update: {
+ request: {
+ resourceId: Arg(0, "string"),
+ text: Arg(1, "string"),
+ transition: Arg(2, "boolean"),
+ cause: Arg(3, "nullable:string"),
+ },
+ response: {},
+ },
+ },
+});
+
+exports.styleSheetsSpec = styleSheetsSpec;
diff --git a/devtools/shared/specs/style/moz.build b/devtools/shared/specs/style/moz.build
new file mode 100644
index 0000000000..56883cc51a
--- /dev/null
+++ b/devtools/shared/specs/style/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DevToolsModules(
+ "style-types.js",
+)
diff --git a/devtools/shared/specs/style/style-types.js b/devtools/shared/specs/style/style-types.js
new file mode 100644
index 0000000000..0a86353b4d
--- /dev/null
+++ b/devtools/shared/specs/style/style-types.js
@@ -0,0 +1,78 @@
+/* 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 { RetVal, types } = require("resource://devtools/shared/protocol.js");
+
+// Predeclare the domstylerule actor type
+types.addActorType("domstylerule");
+
+/**
+ * When asking for the styles applied to a node, we return a list of
+ * appliedstyle json objects that lists the rules that apply to the node
+ * and which element they were inherited from (if any).
+ *
+ * Note appliedstyle only sends the list of actorIDs and is not a valid return
+ * value on its own. appliedstyle should be returned with the actual list of
+ * StyleRuleActor and StyleSheetActor. See appliedStylesReturn.
+ */
+types.addDictType("appliedstyle", {
+ rule: "domstylerule#actorid",
+ inherited: "nullable:domnode#actorid",
+ keyframes: "nullable:domstylerule#actorid",
+});
+
+types.addDictType("matchedselector", {
+ rule: "domstylerule#actorid",
+ selector: "string",
+ value: "string",
+ status: "number",
+});
+
+types.addDictType("appliedStylesReturn", {
+ entries: "array:appliedstyle",
+ rules: "array:domstylerule",
+});
+
+types.addDictType("modifiedStylesReturn", {
+ isMatching: RetVal("boolean"),
+ ruleProps: RetVal("nullable:appliedStylesReturn"),
+});
+
+types.addDictType("fontpreview", {
+ data: "nullable:longstring",
+ size: "json",
+});
+
+types.addDictType("fontvariationaxis", {
+ tag: "string",
+ name: "string",
+ minValue: "number",
+ maxValue: "number",
+ defaultValue: "number",
+});
+
+types.addDictType("fontvariationinstancevalue", {
+ axis: "string",
+ value: "number",
+});
+
+types.addDictType("fontvariationinstance", {
+ name: "string",
+ values: "array:fontvariationinstancevalue",
+});
+
+types.addDictType("fontface", {
+ name: "string",
+ CSSFamilyName: "string",
+ rule: "nullable:domstylerule",
+ srcIndex: "number",
+ URI: "string",
+ format: "string",
+ preview: "nullable:fontpreview",
+ localName: "string",
+ metadata: "string",
+ variationAxes: "array:fontvariationaxis",
+ variationInstances: "array:fontvariationinstance",
+});
diff --git a/devtools/shared/specs/symbol-iterator.js b/devtools/shared/specs/symbol-iterator.js
new file mode 100644
index 0000000000..c3345bcdd3
--- /dev/null
+++ b/devtools/shared/specs/symbol-iterator.js
@@ -0,0 +1,42 @@
+/* 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 {
+ generateActorSpec,
+ Option,
+ RetVal,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("symboliterator.data", {
+ ownSymbols: "array:symboliterator.ownsymbols",
+});
+
+types.addDictType("symboliterator.ownsymbols", {
+ name: "string",
+ descriptor: "nullable:object.descriptor",
+});
+
+const symbolIteratorSpec = generateActorSpec({
+ typeName: "symbolIterator",
+
+ methods: {
+ slice: {
+ request: {
+ start: Option(0, "number"),
+ count: Option(0, "number"),
+ },
+ response: RetVal("symboliterator.data"),
+ },
+ all: {
+ request: {},
+ response: RetVal("symboliterator.data"),
+ },
+ release: { release: true },
+ },
+});
+
+exports.symbolIteratorSpec = symbolIteratorSpec;
diff --git a/devtools/shared/specs/symbol.js b/devtools/shared/specs/symbol.js
new file mode 100644
index 0000000000..77e44ce1e4
--- /dev/null
+++ b/devtools/shared/specs/symbol.js
@@ -0,0 +1,20 @@
+/* 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 { generateActorSpec } = require("resource://devtools/shared/protocol.js");
+
+const symbolSpec = generateActorSpec({
+ typeName: "symbol",
+
+ methods: {
+ release: {
+ request: {},
+ response: {},
+ },
+ },
+});
+
+exports.symbolSpec = symbolSpec;
diff --git a/devtools/shared/specs/target-configuration.js b/devtools/shared/specs/target-configuration.js
new file mode 100644
index 0000000000..bfad03fe48
--- /dev/null
+++ b/devtools/shared/specs/target-configuration.js
@@ -0,0 +1,50 @@
+/* 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 {
+ generateActorSpec,
+ Arg,
+ RetVal,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("target-configuration.configuration", {
+ cacheDisabled: "nullable:boolean",
+ colorSchemeSimulation: "nullable:string",
+ customFormatters: "nullable:boolean",
+ customUserAgent: "nullable:string",
+ javascriptEnabled: "nullable:boolean",
+ overrideDPPX: "nullable:number",
+ printSimulationEnabled: "nullable:boolean",
+ rdmPaneOrientation: "nullable:json",
+ reloadOnTouchSimulationToggle: "nullable:boolean",
+ restoreFocus: "nullable:boolean",
+ serviceWorkersTestingEnabled: "nullable:boolean",
+ touchEventsOverride: "nullable:string",
+});
+
+const targetConfigurationSpec = generateActorSpec({
+ typeName: "target-configuration",
+
+ methods: {
+ updateConfiguration: {
+ request: {
+ configuration: Arg(0, "target-configuration.configuration"),
+ },
+ response: {
+ configuration: RetVal("target-configuration.configuration"),
+ },
+ },
+ isJavascriptEnabled: {
+ request: {},
+ response: {
+ javascriptEnabled: RetVal("boolean"),
+ },
+ },
+ },
+});
+
+exports.targetConfigurationSpec = targetConfigurationSpec;
diff --git a/devtools/shared/specs/targets/content-process.js b/devtools/shared/specs/targets/content-process.js
new file mode 100644
index 0000000000..3c7edef4a2
--- /dev/null
+++ b/devtools/shared/specs/targets/content-process.js
@@ -0,0 +1,55 @@
+/* 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,
+ Arg,
+ Option,
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("contentProcessTarget.workers", {
+ error: "nullable:string",
+ workers: "nullable:array:workerDescriptor",
+});
+
+const contentProcessTargetSpec = generateActorSpec({
+ typeName: "contentProcessTarget",
+
+ methods: {
+ listWorkers: {
+ request: {},
+ response: RetVal("contentProcessTarget.workers"),
+ },
+
+ pauseMatchingServiceWorkers: {
+ request: {
+ origin: Option(0, "string"),
+ },
+ response: {},
+ },
+ },
+
+ events: {
+ workerListChanged: {
+ type: "workerListChanged",
+ },
+ "resource-available-form": {
+ type: "resource-available-form",
+ resources: Arg(0, "array:json"),
+ },
+ "resource-destroyed-form": {
+ type: "resource-destroyed-form",
+ resources: Arg(0, "array:json"),
+ },
+ "resource-updated-form": {
+ type: "resource-updated-form",
+ resources: Arg(0, "array:json"),
+ },
+ },
+});
+
+exports.contentProcessTargetSpec = contentProcessTargetSpec;
diff --git a/devtools/shared/specs/targets/moz.build b/devtools/shared/specs/targets/moz.build
new file mode 100644
index 0000000000..9c22a1a241
--- /dev/null
+++ b/devtools/shared/specs/targets/moz.build
@@ -0,0 +1,13 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DevToolsModules(
+ "content-process.js",
+ "parent-process.js",
+ "webextension.js",
+ "window-global.js",
+ "worker.js",
+)
diff --git a/devtools/shared/specs/targets/parent-process.js b/devtools/shared/specs/targets/parent-process.js
new file mode 100644
index 0000000000..dca2c777fa
--- /dev/null
+++ b/devtools/shared/specs/targets/parent-process.js
@@ -0,0 +1,24 @@
+/* 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 { generateActorSpec } = require("resource://devtools/shared/protocol.js");
+const { extend } = require("resource://devtools/shared/extend.js");
+const {
+ windowGlobalTargetSpecPrototype,
+} = require("resource://devtools/shared/specs/targets/window-global.js");
+
+const parentProcessTargetSpecPrototype = extend(
+ windowGlobalTargetSpecPrototype,
+ {
+ typeName: "parentProcessTarget",
+ }
+);
+
+const parentProcessTargetSpec = generateActorSpec(
+ parentProcessTargetSpecPrototype
+);
+
+exports.parentProcessTargetSpecPrototype = parentProcessTargetSpecPrototype;
+exports.parentProcessTargetSpec = parentProcessTargetSpec;
diff --git a/devtools/shared/specs/targets/webextension.js b/devtools/shared/specs/targets/webextension.js
new file mode 100644
index 0000000000..4eeffb3da7
--- /dev/null
+++ b/devtools/shared/specs/targets/webextension.js
@@ -0,0 +1,18 @@
+/* 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 { generateActorSpec } = require("resource://devtools/shared/protocol.js");
+const { extend } = require("resource://devtools/shared/extend.js");
+const {
+ parentProcessTargetSpecPrototype,
+} = require("resource://devtools/shared/specs/targets/parent-process.js");
+
+const webExtensionTargetSpec = generateActorSpec(
+ extend(parentProcessTargetSpecPrototype, {
+ typeName: "webExtensionTarget",
+ })
+);
+
+exports.webExtensionTargetSpec = webExtensionTargetSpec;
diff --git a/devtools/shared/specs/targets/window-global.js b/devtools/shared/specs/targets/window-global.js
new file mode 100644
index 0000000000..597e0eb0e8
--- /dev/null
+++ b/devtools/shared/specs/targets/window-global.js
@@ -0,0 +1,156 @@
+/* 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,
+ Arg,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("windowGlobalTarget.switchtoframe", {
+ message: "string",
+});
+
+types.addDictType("windowGlobalTarget.listframes", {
+ frames: "array:windowGlobalTarget.window",
+});
+
+types.addDictType("windowGlobalTarget.window", {
+ id: "string",
+ parentID: "nullable:string",
+ url: "nullable:string", // should be present if not destroying
+ title: "nullable:string", // should be present if not destroying
+ destroy: "nullable:boolean", // not present if not destroying
+});
+
+types.addDictType("windowGlobalTarget.workers", {
+ workers: "array:workerDescriptor",
+});
+
+// @backward-compat { legacy }
+// reload is preserved for third party tools. See Bug 1717837.
+// DevTools should use Descriptor::reloadDescriptor instead.
+types.addDictType("windowGlobalTarget.reload", {
+ force: "boolean",
+});
+
+// @backward-compat { version 87 } See backward-compat note for `reconfigure`.
+types.addDictType("windowGlobalTarget.reconfigure", {
+ cacheDisabled: "nullable:boolean",
+ colorSchemeSimulation: "nullable:string",
+ printSimulationEnabled: "nullable:boolean",
+ restoreFocus: "nullable:boolean",
+ serviceWorkersTestingEnabled: "nullable:boolean",
+});
+
+const windowGlobalTargetSpecPrototype = {
+ typeName: "windowGlobalTarget",
+
+ methods: {
+ detach: {
+ request: {},
+ response: {},
+ },
+ focus: {
+ request: {},
+ response: {},
+ },
+ goForward: {
+ request: {},
+ response: {},
+ },
+ goBack: {
+ request: {},
+ response: {},
+ },
+ // @backward-compat { legacy }
+ // reload is preserved for third party tools. See Bug 1717837.
+ // DevTools should use Descriptor::reloadDescriptor instead.
+ reload: {
+ request: {
+ options: Option(0, "windowGlobalTarget.reload"),
+ },
+ response: {},
+ },
+ navigateTo: {
+ request: {
+ url: Option(0, "string"),
+ },
+ response: {},
+ },
+ // @backward-compat { version 87 } Starting with version 87, targets which
+ // support the watcher will rely on the configuration actor to update their
+ // configuration flags. However we need to keep this request until all
+ // browsing context targets support the watcher (eg webextensions).
+ reconfigure: {
+ request: {
+ options: Option(0, "windowGlobalTarget.reconfigure"),
+ },
+ response: {},
+ },
+ switchToFrame: {
+ request: {
+ windowId: Option(0, "string"),
+ },
+ response: RetVal("windowGlobalTarget.switchtoframe"),
+ },
+ listFrames: {
+ request: {},
+ response: RetVal("windowGlobalTarget.listframes"),
+ },
+ listWorkers: {
+ request: {},
+ response: RetVal("windowGlobalTarget.workers"),
+ },
+ logInPage: {
+ request: {
+ text: Option(0, "string"),
+ category: Option(0, "string"),
+ flags: Option(0, "string"),
+ },
+ response: {},
+ },
+ },
+ events: {
+ tabNavigated: {
+ type: "tabNavigated",
+ url: Option(0, "string"),
+ title: Option(0, "string"),
+ state: Option(0, "string"),
+ isFrameSwitching: Option(0, "boolean"),
+ },
+ frameUpdate: {
+ type: "frameUpdate",
+ frames: Option(0, "nullable:array:windowGlobalTarget.window"),
+ selected: Option(0, "nullable:number"),
+ destroyAll: Option(0, "nullable:boolean"),
+ },
+ workerListChanged: {
+ type: "workerListChanged",
+ },
+
+ "resource-available-form": {
+ type: "resource-available-form",
+ resources: Arg(0, "array:json"),
+ },
+ "resource-destroyed-form": {
+ type: "resource-destroyed-form",
+ resources: Arg(0, "array:json"),
+ },
+ "resource-updated-form": {
+ type: "resource-updated-form",
+ resources: Arg(0, "array:json"),
+ },
+ },
+};
+
+const windowGlobalTargetSpec = generateActorSpec(
+ windowGlobalTargetSpecPrototype
+);
+
+exports.windowGlobalTargetSpecPrototype = windowGlobalTargetSpecPrototype;
+exports.windowGlobalTargetSpec = windowGlobalTargetSpec;
diff --git a/devtools/shared/specs/targets/worker.js b/devtools/shared/specs/targets/worker.js
new file mode 100644
index 0000000000..d329f5b9dd
--- /dev/null
+++ b/devtools/shared/specs/targets/worker.js
@@ -0,0 +1,30 @@
+/* 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 {
+ Arg,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const workerTargetSpec = generateActorSpec({
+ typeName: "workerTarget",
+ methods: {},
+ events: {
+ "resource-available-form": {
+ type: "resource-available-form",
+ resources: Arg(0, "array:json"),
+ },
+ "resource-destroyed-form": {
+ type: "resource-destroyed-form",
+ resources: Arg(0, "array:json"),
+ },
+ "resource-updated-form": {
+ type: "resource-updated-form",
+ resources: Arg(0, "array:json"),
+ },
+ },
+});
+
+exports.workerTargetSpec = workerTargetSpec;
diff --git a/devtools/shared/specs/thread-configuration.js b/devtools/shared/specs/thread-configuration.js
new file mode 100644
index 0000000000..6d412097fe
--- /dev/null
+++ b/devtools/shared/specs/thread-configuration.js
@@ -0,0 +1,31 @@
+/* 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 {
+ generateActorSpec,
+ Arg,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("thread-configuration.configuration", {
+ pauseOnExceptions: "nullable:boolean",
+ ignoreCaughtExceptions: "nullable:boolean",
+});
+
+const threadConfigurationSpec = generateActorSpec({
+ typeName: "thread-configuration",
+
+ methods: {
+ updateConfiguration: {
+ request: {
+ configuration: Arg(0, "thread-configuration.configuration"),
+ },
+ response: {},
+ },
+ },
+});
+
+exports.threadConfigurationSpec = threadConfigurationSpec;
diff --git a/devtools/shared/specs/thread.js b/devtools/shared/specs/thread.js
new file mode 100644
index 0000000000..1a4f862fb1
--- /dev/null
+++ b/devtools/shared/specs/thread.js
@@ -0,0 +1,189 @@
+/* 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 {
+ Arg,
+ Option,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("available-breakpoint-group", {
+ name: "string",
+ events: "array:available-breakpoint-event",
+});
+
+types.addDictType("available-breakpoint-event", {
+ id: "string",
+ name: "string",
+});
+
+types.addDictType("thread.frames", {
+ frames: "array:frame",
+});
+
+types.addDictType("thread.breakpoint-options", {
+ condition: "nullable:string",
+ logValue: "nullable:string",
+});
+
+types.addDictType("paused-reason", {
+ type: "string",
+
+ // Used for any pause type that wants to describe why the pause happened.
+ message: "nullable:string",
+
+ // Used for the stepping pause types.
+ frameFinished: "nullable:json",
+
+ // Used for the "exception" pause type.
+ exception: "nullable:json",
+
+ // Used for the "interrupted" pause type.
+ onNext: "nullable:boolean",
+
+ // Used for the "eventBreakpoint" pause type.
+ breakpoint: "nullable:json",
+
+ // Used for the "mutationBreakpoint" pause type.
+ mutationType: "nullable:string",
+});
+
+const threadSpec = generateActorSpec({
+ typeName: "thread",
+
+ events: {
+ paused: {
+ actor: Option(0, "nullable:string"),
+ frame: Option(0, "frame"),
+ why: Option(0, "paused-reason"),
+ },
+ resumed: {},
+ newSource: {
+ source: Option(0, "json"),
+ },
+ },
+
+ methods: {
+ attach: {
+ request: {
+ options: Arg(0, "json"),
+ },
+ response: {},
+ },
+ reconfigure: {
+ request: {
+ options: Arg(0, "json"),
+ },
+ response: {},
+ },
+ resume: {
+ request: {
+ resumeLimit: Arg(0, "nullable:json"),
+ frameActorID: Arg(1, "nullable:string"),
+ },
+ response: RetVal("nullable:json"),
+ },
+ frames: {
+ request: {
+ start: Arg(0, "number"),
+ count: Arg(1, "number"),
+ },
+ response: RetVal("thread.frames"),
+ },
+ interrupt: {
+ request: {
+ when: Arg(0, "json"),
+ },
+ },
+ sources: {
+ response: {
+ sources: RetVal("array:json"),
+ },
+ },
+ skipBreakpoints: {
+ request: {
+ skip: Arg(0, "json"),
+ },
+ response: {
+ skip: Arg(0, "json"),
+ },
+ },
+ dumpThread: {
+ request: {},
+ response: RetVal("json"),
+ },
+ dumpPools: {
+ request: {},
+ response: RetVal("json"),
+ },
+ setBreakpoint: {
+ request: {
+ location: Arg(0, "json"),
+ options: Arg(1, "thread.breakpoint-options"),
+ },
+ },
+ removeBreakpoint: {
+ request: {
+ location: Arg(0, "json"),
+ },
+ },
+ setXHRBreakpoint: {
+ request: {
+ path: Arg(0, "string"),
+ method: Arg(1, "string"),
+ },
+ response: {
+ value: RetVal("boolean"),
+ },
+ },
+ removeXHRBreakpoint: {
+ request: {
+ path: Arg(0, "string"),
+ method: Arg(1, "string"),
+ },
+ response: {
+ value: RetVal("boolean"),
+ },
+ },
+ getAvailableEventBreakpoints: {
+ response: {
+ value: RetVal("array:available-breakpoint-group"),
+ },
+ },
+ getActiveEventBreakpoints: {
+ response: {
+ ids: RetVal("array:string"),
+ },
+ },
+ setActiveEventBreakpoints: {
+ request: {
+ ids: Arg(0, "array:string"),
+ },
+ },
+ pauseOnExceptions: {
+ request: {
+ pauseOnExceptions: Arg(0, "string"),
+ ignoreCaughtExceptions: Arg(1, "string"),
+ },
+ },
+
+ toggleEventLogging: {
+ request: {
+ logEventBreakpoints: Arg(0, "string"),
+ },
+ },
+
+ isAttached: {
+ request: {},
+ response: {
+ value: RetVal("boolean"),
+ },
+ },
+ },
+});
+
+exports.threadSpec = threadSpec;
diff --git a/devtools/shared/specs/tracer.js b/devtools/shared/specs/tracer.js
new file mode 100644
index 0000000000..78ac609457
--- /dev/null
+++ b/devtools/shared/specs/tracer.js
@@ -0,0 +1,27 @@
+/* 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 {
+ generateActorSpec,
+ Arg,
+} = require("resource://devtools/shared/protocol.js");
+
+const tracerSpec = generateActorSpec({
+ typeName: "tracer",
+
+ methods: {
+ startTracing: {
+ request: {
+ logMethod: Arg(0, "string"),
+ },
+ },
+ stopTracing: {
+ request: {},
+ },
+ },
+});
+
+exports.tracerSpec = tracerSpec;
diff --git a/devtools/shared/specs/walker.js b/devtools/shared/specs/walker.js
new file mode 100644
index 0000000000..b66311b720
--- /dev/null
+++ b/devtools/shared/specs/walker.js
@@ -0,0 +1,389 @@
+/* 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 {
+ Arg,
+ Option,
+ RetVal,
+ generateActorSpec,
+ types,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("dommutation", {});
+
+types.addDictType("searchresult", {
+ list: "domnodelist",
+ // Right now there is isn't anything required for metadata,
+ // but it's json so it can be extended with extra data.
+ metadata: "array:json",
+});
+
+// Some common request/response templates for the dom walker
+
+var nodeArrayMethod = {
+ request: {
+ node: Arg(0, "domnode"),
+ maxNodes: Option(1),
+ center: Option(1, "domnode"),
+ start: Option(1, "domnode"),
+ },
+ response: RetVal(
+ types.addDictType("domtraversalarray", {
+ nodes: "array:domnode",
+ })
+ ),
+};
+
+var traversalMethod = {
+ request: {
+ node: Arg(0, "domnode"),
+ },
+ response: {
+ node: RetVal("nullable:domnode"),
+ },
+};
+
+const walkerSpec = generateActorSpec({
+ typeName: "domwalker",
+
+ events: {
+ "new-mutations": {
+ type: "newMutations",
+ },
+ "root-available": {
+ type: "root-available",
+ node: Arg(0, "nullable:domnode"),
+ },
+ "root-destroyed": {
+ type: "root-destroyed",
+ node: Arg(0, "nullable:domnode"),
+ },
+ "picker-node-picked": {
+ type: "pickerNodePicked",
+ node: Arg(0, "disconnectedNode"),
+ },
+ "picker-node-previewed": {
+ type: "pickerNodePreviewed",
+ node: Arg(0, "disconnectedNode"),
+ },
+ "picker-node-hovered": {
+ type: "pickerNodeHovered",
+ node: Arg(0, "disconnectedNode"),
+ },
+ "picker-node-canceled": {
+ type: "pickerNodeCanceled",
+ },
+ "display-change": {
+ type: "display-change",
+ nodes: Arg(0, "array:domnode"),
+ },
+ "scrollable-change": {
+ type: "scrollable-change",
+ nodes: Arg(0, "array:domnode"),
+ },
+ "overflow-change": {
+ type: "overflow-change",
+ nodes: Arg(0, "array:domnode"),
+ },
+ // The walker actor emits a useful "resize" event to its front to let
+ // clients know when the browser window gets resized. This may be useful
+ // for refreshing a DOM node's styles for example, since those may depend on
+ // media-queries.
+ resize: {
+ type: "resize",
+ },
+ },
+
+ methods: {
+ release: {
+ release: true,
+ },
+ document: {
+ request: { node: Arg(0, "nullable:domnode") },
+ response: { node: RetVal("domnode") },
+ },
+ documentElement: {
+ request: { node: Arg(0, "nullable:domnode") },
+ response: { node: RetVal("domnode") },
+ },
+ retainNode: {
+ request: { node: Arg(0, "domnode") },
+ response: {},
+ },
+ unretainNode: {
+ request: { node: Arg(0, "domnode") },
+ response: {},
+ },
+ releaseNode: {
+ request: {
+ node: Arg(0, "domnode"),
+ force: Option(1),
+ },
+ },
+ children: nodeArrayMethod,
+ nextSibling: traversalMethod,
+ previousSibling: traversalMethod,
+ findInspectingNode: {
+ request: {},
+ response: RetVal("disconnectedNode"),
+ },
+ querySelector: {
+ request: {
+ node: Arg(0, "domnode"),
+ selector: Arg(1),
+ },
+ response: RetVal("disconnectedNode"),
+ },
+ querySelectorAll: {
+ request: {
+ node: Arg(0, "domnode"),
+ selector: Arg(1),
+ },
+ response: {
+ list: RetVal("domnodelist"),
+ },
+ },
+ search: {
+ request: {
+ query: Arg(0),
+ },
+ response: {
+ list: RetVal("searchresult"),
+ },
+ },
+ getSuggestionsForQuery: {
+ request: {
+ query: Arg(0),
+ completing: Arg(1),
+ selectorState: Arg(2),
+ },
+ response: {
+ list: RetVal("array:array:string"),
+ },
+ },
+ addPseudoClassLock: {
+ request: {
+ node: Arg(0, "domnode"),
+ pseudoClass: Arg(1),
+ parents: Option(2),
+ enabled: Option(2, "boolean"),
+ },
+ response: {},
+ },
+ hideNode: {
+ request: { node: Arg(0, "domnode") },
+ },
+ unhideNode: {
+ request: { node: Arg(0, "domnode") },
+ },
+ removePseudoClassLock: {
+ request: {
+ node: Arg(0, "domnode"),
+ pseudoClass: Arg(1),
+ parents: Option(2),
+ },
+ response: {},
+ },
+ clearPseudoClassLocks: {
+ request: {
+ node: Arg(0, "nullable:domnode"),
+ },
+ response: {},
+ },
+ innerHTML: {
+ request: {
+ node: Arg(0, "domnode"),
+ },
+ response: {
+ value: RetVal("longstring"),
+ },
+ },
+ setInnerHTML: {
+ request: {
+ node: Arg(0, "domnode"),
+ value: Arg(1, "string"),
+ },
+ response: {},
+ },
+ outerHTML: {
+ request: {
+ node: Arg(0, "domnode"),
+ },
+ response: {
+ value: RetVal("longstring"),
+ },
+ },
+ setOuterHTML: {
+ request: {
+ node: Arg(0, "domnode"),
+ value: Arg(1, "string"),
+ },
+ response: {},
+ },
+ insertAdjacentHTML: {
+ request: {
+ node: Arg(0, "domnode"),
+ position: Arg(1, "string"),
+ value: Arg(2, "string"),
+ },
+ response: RetVal("disconnectedNodeArray"),
+ },
+ duplicateNode: {
+ request: {
+ node: Arg(0, "domnode"),
+ },
+ response: {},
+ },
+ removeNode: {
+ request: {
+ node: Arg(0, "domnode"),
+ },
+ response: {
+ nextSibling: RetVal("nullable:domnode"),
+ },
+ },
+ removeNodes: {
+ request: {
+ node: Arg(0, "array:domnode"),
+ },
+ response: {},
+ },
+ insertBefore: {
+ request: {
+ node: Arg(0, "domnode"),
+ parent: Arg(1, "domnode"),
+ sibling: Arg(2, "nullable:domnode"),
+ },
+ response: {},
+ },
+ editTagName: {
+ request: {
+ node: Arg(0, "domnode"),
+ tagName: Arg(1, "string"),
+ },
+ response: {},
+ },
+ getMutations: {
+ request: {
+ cleanup: Option(0),
+ },
+ response: {
+ mutations: RetVal("array:dommutation"),
+ },
+ },
+ isInDOMTree: {
+ request: { node: Arg(0, "domnode") },
+ response: { attached: RetVal("boolean") },
+ },
+ getNodeActorFromWindowID: {
+ request: {
+ windowID: Arg(0, "string"),
+ },
+ response: {
+ nodeFront: RetVal("nullable:disconnectedNode"),
+ },
+ },
+ getNodeActorFromContentDomReference: {
+ request: {
+ contentDomReference: Arg(0, "json"),
+ },
+ response: {
+ nodeFront: RetVal("nullable:disconnectedNode"),
+ },
+ },
+ getStyleSheetOwnerNode: {
+ request: {
+ styleSheetActorID: Arg(0, "string"),
+ },
+ response: {
+ ownerNode: RetVal("nullable:disconnectedNode"),
+ },
+ },
+ getNodeFromActor: {
+ request: {
+ actorID: Arg(0, "string"),
+ path: Arg(1, "array:string"),
+ },
+ response: {
+ node: RetVal("nullable:disconnectedNode"),
+ },
+ },
+ getLayoutInspector: {
+ request: {},
+ response: {
+ actor: RetVal("layout"),
+ },
+ },
+ getParentGridNode: {
+ request: {
+ node: Arg(0, "nullable:domnode"),
+ },
+ response: {
+ node: RetVal("nullable:domnode"),
+ },
+ },
+ getOffsetParent: {
+ request: {
+ node: Arg(0, "nullable:domnode"),
+ },
+ response: {
+ node: RetVal("nullable:domnode"),
+ },
+ },
+ setMutationBreakpoints: {
+ request: {
+ node: Arg(0, "nullable:domnode"),
+ subtree: Option(1, "nullable:boolean"),
+ removal: Option(1, "nullable:boolean"),
+ attribute: Option(1, "nullable:boolean"),
+ },
+ response: {},
+ },
+ getEmbedderElement: {
+ request: {
+ browsingContextID: Arg(0, "string"),
+ },
+ response: {
+ nodeFront: RetVal("disconnectedNode"),
+ },
+ },
+ pick: {
+ request: {
+ doFocus: Arg(0, "nullable:boolean"),
+ isLocalTab: Arg(1, "nullable:boolean"),
+ },
+ },
+ cancelPick: {
+ request: {},
+ response: {},
+ },
+ clearPicker: {
+ request: {},
+ oneway: true,
+ },
+ watchRootNode: {
+ request: {},
+ response: {},
+ },
+ getOverflowCausingElements: {
+ request: {
+ node: Arg(0, "domnode"),
+ },
+ response: {
+ list: RetVal("disconnectedNodeArray"),
+ },
+ },
+ getScrollableAncestorNode: {
+ request: {
+ node: Arg(0, "domnode"),
+ },
+ response: {
+ node: RetVal("nullable:domnode"),
+ },
+ },
+ },
+});
+
+exports.walkerSpec = walkerSpec;
diff --git a/devtools/shared/specs/watcher.js b/devtools/shared/specs/watcher.js
new file mode 100644
index 0000000000..9ba19900eb
--- /dev/null
+++ b/devtools/shared/specs/watcher.js
@@ -0,0 +1,123 @@
+/* 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 {
+ generateActorSpec,
+ Arg,
+ RetVal,
+} = require("resource://devtools/shared/protocol.js");
+
+const watcherSpecPrototype = {
+ typeName: "watcher",
+
+ methods: {
+ watchTargets: {
+ request: {
+ targetType: Arg(0, "string"),
+ },
+ response: {},
+ },
+
+ unwatchTargets: {
+ request: {
+ targetType: Arg(0, "string"),
+ options: Arg(1, "nullable:json"),
+ },
+ oneway: true,
+ },
+
+ getParentBrowsingContextID: {
+ request: {
+ browsingContextID: Arg(0, "number"),
+ },
+ response: {
+ browsingContextID: RetVal("nullable:number"),
+ },
+ },
+
+ watchResources: {
+ request: {
+ resourceTypes: Arg(0, "array:string"),
+ },
+ response: {},
+ },
+
+ unwatchResources: {
+ request: {
+ resourceTypes: Arg(0, "array:string"),
+ },
+ oneway: true,
+ },
+
+ clearResources: {
+ request: {
+ resourceTypes: Arg(0, "array:string"),
+ },
+ oneway: true,
+ },
+
+ getNetworkParentActor: {
+ request: {},
+ response: {
+ network: RetVal("networkParent"),
+ },
+ },
+
+ getBlackboxingActor: {
+ request: {},
+ response: {
+ blackboxing: RetVal("blackboxing"),
+ },
+ },
+
+ getBreakpointListActor: {
+ request: {},
+ response: {
+ breakpointList: RetVal("breakpoint-list"),
+ },
+ },
+
+ getTargetConfigurationActor: {
+ request: {},
+ response: {
+ configuration: RetVal("target-configuration"),
+ },
+ },
+
+ getThreadConfigurationActor: {
+ request: {},
+ response: {
+ configuration: RetVal("thread-configuration"),
+ },
+ },
+ },
+
+ events: {
+ "target-available-form": {
+ type: "target-available-form",
+ target: Arg(0, "json"),
+ },
+ "target-destroyed-form": {
+ type: "target-destroyed-form",
+ target: Arg(0, "json"),
+ options: Arg(1, "nullable:json"),
+ },
+
+ "resource-available-form": {
+ type: "resource-available-form",
+ resources: Arg(0, "array:json"),
+ },
+ "resource-destroyed-form": {
+ type: "resource-destroyed-form",
+ resources: Arg(0, "array:json"),
+ },
+ "resource-updated-form": {
+ type: "resource-updated-form",
+ resources: Arg(0, "array:json"),
+ },
+ },
+};
+
+exports.watcherSpec = generateActorSpec(watcherSpecPrototype);
diff --git a/devtools/shared/specs/webconsole.js b/devtools/shared/specs/webconsole.js
new file mode 100644
index 0000000000..c861fd793a
--- /dev/null
+++ b/devtools/shared/specs/webconsole.js
@@ -0,0 +1,201 @@
+/* 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,
+ Arg,
+} = require("resource://devtools/shared/protocol.js");
+
+types.addDictType("console.startlisteners", {
+ startedListeners: "array:string",
+});
+
+types.addDictType("console.stoplisteners", {
+ stoppedListeners: "array:string",
+});
+
+types.addDictType("console.autocomplete", {
+ matches: "array:string",
+ matchProp: "string",
+});
+
+types.addDictType("console.evaluatejsasync", {
+ resultID: "string",
+});
+
+types.addDictType("console.cachedmessages", {
+ // this type is a union of two potential return types:
+ // { error, message } and { _type, message, timeStamp }
+ error: "nullable:string",
+ message: "longstring",
+ _type: "nullable:string",
+ timeStamp: "nullable:string",
+});
+
+const webconsoleSpecPrototype = {
+ typeName: "console",
+
+ events: {
+ evaluationResult: {
+ resultID: Option(0, "string"),
+ awaitResult: Option(0, "nullable:boolean"),
+ errorMessageName: Option(0, "nullable:string"),
+ exception: Option(0, "nullable:json"),
+ exceptionMessage: Option(0, "nullable:string"),
+ exceptionDocURL: Option(0, "nullable:string"),
+ exceptionStack: Option(0, "nullable:json"),
+ hasException: Option(0, "nullable:boolean"),
+ frame: Option(0, "nullable:json"),
+ helperResult: Option(0, "nullable:json"),
+ input: Option(0, "nullable:string"),
+ notes: Option(0, "nullable:string"),
+ result: Option(0, "nullable:json"),
+ startTime: Option(0, "number"),
+ timestamp: Option(0, "number"),
+ topLevelAwaitRejected: Option(0, "nullable:boolean"),
+ },
+ fileActivity: {
+ uri: Option(0, "string"),
+ },
+ pageError: {
+ pageError: Option(0, "json"),
+ },
+ logMessage: {
+ message: Option(0, "json"),
+ timeStamp: Option(0, "string"),
+ },
+ consoleAPICall: {
+ message: Option(0, "json"),
+ clonedFromContentProcess: Option(0, "nullable:boolean"),
+ },
+ reflowActivity: {
+ interruptible: Option(0, "boolean"),
+ start: Option(0, "number"),
+ end: Option(0, "number"),
+ sourceURL: Option(0, "nullable:string"),
+ sourceLine: Option(0, "nullable:number"),
+ functionName: Option(0, "nullable:string"),
+ },
+ // This event is modified re-emitted on the client as "networkEvent".
+ // In order to avoid a naming collision, we rename the server event.
+ serverNetworkEvent: {
+ type: "networkEvent",
+ eventActor: Option(0, "json"),
+ },
+ inspectObject: {
+ objectActor: Option(0, "json"),
+ },
+ documentEvent: {
+ name: Option(0, "string"),
+ time: Option(0, "string"),
+ hasNativeConsoleAPI: Option(0, "boolean"),
+ },
+ },
+
+ methods: {
+ /**
+ * Start the given Web Console listeners.
+ *
+ * @see webconsoleFront LISTENERS
+ * @Arg array events
+ * Array of events you want to start. See this.LISTENERS for
+ * known events.
+ */
+ startListeners: {
+ request: {
+ listeners: Arg(0, "array:string"),
+ },
+ response: RetVal("console.startlisteners"),
+ },
+ /**
+ * Stop the given Web Console listeners.
+ *
+ * @see webconsoleFront LISTENERS
+ * @Arg array events
+ * Array of events you want to stop. See this.LISTENERS for
+ * known events.
+ * @Arg function onResponse
+ * Function to invoke when the server response is received.
+ */
+ stopListeners: {
+ request: {
+ listeners: Arg(0, "nullable:array:string"),
+ },
+ response: RetVal("console.stoplisteners"),
+ },
+ /**
+ * Retrieve the cached messages from the server.
+ *
+ * @see webconsoleFront CACHED_MESSAGES
+ * @Arg array types
+ * The array of message types you want from the server. See
+ * this.CACHED_MESSAGES for known types.
+ */
+ getCachedMessages: {
+ request: {
+ messageTypes: Arg(0, "array:string"),
+ },
+ // the return value here has a field "string" which can either be a longStringActor
+ // or a plain string. Since we do not have union types, we cannot fully type this
+ // response
+ response: RetVal("console.cachedmessages"),
+ },
+ evaluateJSAsync: {
+ request: {
+ text: Option(0, "string"),
+ frameActor: Option(0, "string"),
+ url: Option(0, "string"),
+ selectedNodeActor: Option(0, "string"),
+ selectedObjectActor: Option(0, "string"),
+ innerWindowID: Option(0, "number"),
+ mapped: Option(0, "nullable:json"),
+ eager: Option(0, "nullable:boolean"),
+ },
+ response: RetVal("console.evaluatejsasync"),
+ },
+ /**
+ * Autocomplete a JavaScript expression.
+ *
+ * @Arg {String} string
+ * The code you want to autocomplete.
+ * @Arg {Number} cursor
+ * Cursor location inside the string. Index starts from 0.
+ * @Arg {String} frameActor
+ * The id of the frame actor that made the call.
+ * @Arg {String} selectedNodeActor: Actor id of the selected node in the inspector.
+ * @Arg {Array} authorizedEvaluations
+ * Array of the properties access which can be executed by the engine.
+ * Example: [["x", "myGetter"], ["x", "myGetter", "y", "anotherGetter"]] to
+ * retrieve properties of `x.myGetter.` and `x.myGetter.y.anotherGetter`.
+ */
+ autocomplete: {
+ request: {
+ text: Arg(0, "string"),
+ cursor: Arg(1, "nullable:number"),
+ frameActor: Arg(2, "nullable:string"),
+ selectedNodeActor: Arg(3, "nullable:string"),
+ authorizedEvaluations: Arg(4, "nullable:json"),
+ expressionVars: Arg(5, "nullable:json"),
+ },
+ response: RetVal("console.autocomplete"),
+ },
+
+ /**
+ * Same as clearMessagesCache, but wait for the server response.
+ */
+ clearMessagesCacheAsync: {
+ request: {},
+ },
+ },
+};
+
+const webconsoleSpec = generateActorSpec(webconsoleSpecPrototype);
+
+exports.webconsoleSpecPrototype = webconsoleSpecPrototype;
+exports.webconsoleSpec = webconsoleSpec;
diff --git a/devtools/shared/specs/worker/moz.build b/devtools/shared/specs/worker/moz.build
new file mode 100644
index 0000000000..dae0e2d606
--- /dev/null
+++ b/devtools/shared/specs/worker/moz.build
@@ -0,0 +1,11 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DevToolsModules(
+ "push-subscription.js",
+ "service-worker-registration.js",
+ "service-worker.js",
+)
diff --git a/devtools/shared/specs/worker/push-subscription.js b/devtools/shared/specs/worker/push-subscription.js
new file mode 100644
index 0000000000..f68a74eb00
--- /dev/null
+++ b/devtools/shared/specs/worker/push-subscription.js
@@ -0,0 +1,12 @@
+/* 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 { generateActorSpec } = require("resource://devtools/shared/protocol.js");
+
+const pushSubscriptionSpec = generateActorSpec({
+ typeName: "pushSubscription",
+});
+
+exports.pushSubscriptionSpec = pushSubscriptionSpec;
diff --git a/devtools/shared/specs/worker/service-worker-registration.js b/devtools/shared/specs/worker/service-worker-registration.js
new file mode 100644
index 0000000000..b6b0fd5286
--- /dev/null
+++ b/devtools/shared/specs/worker/service-worker-registration.js
@@ -0,0 +1,48 @@
+/* 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 {
+ RetVal,
+ generateActorSpec,
+} = require("resource://devtools/shared/protocol.js");
+
+const serviceWorkerRegistrationSpec = generateActorSpec({
+ typeName: "serviceWorkerRegistration",
+
+ events: {
+ "push-subscription-modified": {
+ type: "push-subscription-modified",
+ },
+ "registration-changed": {
+ type: "registration-changed",
+ },
+ },
+
+ methods: {
+ allowShutdown: {
+ request: {},
+ },
+ preventShutdown: {
+ request: {},
+ },
+ push: {
+ request: {},
+ },
+ start: {
+ request: {},
+ },
+ unregister: {
+ request: {},
+ },
+ getPushSubscription: {
+ request: {},
+ response: {
+ subscription: RetVal("nullable:pushSubscription"),
+ },
+ },
+ },
+});
+
+exports.serviceWorkerRegistrationSpec = serviceWorkerRegistrationSpec;
diff --git a/devtools/shared/specs/worker/service-worker.js b/devtools/shared/specs/worker/service-worker.js
new file mode 100644
index 0000000000..8ddf151890
--- /dev/null
+++ b/devtools/shared/specs/worker/service-worker.js
@@ -0,0 +1,12 @@
+/* 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 { generateActorSpec } = require("resource://devtools/shared/protocol.js");
+
+const serviceWorkerSpec = generateActorSpec({
+ typeName: "serviceWorker",
+});
+
+exports.serviceWorkerSpec = serviceWorkerSpec;