Bug 1365847 - Do not search for unselected <xul:deck> items.
MozReview-Commit-ID: BBeg2RdUtHV
--- a/browser/components/preferences/in-content-new/findInPage.js
+++ b/browser/components/preferences/in-content-new/findInPage.js
@@ -295,46 +295,72 @@ var gSearchResultsPane = {
// Searching some elements, such as xul:label, store their user-visible text in a "value" attribute.
// Value will be skipped for menuitem since value in menuitem could represent index number to distinct each item.
let valueResult = nodeObject.tagName !== "menuitem" ?
this.stringMatchesFilters(nodeObject.getAttribute("value"), searchPhrase) : false;
// Searching some elements, such as xul:button, buttons to open subdialogs.
let keywordsResult = this.stringMatchesFilters(nodeObject.getAttribute("searchkeywords"), searchPhrase);
- // Creating tooltips for buttons
- if (keywordsResult && nodeObject.tagName === "button") {
+ // Creating tooltips for buttons and menulists.
+ if (keywordsResult && (nodeObject.tagName === "button" || nodeObject.tagName == "menulist")) {
this.listSearchTooltips.push(nodeObject);
}
if ((nodeObject.tagName == "button" ||
nodeObject.tagName == "menulist" ||
nodeObject.tagName == "menuitem") &&
(labelResult || valueResult || keywordsResult)) {
nodeObject.setAttribute("highlightable", "true");
}
matchesFound = matchesFound || complexTextNodesResult || labelResult || valueResult || keywordsResult;
}
- for (let i = 0; i < nodeObject.childNodes.length; i++) {
- // Search only if child node is not hidden
- if (!nodeObject.childNodes[i].hidden && nodeObject.getAttribute("data-hidden-from-search") !== "true") {
- let result = this.searchWithinNode(nodeObject.childNodes[i], searchPhrase);
- // Creating tooltips for menulist element
- if (result && nodeObject.tagName === "menulist") {
- this.listSearchTooltips.push(nodeObject);
- }
+ // Should not search unselected child nodes of a <xul:deck> element
+ // except the "historyPane" <xul:deck> element.
+ if (nodeObject.tagName == "deck" && nodeObject.id != "historyPane") {
+ let index = nodeObject.selectedIndex;
+ if (index != -1) {
+ let result = this.searchChildNodeIfVisible(nodeObject, index, searchPhrase);
+ matchesFound = matchesFound || result;
+ }
+ } else {
+ for (let i = 0; i < nodeObject.childNodes.length; i++) {
+ let result = this.searchChildNodeIfVisible(nodeObject, i, searchPhrase);
matchesFound = matchesFound || result;
}
}
return matchesFound;
},
/**
+ * Search for a phrase within a child node if it is visible.
+ *
+ * @param Node nodeObject
+ * The parent DOM Element
+ * @param Number index
+ * The index for the childNode
+ * @param String searchPhrase
+ * @returns boolean
+ * Returns true when found the specific childNode, false otherwise
+ */
+ searchChildNodeIfVisible(nodeObject, index, searchPhrase) {
+ let result = false;
+ if (!nodeObject.childNodes[index].hidden && nodeObject.getAttribute("data-hidden-from-search") !== "true") {
+ result = this.searchWithinNode(nodeObject.childNodes[index], searchPhrase);
+ // Creating tooltips for menulist element
+ if (result && nodeObject.tagName === "menulist") {
+ this.listSearchTooltips.push(nodeObject);
+ }
+ }
+ return result;
+ },
+
+ /**
* Inserting a div structure infront of the DOM element matched textContent.
* Then calculation the offsets to position the tooltip in the correct place.
*
* @param Node currentNode
* DOM Element
* @param String query
* Word or words that are being searched for
*/
--- a/browser/components/preferences/in-content-new/tests/browser.ini
+++ b/browser/components/preferences/in-content-new/tests/browser.ini
@@ -8,17 +8,18 @@ support-files =
[browser_applications_selection.js]
[browser_advanced_update.js]
skip-if = !updater
[browser_basic_rebuild_fonts_test.js]
[browser_bug410900.js]
[browser_bug705422.js]
[browser_bug731866.js]
-[browser_search_within_preferences.js]
+[browser_search_within_preferences_1.js]
+[browser_search_within_preferences_2.js]
[browser_search_subdialogs_within_preferences_1.js]
[browser_search_subdialogs_within_preferences_2.js]
[browser_search_subdialogs_within_preferences_3.js]
[browser_search_subdialogs_within_preferences_4.js]
[browser_bug795764_cachedisabled.js]
[browser_bug1018066_resetScrollPosition.js]
[browser_bug1020245_openPreferences_to_paneContent.js]
[browser_bug1184989_prevent_scrolling_when_preferences_flipped.js]
rename from browser/components/preferences/in-content-new/tests/browser_search_within_preferences.js
rename to browser/components/preferences/in-content-new/tests/browser_search_within_preferences_1.js
--- a/browser/components/preferences/in-content-new/tests/browser_search_within_preferences.js
+++ b/browser/components/preferences/in-content-new/tests/browser_search_within_preferences_1.js
@@ -1,28 +1,31 @@
-/*
-* This file contains tests for the Preferences search bar.
-*/
+"use strict";
+/**
+ * This file contains tests for the Preferences search bar.
+ */
requestLongerTimeout(2);
/**
* Tests to see if search bar is being hidden when pref is turned off
*/
add_task(async function() {
await SpecialPowers.pushPrefEnv({"set": [["browser.preferences.search", false]]});
await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
let searchInput = gBrowser.contentDocument.querySelectorAll("#searchInput");
is(searchInput.length, 1, "There should only be one element name searchInput querySelectorAll");
is_element_hidden(searchInput[0], "Search box should be hidden");
await BrowserTestUtils.removeTab(gBrowser.selectedTab);
await SpecialPowers.popPrefEnv();
});
-// Enabling Searching functionatily. Will display search bar form this testcase forward.
+/**
+ * Enabling searching functionality. Will display search bar from this testcase forward.
+ */
add_task(async function() {
await SpecialPowers.pushPrefEnv({"set": [["browser.preferences.search", true]]});
});
/**
* Tests to see if search bar is being shown when pref is turned on
*/
add_task(async function() {
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content-new/tests/browser_search_within_preferences_2.js
@@ -0,0 +1,58 @@
+"use strict";
+/**
+ * This file contains tests for the Preferences search bar.
+ */
+
+/**
+ * Enabling searching functionality. Will display search bar from this testcase forward.
+ */
+add_task(async function() {
+ await SpecialPowers.pushPrefEnv({"set": [["browser.preferences.search", true]]});
+});
+
+/**
+ * Test that we only search the selected child of a XUL deck.
+ * When we search "Forget this Email",
+ * it should not show the "Forget this Email" button if the Firefox account is not logged in yet.
+ */
+add_task(async function() {
+ await openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+
+ // Ensure the "Create Account" button in the hidden child of the <xul:deck>
+ // is selected and displayed on the screen.
+ let weavePrefsDeck = gBrowser.contentDocument.getElementById("weavePrefsDeck");
+ is(weavePrefsDeck.selectedIndex, 0, "Should select the #noFxaAccount child node");
+ let noFxaSignUp = weavePrefsDeck.childNodes[0].querySelector("#noFxaSignUp");
+ is(noFxaSignUp.label, "Create Account", "The Create Account button should exist");
+
+ // Performs search.
+ let searchInput = gBrowser.contentDocument.getElementById("searchInput");
+ searchInput.focus();
+ searchInput.value = "Create Account";
+ searchInput.doCommand();
+
+ let mainPrefTag = gBrowser.contentDocument.getElementById("mainPrefPane");
+ for (let i = 0; i < mainPrefTag.childElementCount; i++) {
+ let child = mainPrefTag.children[i];
+ if (child.id == "header-searchResults" ||
+ child.id == "weavePrefsDeck") {
+ is_element_visible(child, "Should be in search results");
+ } else if (child.id) {
+ is_element_hidden(child, "Should not be in search results");
+ }
+ }
+
+ // Ensure the "Forget this Email" button exists in the hidden child of the <xul:deck>.
+ let unlinkFxaAccount = weavePrefsDeck.childNodes[1].querySelector("#unverifiedUnlinkFxaAccount");
+ is(unlinkFxaAccount.label, "Forget this Email", "The Forget this Email button should exist");
+
+ // Performs search.
+ searchInput.focus();
+ searchInput.value = "Forget this Email";
+ searchInput.doCommand();
+
+ let noResultsEl = gBrowser.contentDocument.querySelector(".no-results-message");
+ is_element_visible(noResultsEl, "Should be reporting no results");
+
+ await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});