Bug 1468754 Part 1: Add a ChangesActor to devtools.
MozReview-Commit-ID: 1Y8esljnLk9
new file mode 100644
--- /dev/null
+++ b/devtools/server/actors/changes.js
@@ -0,0 +1,113 @@
+/* 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 { changesSpec } = require("devtools/shared/specs/changes");
+
+/**
+ * The ChangesActor stores a stack of changes made by devtools on
+ * the document in the associated tab.
+ */
+const ChangesActor = protocol.ActorClassWithSpec(changesSpec, {
+ /**
+ * Create a ChangesActor.
+ *
+ * @param {InspectorActor} inspector
+ * The InspectorActor that owns this ChangesActor.
+ */
+ initialize: function(inspector) {
+ protocol.Actor.prototype.initialize.call(this, null);
+ this.inspector = inspector;
+
+ this.changes = [];
+ },
+
+ destroy: function() {
+ protocol.Actor.prototype.destroy.call(this);
+ this.inspector = null;
+ },
+
+ get conn() {
+ return this.inspector.conn;
+ },
+
+ form: function(detail) {
+ if (detail === "actorid") {
+ return this.actorID;
+ }
+
+ return {
+ actor: this.actorID,
+ };
+ },
+
+ changeCount: function() {
+ return this.changes.length;
+ },
+
+ change: function(index) {
+ if (index >= 0 && index < this.changes.length) {
+ // Return a copy of the change at index.
+ return Object.assign({}, this.changes[index]);
+ }
+ // No change at that index -- return undefined.
+ return undefined;
+ },
+
+ changes: function() {
+ return this.changes.slice();
+ },
+
+ pushStylesheetChange: function(stylesheet, offset, oldText, newText) {
+ const change = {
+ description: "(localize me) Change '" + oldText + "' to '" + newText + "'.",
+ stylesheetChange: {
+ stylesheet: stylesheet,
+ offset: offset,
+ oldText: oldText,
+ newText: newText,
+ },
+ };
+ this.changes.push(change);
+ },
+
+ pushAttributeChange: function(node, ns, attribute, oldText, newText) {
+ // Compose a human-readable description of the change.
+ let description;
+ if (!oldText) {
+ // Adding an attribute.
+ description = "(localize me) Add " + node + " attribute " + (ns ? ns + ":" : "") + attribute + " with value '" + newText + "'.";
+ } else if (!newText) {
+ // Removing an attribute.
+ description = "(localize me) Remove " + node + " attribute " + (ns ? ns + ":" : "") + attribute + ".";
+ } else {
+ // Changing an attribute.
+ description = "(localize me) Change " + node + " attribute " + (ns ? ns + ":" : "") + attribute + " from '" + oldText + "' to '" + newText + "'.";
+ }
+
+ const change = {
+ description: description,
+ attributeChange: {
+ node: node,
+ ns: ns,
+ attribute: attribute,
+ oldText: oldText,
+ newText: newText,
+ },
+ };
+ this.changes.push(change);
+ },
+
+ popChange: function() {
+ return this.changes.pop();
+ },
+
+ clearChanges: function() {
+ this.changes.length = 0;
+ }
+});
+
+exports.ChangesActor = ChangesActor;
--- a/devtools/server/actors/moz.build
+++ b/devtools/server/actors/moz.build
@@ -23,16 +23,17 @@ DevToolsModules(
'accessibility.js',
'actor-registry.js',
'animation-type-longhand.js',
'animation.js',
'array-buffer.js',
'breakpoint.js',
'call-watcher.js',
'canvas.js',
+ 'changes.js',
'common.js',
'css-properties.js',
'csscoverage.js',
'device.js',
'emulation.js',
'environment.js',
'errordocs.js',
'frame.js',
new file mode 100644
--- /dev/null
+++ b/devtools/shared/fronts/changes.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 {
+ FrontClassWithSpec
+} = require("devtools/shared/protocol");
+const {
+ changesSpec
+} = require("devtools/shared/specs/changes");
+
+/**
+ * ChangesFront, the front object for the ChangesActor
+ */
+const ChangesFront = FrontClassWithSpec(changesSpec, {
+ form: function(form, detail) {
+ if (detail === "actorid") {
+ this.actorID = form;
+ return;
+ }
+ this._form = form;
+ }
+});
+
+exports.ChangesFront = ChangesFront;
--- a/devtools/shared/fronts/moz.build
+++ b/devtools/shared/fronts/moz.build
@@ -9,16 +9,17 @@ DIRS += [
]
DevToolsModules(
'accessibility.js',
'actor-registry.js',
'animation.js',
'call-watcher.js',
'canvas.js',
+ 'changes.js',
'css-properties.js',
'csscoverage.js',
'device.js',
'emulation.js',
'framerate.js',
'gcli.js',
'highlighters.js',
'inspector.js',
new file mode 100644
--- /dev/null
+++ b/devtools/shared/specs/changes.js
@@ -0,0 +1,96 @@
+/* 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,
+ types,
+} = require("devtools/shared/protocol");
+
+types.addDictType("change", {
+ // A human-readable, localized description of the change
+ description: "string",
+
+ // A union of possible types of changes
+ stylesheetChange: "nullable:stylesheetChange",
+ attributeChange: "nullable:attributeChange",
+});
+
+types.addDictType("stylesheetChange", {
+ stylesheet: "stylesheet",
+
+ // The location of the changed text within the stylesheet
+ offset: "number",
+
+ // The old and new text
+ oldText: "string",
+ newText: "string",
+});
+
+types.addDictType("attributeChange", {
+ node: "domnode",
+ ns: "string",
+ attribute: "string",
+
+ // The old and new text
+ oldText: "string",
+ newText: "string",
+});
+
+const changesSpec = generateActorSpec({
+ typeName: "changes",
+
+ methods: {
+ changeCount: {
+ request: {},
+ response: { count: RetVal("number") }
+ },
+
+ change: {
+ request: { index: Arg(0, "number") },
+ response: { change: RetVal("nullable:change") }
+ },
+
+ changes: {
+ request: {},
+ response: { changes: RetVal("array:change") }
+ },
+
+ pushStylesheetChange: {
+ request: {
+ stylesheet: Arg(0, "stylesheet"),
+ offset: Arg(1, "number"),
+ oldText: Arg(2, "string"),
+ newText: Arg(3, "string"),
+ },
+ response: { change: RetVal("change") }
+ },
+
+ pushAttributeChange: {
+ request: {
+ node: Arg(0, "domnode"),
+ ns: Arg(1, "string"),
+ attribute: Arg(2, "string"),
+ oldText: Arg(3, "string"),
+ newText: Arg(4, "string"),
+ },
+ response: { change: RetVal("change") }
+ },
+
+ popChange: {
+ request: {},
+ response: { change: RetVal("nullable:change") }
+ },
+
+ clearChanges: {
+ request: {},
+ response: {}
+ },
+ }
+});
+
+exports.changesSpec = changesSpec;
--- a/devtools/shared/specs/index.js
+++ b/devtools/shared/specs/index.js
@@ -215,16 +215,21 @@ const Types = exports.__TypesForTests =
front: "devtools/shared/fronts/string",
},
{
types: ["pagestyle", "domstylerule"],
spec: "devtools/shared/specs/styles",
front: "devtools/shared/fronts/styles",
},
{
+ types: ["changes"],
+ spec: "devtools/shared/specs/changes",
+ front: "devtools/shared/fronts/changes",
+ },
+ {
types: ["mediarule", "stylesheet", "stylesheets"],
spec: "devtools/shared/specs/stylesheets",
front: "devtools/shared/fronts/stylesheets",
},
{
types: ["symbol"],
spec: "devtools/shared/specs/symbol",
front: null,
--- a/devtools/shared/specs/moz.build
+++ b/devtools/shared/specs/moz.build
@@ -12,16 +12,17 @@ DIRS += [
DevToolsModules(
'accessibility.js',
'actor-registry.js',
'animation.js',
'breakpoint.js',
'call-watcher.js',
'canvas.js',
+ 'changes.js',
'css-properties.js',
'csscoverage.js',
'device.js',
'emulation.js',
'environment.js',
'frame.js',
'framerate.js',
'gcli.js',