Bug 1110767 - Instantly show the search engine when it is selected in the search bar header text. r=florian

This commit is contained in:
Chris 2015-04-13 14:52:42 -07:00
parent 2773a89419
commit 109759719f
5 changed files with 183 additions and 2 deletions

View file

@ -1044,6 +1044,14 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
<xul:label anonid="searchbar-oneoffheader-searchtext" flex="1" crop="end" class="search-panel-input-value"/>
<xul:label anonid="searchbar-oneoffheader-after" flex="10000" value="&searchWith.label;"/>
</xul:hbox>
<xul:hbox anonid="search-panel-searchonengine"
class="search-panel-current-input">
<xul:label anonid="searchbar-oneoffheader-beforeengine" value="&search.label;"/>
<xul:label anonid="searchbar-oneoffheader-engine" flex="1" crop="end"
class="search-panel-input-value"/>
<xul:label anonid="searchbar-oneoffheader-afterengine" flex="10000"
value="&searchAfter.label;"/>
</xul:hbox>
</xul:deck>
<xul:description anonid="search-panel-one-offs"
role="group"
@ -1140,11 +1148,15 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
let inputHandler = function() {
headerSearchText.setAttribute("value", textbox.value);
let groupText;
let isOneOffSelected =
this.selectedButton &&
this.selectedButton.classList.contains("searchbar-engine-one-off-item");
if (textbox.value) {
self.removeAttribute("showonlysettings");
groupText = headerSearchText.previousSibling.value +
'"' + headerSearchText.value + '"' +
headerSearchText.nextSibling.value;
if (!isOneOffSelected)
headerPanel.selectedIndex = 1;
}
else {
@ -1152,6 +1164,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
document.getAnonymousElementByAttribute(self, "anonid",
"searchbar-oneoffheader-search");
groupText = noSearchHeader.value;
if (!isOneOffSelected)
headerPanel.selectedIndex = 0;
}
list.setAttribute("aria-label", groupText);

View file

@ -1021,14 +1021,29 @@
if (this._selectedButton)
this._selectedButton.removeAttribute("selected");
let textbox = document.getBindingParent(this).textbox;
let header =
document.getAnonymousElementByAttribute(this.popup, "anonid",
"search-panel-one-offs-header");
// Avoid selecting dummy buttons.
if (val && !val.classList.contains("dummy")) {
val.setAttribute("selected", "true");
this._selectedButton = val;
if (val.classList.contains("searchbar-engine-one-off-item")) {
let headerEngineText =
document.getAnonymousElementByAttribute(this.popup, "anonid",
"searchbar-oneoffheader-engine");
header.selectedIndex = 2;
headerEngineText.value = val.engine.name;
}
else {
header.selectedIndex = textbox.value ? 1 : 0;
}
this.setAttribute("aria-activedescendant", val.id);
return;
}
header.selectedIndex = textbox.value ? 1 : 0;
this.removeAttribute("aria-activedescendant");
this._selectedButton = null;
]]></setter>

View file

@ -36,6 +36,8 @@ skip-if = e10s # Bug ?????? - some issue with progress listeners [JavaScript Err
[browser_healthreport.js]
[browser_hiddenOneOffs_cleanup.js]
[browser_hiddenOneOffs_diacritics.js]
[browser_oneOffHeader.js]
skip-if = e10s # bug ?????? - Test alters the searchbar textbox value which causes issues with other tests in e10s.
[browser_private_search_perwindowpb.js]
skip-if = e10s # Bug ?????? - Test uses load event and checks event.target.
[browser_yahoo.js]

View file

@ -0,0 +1,141 @@
/* 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/. */
// Tests that keyboard navigation in the search panel works as designed.
const isMac = ("nsILocalFileMac" in Ci);
const searchbar = document.getElementById("searchbar");
const textbox = searchbar._textbox;
const searchPopup = document.getElementById("PopupSearchAutoComplete");
const searchIcon = document.getAnonymousElementByAttribute(searchbar, "anonid",
"searchbar-search-button");
const searchSettings =
document.getAnonymousElementByAttribute(searchPopup, "anonid",
"search-settings");
let header =
document.getAnonymousElementByAttribute(searchPopup, "anonid",
"search-panel-one-offs-header");
function getHeaderText() {
let headerChild = header.selectedPanel;
while (headerChild.hasChildNodes()) {
headerChild = headerChild.firstChild;
}
let headerStrings = [];
for (let label = headerChild; label; label = label.nextSibling) {
headerStrings.push(label.value);
}
return headerStrings.join("");
}
// Get an array of the one-off buttons.
function getOneOffs() {
let oneOffs = [];
let oneOff =
document.getAnonymousElementByAttribute(searchPopup, "anonid",
"search-panel-one-offs");
for (oneOff = oneOff.firstChild; oneOff; oneOff = oneOff.nextSibling) {
if (oneOff.classList.contains("dummy"))
break;
oneOffs.push(oneOff);
}
return oneOffs;
}
const msg = isMac ? 5 : 1;
const utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
const scale = utils.screenPixelsPerCSSPixel;
function* synthesizeNativeMouseMove(aElement) {
let rect = aElement.getBoundingClientRect();
let win = aElement.ownerDocument.defaultView;
let x = win.mozInnerScreenX + (rect.left + rect.right) / 2;
let y = win.mozInnerScreenY + (rect.top + rect.bottom) / 2;
// Wait for the mouseup event to occur before continuing.
return new Promise((resolve, reject) => {
function eventOccurred(e)
{
aElement.removeEventListener("mouseover", eventOccurred, true);
resolve();
}
aElement.addEventListener("mouseover", eventOccurred, true);
utils.sendNativeMouseEvent(x * scale, y * scale, msg, 0, null);
});
}
add_task(function* init() {
yield promiseNewEngine("testEngine.xml");
});
add_task(function* test_notext() {
let promise = promiseEvent(searchPopup, "popupshown");
info("Opening search panel");
EventUtils.synthesizeMouseAtCenter(searchIcon, {});
yield promise;
is(header.getAttribute("selectedIndex"), 0,
"Header has the correct index selected with no search terms.");
is(getHeaderText(), "Search with:",
"Search header string is correct when no search terms have been entered");
yield synthesizeNativeMouseMove(searchSettings);
is(header.getAttribute("selectedIndex"), 0,
"Header has the correct index when no search terms have been entered and the Change Search Settings button is selected.");
is(getHeaderText(), "Search with:",
"Header has the correct text when no search terms have been entered and the Change Search Settings button is selected.");
let buttons = getOneOffs();
yield synthesizeNativeMouseMove(buttons[0]);
is(header.getAttribute("selectedIndex"), 2,
"Header has the correct index selected when a search engine has been selected");
is(getHeaderText(), "Search " + buttons[0].engine.name,
"Is the header text correct when a search engine is selected and no terms have been entered.");
promise = promiseEvent(searchPopup, "popuphidden");
info("Closing search panel");
EventUtils.synthesizeKey("VK_ESCAPE", {});
yield promise;
});
add_task(function* test_text() {
textbox.value = "foo";
registerCleanupFunction(() => {
textbox.value = "";
});
let promise = promiseEvent(searchPopup, "popupshown");
info("Opening search panel");
SimpleTest.executeSoon(() => {
EventUtils.synthesizeMouseAtCenter(searchIcon, {});
});
yield promise;
is(header.getAttribute("selectedIndex"), 1,
"Header has the correct index selected with a search term.");
is(getHeaderText(), "Search for foo with:",
"Search header string is correct when a search term has been entered");
let buttons = getOneOffs();
yield synthesizeNativeMouseMove(buttons[0]);
is(header.getAttribute("selectedIndex"), 2,
"Header has the correct index selected when a search engine has been selected");
is(getHeaderText(), "Search " + buttons[0].engine.name,
"Is the header text correct when search terms are entered after a search engine has been selected.");
yield synthesizeNativeMouseMove(searchSettings);
is(header.getAttribute("selectedIndex"), 1,
"Header has the correct index selected when search terms have been entered and the Change Search Settings button is selected.");
is(getHeaderText(), "Search for foo with:",
"Header has the correct text when search terms have been entered and the Change Search Settings button is selected.");
promise = promiseEvent(searchPopup, "popuphidden");
info("Closing search panel");
EventUtils.synthesizeKey("VK_ESCAPE", {});
yield promise;
});

View file

@ -423,6 +423,16 @@ These should match what Safari and other Apple applications use on OS X Lion. --
search providers: "Search for <used typed keywords> with:" -->
<!ENTITY searchFor.label "Search for ">
<!ENTITY searchWith.label " with:">
<!-- LOCALIZATION NOTE (search.label, searchAfter.label):
This string is used to build the header above the list of one-click search
providers when a one off engine has been selected. The searchAfter text is
intentionally left empty for en-US and can be used by other localizations to
display a string after the search engine name. This string will be displayed
as: "Search <selected engine name><searchAfter.label text>" -->
<!ENTITY search.label "Search ">
<!ENTITY searchAfter.label "">
<!-- LOCALIZATION NOTE (searchWithHeader.label):
The wording of this string should be as close as possible to
searchFor.label and searchWith.label. This string will be used instead of