summaryrefslogtreecommitdiffstats
path: root/devtools/shared/specs
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/specs')
-rw-r--r--devtools/shared/specs/actor-registry.js43
-rw-r--r--devtools/shared/specs/addons.js19
-rw-r--r--devtools/shared/specs/animation.js151
-rw-r--r--devtools/shared/specs/breakpoint.js16
-rw-r--r--devtools/shared/specs/call-watcher.js79
-rw-r--r--devtools/shared/specs/canvas.js131
-rw-r--r--devtools/shared/specs/css-properties.js20
-rw-r--r--devtools/shared/specs/csscoverage.js44
-rw-r--r--devtools/shared/specs/device.js19
-rw-r--r--devtools/shared/specs/director-manager.js190
-rw-r--r--devtools/shared/specs/director-registry.js41
-rw-r--r--devtools/shared/specs/emulation.js106
-rw-r--r--devtools/shared/specs/environment.js27
-rw-r--r--devtools/shared/specs/eventlooplag.js31
-rw-r--r--devtools/shared/specs/frame.js14
-rw-r--r--devtools/shared/specs/framerate.js34
-rw-r--r--devtools/shared/specs/gcli.js86
-rw-r--r--devtools/shared/specs/heap-snapshot-file.js20
-rw-r--r--devtools/shared/specs/highlighters.js63
-rw-r--r--devtools/shared/specs/inspector.js445
-rw-r--r--devtools/shared/specs/layout.js33
-rw-r--r--devtools/shared/specs/memory.js124
-rw-r--r--devtools/shared/specs/moz.build50
-rw-r--r--devtools/shared/specs/node.js67
-rw-r--r--devtools/shared/specs/performance-entries.js25
-rw-r--r--devtools/shared/specs/performance-recording.js12
-rw-r--r--devtools/shared/specs/performance.js88
-rw-r--r--devtools/shared/specs/preference.js47
-rw-r--r--devtools/shared/specs/profiler.js121
-rw-r--r--devtools/shared/specs/promises.js56
-rw-r--r--devtools/shared/specs/reflow.js33
-rw-r--r--devtools/shared/specs/script.js14
-rw-r--r--devtools/shared/specs/settings.js31
-rw-r--r--devtools/shared/specs/source.js40
-rw-r--r--devtools/shared/specs/storage.js279
-rw-r--r--devtools/shared/specs/string.js87
-rw-r--r--devtools/shared/specs/styleeditor.js61
-rw-r--r--devtools/shared/specs/styles.js206
-rw-r--r--devtools/shared/specs/stylesheets.js120
-rw-r--r--devtools/shared/specs/timeline.js118
-rw-r--r--devtools/shared/specs/webaudio.js163
-rw-r--r--devtools/shared/specs/webgl.js101
-rw-r--r--devtools/shared/specs/worker.js78
43 files changed, 3533 insertions, 0 deletions
diff --git a/devtools/shared/specs/actor-registry.js b/devtools/shared/specs/actor-registry.js
new file mode 100644
index 000000000..0f57dc8d2
--- /dev/null
+++ b/devtools/shared/specs/actor-registry.js
@@ -0,0 +1,43 @@
+/* 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("devtools/shared/protocol");
+
+const actorActorSpec = generateActorSpec({
+ typeName: "actorActor",
+
+ methods: {
+ unregister: {
+ request: {},
+ response: {}
+ }
+ },
+});
+
+exports.actorActorSpec = actorActorSpec;
+
+const actorRegistrySpec = generateActorSpec({
+ typeName: "actorRegistry",
+
+ methods: {
+ registerActor: {
+ request: {
+ sourceText: Arg(0, "string"),
+ filename: Arg(1, "string"),
+ options: Arg(2, "json")
+ },
+
+ response: {
+ actorActor: RetVal("actorActor")
+ }
+ }
+ }
+});
+
+exports.actorRegistrySpec = actorRegistrySpec;
diff --git a/devtools/shared/specs/addons.js b/devtools/shared/specs/addons.js
new file mode 100644
index 000000000..6246b9d1f
--- /dev/null
+++ b/devtools/shared/specs/addons.js
@@ -0,0 +1,19 @@
+/* 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("devtools/shared/protocol");
+
+const addonsSpec = generateActorSpec({
+ typeName: "addons",
+
+ methods: {
+ installTemporaryAddon: {
+ request: { addonPath: Arg(0, "string") },
+ response: { addon: RetVal("json") },
+ },
+ },
+});
+
+exports.addonsSpec = addonsSpec;
diff --git a/devtools/shared/specs/animation.js b/devtools/shared/specs/animation.js
new file mode 100644
index 000000000..20af12c23
--- /dev/null
+++ b/devtools/shared/specs/animation.js
@@ -0,0 +1,151 @@
+/* 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("devtools/shared/protocol");
+require("devtools/shared/specs/inspector");
+
+/**
+ * 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")
+ }
+ },
+ pause: {
+ request: {},
+ response: {}
+ },
+ play: {
+ request: {},
+ response: {}
+ },
+ ready: {
+ request: {},
+ response: {}
+ },
+ setCurrentTime: {
+ request: {
+ currentTime: Arg(0, "number")
+ },
+ response: {}
+ },
+ setPlaybackRate: {
+ request: {
+ currentTime: Arg(0, "number")
+ },
+ response: {}
+ },
+ getFrames: {
+ request: {},
+ response: {
+ frames: RetVal("json")
+ }
+ },
+ getProperties: {
+ request: {},
+ response: {
+ properties: RetVal("array: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")
+ }
+ },
+ stopAnimationPlayerUpdates: {
+ request: {},
+ response: {}
+ },
+ pauseAll: {
+ request: {},
+ response: {}
+ },
+ playAll: {
+ request: {},
+ response: {}
+ },
+ toggleAll: {
+ request: {},
+ response: {}
+ },
+ toggleSeveral: {
+ request: {
+ players: Arg(0, "array:animationplayer"),
+ shouldPause: Arg(1, "boolean")
+ },
+ 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/breakpoint.js b/devtools/shared/specs/breakpoint.js
new file mode 100644
index 000000000..e30c03ce8
--- /dev/null
+++ b/devtools/shared/specs/breakpoint.js
@@ -0,0 +1,16 @@
+/* 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("devtools/shared/protocol");
+
+const breakpointSpec = generateActorSpec({
+ typeName: "breakpoint",
+
+ methods: {
+ delete: {}
+ },
+});
+
+exports.breakpointSpec = breakpointSpec;
diff --git a/devtools/shared/specs/call-watcher.js b/devtools/shared/specs/call-watcher.js
new file mode 100644
index 000000000..34d63111a
--- /dev/null
+++ b/devtools/shared/specs/call-watcher.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 protocol = require("devtools/shared/protocol");
+const { Arg, RetVal, Option, generateActorSpec } = protocol;
+
+/**
+ * Type describing a single function call in a stack trace.
+ */
+protocol.types.addDictType("call-stack-item", {
+ name: "string",
+ file: "string",
+ line: "number"
+});
+
+/**
+ * Type describing an overview of a function call.
+ */
+protocol.types.addDictType("call-details", {
+ type: "number",
+ name: "string",
+ stack: "array:call-stack-item"
+});
+
+const functionCallSpec = generateActorSpec({
+ typeName: "function-call",
+
+ methods: {
+ getDetails: {
+ response: { info: RetVal("call-details") }
+ },
+ },
+});
+
+exports.functionCallSpec = functionCallSpec;
+
+const callWatcherSpec = generateActorSpec({
+ typeName: "call-watcher",
+
+ events: {
+ /**
+ * Events emitted when the `onCall` function isn't provided.
+ */
+ "call": {
+ type: "call",
+ function: Arg(0, "function-call")
+ }
+ },
+
+ methods: {
+ setup: {
+ request: {
+ tracedGlobals: Option(0, "nullable:array:string"),
+ tracedFunctions: Option(0, "nullable:array:string"),
+ startRecording: Option(0, "boolean"),
+ performReload: Option(0, "boolean"),
+ holdWeak: Option(0, "boolean"),
+ storeCalls: Option(0, "boolean")
+ },
+ oneway: true
+ },
+ finalize: {
+ oneway: true
+ },
+ isRecording: {
+ response: RetVal("boolean")
+ },
+ initTimestampEpoch: {},
+ resumeRecording: {},
+ pauseRecording: {
+ response: { calls: RetVal("array:function-call") }
+ },
+ eraseRecording: {},
+ }
+});
+
+exports.callWatcherSpec = callWatcherSpec;
diff --git a/devtools/shared/specs/canvas.js b/devtools/shared/specs/canvas.js
new file mode 100644
index 000000000..dcb26f9a9
--- /dev/null
+++ b/devtools/shared/specs/canvas.js
@@ -0,0 +1,131 @@
+/* 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("devtools/shared/protocol");
+const {Arg, Option, RetVal, generateActorSpec} = protocol;
+
+/**
+ * Type representing an ArrayBufferView, serialized fast(er).
+ *
+ * Don't create a new array buffer view from the parsed array on the frontend.
+ * Consumers may copy the data into an existing buffer, or create a new one if
+ * necesasry. For example, this avoids the need for a redundant copy when
+ * populating ImageData objects, at the expense of transferring char views
+ * of a pixel buffer over the protocol instead of a packed int view.
+ *
+ * XXX: It would be nice if on local connections (only), we could just *give*
+ * the buffer directly to the front, instead of going through all this
+ * serialization redundancy.
+ */
+protocol.types.addType("array-buffer-view", {
+ write: (v) => "[" + Array.join(v, ",") + "]",
+ read: (v) => JSON.parse(v)
+});
+
+/**
+ * Type describing a thumbnail or screenshot in a recorded animation frame.
+ */
+protocol.types.addDictType("snapshot-image", {
+ index: "number",
+ width: "number",
+ height: "number",
+ scaling: "number",
+ flipped: "boolean",
+ pixels: "array-buffer-view"
+});
+
+/**
+ * Type describing an overview of a recorded animation frame.
+ */
+protocol.types.addDictType("snapshot-overview", {
+ calls: "array:function-call",
+ thumbnails: "array:snapshot-image",
+ screenshot: "snapshot-image"
+});
+
+exports.CANVAS_CONTEXTS = [
+ "CanvasRenderingContext2D",
+ "WebGLRenderingContext"
+];
+
+exports.ANIMATION_GENERATORS = [
+ "requestAnimationFrame"
+];
+
+exports.LOOP_GENERATORS = [
+ "setTimeout"
+];
+
+exports.DRAW_CALLS = [
+ // 2D canvas
+ "fill",
+ "stroke",
+ "clearRect",
+ "fillRect",
+ "strokeRect",
+ "fillText",
+ "strokeText",
+ "drawImage",
+
+ // WebGL
+ "clear",
+ "drawArrays",
+ "drawElements",
+ "finish",
+ "flush"
+];
+
+exports.INTERESTING_CALLS = [
+ // 2D canvas
+ "save",
+ "restore",
+
+ // WebGL
+ "useProgram"
+];
+
+const frameSnapshotSpec = generateActorSpec({
+ typeName: "frame-snapshot",
+
+ methods: {
+ getOverview: {
+ response: { overview: RetVal("snapshot-overview") }
+ },
+ generateScreenshotFor: {
+ request: { call: Arg(0, "function-call") },
+ response: { screenshot: RetVal("snapshot-image") }
+ },
+ },
+});
+
+exports.frameSnapshotSpec = frameSnapshotSpec;
+
+const canvasSpec = generateActorSpec({
+ typeName: "canvas",
+
+ methods: {
+ setup: {
+ request: { reload: Option(0, "boolean") },
+ oneway: true
+ },
+ finalize: {
+ oneway: true
+ },
+ isInitialized: {
+ response: { initialized: RetVal("boolean") }
+ },
+ isRecording: {
+ response: { recording: RetVal("boolean") }
+ },
+ recordAnimationFrame: {
+ response: { snapshot: RetVal("nullable:frame-snapshot") }
+ },
+ stopRecordingAnimationFrame: {
+ oneway: true
+ },
+ }
+});
+
+exports.canvasSpec = canvasSpec;
diff --git a/devtools/shared/specs/css-properties.js b/devtools/shared/specs/css-properties.js
new file mode 100644
index 000000000..76c85bd74
--- /dev/null
+++ b/devtools/shared/specs/css-properties.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 { RetVal, generateActorSpec } = require("devtools/shared/protocol");
+
+const cssPropertiesSpec = generateActorSpec({
+ typeName: "cssProperties",
+
+ methods: {
+ getCSSDatabase: {
+ request: {},
+
+ response: RetVal("json"),
+ }
+ }
+});
+
+exports.cssPropertiesSpec = cssPropertiesSpec;
diff --git a/devtools/shared/specs/csscoverage.js b/devtools/shared/specs/csscoverage.js
new file mode 100644
index 000000000..4c58b09a9
--- /dev/null
+++ b/devtools/shared/specs/csscoverage.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("devtools/shared/protocol");
+
+require("devtools/shared/specs/stylesheets");
+
+const cssUsageSpec = generateActorSpec({
+ typeName: "cssUsage",
+
+ events: {
+ "state-change": {
+ type: "stateChange",
+ stateChange: Arg(0, "json")
+ }
+ },
+
+ methods: {
+ start: {
+ request: { url: Arg(0, "boolean") }
+ },
+ stop: {},
+ toggle: {},
+ oneshot: {},
+ createEditorReport: {
+ request: { url: Arg(0, "string") },
+ response: { reports: RetVal("array:json") }
+ },
+ createEditorReportForSheet: {
+ request: { url: Arg(0, "stylesheet") },
+ response: { reports: RetVal("array:json") }
+ },
+ createPageReport: {
+ response: RetVal("json")
+ },
+ _testOnlyVisitedPages: {
+ response: { value: RetVal("array:string") }
+ },
+ },
+});
+
+exports.cssUsageSpec = cssUsageSpec;
diff --git a/devtools/shared/specs/device.js b/devtools/shared/specs/device.js
new file mode 100644
index 000000000..3237d1593
--- /dev/null
+++ b/devtools/shared/specs/device.js
@@ -0,0 +1,19 @@
+/* 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("devtools/shared/protocol");
+
+const deviceSpec = generateActorSpec({
+ typeName: "device",
+
+ methods: {
+ getDescription: {request: {}, response: { value: RetVal("json")}},
+ getWallpaper: {request: {}, response: { value: RetVal("longstring")}},
+ screenshotToDataURL: {request: {}, response: { value: RetVal("longstring")}},
+ getRawPermissionsTable: {request: {}, response: { value: RetVal("json")}},
+ },
+});
+
+exports.deviceSpec = deviceSpec;
diff --git a/devtools/shared/specs/director-manager.js b/devtools/shared/specs/director-manager.js
new file mode 100644
index 000000000..8a9bf77ee
--- /dev/null
+++ b/devtools/shared/specs/director-manager.js
@@ -0,0 +1,190 @@
+/* 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("devtools/shared/protocol");
+
+/**
+ * Type describing a messageport event
+ */
+types.addDictType("messageportevent", {
+ isTrusted: "boolean",
+ data: "nullable:primitive",
+ origin: "nullable:string",
+ lastEventId: "nullable:string",
+ source: "messageport",
+ ports: "nullable:array:messageport"
+});
+
+const messagePortSpec = generateActorSpec({
+ typeName: "messageport",
+
+ /**
+ * Events emitted by this actor.
+ */
+ events: {
+ message: {
+ type: "message",
+ msg: Arg(0, "nullable:messageportevent")
+ }
+ },
+
+ methods: {
+ postMessage: {
+ oneway: true,
+ request: {
+ msg: Arg(0, "nullable:json")
+ }
+ },
+ start: {
+ oneway: true,
+ request: {}
+ },
+ close: {
+ oneway: true,
+ request: {}
+ },
+ finalize: {
+ oneway: true
+ },
+ },
+});
+
+exports.messagePortSpec = messagePortSpec;
+
+/**
+ * Type describing a director-script error
+ */
+types.addDictType("director-script-error", {
+ directorScriptId: "string",
+ message: "nullable:string",
+ stack: "nullable:string",
+ fileName: "nullable:string",
+ lineNumber: "nullable:number",
+ columnNumber: "nullable:number"
+});
+
+/**
+ * Type describing a director-script attach event
+ */
+types.addDictType("director-script-attach", {
+ directorScriptId: "string",
+ url: "string",
+ innerId: "number",
+ port: "nullable:messageport"
+});
+
+/**
+ * Type describing a director-script detach event
+ */
+types.addDictType("director-script-detach", {
+ directorScriptId: "string",
+ innerId: "number"
+});
+
+const directorScriptSpec = generateActorSpec({
+ typeName: "director-script",
+
+ /**
+ * Events emitted by this actor.
+ */
+ events: {
+ error: {
+ type: "error",
+ data: Arg(0, "director-script-error")
+ },
+ attach: {
+ type: "attach",
+ data: Arg(0, "director-script-attach")
+ },
+ detach: {
+ type: "detach",
+ data: Arg(0, "director-script-detach")
+ }
+ },
+
+ methods: {
+ setup: {
+ request: {
+ reload: Option(0, "boolean"),
+ skipAttach: Option(0, "boolean")
+ },
+ oneway: true
+ },
+ getMessagePort: {
+ request: { },
+ response: {
+ port: RetVal("nullable:messageport")
+ }
+ },
+ finalize: {
+ oneway: true
+ },
+ },
+});
+
+exports.directorScriptSpec = directorScriptSpec;
+
+const directorManagerSpec = generateActorSpec({
+ typeName: "director-manager",
+
+ /**
+ * Events emitted by this actor.
+ */
+ events: {
+ "director-script-error": {
+ type: "error",
+ data: Arg(0, "director-script-error")
+ },
+ "director-script-attach": {
+ type: "attach",
+ data: Arg(0, "director-script-attach")
+ },
+ "director-script-detach": {
+ type: "detach",
+ data: Arg(0, "director-script-detach")
+ }
+ },
+
+ methods: {
+ list: {
+ response: {
+ directorScripts: RetVal("json")
+ }
+ },
+ enableByScriptIds: {
+ oneway: true,
+ request: {
+ selectedIds: Arg(0, "array:string"),
+ reload: Option(1, "boolean")
+ }
+ },
+ disableByScriptIds: {
+ oneway: true,
+ request: {
+ selectedIds: Arg(0, "array:string"),
+ reload: Option(1, "boolean")
+ }
+ },
+ getByScriptId: {
+ request: {
+ scriptId: Arg(0, "string")
+ },
+ response: {
+ directorScript: RetVal("director-script")
+ }
+ },
+ finalize: {
+ oneway: true
+ },
+ },
+});
+
+exports.directorManagerSpec = directorManagerSpec;
diff --git a/devtools/shared/specs/director-registry.js b/devtools/shared/specs/director-registry.js
new file mode 100644
index 000000000..8ebb08eea
--- /dev/null
+++ b/devtools/shared/specs/director-registry.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 {Arg, Option, RetVal, generateActorSpec} = require("devtools/shared/protocol");
+
+const directorRegistrySpec = generateActorSpec({
+ typeName: "director-registry",
+
+ methods: {
+ finalize: {
+ oneway: true
+ },
+ install: {
+ request: {
+ scriptId: Arg(0, "string"),
+ scriptCode: Option(1, "string"),
+ scriptOptions: Option(1, "nullable:json")
+ },
+ response: {
+ success: RetVal("boolean")
+ }
+ },
+ uninstall: {
+ request: {
+ scritpId: Arg(0, "string")
+ },
+ response: {
+ success: RetVal("boolean")
+ }
+ },
+ list: {
+ response: {
+ directorScripts: RetVal("array:string")
+ }
+ },
+ },
+});
+
+exports.directorRegistrySpec = directorRegistrySpec;
diff --git a/devtools/shared/specs/emulation.js b/devtools/shared/specs/emulation.js
new file mode 100644
index 000000000..1267feaf9
--- /dev/null
+++ b/devtools/shared/specs/emulation.js
@@ -0,0 +1,106 @@
+/* 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("devtools/shared/protocol");
+
+const emulationSpec = generateActorSpec({
+ typeName: "emulation",
+
+ methods: {
+ setDPPXOverride: {
+ request: {
+ dppx: Arg(0, "number")
+ },
+ response: {
+ valueChanged: RetVal("boolean")
+ }
+ },
+
+ getDPPXOverride: {
+ request: {},
+ response: {
+ dppx: RetVal("number")
+ }
+ },
+
+ clearDPPXOverride: {
+ request: {},
+ response: {
+ valueChanged: RetVal("boolean")
+ }
+ },
+
+ setNetworkThrottling: {
+ request: {
+ options: Arg(0, "json")
+ },
+ response: {
+ valueChanged: RetVal("boolean")
+ }
+ },
+
+ getNetworkThrottling: {
+ request: {},
+ response: {
+ state: RetVal("json")
+ }
+ },
+
+ clearNetworkThrottling: {
+ request: {},
+ response: {
+ valueChanged: RetVal("boolean")
+ }
+ },
+
+ setTouchEventsOverride: {
+ request: {
+ flag: Arg(0, "number")
+ },
+ response: {
+ valueChanged: RetVal("boolean")
+ }
+ },
+
+ getTouchEventsOverride: {
+ request: {},
+ response: {
+ flag: RetVal("number")
+ }
+ },
+
+ clearTouchEventsOverride: {
+ request: {},
+ response: {
+ valueChanged: RetVal("boolean")
+ }
+ },
+
+ setUserAgentOverride: {
+ request: {
+ flag: Arg(0, "string")
+ },
+ response: {
+ valueChanged: RetVal("boolean")
+ }
+ },
+
+ getUserAgentOverride: {
+ request: {},
+ response: {
+ userAgent: RetVal("string")
+ }
+ },
+
+ clearUserAgentOverride: {
+ request: {},
+ response: {
+ valueChanged: RetVal("boolean")
+ }
+ },
+ }
+});
+
+exports.emulationSpec = emulationSpec;
diff --git a/devtools/shared/specs/environment.js b/devtools/shared/specs/environment.js
new file mode 100644
index 000000000..d320d98a4
--- /dev/null
+++ b/devtools/shared/specs/environment.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 {Arg, RetVal, generateActorSpec} = require("devtools/shared/protocol");
+
+const environmentSpec = generateActorSpec({
+ typeName: "environment",
+
+ methods: {
+ assign: {
+ request: {
+ name: Arg(1),
+ value: Arg(2)
+ }
+ },
+ bindings: {
+ request: {},
+ response: {
+ bindings: RetVal("json")
+ }
+ },
+ },
+});
+
+exports.environmentSpec = environmentSpec;
diff --git a/devtools/shared/specs/eventlooplag.js b/devtools/shared/specs/eventlooplag.js
new file mode 100644
index 000000000..1498d5f63
--- /dev/null
+++ b/devtools/shared/specs/eventlooplag.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 { Arg, RetVal, generateActorSpec } = require("devtools/shared/protocol");
+
+const eventLoopLagSpec = generateActorSpec({
+ typeName: "eventLoopLag",
+
+ events: {
+ "event-loop-lag": {
+ type: "event-loop-lag",
+ // duration of the lag in milliseconds.
+ time: Arg(0, "number")
+ }
+ },
+
+ methods: {
+ start: {
+ request: {},
+ response: {success: RetVal("number")}
+ },
+ stop: {
+ request: {},
+ response: {}
+ }
+ }
+});
+
+exports.eventLoopLagSpec = eventLoopLagSpec;
diff --git a/devtools/shared/specs/frame.js b/devtools/shared/specs/frame.js
new file mode 100644
index 000000000..6365d6e90
--- /dev/null
+++ b/devtools/shared/specs/frame.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("devtools/shared/protocol");
+
+const frameSpec = generateActorSpec({
+ typeName: "frame",
+
+ methods: {},
+});
+
+exports.frameSpec = frameSpec;
diff --git a/devtools/shared/specs/framerate.js b/devtools/shared/specs/framerate.js
new file mode 100644
index 000000000..9fb2dff5d
--- /dev/null
+++ b/devtools/shared/specs/framerate.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 { Arg, RetVal, generateActorSpec } = require("devtools/shared/protocol");
+
+const framerateSpec = generateActorSpec({
+ typeName: "framerate",
+
+ methods: {
+ startRecording: {},
+ stopRecording: {
+ request: {
+ beginAt: Arg(0, "nullable:number"),
+ endAt: Arg(1, "nullable:number")
+ },
+ response: { ticks: RetVal("array:number") }
+ },
+ cancelRecording: {},
+ isRecording: {
+ response: { recording: RetVal("boolean") }
+ },
+ getPendingTicks: {
+ request: {
+ beginAt: Arg(0, "nullable:number"),
+ endAt: Arg(1, "nullable:number")
+ },
+ response: { ticks: RetVal("array:number") }
+ }
+ }
+});
+
+exports.framerateSpec = framerateSpec;
diff --git a/devtools/shared/specs/gcli.js b/devtools/shared/specs/gcli.js
new file mode 100644
index 000000000..2e0768bc8
--- /dev/null
+++ b/devtools/shared/specs/gcli.js
@@ -0,0 +1,86 @@
+/* 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("devtools/shared/protocol");
+
+const gcliSpec = generateActorSpec({
+ typeName: "gcli",
+
+ events: {
+ "commands-changed": {
+ type: "commandsChanged"
+ }
+ },
+
+ methods: {
+ _testOnlyAddItemsByModule: {
+ request: {
+ customProps: Arg(0, "array:string")
+ }
+ },
+ _testOnlyRemoveItemsByModule: {
+ request: {
+ customProps: Arg(0, "array:string")
+ }
+ },
+ specs: {
+ request: {
+ customProps: Arg(0, "nullable:array:string")
+ },
+ response: {
+ value: RetVal("array:json")
+ }
+ },
+ execute: {
+ request: {
+ // The command string
+ typed: Arg(0, "string")
+ },
+ response: RetVal("json")
+ },
+ state: {
+ request: {
+ // The command string
+ typed: Arg(0, "string"),
+ // Cursor start position
+ start: Arg(1, "number"),
+ // The prediction offset (# times UP/DOWN pressed)
+ rank: Arg(2, "number")
+ },
+ response: RetVal("json")
+ },
+ parseType: {
+ request: {
+ // The command string
+ typed: Arg(0, "string"),
+ // The name of the parameter to parse
+ paramName: Arg(1, "string")
+ },
+ response: RetVal("json")
+ },
+ nudgeType: {
+ request: {
+ // The command string
+ typed: Arg(0, "string"),
+ // +1/-1 for increment / decrement
+ by: Arg(1, "number"),
+ // The name of the parameter to parse
+ paramName: Arg(2, "string")
+ },
+ response: RetVal("string")
+ },
+ getSelectionLookup: {
+ request: {
+ // The command containing the parameter in question
+ commandName: Arg(0, "string"),
+ // The name of the parameter
+ paramName: Arg(1, "string"),
+ },
+ response: RetVal("json")
+ }
+ }
+});
+
+exports.gcliSpec = gcliSpec;
diff --git a/devtools/shared/specs/heap-snapshot-file.js b/devtools/shared/specs/heap-snapshot-file.js
new file mode 100644
index 000000000..dfd03e1fa
--- /dev/null
+++ b/devtools/shared/specs/heap-snapshot-file.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 { Arg, generateActorSpec } = require("devtools/shared/protocol");
+
+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 000000000..8335b22d9
--- /dev/null
+++ b/devtools/shared/specs/highlighters.js
@@ -0,0 +1,63 @@
+/* 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("devtools/shared/protocol");
+
+const highlighterSpec = generateActorSpec({
+ typeName: "highlighter",
+
+ methods: {
+ showBoxModel: {
+ request: {
+ node: Arg(0, "domnode"),
+ region: Option(1),
+ hideInfoBar: Option(1),
+ hideGuides: Option(1),
+ showOnly: Option(1),
+ onlyRegionArea: Option(1)
+ }
+ },
+ hideBoxModel: {
+ request: {}
+ },
+ pick: {},
+ pickAndFocus: {},
+ cancelPick: {}
+ }
+});
+
+exports.highlighterSpec = highlighterSpec;
+
+const customHighlighterSpec = generateActorSpec({
+ typeName: "customhighlighter",
+
+ methods: {
+ release: {
+ release: true
+ },
+ show: {
+ request: {
+ node: Arg(0, "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/inspector.js b/devtools/shared/specs/inspector.js
new file mode 100644
index 000000000..28736ed34
--- /dev/null
+++ b/devtools/shared/specs/inspector.js
@@ -0,0 +1,445 @@
+/* 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("devtools/shared/protocol");
+const { nodeSpec } = require("devtools/shared/specs/node");
+require("devtools/shared/specs/styles");
+require("devtools/shared/specs/highlighters");
+require("devtools/shared/specs/layout");
+
+exports.nodeSpec = nodeSpec;
+
+/**
+ * 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"
+});
+
+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"
+});
+
+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;
+
+// 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"),
+ whatToShow: Option(1)
+ },
+ response: RetVal(types.addDictType("domtraversalarray", {
+ nodes: "array:domnode"
+ }))
+};
+
+var traversalMethod = {
+ request: {
+ node: Arg(0, "domnode"),
+ whatToShow: Option(1)
+ },
+ response: {
+ node: RetVal("nullable:domnode")
+ }
+};
+
+const walkerSpec = generateActorSpec({
+ typeName: "domwalker",
+
+ events: {
+ "new-mutations": {
+ type: "newMutations"
+ },
+ "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"
+ },
+ "highlighter-ready": {
+ type: "highlighter-ready"
+ },
+ "highlighter-hide": {
+ type: "highlighter-hide"
+ },
+ "display-change": {
+ type: "display-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
+ },
+ pick: {
+ request: {},
+ response: RetVal("disconnectedNode")
+ },
+ cancelPick: {},
+ highlight: {
+ request: {node: Arg(0, "nullable:domnode")}
+ },
+ document: {
+ request: { node: Arg(0, "nullable:domnode") },
+ response: { node: RetVal("domnode") },
+ },
+ documentElement: {
+ request: { node: Arg(0, "nullable:domnode") },
+ response: { node: RetVal("domnode") },
+ },
+ parents: {
+ request: {
+ node: Arg(0, "domnode"),
+ sameDocument: Option(1),
+ sameTypeRootTreeItem: Option(1)
+ },
+ response: {
+ nodes: RetVal("array: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,
+ siblings: 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")
+ }
+ },
+ multiFrameQuerySelectorAll: {
+ request: {
+ selector: Arg(0)
+ },
+ 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)
+ },
+ 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") }
+ },
+ getNodeActorFromObjectActor: {
+ request: {
+ objectActorID: Arg(0, "string")
+ },
+ 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")
+ }
+ }
+ }
+});
+
+exports.walkerSpec = walkerSpec;
+
+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")
+ }
+ },
+ getHighlighter: {
+ request: {
+ autohide: Arg(0, "boolean")
+ },
+ response: {
+ highligter: RetVal("highlighter")
+ }
+ },
+ 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: {}
+ }
+ }
+});
+
+exports.inspectorSpec = inspectorSpec;
diff --git a/devtools/shared/specs/layout.js b/devtools/shared/specs/layout.js
new file mode 100644
index 000000000..80a0d5f9b
--- /dev/null
+++ b/devtools/shared/specs/layout.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, generateActorSpec, RetVal } = require("devtools/shared/protocol");
+require("devtools/shared/specs/node");
+
+const gridSpec = generateActorSpec({
+ typeName: "grid",
+
+ methods: {},
+});
+
+const layoutSpec = generateActorSpec({
+ typeName: "layout",
+
+ methods: {
+ getAllGrids: {
+ request: {
+ rootNode: Arg(0, "domnode"),
+ traverseFrames: Arg(1, "boolean")
+ },
+ response: {
+ grids: RetVal("array:grid")
+ }
+ }
+ },
+});
+
+exports.gridSpec = gridSpec;
+exports.layoutSpec = layoutSpec;
diff --git a/devtools/shared/specs/memory.js b/devtools/shared/specs/memory.js
new file mode 100644
index 000000000..3bff6dc38
--- /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("devtools/shared/protocol");
+
+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: "attached"
+ }
+ },
+ detach: {
+ request: {},
+ response: {
+ type: "detached"
+ }
+ },
+ 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 000000000..52a810637
--- /dev/null
+++ b/devtools/shared/specs/moz.build
@@ -0,0 +1,50 @@
+# -*- 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(
+ 'actor-registry.js',
+ 'addons.js',
+ 'animation.js',
+ 'breakpoint.js',
+ 'call-watcher.js',
+ 'canvas.js',
+ 'css-properties.js',
+ 'csscoverage.js',
+ 'device.js',
+ 'director-manager.js',
+ 'director-registry.js',
+ 'emulation.js',
+ 'environment.js',
+ 'eventlooplag.js',
+ 'frame.js',
+ 'framerate.js',
+ 'gcli.js',
+ 'heap-snapshot-file.js',
+ 'highlighters.js',
+ 'inspector.js',
+ 'layout.js',
+ 'memory.js',
+ 'node.js',
+ 'performance-entries.js',
+ 'performance-recording.js',
+ 'performance.js',
+ 'preference.js',
+ 'profiler.js',
+ 'promises.js',
+ 'reflow.js',
+ 'script.js',
+ 'settings.js',
+ 'source.js',
+ 'storage.js',
+ 'string.js',
+ 'styleeditor.js',
+ 'styles.js',
+ 'stylesheets.js',
+ 'timeline.js',
+ 'webaudio.js',
+ 'webgl.js',
+ 'worker.js'
+)
diff --git a/devtools/shared/specs/node.js b/devtools/shared/specs/node.js
new file mode 100644
index 000000000..ea3d1b264
--- /dev/null
+++ b/devtools/shared/specs/node.js
@@ -0,0 +1,67 @@
+/* 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("devtools/shared/protocol.js");
+
+types.addDictType("imageData", {
+ // The image data
+ data: "nullable:longstring",
+ // The original image dimensions
+ size: "json"
+});
+
+const nodeSpec = generateActorSpec({
+ typeName: "domnode",
+
+ methods: {
+ getNodeValue: {
+ request: {},
+ response: {
+ value: RetVal("longstring")
+ }
+ },
+ setNodeValue: {
+ request: { value: Arg(0) },
+ response: {}
+ },
+ getUniqueSelector: {
+ request: {},
+ response: {
+ value: RetVal("string")
+ }
+ },
+ scrollIntoView: {
+ request: {},
+ response: {}
+ },
+ getImageData: {
+ request: {maxDim: Arg(0, "nullable:number")},
+ response: RetVal("imageData")
+ },
+ getEventListenerInfo: {
+ request: {},
+ response: {
+ events: RetVal("json")
+ }
+ },
+ modifyAttributes: {
+ request: {
+ modifications: Arg(0, "array:json")
+ },
+ response: {}
+ },
+ getFontFamilyDataURL: {
+ request: {font: Arg(0, "string"), fillStyle: Arg(1, "nullable:string")},
+ response: RetVal("imageData")
+ }
+ }
+});
+
+exports.nodeSpec = nodeSpec;
diff --git a/devtools/shared/specs/performance-entries.js b/devtools/shared/specs/performance-entries.js
new file mode 100644
index 000000000..107afb779
--- /dev/null
+++ b/devtools/shared/specs/performance-entries.js
@@ -0,0 +1,25 @@
+/* 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("devtools/shared/protocol");
+
+const performanceEntriesSpec = generateActorSpec({
+ typeName: "performanceEntries",
+
+ events: {
+ "entry": {
+ type: "entry",
+ // object containing performance entry name, type, origin, and epoch.
+ detail: Arg(0, "json")
+ }
+ },
+
+ methods: {
+ start: {},
+ stop: {}
+ }
+});
+
+exports.performanceEntriesSpec = performanceEntriesSpec;
diff --git a/devtools/shared/specs/performance-recording.js b/devtools/shared/specs/performance-recording.js
new file mode 100644
index 000000000..562abc6f7
--- /dev/null
+++ b/devtools/shared/specs/performance-recording.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("devtools/shared/protocol");
+
+const performanceRecordingSpec = generateActorSpec({
+ typeName: "performance-recording"
+});
+
+exports.performanceRecordingSpec = performanceRecordingSpec;
diff --git a/devtools/shared/specs/performance.js b/devtools/shared/specs/performance.js
new file mode 100644
index 000000000..30a570e9a
--- /dev/null
+++ b/devtools/shared/specs/performance.js
@@ -0,0 +1,88 @@
+/* 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("devtools/shared/protocol");
+require("devtools/shared/specs/performance-recording");
+
+const performanceSpec = generateActorSpec({
+ typeName: "performance",
+
+ /**
+ * The set of events the PerformanceActor emits over RDP.
+ */
+ events: {
+ "recording-started": {
+ recording: Arg(0, "performance-recording"),
+ },
+ "recording-stopping": {
+ recording: Arg(0, "performance-recording"),
+ },
+ "recording-stopped": {
+ recording: Arg(0, "performance-recording"),
+ data: Arg(1, "json"),
+ },
+ "profiler-status": {
+ data: Arg(0, "json"),
+ },
+ "console-profile-start": {},
+ "timeline-data": {
+ name: Arg(0, "string"),
+ data: Arg(1, "json"),
+ recordings: Arg(2, "array:performance-recording"),
+ },
+ },
+
+ methods: {
+ connect: {
+ request: { options: Arg(0, "nullable:json") },
+ response: RetVal("json")
+ },
+
+ canCurrentlyRecord: {
+ request: {},
+ response: { value: RetVal("json") }
+ },
+
+ startRecording: {
+ request: {
+ options: Arg(0, "nullable:json"),
+ },
+ response: {
+ recording: RetVal("nullable:performance-recording")
+ }
+ },
+
+ stopRecording: {
+ request: {
+ options: Arg(0, "performance-recording"),
+ },
+ response: {
+ recording: RetVal("performance-recording")
+ }
+ },
+
+ isRecording: {
+ request: {},
+ response: { isRecording: RetVal("boolean") }
+ },
+
+ getRecordings: {
+ request: {},
+ response: { recordings: RetVal("array:performance-recording") }
+ },
+
+ getConfiguration: {
+ request: {},
+ response: { config: RetVal("json") }
+ },
+
+ setProfilerStatusInterval: {
+ request: { interval: Arg(0, "number") },
+ response: { oneway: true }
+ },
+ }
+});
+
+exports.performanceSpec = performanceSpec;
diff --git a/devtools/shared/specs/preference.js b/devtools/shared/specs/preference.js
new file mode 100644
index 000000000..54123d813
--- /dev/null
+++ b/devtools/shared/specs/preference.js
@@ -0,0 +1,47 @@
+/* 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("devtools/shared/protocol");
+
+const preferenceSpec = generateActorSpec({
+ typeName: "preference",
+
+ methods: {
+ 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/profiler.js b/devtools/shared/specs/profiler.js
new file mode 100644
index 000000000..a4a6f384e
--- /dev/null
+++ b/devtools/shared/specs/profiler.js
@@ -0,0 +1,121 @@
+/* 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("devtools/shared/protocol");
+
+types.addType("profiler-data", {
+ // On Fx42+, the profile is only deserialized on the front; older
+ // servers will get the profiler data as an object from nsIProfiler,
+ // causing one parse/stringify cycle, then again implicitly in a packet.
+ read: (v) => {
+ if (typeof v.profile === "string") {
+ // Create a new response object since `profile` is read only.
+ let newValue = Object.create(null);
+ newValue.profile = JSON.parse(v.profile);
+ newValue.currentTime = v.currentTime;
+ return newValue;
+ }
+ return v;
+ }
+});
+
+const profilerSpec = generateActorSpec({
+ typeName: "profiler",
+
+ /**
+ * The set of events the ProfilerActor emits over RDP.
+ */
+ events: {
+ "console-api-profiler": {
+ data: Arg(0, "json"),
+ },
+ "profiler-started": {
+ data: Arg(0, "json"),
+ },
+ "profiler-stopped": {
+ data: Arg(0, "json"),
+ },
+ "profiler-status": {
+ data: Arg(0, "json"),
+ },
+
+ // Only for older geckos, pre-protocol.js ProfilerActor (<Fx42).
+ // Emitted on other events as a transition from older profiler events
+ // to newer ones.
+ "eventNotification": {
+ subject: Option(0, "json"),
+ topic: Option(0, "string"),
+ details: Option(0, "json")
+ }
+ },
+
+ methods: {
+ startProfiler: {
+ // Write out every property in the request, since we want all these options to be
+ // on the packet's top-level for backwards compatibility, when the profiler actor
+ // was not using protocol.js (<Fx42)
+ request: {
+ entries: Option(0, "nullable:number"),
+ interval: Option(0, "nullable:number"),
+ features: Option(0, "nullable:array:string"),
+ threadFilters: Option(0, "nullable:array:string"),
+ },
+ response: RetVal("json"),
+ },
+ stopProfiler: {
+ response: RetVal("json"),
+ },
+ getProfile: {
+ request: {
+ startTime: Option(0, "nullable:number"),
+ stringify: Option(0, "nullable:boolean")
+ },
+ response: RetVal("profiler-data")
+ },
+ getFeatures: {
+ response: RetVal("json")
+ },
+ getBufferInfo: {
+ response: RetVal("json")
+ },
+ getStartOptions: {
+ response: RetVal("json")
+ },
+ isActive: {
+ response: RetVal("json")
+ },
+ getSharedLibraryInformation: {
+ response: RetVal("json")
+ },
+ registerEventNotifications: {
+ // Explicitly enumerate the arguments
+ // @see ProfilerActor#startProfiler
+ request: {
+ events: Option(0, "nullable:array:string"),
+ },
+ response: RetVal("json")
+ },
+ unregisterEventNotifications: {
+ // Explicitly enumerate the arguments
+ // @see ProfilerActor#startProfiler
+ request: {
+ events: Option(0, "nullable:array:string"),
+ },
+ response: RetVal("json")
+ },
+ setProfilerStatusInterval: {
+ request: { interval: Arg(0, "number") },
+ oneway: true
+ }
+ }
+});
+
+exports.profilerSpec = profilerSpec;
diff --git a/devtools/shared/specs/promises.js b/devtools/shared/specs/promises.js
new file mode 100644
index 000000000..ef57c3bae
--- /dev/null
+++ b/devtools/shared/specs/promises.js
@@ -0,0 +1,56 @@
+/* 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("devtools/shared/protocol");
+
+// Teach protocol.js how to deal with legacy actor types
+types.addType("ObjectActor", {
+ write: actor => actor.grip(),
+ read: grip => grip
+});
+
+const promisesSpec = generateActorSpec({
+ typeName: "promises",
+
+ events: {
+ // Event emitted for new promises allocated in debuggee and bufferred by
+ // sending the list of promise objects in a batch.
+ "new-promises": {
+ type: "new-promises",
+ data: Arg(0, "array:ObjectActor"),
+ },
+ // Event emitted for promise settlements.
+ "promises-settled": {
+ type: "promises-settled",
+ data: Arg(0, "array:ObjectActor")
+ }
+ },
+
+ methods: {
+ attach: {
+ request: {},
+ response: {},
+ },
+
+ detach: {
+ request: {},
+ response: {},
+ },
+
+ listPromises: {
+ request: {},
+ response: {
+ promises: RetVal("array:ObjectActor"),
+ },
+ }
+ }
+});
+
+exports.promisesSpec = promisesSpec;
diff --git a/devtools/shared/specs/reflow.js b/devtools/shared/specs/reflow.js
new file mode 100644
index 000000000..a33c7a2cf
--- /dev/null
+++ b/devtools/shared/specs/reflow.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, generateActorSpec} = require("devtools/shared/protocol");
+
+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/script.js b/devtools/shared/specs/script.js
new file mode 100644
index 000000000..f24426dee
--- /dev/null
+++ b/devtools/shared/specs/script.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("devtools/shared/protocol");
+
+const threadSpec = generateActorSpec({
+ typeName: "context",
+
+ methods: {},
+});
+
+exports.threadSpec = threadSpec;
diff --git a/devtools/shared/specs/settings.js b/devtools/shared/specs/settings.js
new file mode 100644
index 000000000..482c8f473
--- /dev/null
+++ b/devtools/shared/specs/settings.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 {Arg, RetVal, generateActorSpec} = require("devtools/shared/protocol");
+
+const settingsSpec = generateActorSpec({
+ typeName: "settings",
+
+ methods: {
+ getSetting: {
+ request: { value: Arg(0) },
+ response: { value: RetVal("json") }
+ },
+ setSetting: {
+ request: { name: Arg(0), value: Arg(1) },
+ response: {}
+ },
+ getAllSettings: {
+ request: {},
+ response: { value: RetVal("json") }
+ },
+ clearUserSetting: {
+ request: { name: Arg(0) },
+ response: {}
+ }
+ },
+});
+
+exports.settingsSpec = settingsSpec;
diff --git a/devtools/shared/specs/source.js b/devtools/shared/specs/source.js
new file mode 100644
index 000000000..66bcf89e2
--- /dev/null
+++ b/devtools/shared/specs/source.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("devtools/shared/protocol");
+
+const sourceSpec = generateActorSpec({
+ typeName: "source",
+
+ methods: {
+ getExecutableLines: { response: { lines: RetVal("json") } },
+ onSource: {
+ request: { type: "source" },
+ response: RetVal("json")
+ },
+ prettyPrint: {
+ request: { indent: Arg(0, "number") },
+ response: RetVal("json")
+ },
+ disablePrettyPrint: {
+ response: RetVal("json")
+ },
+ blackbox: { response: { pausedInSource: RetVal("boolean") } },
+ unblackbox: {},
+ setBreakpoint: {
+ request: {
+ location: {
+ line: Arg(0, "number"),
+ column: Arg(1, "nullable:number")
+ },
+ condition: Arg(2, "nullable:string"),
+ noSliding: Arg(3, "nullable:boolean")
+ },
+ response: RetVal("json")
+ },
+ },
+});
+
+exports.sourceSpec = sourceSpec;
diff --git a/devtools/shared/specs/storage.js b/devtools/shared/specs/storage.js
new file mode 100644
index 000000000..d6ddaefe5
--- /dev/null
+++ b/devtools/shared/specs/storage.js
@@ -0,0 +1,279 @@
+/* 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("devtools/shared/protocol");
+const { Arg, RetVal, types } = protocol;
+
+let childSpecs = {};
+
+function createStorageSpec(options) {
+ // common methods for all storage types
+ let 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
+ });
+}
+
+// Cookies store object
+types.addDictType("cookieobject", {
+ name: "string",
+ value: "longstring",
+ path: "nullable:string",
+ host: "string",
+ isDomain: "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 = {
+ getEditableFields: {
+ 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,
+ {
+ removeAll: {
+ 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,
+ {
+ 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("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", {
+ name: "nullable:string",
+ db: "nullable:string",
+ objectStore: "nullable:string",
+ origin: "nullable:string",
+ version: "nullable:number",
+ 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"
+});
+
+// Generate a type definition for an object with actors for all storage types.
+types.addDictType("storelist", Object.keys(childSpecs).reduce((obj, type) => {
+ obj[type] = type;
+ return obj;
+}, {}));
+
+exports.childSpecs = childSpecs;
+
+exports.storageSpec = protocol.generateActorSpec({
+ typeName: "storage",
+
+ /**
+ * List of event notifications that the server can send to the client.
+ *
+ * - stores-update : When any store object in any storage type changes.
+ * - stores-cleared : When all the store objects are removed.
+ * - stores-reloaded : When all stores are reloaded. This generally mean that
+ * we should refetch everything again.
+ */
+ events: {
+ "stores-update": {
+ type: "storesUpdate",
+ data: Arg(0, "storeUpdateObject")
+ },
+ "stores-cleared": {
+ type: "storesCleared",
+ data: Arg(0, "json")
+ },
+ "stores-reloaded": {
+ type: "storesReloaded",
+ data: Arg(0, "json")
+ }
+ },
+
+ methods: {
+ listStores: {
+ request: {},
+ response: RetVal("storelist")
+ },
+ }
+});
diff --git a/devtools/shared/specs/string.js b/devtools/shared/specs/string.js
new file mode 100644
index 000000000..f759d4052
--- /dev/null
+++ b/devtools/shared/specs/string.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 protocol = require("devtools/shared/protocol");
+const {Arg, RetVal, generateActorSpec} = protocol;
+const promise = require("promise");
+const {Class} = require("sdk/core/heritage");
+
+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.
+ */
+const SimpleStringFront = Class({
+ initialize: function (str) {
+ this.str = str;
+ },
+
+ get length() {
+ return this.str.length;
+ },
+
+ get initial() {
+ return this.str;
+ },
+
+ string: function () {
+ return promise.resolve(this.str);
+ },
+
+ substring: function (start, end) {
+ return promise.resolve(this.str.substring(start, end));
+ },
+
+ release: function () {
+ 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/styleeditor.js b/devtools/shared/specs/styleeditor.js
new file mode 100644
index 000000000..e93b7e56f
--- /dev/null
+++ b/devtools/shared/specs/styleeditor.js
@@ -0,0 +1,61 @@
+/* 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("devtools/shared/protocol");
+
+const oldStyleSheetSpec = generateActorSpec({
+ typeName: "old-stylesheet",
+
+ events: {
+ "property-change": {
+ type: "propertyChange",
+ property: Arg(0, "string"),
+ value: Arg(1, "json")
+ },
+ "source-load": {
+ type: "sourceLoad",
+ source: Arg(0, "string")
+ },
+ "style-applied": {
+ type: "styleApplied"
+ }
+ },
+
+ methods: {
+ toggleDisabled: {
+ response: { disabled: RetVal("boolean")}
+ },
+ fetchSource: {},
+ update: {
+ request: {
+ text: Arg(0, "string"),
+ transition: Arg(1, "boolean")
+ }
+ }
+ }
+});
+
+exports.oldStyleSheetSpec = oldStyleSheetSpec;
+
+const styleEditorSpec = generateActorSpec({
+ typeName: "styleeditor",
+
+ events: {
+ "document-load": {
+ type: "documentLoad",
+ styleSheets: Arg(0, "array:old-stylesheet")
+ }
+ },
+
+ method: {
+ newDocument: {},
+ newStyleSheet: {
+ request: { text: Arg(0, "string") },
+ response: { styleSheet: RetVal("old-stylesheet") }
+ }
+ }
+});
+
+exports.styleEditorSpec = styleEditorSpec;
diff --git a/devtools/shared/specs/styles.js b/devtools/shared/specs/styles.js
new file mode 100644
index 000000000..225d712a4
--- /dev/null
+++ b/devtools/shared/specs/styles.js
@@ -0,0 +1,206 @@
+/* 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("devtools/shared/protocol");
+require("devtools/shared/specs/node");
+require("devtools/shared/specs/stylesheets");
+
+// Predeclare the domstylerule actor type
+types.addActorType("domstylerule");
+
+/**
+ * DOM Nodes returned by the style actor will be owned by the DOM walker
+ * for the connection.
+ */
+types.addLifetime("walker", "walker");
+
+/**
+ * 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",
+ sheets: "array:stylesheet"
+});
+
+types.addDictType("modifiedStylesReturn", {
+ isMatching: RetVal("boolean"),
+ ruleProps: RetVal("nullable:appliedStylesReturn")
+});
+
+types.addDictType("fontpreview", {
+ data: "nullable:longstring",
+ size: "json"
+});
+
+types.addDictType("fontface", {
+ name: "string",
+ CSSFamilyName: "string",
+ rule: "nullable:domstylerule",
+ srcIndex: "number",
+ URI: "string",
+ format: "string",
+ preview: "nullable:fontpreview",
+ localName: "string",
+ metadata: "string"
+});
+
+const pageStyleSpec = generateActorSpec({
+ typeName: "pagestyle",
+
+ events: {
+ "stylesheet-updated": {
+ type: "styleSheetUpdated",
+ styleSheet: Arg(0, "stylesheet")
+ }
+ },
+
+ methods: {
+ getComputed: {
+ request: {
+ node: Arg(0, "domnode"),
+ markMatched: Option(1, "boolean"),
+ onlyMatched: Option(1, "boolean"),
+ filter: Option(1, "string"),
+ },
+ response: {
+ computed: RetVal("json")
+ }
+ },
+ getAllUsedFontFaces: {
+ request: {
+ includePreviews: Option(0, "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"),
+ 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",
+ sheets: "array:stylesheet",
+ matched: "array:matchedselector"
+ }))
+ },
+ getApplied: {
+ request: {
+ node: Arg(0, "domnode"),
+ inherited: Option(1, "boolean"),
+ matchedSelectors: 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"),
+ editAuthored: Arg(2, "boolean")
+ },
+ response: RetVal("appliedStylesReturn")
+ }
+ }
+});
+
+exports.pageStyleSpec = pageStyleSpec;
+
+const styleRuleSpec = generateActorSpec({
+ typeName: "domstylerule",
+
+ events: {
+ "location-changed": {
+ type: "locationChanged",
+ line: Arg(0, "number"),
+ column: Arg(1, "number")
+ },
+ },
+
+ methods: {
+ setRuleText: {
+ request: { modification: Arg(0, "string") },
+ response: { rule: RetVal("domstylerule") }
+ },
+ modifyProperties: {
+ request: { modifications: Arg(0, "array:json") },
+ response: { rule: RetVal("domstylerule") }
+ },
+ modifySelector: {
+ request: { selector: Arg(0, "string") },
+ response: { isModified: RetVal("boolean") },
+ },
+ modifySelector2: {
+ request: {
+ node: Arg(0, "domnode"),
+ value: Arg(1, "string"),
+ editAuthored: Arg(2, "boolean")
+ },
+ response: RetVal("modifiedStylesReturn")
+ }
+ }
+});
+
+exports.styleRuleSpec = styleRuleSpec;
+
+// The PageStyle actor flattens the DOM CSS objects a little bit, merging
+// Rules and their Styles into one actor. For elements (which have a style
+// but no associated rule) we fake a rule with the following style id.
+const ELEMENT_STYLE = 100;
+exports.ELEMENT_STYLE = ELEMENT_STYLE;
diff --git a/devtools/shared/specs/stylesheets.js b/devtools/shared/specs/stylesheets.js
new file mode 100644
index 000000000..c89a7c088
--- /dev/null
+++ b/devtools/shared/specs/stylesheets.js
@@ -0,0 +1,120 @@
+/* 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("devtools/shared/protocol");
+
+const originalSourceSpec = generateActorSpec({
+ typeName: "originalsource",
+
+ methods: {
+ getText: {
+ response: {
+ text: RetVal("longstring")
+ }
+ }
+ }
+});
+
+exports.originalSourceSpec = originalSourceSpec;
+
+const mediaRuleSpec = generateActorSpec({
+ typeName: "mediarule",
+
+ events: {
+ "matches-change": {
+ type: "matchesChange",
+ matches: Arg(0, "boolean"),
+ }
+ }
+});
+
+exports.mediaRuleSpec = mediaRuleSpec;
+
+types.addActorType("stylesheet");
+
+const styleSheetSpec = generateActorSpec({
+ typeName: "stylesheet",
+
+ events: {
+ "property-change": {
+ type: "propertyChange",
+ property: Arg(0, "string"),
+ value: Arg(1, "json")
+ },
+ "style-applied": {
+ type: "styleApplied",
+ kind: Arg(0, "number"),
+ styleSheet: Arg(1, "stylesheet")
+ },
+ "media-rules-changed": {
+ type: "mediaRulesChanged",
+ rules: Arg(0, "array:mediarule")
+ }
+ },
+
+ methods: {
+ toggleDisabled: {
+ response: { disabled: RetVal("boolean")}
+ },
+ getText: {
+ response: {
+ text: RetVal("longstring")
+ }
+ },
+ getOriginalSources: {
+ request: {},
+ response: {
+ originalSources: RetVal("nullable:array:originalsource")
+ }
+ },
+ getOriginalLocation: {
+ request: {
+ line: Arg(0, "number"),
+ column: Arg(1, "number")
+ },
+ response: RetVal(types.addDictType("originallocationresponse", {
+ source: "string",
+ line: "number",
+ column: "number"
+ }))
+ },
+ getMediaRules: {
+ request: {},
+ response: {
+ mediaRules: RetVal("nullable:array:mediarule")
+ }
+ },
+ update: {
+ request: {
+ text: Arg(0, "string"),
+ transition: Arg(1, "boolean")
+ }
+ }
+ }
+});
+
+exports.styleSheetSpec = styleSheetSpec;
+
+const styleSheetsSpec = generateActorSpec({
+ typeName: "stylesheets",
+
+ methods: {
+ getStyleSheets: {
+ request: {},
+ response: { styleSheets: RetVal("array:stylesheet") }
+ },
+ addStyleSheet: {
+ request: { text: Arg(0, "string") },
+ response: { styleSheet: RetVal("stylesheet") }
+ }
+ }
+});
+
+exports.styleSheetsSpec = styleSheetsSpec;
diff --git a/devtools/shared/specs/timeline.js b/devtools/shared/specs/timeline.js
new file mode 100644
index 000000000..653ebef49
--- /dev/null
+++ b/devtools/shared/specs/timeline.js
@@ -0,0 +1,118 @@
+/* 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,
+ Option,
+ generateActorSpec,
+ types
+} = require("devtools/shared/protocol");
+
+/**
+ * Type representing an array of numbers as strings, serialized fast(er).
+ * http://jsperf.com/json-stringify-parse-vs-array-join-split/3
+ *
+ * XXX: It would be nice if on local connections (only), we could just *give*
+ * the array directly to the front, instead of going through all this
+ * serialization redundancy.
+ */
+types.addType("array-of-numbers-as-strings", {
+ write: (v) => v.join(","),
+ // In Gecko <= 37, `v` is an array; do not transform in this case.
+ read: (v) => typeof v === "string" ? v.split(",") : v
+});
+
+const timelineSpec = generateActorSpec({
+ typeName: "timeline",
+
+ events: {
+ /**
+ * Events emitted when "DOMContentLoaded" and "Load" markers are received.
+ */
+ "doc-loading": {
+ type: "doc-loading",
+ marker: Arg(0, "json"),
+ endTime: Arg(0, "number")
+ },
+
+ /**
+ * The "markers" events emitted every DEFAULT_TIMELINE_DATA_PULL_TIMEOUT ms
+ * at most, when profile markers are found. The timestamps on each marker
+ * are relative to when recording was started.
+ */
+ "markers": {
+ type: "markers",
+ markers: Arg(0, "json"),
+ endTime: Arg(1, "number")
+ },
+
+ /**
+ * The "memory" events emitted in tandem with "markers", if this was enabled
+ * when the recording started. The `delta` timestamp on this measurement is
+ * relative to when recording was started.
+ */
+ "memory": {
+ type: "memory",
+ delta: Arg(0, "number"),
+ measurement: Arg(1, "json")
+ },
+
+ /**
+ * The "ticks" events (from the refresh driver) emitted in tandem with
+ * "markers", if this was enabled when the recording started. All ticks
+ * are timestamps with a zero epoch.
+ */
+ "ticks": {
+ type: "ticks",
+ delta: Arg(0, "number"),
+ timestamps: Arg(1, "array-of-numbers-as-strings")
+ },
+
+ /**
+ * The "frames" events emitted in tandem with "markers", containing
+ * JS stack frames. The `delta` timestamp on this frames packet is
+ * relative to when recording was started.
+ */
+ "frames": {
+ type: "frames",
+ delta: Arg(0, "number"),
+ frames: Arg(1, "json")
+ }
+ },
+
+ methods: {
+ isRecording: {
+ request: {},
+ response: {
+ value: RetVal("boolean")
+ }
+ },
+
+ start: {
+ request: {
+ withMarkers: Option(0, "boolean"),
+ withTicks: Option(0, "boolean"),
+ withMemory: Option(0, "boolean"),
+ withFrames: Option(0, "boolean"),
+ withGCEvents: Option(0, "boolean"),
+ withDocLoadingEvents: Option(0, "boolean")
+ },
+ response: {
+ value: RetVal("number")
+ }
+ },
+
+ stop: {
+ response: {
+ // Set as possibly nullable due to the end time possibly being
+ // undefined during destruction
+ value: RetVal("nullable:number")
+ }
+ },
+ },
+});
+
+exports.timelineSpec = timelineSpec;
diff --git a/devtools/shared/specs/webaudio.js b/devtools/shared/specs/webaudio.js
new file mode 100644
index 000000000..9dfb92467
--- /dev/null
+++ b/devtools/shared/specs/webaudio.js
@@ -0,0 +1,163 @@
+/* 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("devtools/shared/protocol");
+
+exports.NODE_CREATION_METHODS = [
+ "createBufferSource", "createMediaElementSource", "createMediaStreamSource",
+ "createMediaStreamDestination", "createScriptProcessor", "createAnalyser",
+ "createGain", "createDelay", "createBiquadFilter", "createWaveShaper",
+ "createPanner", "createConvolver", "createChannelSplitter", "createChannelMerger",
+ "createDynamicsCompressor", "createOscillator", "createStereoPanner"
+];
+
+exports.AUTOMATION_METHODS = [
+ "setValueAtTime", "linearRampToValueAtTime", "exponentialRampToValueAtTime",
+ "setTargetAtTime", "setValueCurveAtTime", "cancelScheduledValues"
+];
+
+exports.NODE_ROUTING_METHODS = [
+ "connect", "disconnect"
+];
+
+types.addActorType("audionode");
+const audionodeSpec = generateActorSpec({
+ typeName: "audionode",
+
+ methods: {
+ getType: { response: { type: RetVal("string") }},
+ isBypassed: {
+ response: { bypassed: RetVal("boolean") }
+ },
+ bypass: {
+ request: { enable: Arg(0, "boolean") },
+ response: { bypassed: RetVal("boolean") }
+ },
+ setParam: {
+ request: {
+ param: Arg(0, "string"),
+ value: Arg(1, "nullable:primitive")
+ },
+ response: { error: RetVal("nullable:json") }
+ },
+ getParam: {
+ request: {
+ param: Arg(0, "string")
+ },
+ response: { text: RetVal("nullable:primitive") }
+ },
+ getParamFlags: {
+ request: { param: Arg(0, "string") },
+ response: { flags: RetVal("nullable:primitive") }
+ },
+ getParams: {
+ response: { params: RetVal("json") }
+ },
+ connectParam: {
+ request: {
+ destActor: Arg(0, "audionode"),
+ paramName: Arg(1, "string"),
+ output: Arg(2, "nullable:number")
+ },
+ response: { error: RetVal("nullable:json") }
+ },
+ connectNode: {
+ request: {
+ destActor: Arg(0, "audionode"),
+ output: Arg(1, "nullable:number"),
+ input: Arg(2, "nullable:number")
+ },
+ response: { error: RetVal("nullable:json") }
+ },
+ disconnect: {
+ request: { output: Arg(0, "nullable:number") },
+ response: { error: RetVal("nullable:json") }
+ },
+ getAutomationData: {
+ request: { paramName: Arg(0, "string") },
+ response: { values: RetVal("nullable:json") }
+ },
+ addAutomationEvent: {
+ request: {
+ paramName: Arg(0, "string"),
+ eventName: Arg(1, "string"),
+ args: Arg(2, "nullable:json")
+ },
+ response: { error: RetVal("nullable:json") }
+ },
+ }
+});
+
+exports.audionodeSpec = audionodeSpec;
+
+const webAudioSpec = generateActorSpec({
+ typeName: "webaudio",
+
+ /**
+ * Events emitted by this actor.
+ */
+ events: {
+ "start-context": {
+ type: "startContext"
+ },
+ "connect-node": {
+ type: "connectNode",
+ source: Option(0, "audionode"),
+ dest: Option(0, "audionode")
+ },
+ "disconnect-node": {
+ type: "disconnectNode",
+ source: Arg(0, "audionode")
+ },
+ "connect-param": {
+ type: "connectParam",
+ source: Option(0, "audionode"),
+ dest: Option(0, "audionode"),
+ param: Option(0, "string")
+ },
+ "change-param": {
+ type: "changeParam",
+ source: Option(0, "audionode"),
+ param: Option(0, "string"),
+ value: Option(0, "string")
+ },
+ "create-node": {
+ type: "createNode",
+ source: Arg(0, "audionode")
+ },
+ "destroy-node": {
+ type: "destroyNode",
+ source: Arg(0, "audionode")
+ },
+ "automation-event": {
+ type: "automationEvent",
+ node: Option(0, "audionode"),
+ paramName: Option(0, "string"),
+ eventName: Option(0, "string"),
+ args: Option(0, "json")
+ }
+ },
+
+ methods: {
+ getDefinition: {
+ response: { definition: RetVal("json") }
+ },
+ setup: {
+ request: { reload: Option(0, "boolean") },
+ oneway: true
+ },
+ finalize: {
+ oneway: true
+ }
+ }
+});
+
+exports.webAudioSpec = webAudioSpec;
diff --git a/devtools/shared/specs/webgl.js b/devtools/shared/specs/webgl.js
new file mode 100644
index 000000000..f97610f3c
--- /dev/null
+++ b/devtools/shared/specs/webgl.js
@@ -0,0 +1,101 @@
+/* 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("devtools/shared/protocol");
+
+const shaderSpec = generateActorSpec({
+ typeName: "gl-shader",
+
+ methods: {
+ getText: {
+ response: { text: RetVal("string") }
+ },
+ compile: {
+ request: { text: Arg(0, "string") },
+ response: { error: RetVal("nullable:json") }
+ },
+ },
+});
+
+exports.shaderSpec = shaderSpec;
+
+const programSpec = generateActorSpec({
+ typeName: "gl-program",
+
+ methods: {
+ getVertexShader: {
+ response: { shader: RetVal("gl-shader") }
+ },
+ getFragmentShader: {
+ response: { shader: RetVal("gl-shader") }
+ },
+ highlight: {
+ request: { tint: Arg(0, "array:number") },
+ oneway: true
+ },
+ unhighlight: {
+ oneway: true
+ },
+ blackbox: {
+ oneway: true
+ },
+ unblackbox: {
+ oneway: true
+ },
+ }
+});
+
+exports.programSpec = programSpec;
+
+const webGLSpec = generateActorSpec({
+ typeName: "webgl",
+
+ /**
+ * Events emitted by this actor. The "program-linked" event is fired every
+ * time a WebGL program was linked with its respective two shaders.
+ */
+ events: {
+ "program-linked": {
+ type: "programLinked",
+ program: Arg(0, "gl-program")
+ },
+ "global-destroyed": {
+ type: "globalDestroyed",
+ program: Arg(0, "number")
+ },
+ "global-created": {
+ type: "globalCreated",
+ program: Arg(0, "number")
+ }
+ },
+
+ methods: {
+ setup: {
+ request: { reload: Option(0, "boolean") },
+ oneway: true
+ },
+ finalize: {
+ oneway: true
+ },
+ getPrograms: {
+ response: { programs: RetVal("array:gl-program") }
+ },
+ waitForFrame: {
+ response: { success: RetVal("nullable:json") }
+ },
+ getPixel: {
+ request: {
+ selector: Option(0, "string"),
+ position: Option(0, "json")
+ },
+ response: { pixels: RetVal("json") }
+ },
+ _getAllPrograms: {
+ response: { programs: RetVal("array:gl-program") }
+ }
+ }
+});
+
+exports.webGLSpec = webGLSpec;
diff --git a/devtools/shared/specs/worker.js b/devtools/shared/specs/worker.js
new file mode 100644
index 000000000..568f55ec0
--- /dev/null
+++ b/devtools/shared/specs/worker.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 {Arg, RetVal, generateActorSpec} = require("devtools/shared/protocol");
+
+const workerSpec = generateActorSpec({
+ typeName: "worker",
+
+ methods: {
+ attach: {
+ request: {},
+ response: RetVal("json")
+ },
+ detach: {
+ request: {},
+ response: RetVal("json")
+ },
+ connect: {
+ request: {
+ options: Arg(0, "json"),
+ },
+ response: RetVal("json")
+ },
+ push: {
+ request: {},
+ response: RetVal("json")
+ },
+ },
+});
+
+exports.workerSpec = workerSpec;
+
+const pushSubscriptionSpec = generateActorSpec({
+ typeName: "pushSubscription",
+});
+
+exports.pushSubscriptionSpec = pushSubscriptionSpec;
+
+const serviceWorkerRegistrationSpec = generateActorSpec({
+ typeName: "serviceWorkerRegistration",
+
+ events: {
+ "push-subscription-modified": {
+ type: "push-subscription-modified"
+ },
+ "registration-changed": {
+ type: "registration-changed"
+ }
+ },
+
+ methods: {
+ start: {
+ request: {},
+ response: RetVal("json")
+ },
+ unregister: {
+ request: {},
+ response: RetVal("json")
+ },
+ getPushSubscription: {
+ request: {},
+ response: {
+ subscription: RetVal("nullable:pushSubscription")
+ }
+ },
+ },
+});
+
+exports.serviceWorkerRegistrationSpec = serviceWorkerRegistrationSpec;
+
+const serviceWorkerSpec = generateActorSpec({
+ typeName: "serviceWorker",
+});
+
+exports.serviceWorkerSpec = serviceWorkerSpec;
+