Bug 1068852 - Highlight search suggestions on hover/mouseover. r=MattN

This commit is contained in:
Drew Willcoxon :adw 2014-09-17 13:37:00 +02:00
parent e198245b30
commit adfedbd7d8
3 changed files with 50 additions and 10 deletions

View File

@ -96,24 +96,24 @@ SearchSuggestionUIController.prototype = {
row.classList.add("selected");
row.firstChild.setAttribute("aria-selected", "true");
this._table.setAttribute("aria-activedescendant", row.firstChild.id);
this.input.value = this.suggestionAtIndex(i);
}
else {
row.classList.remove("selected");
row.firstChild.setAttribute("aria-selected", "false");
}
}
// Update the input when there is no selection.
if (idx < 0) {
this.input.value = this._stickyInputValue;
}
},
get numSuggestions() {
return this._table.children.length;
},
selectAndUpdateInput: function (idx) {
this.selectedIndex = idx;
this.input.value = idx >= 0 ? this.suggestionAtIndex(idx) :
this._stickyInputValue;
},
suggestionAtIndex: function (idx) {
let row = this._table.children[idx];
return row ? row.textContent : null;
@ -125,7 +125,7 @@ SearchSuggestionUIController.prototype = {
let suggestionStr = this.suggestionAtIndex(idx);
this._sendMsg("RemoveFormHistoryEntry", suggestionStr);
this._table.children[idx].remove();
this.selectedIndex = -1;
this.selectAndUpdateInput(-1);
}
},
@ -150,7 +150,7 @@ SearchSuggestionUIController.prototype = {
this._stickyInputValue = "";
this._hideSuggestions();
}
this.selectedIndex = -1;
this.selectAndUpdateInput(-1);
},
_onKeypress: function (event) {
@ -208,7 +208,7 @@ SearchSuggestionUIController.prototype = {
else if (this.numSuggestions <= newSelectedIndex) {
newSelectedIndex = -1;
}
this.selectedIndex = newSelectedIndex;
this.selectAndUpdateInput(newSelectedIndex);
// Prevent the input's caret from moving.
event.preventDefault();
@ -223,6 +223,10 @@ SearchSuggestionUIController.prototype = {
this._hideSuggestions();
},
_onMousemove: function (event) {
this.selectedIndex = this._indexOfTableRowOrDescendent(event.target);
},
_onMousedown: function (event) {
let idx = this._indexOfTableRowOrDescendent(event.target);
let suggestion = this.suggestionAtIndex(idx);
@ -300,6 +304,7 @@ SearchSuggestionUIController.prototype = {
row.classList.add("searchSuggestionRow");
row.classList.add(type);
row.setAttribute("role", "presentation");
row.addEventListener("mousemove", this);
row.addEventListener("mousedown", this);
let entry = document.createElementNS(HTML_NS, "td");
@ -343,7 +348,7 @@ SearchSuggestionUIController.prototype = {
while (this._table.firstElementChild) {
this._table.firstElementChild.remove();
}
this.selectedIndex = -1;
this.selectAndUpdateInput(-1);
},
_indexOfTableRowOrDescendent: function (row) {

View File

@ -102,6 +102,14 @@ add_task(function* mouse() {
let state = yield msg("key", { key: "x", waitForSuggestions: true });
checkState(state, "x", ["xfoo", "xbar"], -1);
// Mouse over the first suggestion.
state = yield msg("mousemove", 0);
checkState(state, "x", ["xfoo", "xbar"], 0);
// Mouse over the second suggestion.
state = yield msg("mousemove", 1);
checkState(state, "x", ["xfoo", "xbar"], 1);
// Click the second suggestion. This should make it sticky. To make sure it
// sticks, trigger suggestions again and cycle through them by pressing Down
// until nothing is selected again.

View File

@ -37,6 +37,33 @@ let messageHandlers = {
ack();
},
mousemove: function (suggestionIdx) {
// Copied from widget/tests/test_panel_mouse_coords.xul and
// browser/base/content/test/newtab/head.js
let row = gController._table.children[suggestionIdx];
let rect = row.getBoundingClientRect();
let left = content.mozInnerScreenX + rect.left;
let x = left + rect.width / 2;
let y = content.mozInnerScreenY + rect.top + rect.height / 2;
let utils = content.SpecialPowers.getDOMWindowUtils(content);
let scale = utils.screenPixelsPerCSSPixel;
let widgetToolkit = content.SpecialPowers.
Cc["@mozilla.org/xre/app-info;1"].
getService(content.SpecialPowers.Ci.nsIXULRuntime).
widgetToolkit;
let nativeMsg = widgetToolkit == "cocoa" ? 5 : // NSMouseMoved
widgetToolkit == "windows" ? 1 : // MOUSEEVENTF_MOVE
3; // GDK_MOTION_NOTIFY
row.addEventListener("mousemove", function onMove() {
row.removeEventListener("mousemove", onMove);
ack();
});
utils.sendNativeMouseEvent(x * scale, y * scale, nativeMsg, 0, null);
},
mousedown: function (suggestionIdx) {
gController.onClick = () => {
gController.onClick = null;