Bug 719933 - In the Inspector, the arrowkeys shortcuts should be used only when the higlighter or the toolbar are focused. r=rcampbell

This commit is contained in:
Paul Rouget 2012-01-24 19:56:47 +01:00
parent 4515a46e4e
commit 174ef593dc
3 changed files with 107 additions and 80 deletions

View File

@ -141,7 +141,7 @@ TreePanel.prototype = {
this.treeLoaded = true;
this.treeIFrame.addEventListener("click", this.onTreeClick.bind(this), false);
this.treeIFrame.addEventListener("dblclick", this.onTreeDblClick.bind(this), false);
this.treeIFrame.addEventListener("keypress", this.IUI, false);
this.treeIFrame.focus();
delete this.initializingTreePanel;
Services.obs.notifyObservers(null,
this.IUI.INSPECTOR_NOTIFICATIONS.TREEPANELREADY, null);
@ -233,7 +233,7 @@ TreePanel.prototype = {
} catch(e) {
treeBox.height = 112;
}
treeBox.minHeight = 64;
treeBox.flex = 1;
toolbarParent.insertBefore(treeBox, toolbar);
@ -466,9 +466,6 @@ TreePanel.prototype = {
editorInput.value = aAttrVal;
editorInput.select();
// remove tree key navigation events
this.treeIFrame.removeEventListener("keypress", this.IUI, false);
// listen for editor specific events
this.bindEditorEvent(editor, "click", function(aEvent) {
aEvent.stopPropagation();
@ -561,9 +558,6 @@ TreePanel.prototype = {
this.editingContext = null;
this.editingEvents = {};
// re-add navigation listener
this.treeIFrame.addEventListener("keypress", this.IUI, false);
// event notification
Services.obs.notifyObservers(null, this.IUI.INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED,
null);
@ -700,7 +694,6 @@ TreePanel.prototype = {
}
if (this.treeIFrame) {
this.treeIFrame.removeEventListener("keypress", this.IUI, false);
this.treeIFrame.removeEventListener("dblclick", this.onTreeDblClick, false);
this.treeIFrame.removeEventListener("click", this.onTreeClick, false);
let parent = this.treeIFrame.parentNode;

View File

@ -756,69 +756,6 @@ Highlighter.prototype = {
aEvent.preventDefault();
aEvent.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_LEFT:
let node;
if (this.node) {
node = this.node.parentNode;
} else {
node = this.defaultSelection;
}
if (node && this.isNodeHighlightable(node)) {
this.highlight(node);
}
aEvent.preventDefault();
aEvent.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_RIGHT:
if (this.node) {
// Find the first child that is highlightable.
for (let i = 0; i < this.node.childNodes.length; i++) {
node = this.node.childNodes[i];
if (node && this.isNodeHighlightable(node)) {
break;
}
}
} else {
node = this.defaultSelection;
}
if (node && this.isNodeHighlightable(node)) {
this.highlight(node, true);
}
aEvent.preventDefault();
aEvent.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_UP:
if (this.node) {
// Find a previous sibling that is highlightable.
node = this.node.previousSibling;
while (node && !this.isNodeHighlightable(node)) {
node = node.previousSibling;
}
} else {
node = this.defaultSelection;
}
if (node && this.isNodeHighlightable(node)) {
this.highlight(node, true);
}
aEvent.preventDefault();
aEvent.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_DOWN:
if (this.node) {
// Find a next sibling that is highlightable.
node = this.node.nextSibling;
while (node && !this.isNodeHighlightable(node)) {
node = node.nextSibling;
}
} else {
node = this.defaultSelection;
}
if (node && this.isNodeHighlightable(node)) {
this.highlight(node, true);
}
aEvent.preventDefault();
aEvent.stopPropagation();
break;
}
}
},

View File

@ -286,6 +286,8 @@ InspectorUI.prototype = {
// initialize the highlighter
this.highlighter = new Highlighter(this.chromeWin);
this.setupNavigationKeys();
this.highlighterReady();
},
@ -349,6 +351,36 @@ InspectorUI.prototype = {
}
},
/**
* Browse nodes according to the breadcrumbs layout, only for some specific
* elements of the UI.
*/
setupNavigationKeys: function IUI_setupNavigationKeys()
{
// UI elements that are arrow keys sensitive:
// - highlighter veil;
// - content window (when the highlighter `veil is pointer-events:none`;
// - the Inspector toolbar.
this.onKeypress = this.onKeypress.bind(this);
this.highlighter.highlighterContainer.addEventListener("keypress",
this.onKeypress, true);
this.win.addEventListener("keypress", this.onKeypress, true);
this.toolbar.addEventListener("keypress", this.onKeypress, true);
},
/**
* Remove the event listeners for the arrowkeys.
*/
removeNavigationKeys: function IUI_removeNavigationKeys()
{
this.highlighter.highlighterContainer.removeEventListener("keypress",
this.onKeypress, true);
this.win.removeEventListener("keypress", this.onKeypress, true);
this.toolbar.removeEventListener("keypress", this.onKeypress, true);
},
/**
* Close inspector UI and associated panels. Unhighlight and stop inspecting.
* Remove event listeners for document scrolling, resize,
@ -375,6 +407,8 @@ InspectorUI.prototype = {
this.closing = true;
this.toolbar.hidden = true;
this.removeNavigationKeys();
this.progressListener.destroy();
delete this.progressListener;
@ -592,6 +626,14 @@ InspectorUI.prototype = {
false);
}
break;
case "keypress":
switch (event.keyCode) {
case this.chromeWin.KeyEvent.DOM_VK_ESCAPE:
this.closeInspectorUI(false);
event.preventDefault();
event.stopPropagation();
break;
}
case "pagehide":
win = event.originalTarget.defaultView;
// Skip iframes/frames.
@ -611,18 +653,66 @@ InspectorUI.prototype = {
false);
}
break;
case "keypress":
switch (event.keyCode) {
case this.chromeWin.KeyEvent.DOM_VK_ESCAPE:
this.closeInspectorUI(false);
event.preventDefault();
event.stopPropagation();
break;
}
},
/*
* handles "keypress" events.
*/
onKeypress: function IUI_onKeypress(event)
{
let node = null;
let bc = this.breadcrumbs;
switch (event.keyCode) {
case this.chromeWin.KeyEvent.DOM_VK_LEFT:
if (bc.currentIndex != 0)
node = bc.nodeHierarchy[bc.currentIndex - 1].node;
if (node && this.highlighter.isNodeHighlightable(node))
this.highlighter.highlight(node);
event.preventDefault();
event.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_RIGHT:
if (bc.currentIndex < bc.nodeHierarchy.length - 1)
node = bc.nodeHierarchy[bc.currentIndex + 1].node;
if (node && this.highlighter.isNodeHighlightable(node)) {
this.highlighter.highlight(node);
}
event.preventDefault();
event.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_UP:
if (this.selection) {
// Find a previous sibling that is highlightable.
node = this.selection.previousSibling;
while (node && !this.highlighter.isNodeHighlightable(node)) {
node = node.previousSibling;
}
}
if (node && this.highlighter.isNodeHighlightable(node)) {
this.highlighter.highlight(node, true);
}
event.preventDefault();
event.stopPropagation();
break;
case this.chromeWin.KeyEvent.DOM_VK_DOWN:
if (this.selection) {
// Find a next sibling that is highlightable.
node = this.selection.nextSibling;
while (node && !this.highlighter.isNodeHighlightable(node)) {
node = node.nextSibling;
}
}
if (node && this.highlighter.isNodeHighlightable(node)) {
this.highlighter.highlight(node, true);
}
event.preventDefault();
event.stopPropagation();
break;
}
},
/////////////////////////////////////////////////////////////////////////
//// CssRuleView methods
@ -1720,6 +1810,8 @@ HTMLBreadcrumbs.prototype = {
}
if (aIdx > -1) {
this.nodeHierarchy[aIdx].button.setAttribute("checked", "true");
if (this.hadFocus)
this.nodeHierarchy[aIdx].button.focus();
}
this.currentIndex = aIdx;
},
@ -1895,6 +1987,10 @@ HTMLBreadcrumbs.prototype = {
{
this.menu.hidePopup();
let cmdDispatcher = this.IUI.chromeDoc.commandDispatcher;
this.hadFocus = (cmdDispatcher.focusedElement &&
cmdDispatcher.focusedElement.parentNode == this.container);
let selection = this.IUI.selection;
let idx = this.indexOf(selection);
@ -1924,7 +2020,8 @@ HTMLBreadcrumbs.prototype = {
// Make sure the selected node and its neighbours are visible.
this.scroll();
}
},
}
/////////////////////////////////////////////////////////////////////////