--- a/inspector-actor-pseudoclass.diff
+++ b/inspector-actor-pseudoclass.diff
@@ -1,14 +1,14 @@
# HG changeset patch
# User Dave Camp <dcamp@mozilla.com>
# Date 1370924321 25200
# Mon Jun 10 21:18:41 2013 -0700
# Node ID b400cc70cce3af826333cb4fc51109420cf74e5b
-# Parent 51766479c3c9b9c3ec81f9109babbfe726c9654d
+# Parent 6463faecc4d6b040b3f663f33f69af7a01c62165
[mq]: inspector-actor-pseudoclass.diff
diff --git a/toolkit/devtools/server/actors/inspector.js b/toolkit/devtools/server/actors/inspector.js
--- a/toolkit/devtools/server/actors/inspector.js
+++ b/toolkit/devtools/server/actors/inspector.js
@@ -47,16 +47,18 @@ const protocol = require("devtools/serve
const {Arg, Option, method, RetVal, types} = protocol;
const {LongStringActor, ShortLongString} = require("devtools/server/actors/string");
@@ -75,17 +75,17 @@ diff --git a/toolkit/devtools/server/act
/**
* Returns a LongStringActor with the node's value.
*/
getNodeValue: method(function() {
return new LongStringActor(this.conn, this.rawNode.nodeValue || "");
}, {
request: {},
response: {
-@@ -280,16 +298,18 @@ let NodeFront = protocol.FrontClass(Node
+@@ -282,16 +300,18 @@ let NodeFront = protocol.FrontClass(Node
name: change.attributeName,
namespace: change.attributeNamespace,
value: change.newValue
});
}
} else if (change.type === "characterData") {
this._form.shortValue = change.newValue;
this._form.incompleteValue = change.incompleteValue;
@@ -94,17 +94,17 @@ diff --git a/toolkit/devtools/server/act
}
},
// Some accessors to make NodeFront feel more like an nsIDOMNode
get id() this.getAttribute("id"),
get nodeType() this._form.nodeType,
-@@ -318,16 +338,21 @@ let NodeFront = protocol.FrontClass(Node
+@@ -320,16 +340,21 @@ let NodeFront = protocol.FrontClass(Node
},
hasAttribute: function(name) {
this._cacheAttributes();
return (name in this._attrMap);
},
get attributes() this._form.attrs,
@@ -116,35 +116,35 @@ diff --git a/toolkit/devtools/server/act
getNodeValue: protocol.custom(function() {
if (!this.incompleteValue) {
return delayedResolve(new ShortLongString(this.shortValue));
} else {
return this._getNodeValue();
}
}, {
impl: "_getNodeValue"
-@@ -634,16 +659,17 @@ var WalkerActor = protocol.ActorClass({
+@@ -636,16 +661,17 @@ var WalkerActor = protocol.ActorClass({
* @param DebuggerServerConnection conn
* The server connection.
*/
initialize: function(conn, document, webProgress, options) {
protocol.Actor.prototype.initialize.call(this, conn);
this.rootDoc = document;
this._refMap = new Map();
this._pendingMutations = [];
+ this._activePseudoClassLocks = new Set();
// Nodes which have been removed from the client's known
// ownership tree are considered "orphaned", and stored in
// this set.
this._orphaned = new Set();
- this.onMutations = this.onMutations.bind(this);
- this.onFrameLoad = this.onFrameLoad.bind(this);
-@@ -668,24 +694,29 @@ var WalkerActor = protocol.ActorClass({
+ // The client can tell the walker that it is interested in a node
+ // even when it is orphaned with the `retainNode` method. This
+@@ -675,24 +701,29 @@ var WalkerActor = protocol.ActorClass({
},
toString: function() {
return "[WalkerActor " + this.actorID + "]";
},
destroy: function() {
protocol.Actor.prototype.destroy.call(this);
@@ -164,17 +164,17 @@ diff --git a/toolkit/devtools/server/act
this._refMap.delete(actor.rawNode);
}
protocol.Actor.prototype.unmanage.call(this, actor);
},
_ref: function(node) {
let actor = this._refMap.get(node);
if (actor) return actor;
-@@ -1073,16 +1104,147 @@ var WalkerActor = protocol.ActorClass({
+@@ -1130,16 +1161,141 @@ var WalkerActor = protocol.ActorClass({
selector: Arg(1)
},
response: {
list: RetVal("domnodelist")
}
}),
/**
@@ -209,27 +209,21 @@ diff --git a/toolkit/devtools/server/act
+ node: Arg(0, "domnode"),
+ pseudoClass: Arg(1),
+ parents: Option(2)
+ },
+ response: {}
+ }),
+
+ _queuePseudoClassMutation: function(node) {
-+ let needEvent = this._pendingMutations.length === 0;
-+
-+ this._pendingMutations.push({
++ this.queueMutation({
+ target: node.actorID,
+ type: "pseudoClassLock",
+ pseudoClassLocks: node.writePseudoClassLocks()
+ });
-+
-+ if (needEvent) {
-+ events.emit(this, "new-mutations");
-+ }
+ },
+
+ _addPseudoClassLock: function(node, pseudo) {
+ if (node.rawNode.nodeType !== Ci.nsIDOMNode.ELEMENT_NODE) {
+ return false;
+ }
+ DOMUtils.addPseudoClassLock(node.rawNode, pseudo);
+ this._activePseudoClassLocks.add(node);
@@ -315,25 +309,25 @@ diff --git a/toolkit/devtools/server/act
*
* Mutation records have a basic structure:
*
* {
* type: attributes|characterData|childList,
diff --git a/toolkit/devtools/server/tests/mochitest/Makefile.in b/toolkit/devtools/server/tests/mochitest/Makefile.in
--- a/toolkit/devtools/server/tests/mochitest/Makefile.in
+++ b/toolkit/devtools/server/tests/mochitest/Makefile.in
-@@ -14,14 +14,15 @@ include $(DEPTH)/config/autoconf.mk
- MOCHITEST_CHROME_FILES = \
+@@ -15,14 +15,15 @@ MOCHITEST_CHROME_FILES = \
inspector-helpers.js \
inspector-traversal-data.html \
test_inspector-mutations-attr.html \
test_inspector-mutations-childlist.html \
test_inspector-mutations-frameload.html \
test_inspector-mutations-value.html \
test_inspector-release.html \
+ test_inspector-retain.html \
+ test_inspector-pseudoclass-lock.html \
test_inspector-traversal.html \
test_unsafeDereference.html \
nonchrome_unsafeDereference.html \
$(NULL)
include $(topsrcdir)/config/rules.mk
diff --git a/toolkit/devtools/server/tests/mochitest/inspector-helpers.js b/toolkit/devtools/server/tests/mochitest/inspector-helpers.js
--- a/inspector-emit-on-destroy.diff
+++ b/inspector-emit-on-destroy.diff
@@ -1,144 +1,33 @@
# HG changeset patch
# User Dave Camp <dcamp@mozilla.com>
# Date 1370924324 25200
# Mon Jun 10 21:18:44 2013 -0700
# Node ID 01d60c2d12387935dc7efb6a1f9d2d4a8df9df50
-# Parent f5cbe11c4e8aa44ca507b48acf9b0ff902f964d3
+# Parent 4a4117afe97e0823ca9ab6719135e75563662ae0
imported patch inspector-emit-on-destroy.diff
diff --git a/toolkit/devtools/server/actors/inspector.js b/toolkit/devtools/server/actors/inspector.js
--- a/toolkit/devtools/server/actors/inspector.js
+++ b/toolkit/devtools/server/actors/inspector.js
-@@ -1148,27 +1148,21 @@ var WalkerActor = protocol.ActorClass({
- node: Arg(0, "domnode"),
- pseudoClass: Arg(1),
- parents: Option(2)
- },
- response: {}
- }),
-
- _queuePseudoClassMutation: function(node) {
-- let needEvent = this._pendingMutations.length === 0;
--
-- this._pendingMutations.push({
-+ this._queueMutation({
- target: node.actorID,
- type: "pseudoClassLock",
- pseudoClassLocks: node.writePseudoClassLocks()
- });
--
-- if (needEvent) {
-- events.emit(this, "new-mutations");
-- }
- },
-
- _addPseudoClassLock: function(node, pseudo) {
- if (node.rawNode.nodeType !== Ci.nsIDOMNode.ELEMENT_NODE) {
- return false;
- }
- DOMUtils.addPseudoClassLock(node.rawNode, pseudo);
- this._activePseudoClassLocks.add(node);
-@@ -1306,27 +1300,37 @@ var WalkerActor = protocol.ActorClass({
- request: {
+@@ -1362,16 +1362,21 @@ var WalkerActor = protocol.ActorClass({
cleanup: Option(0)
},
response: {
mutations: RetVal("array:dommutation")
}
}),
-+ _queueMutation: function (mutation) {
+ queueMutation: function(mutation) {
+ if (!this.actorID) {
+ // We've been destroyed, don't bother.
++ return;
+ }
+
-+ // We only send the `new-mutations` notification once, until the client
-+ // fetches mutations with the `getMutations` packet.
-+ let needEvent = this._pendingMutations.length === 0;
-+ this._pendingMutations.push(mutation);
-+ if (needEvent) {
-+ events.emit(this, "new-mutations");
-+ }
-+ },
-+
- /**
- * Handles mutations from the DOM mutation observer API.
- *
- * @param array[MutationRecord] mutations
- * See https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationRecord
- */
- onMutations: function(mutations) {
-- // We only send the `new-mutations` notification once, until the client
-- // fetches mutations with the `getMutations` packet.
-- let needEvent = this._pendingMutations.length === 0;
--
- for (let change of mutations) {
- let targetActor = this._refMap.get(change.target);
- if (!targetActor) {
- continue;
- }
- let targetNode = change.target;
- let mutation = {
- type: change.type,
-@@ -1373,58 +1377,46 @@ var WalkerActor = protocol.ActorClass({
- // to date.
- this._orphaned.delete(addedActor);
- addedActors.push(addedActor.actorID);
- }
- mutation.numChildren = change.target.childNodes.length;
- mutation.removed = removedActors;
- mutation.added = addedActors;
- }
-- this._pendingMutations.push(mutation);
-- }
-- if (needEvent && this._pendingMutations.length > 0) {
-- events.emit(this, "new-mutations");
-+ this._queueMutation(mutation);
- }
- },
+ // We only send the `new-mutations` notification once, until the client
+ // fetches mutations with the `getMutations` packet.
+ let needEvent = this._pendingMutations.length === 0;
- onFrameLoad: function(window) {
- let frame = window.frameElement;
- let frameActor = this._refMap.get(frame);
- if (!frameActor) {
- return;
- }
-- let needEvent = this._pendingMutations.length === 0;
-- this._pendingMutations.push({
-+ this._queueMutation({
- type: "frameLoad",
- target: frameActor.actorID,
- added: [],
- removed: []
- });
--
-- if (needEvent) {
-- events.emit(this, "new-mutations");
-- }
- },
+ this._pendingMutations.push(mutation);
- onFrameUnload: function(window) {
- let doc = window.document;
- let documentActor = this._refMap.get(doc);
- if (!documentActor) {
- return;
- }
-
-- let needEvent = this._pendingMutations.length === 0;
-- this._pendingMutations.push({
-+ this._queueMutation({
- type: "documentUnload",
- target: documentActor.actorID
- });
- this.releaseNode(documentActor);
-- if (needEvent) {
-- events.emit(this, "new-mutations");
-- }
- }
- });
-
- /**
- * Client side of the DOM walker.
- */
- var WalkerFront = exports.WalkerFront = protocol.FrontClass(WalkerActor, {
- // Set to true if cleanup should be requested after every mutation list.
+ if (needEvent) {
+ events.emit(this, "new-mutations");
--- a/inspector-set-attributes.diff
+++ b/inspector-set-attributes.diff
@@ -1,20 +1,20 @@
# HG changeset patch
# User Dave Camp <dcamp@mozilla.com>
# Date 1370924324 25200
# Mon Jun 10 21:18:44 2013 -0700
# Node ID 74d92274a4d13923e27b5a55f6803d4428998013
-# Parent 93e8a0e236e6dd15bc061cc02f7e286f2540048d
+# Parent 7372255e1d231ce7b01428b3bb273ed2580a1378
imported patch inspector-set-attributes.diff
diff --git a/toolkit/devtools/server/actors/inspector.js b/toolkit/devtools/server/actors/inspector.js
--- a/toolkit/devtools/server/actors/inspector.js
+++ b/toolkit/devtools/server/actors/inspector.js
-@@ -1237,16 +1237,54 @@ var WalkerActor = protocol.ActorClass({
+@@ -1296,16 +1296,54 @@ var WalkerActor = protocol.ActorClass({
}, {
request: {
node: Arg(0, "domnode", { optional: true }),
},
response: {}
}),
/**
@@ -59,41 +59,41 @@ diff --git a/toolkit/devtools/server/act
* Get a node's innerHTML property.
*/
innerHTML: method(function(node) {
return LongStringActor(this.conn, node.rawNode.innerHTML);
}, {
request: {
node: Arg(0, "domnode")
},
-@@ -1496,16 +1534,23 @@ var WalkerFront = exports.WalkerFront =
+@@ -1638,16 +1676,23 @@ var WalkerFront = exports.WalkerFront =
+ querySelector: protocol.custom(function(queryNode, selector) {
return this._querySelector(queryNode, selector).then(response => {
return response.node;
});
}, {
impl: "_querySelector"
}),
- /**
++ /**
+ * Return a new AttributeModificationList for this node.
+ */
+ startModifyingAttributes: function(node) {
+ return AttributeModificationList(this, node);
+ },
+
-+ /**
- * Get any unprocessed mutation records and process them.
- */
- getMutations: protocol.custom(function(options={}) {
- return this._getMutations(options).then(mutations => {
- let emitMutations = [];
- for (let change of mutations) {
- // The target is only an actorID, get the associated front.
- let targetID = change.target;
-@@ -1620,16 +1665,60 @@ var WalkerFront = exports.WalkerFront =
+ _releaseFront: function(node, force) {
+ if (node.retained && !force) {
+ node.reparent(null);
+ this._retainedOrphans.add(node);
+ return;
+ }
+
+ if (node.retained) {
+@@ -1796,16 +1841,60 @@ var WalkerFront = exports.WalkerFront =
for (let extraActor of extras) {
nodeType.read(nodeType.write(extraActor, walkerActor), this);
}
return returnNode;
}
});
/**
@@ -162,19 +162,19 @@ diff --git a/toolkit/devtools/server/tes
inspector-helpers.js \
inspector-traversal-data.html \
+ test_inspector-changeattrs.html \
test_inspector-mutations-attr.html \
test_inspector-mutations-childlist.html \
test_inspector-mutations-frameload.html \
test_inspector-mutations-value.html \
test_inspector-release.html \
+ test_inspector-retain.html \
test_inspector-pseudoclass-lock.html \
test_inspector-traversal.html \
- test_unsafeDereference.html \
diff --git a/toolkit/devtools/server/tests/mochitest/test_inspector-changeattrs.html b/toolkit/devtools/server/tests/mochitest/test_inspector-changeattrs.html
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/server/tests/mochitest/test_inspector-changeattrs.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML>
+<html>
+<!--
--- a/inspector-set-nodevalue.diff
+++ b/inspector-set-nodevalue.diff
@@ -1,20 +1,20 @@
# HG changeset patch
# User Dave Camp <dcamp@mozilla.com>
# Date 1370924324 25200
# Mon Jun 10 21:18:44 2013 -0700
# Node ID e163463312617c7f367e3abff148098d570af2e3
-# Parent 74d92274a4d13923e27b5a55f6803d4428998013
+# Parent 7652ac23f3b284f200aebcd722285609bdd59b9f
imported patch inspector-set-nodevalue.diff
diff --git a/toolkit/devtools/server/actors/inspector.js b/toolkit/devtools/server/actors/inspector.js
--- a/toolkit/devtools/server/actors/inspector.js
+++ b/toolkit/devtools/server/actors/inspector.js
-@@ -1275,16 +1275,32 @@ var WalkerActor = protocol.ActorClass({
+@@ -1334,16 +1334,32 @@ var WalkerActor = protocol.ActorClass({
request: {
node: Arg(0, "domnode"),
modifications: Arg(1, "array:json")
},
response: {}
}),
/**
@@ -55,19 +55,19 @@ diff --git a/toolkit/devtools/server/tes
inspector-traversal-data.html \
test_inspector-changeattrs.html \
+ test_inspector-changevalue.html \
test_inspector-mutations-attr.html \
test_inspector-mutations-childlist.html \
test_inspector-mutations-frameload.html \
test_inspector-mutations-value.html \
test_inspector-release.html \
+ test_inspector-retain.html \
test_inspector-pseudoclass-lock.html \
test_inspector-traversal.html \
- test_unsafeDereference.html \
diff --git a/toolkit/devtools/server/tests/mochitest/test_inspector-changevalue.html b/toolkit/devtools/server/tests/mochitest/test_inspector-changevalue.html
new file mode 100644
--- /dev/null
+++ b/toolkit/devtools/server/tests/mochitest/test_inspector-changevalue.html
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML>
+<html>
+<!--
--- a/series
+++ b/series
@@ -5,18 +5,18 @@ inspector-actor.diff
inspector-pathtoroot.diff
inspector-node-tree.diff
inspector-simple-mutations.diff
inspector-childlist-mutations.diff
inspector-page-navigation.diff
inspector-drop-orphans.diff
inspector-queue-mutations.diff
inspector-retain.diff
+inspector-actor-pseudoclass.diff
inspector-sibling-traversal.diff
-inspector-actor-pseudoclass.diff
target-inspector-changes.diff
inspector-front-islocal.diff
inspector-emit-on-destroy.diff
inspector-innerhtml.diff
inspector-set-attributes.diff
inspector-set-nodevalue.diff
inspector-remote-target.diff
inspector-remote-breadcrumbs.diff
--- a/target-inspector-changes.diff
+++ b/target-inspector-changes.diff
@@ -1,14 +1,14 @@
# HG changeset patch
# User Dave Camp <dcamp@mozilla.com>
# Date 1370924323 25200
# Mon Jun 10 21:18:43 2013 -0700
# Node ID 500c52eb1503bd918f0354a2fed1829dc0039c76
-# Parent b400cc70cce3af826333cb4fc51109420cf74e5b
+# Parent 4e6249c3b4ea7ed7f71c4569bc61c4441d00fd7c
imported patch target-inspector-changes.diff
diff --git a/toolkit/devtools/server/actors/inspector.js b/toolkit/devtools/server/actors/inspector.js
--- a/toolkit/devtools/server/actors/inspector.js
+++ b/toolkit/devtools/server/actors/inspector.js
@@ -140,16 +140,21 @@ var NodeActor = protocol.ActorClass({
publicId: this.rawNode.publicId,
systemId: this.rawNode.systemId,
@@ -26,17 +26,17 @@ diff --git a/toolkit/devtools/server/act
if (this.rawNode.nodeValue) {
// We only include a short version of the value if it's longer than
// gValueSummaryLength
if (this.rawNode.nodeValue.length > gValueSummaryLength) {
form.shortValue = this.rawNode.nodeValue.substring(0, gValueSummaryLength);
form.incompleteValue = true;
} else {
form.shortValue = this.rawNode.nodeValue;
-@@ -322,16 +327,18 @@ let NodeFront = protocol.FrontClass(Node
+@@ -324,16 +329,18 @@ let NodeFront = protocol.FrontClass(Node
get hasChildren() this._form.numChildren > 0,
get numChildren() this._form.numChildren,
get tagName() this.nodeType === Ci.nsIDOMNode.ELEMENT_NODE ? this.nodeName : null,
get shortValue() this._form.shortValue,
get incompleteValue() !!this._form.incompleteValue,
@@ -45,17 +45,17 @@ diff --git a/toolkit/devtools/server/act
// doctype properties
get name() this._form.name,
get publicId() this._form.publicId,
get systemId() this._form.systemId,
getAttribute: function(name) {
let attr = this._getAttribute(name);
return attr ? attr.value : null;
-@@ -419,17 +426,18 @@ let NodeFront = protocol.FrontClass(Node
+@@ -421,17 +428,18 @@ let NodeFront = protocol.FrontClass(Node
/**
* Get an nsIDOMNode for the given node front. This only works locally,
* and is only intended as a stopgap during the transition to the remote
* protocol. If you depend on this you're likely to break soon.
*/
rawNode: function(rawNode) {
if (!this.conn._transport._serverConnection) {
@@ -65,36 +65,17 @@ diff --git a/toolkit/devtools/server/act
}
let actor = this.conn._transport._serverConnection.getActor(this.actorID);
if (!actor) {
throw new Error("Could not find client side for actor " + this.actorID);
}
return actor.rawNode;
}
});
-@@ -1367,17 +1375,17 @@ var WalkerActor = protocol.ActorClass({
- addedActors.push(addedActor.actorID);
- }
- mutation.numChildren = change.target.childNodes.length;
- mutation.removed = removedActors;
- mutation.added = addedActors;
- }
- this._pendingMutations.push(mutation);
- }
-- if (needEvent) {
-+ if (needEvent && this._pendingMutations.length > 0) {
- events.emit(this, "new-mutations");
- }
- },
-
- onFrameLoad: function(window) {
- let frame = window.frameElement;
- let frameActor = this._refMap.get(frame);
- if (!frameActor) {
-@@ -1567,49 +1575,75 @@ var WalkerFront = exports.WalkerFront =
+@@ -1736,49 +1744,75 @@ var WalkerFront = exports.WalkerFront =
// Fetch and process the mutations.
this.getMutations({cleanup: this.autoCleanup}).then(null, console.error);
}),
// XXX hack during transition to remote inspector: get a proper NodeFront
// for a given local node. Only works locally.
frontForRawNode: function(rawNode){
if (!this.conn._transport._serverConnection) {