Bug 1120111 - Adds key listeners to highlighter pick mode to traverse DOM and submit/cancel selection; r=pbrosset

This commit is contained in:
Abhishek Bhattacharya 2015-03-10 07:02:00 +01:00
parent e8ff704fe8
commit 4279389f14
3 changed files with 86 additions and 6 deletions

View File

@ -120,6 +120,7 @@ exports.getHighlighterUtils = function(toolbox) {
if (isRemoteHighlightable()) {
toolbox.walker.on("picker-node-hovered", onPickerNodeHovered);
toolbox.walker.on("picker-node-picked", onPickerNodePicked);
toolbox.walker.on("picker-node-canceled", onPickerNodeCanceled);
yield toolbox.highlighter.pick();
toolbox.emit("picker-started");
@ -151,6 +152,7 @@ exports.getHighlighterUtils = function(toolbox) {
yield toolbox.highlighter.cancelPick();
toolbox.walker.off("picker-node-hovered", onPickerNodeHovered);
toolbox.walker.off("picker-node-picked", onPickerNodePicked);
toolbox.walker.off("picker-node-canceled", onPickerNodeCanceled);
} else {
// If the target doesn't have the highlighter actor, use the walker's
// cancelPick method instead
@ -178,6 +180,13 @@ exports.getHighlighterUtils = function(toolbox) {
stopPicker();
}
/**
* When the picker is canceled
*/
function onPickerNodeCanceled() {
stopPicker();
}
/**
* Show the box model highlighter on a node in the content page.
* The node needs to be a NodeFront, as defined by the inspector actor

View File

@ -228,6 +228,7 @@ let HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
*/
_isPicking: false,
_hoveredNode: null,
_currentNode: null,
pick: method(function() {
if (this._isPicking) {
@ -249,19 +250,82 @@ let HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
this._highlighter.hide();
}, HIGHLIGHTER_PICKED_TIMER);
}
events.emit(this._walker, "picker-node-picked", this._findAndAttachElement(event));
if (!this._currentNode) {
this._currentNode = this._findAndAttachElement(event);
}
events.emit(this._walker, "picker-node-picked", this._currentNode);
};
this._onHovered = event => {
this._preventContentEvent(event);
let res = this._findAndAttachElement(event);
if (this._hoveredNode !== res.node) {
this._highlighter.show(res.node.rawNode);
events.emit(this._walker, "picker-node-hovered", res);
this._hoveredNode = res.node;
this._currentNode = this._findAndAttachElement(event);
if (this._hoveredNode !== this._currentNode.node) {
this._highlighter.show( this._currentNode.node.rawNode);
events.emit(this._walker, "picker-node-hovered", this._currentNode);
this._hoveredNode = this._currentNode.node;
}
};
this._onKey = event => {
if (!this._currentNode || !this._isPicking) {
return;
}
this._preventContentEvent(event);
let currentNode = this._currentNode.node.rawNode;
/**
* KEY: Action/scope
* LEFT_KEY: wider or parent
* RIGHT_KEY: narrower or child
* ENTER/CARRIAGE_RETURN: Picks currentNode
* ESC: Cancels picker, picks currentNode
*/
switch(event.keyCode) {
case Ci.nsIDOMKeyEvent.DOM_VK_LEFT: // wider
if (!currentNode.parentElement) {
return;
}
currentNode = currentNode.parentElement;
break;
case Ci.nsIDOMKeyEvent.DOM_VK_RIGHT: // narrower
if (!currentNode.children.length) {
return;
}
// Set firstElementChild by default
let child = currentNode.firstElementChild;
// If currentNode is parent of hoveredNode, then
// previously selected childNode is set
let hoveredNode = this._hoveredNode.rawNode;
for (let sibling of currentNode.children) {
if (sibling.contains(hoveredNode) || sibling === hoveredNode) {
child = sibling;
}
}
currentNode = child;
break;
case Ci.nsIDOMKeyEvent.DOM_VK_RETURN: // select element
this._onPick(event);
return;
case Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE: // cancel picking
this.cancelPick();
events.emit(this._walker, "picker-node-canceled");
return;
default: return;
}
// Store currently attached element
this._currentNode = this._walker.attachElement(currentNode);
this._highlighter.show(this._currentNode.node.rawNode);
events.emit(this._walker, "picker-node-hovered", this._currentNode);
};
this._tabActor.window.focus();
this._startPickerListeners();
@ -285,6 +349,8 @@ let HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
target.addEventListener("mousedown", this._preventContentEvent, true);
target.addEventListener("mouseup", this._preventContentEvent, true);
target.addEventListener("dblclick", this._preventContentEvent, true);
target.addEventListener("keydown", this._onKey, true);
target.addEventListener("keyup", this._preventContentEvent, true);
},
_stopPickerListeners: function() {
@ -294,6 +360,8 @@ let HighlighterActor = exports.HighlighterActor = protocol.ActorClass({
target.removeEventListener("mousedown", this._preventContentEvent, true);
target.removeEventListener("mouseup", this._preventContentEvent, true);
target.removeEventListener("dblclick", this._preventContentEvent, true);
target.removeEventListener("keydown", this._onKey, true);
target.removeEventListener("keyup", this._preventContentEvent, true);
},
_highlighterReady: function() {

View File

@ -1121,6 +1121,9 @@ var WalkerActor = protocol.ActorClass({
type: "pickerNodeHovered",
node: Arg(0, "disconnectedNode")
},
"picker-node-canceled" : {
type: "pickerNodeCanceled"
},
"highlighter-ready" : {
type: "highlighter-ready"
},