diff --git a/devtools/server/actors/changes.js b/devtools/server/actors/changes.js new file mode 100644 index 000000000000..24e0f593bea4 --- /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; diff --git a/devtools/server/actors/moz.build b/devtools/server/actors/moz.build index 3f19b89f6c61..462cf6deacfa 100644 --- a/devtools/server/actors/moz.build +++ b/devtools/server/actors/moz.build @@ -28,6 +28,7 @@ DevToolsModules( 'array-buffer.js', 'breakpoint.js', 'canvas.js', + 'changes.js', 'common.js', 'css-properties.js', 'csscoverage.js', diff --git a/devtools/server/actors/utils/actor-registry.js b/devtools/server/actors/utils/actor-registry.js index b88368a283ef..df502edd4c30 100644 --- a/devtools/server/actors/utils/actor-registry.js +++ b/devtools/server/actors/utils/actor-registry.js @@ -256,6 +256,11 @@ const ActorRegistry = { constructor: "ScreenshotActor", type: { target: true }, }); + this.registerModule("devtools/server/actors/changes", { + prefix: "changes", + constructor: "ChangesActor", + type: { target: true } + }); }, /** diff --git a/devtools/shared/fronts/changes.js b/devtools/shared/fronts/changes.js new file mode 100644 index 000000000000..0dcf5b4f20c2 --- /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; diff --git a/devtools/shared/fronts/moz.build b/devtools/shared/fronts/moz.build index 202b31344f97..1ea38ae7f80c 100644 --- a/devtools/shared/fronts/moz.build +++ b/devtools/shared/fronts/moz.build @@ -14,6 +14,7 @@ DevToolsModules( 'actor-registry.js', 'animation.js', 'canvas.js', + 'changes.js', 'css-properties.js', 'csscoverage.js', 'device.js', diff --git a/devtools/shared/specs/changes.js b/devtools/shared/specs/changes.js new file mode 100644 index 000000000000..2ddb41183692 --- /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; diff --git a/devtools/shared/specs/index.js b/devtools/shared/specs/index.js index c3eec9c850b2..b443d90b7d48 100644 --- a/devtools/shared/specs/index.js +++ b/devtools/shared/specs/index.js @@ -219,6 +219,11 @@ const Types = exports.__TypesForTests = [ 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", diff --git a/devtools/shared/specs/moz.build b/devtools/shared/specs/moz.build index 14deb294bab5..081f639f0618 100644 --- a/devtools/shared/specs/moz.build +++ b/devtools/shared/specs/moz.build @@ -16,6 +16,7 @@ DevToolsModules( 'animation.js', 'breakpoint.js', 'canvas.js', + 'changes.js', 'css-properties.js', 'csscoverage.js', 'device.js',