new file mode 100644
--- /dev/null
+++ b/devtools/server/actors/changes.js
@@ -0,0 +1,70 @@
+/* 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");
+const TrackChangeEmitter = require("devtools/server/actors/utils/track-change-emitter");
+
+/**
+ * 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 {DebuggerServerConnection} conn
+ * The server connection.
+ * @param {TargetActor} targetActor
+ * The top-level Actor for this tab.
+ */
+ initialize: function(conn, targetActor) {
+ protocol.Actor.prototype.initialize.call(this, conn);
+ this.targetActor = targetActor;
+
+ this.onTrackChange = this.pushChange.bind(this);
+ TrackChangeEmitter.on("track-change", this.onTrackChange);
+
+ this.changes = [];
+ },
+
+ destroy: function() {
+ this.clearChanges();
+ TrackChangeEmitter.off("track-change", this.onTrackChange);
+ protocol.Actor.prototype.destroy.call(this);
+ },
+
+ 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;
+ },
+
+ allChanges: function() {
+ return this.changes.slice();
+ },
+
+ pushChange: function(change) {
+ 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-parent.js',
'accessibility.js',
'actor-registry.js',
'animation-type-longhand.js',
'animation.js',
'array-buffer.js',
'breakpoint.js',
'canvas.js',
+ 'changes.js',
'common.js',
'css-properties.js',
'csscoverage.js',
'device.js',
'emulation.js',
'environment.js',
'errordocs.js',
'frame.js',
--- a/devtools/server/actors/utils/actor-registry.js
+++ b/devtools/server/actors/utils/actor-registry.js
@@ -251,16 +251,21 @@ const ActorRegistry = {
constructor: "AccessibilityActor",
type: { target: true },
});
this.registerModule("devtools/server/actors/screenshot", {
prefix: "screenshot",
constructor: "ScreenshotActor",
type: { target: true },
});
+ this.registerModule("devtools/server/actors/changes", {
+ prefix: "changes",
+ constructor: "ChangesActor",
+ type: { target: true },
+ });
},
/**
* Registers handlers for new target-scoped request types defined dynamically.
*
* Note that the name or actorPrefix of the request type is not allowed to clash with
* existing protocol packet properties, like 'title', 'url' or 'actor', since that would
* break the protocol.
new file mode 100644
--- /dev/null
+++ b/devtools/shared/fronts/changes.js
@@ -0,0 +1,24 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const protocol = require("devtools/shared/protocol");
+const {changesSpec} = require("devtools/shared/specs/changes");
+
+/**
+ * ChangesFront, the front object for the ChangesActor
+ */
+const ChangesFront = protocol.FrontClassWithSpec(changesSpec, {
+ initialize: function (client, {changesActor}) {
+ protocol.Front.prototype.initialize.call(this, client, {actor: changesActor});
+ this.manage(this);
+ },
+
+ destroy: function() {
+ protocol.Front.prototype.destroy.call(this);
+ },
+});
+
+exports.ChangesFront = ChangesFront;
--- a/devtools/shared/fronts/moz.build
+++ b/devtools/shared/fronts/moz.build
@@ -9,16 +9,17 @@ DIRS += [
'targets',
]
DevToolsModules(
'accessibility.js',
'actor-registry.js',
'animation.js',
'canvas.js',
+ 'changes.js',
'css-properties.js',
'csscoverage.js',
'device.js',
'emulation.js',
'framerate.js',
'function-call.js',
'highlighters.js',
'inspector.js',
new file mode 100644
--- /dev/null
+++ b/devtools/shared/specs/changes.js
@@ -0,0 +1,24 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {
+ generateActorSpec,
+ RetVal,
+} = require("devtools/shared/protocol");
+
+const changesSpec = generateActorSpec({
+ typeName: "changes",
+
+ methods: {
+ "allChanges": {
+ response: {
+ changes: RetVal("array:json"),
+ },
+ },
+ },
+});
+
+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
@@ -11,16 +11,17 @@ DIRS += [
]
DevToolsModules(
'accessibility.js',
'actor-registry.js',
'animation.js',
'breakpoint.js',
'canvas.js',
+ 'changes.js',
'css-properties.js',
'csscoverage.js',
'device.js',
'emulation.js',
'environment.js',
'frame.js',
'framerate.js',
'function-call.js',