Bug 1468754 Part 1: Add a ChangesActor to devtools. draft
authorBrad Werth <bwerth@mozilla.com>
Wed, 20 Jun 2018 11:30:35 -0700
changeset 826137 5f698b0fc78d58db1cbff446b0b2a718cbf4188a
parent 826136 25f9a2a123423dee5cb9bed193fbd2cd101d6314
child 826138 20df5c7ae981254f1a424d5953db29c521e28927
push id118245
push userbwerth@mozilla.com
push dateFri, 03 Aug 2018 00:03:09 +0000
bugs1468754
milestone63.0a1
Bug 1468754 Part 1: Add a ChangesActor to devtools. MozReview-Commit-ID: 1Y8esljnLk9
devtools/server/actors/changes.js
devtools/server/actors/moz.build
devtools/shared/fronts/changes.js
devtools/shared/fronts/moz.build
devtools/shared/specs/changes.js
devtools/shared/specs/index.js
devtools/shared/specs/moz.build
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',