Bug 1335905 - Implemented Tooltip/Bubbles
MozReview-Commit-ID: HSdebypwOhD
--- a/browser/components/preferences/in-content/findInPage.js
+++ b/browser/components/preferences/in-content/findInPage.js
@@ -5,16 +5,18 @@
// paneSearchResults needs init function to initialize the object
var gSearchResultsPane = {
findSelection: null,
searchResultsCategory: null,
searchInput: null,
+ listSearchBubbles: [],
+
init() {
let controller = this.getSelectionController();
this.findSelection = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);
this.searchResultsCategory = document.getElementById("category-search-results");
this.searchInput = document.getElementById("searchInput");
this.searchInput.hidden = !Services.prefs.getBoolPref("browser.preferences.search");
if (!this.searchInput.hidden) {
@@ -96,19 +98,19 @@ var gSearchResultsPane = {
/**
* Finds all the special characters of the Regular Expression characters
* and escapes those characters and returns as a string
* example 1: escapeRegexpSpecialCharacters("$40";
* returns 1: '\\$40'
* example 2: escapeRegexpSpecialCharacters("*RRRING* Hello?")
* returns 2: '\\*RRRING\\* Hello\\?'
* Source: http://phpjs.org/functions/preg_quote:491
- *
+ *
* @param String str
- * String that may contain special RegExp characters like
+ * String that may contain special RegExp characters like
* . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
* @param String delimiter
* Additional delimiter to use escape the special characters
* @returns String
* If special characters are found then a new string with escaped characters is returned
*/
escapeRegexpSpecialCharacters (str, delimiter) {
return (str + '')
@@ -213,16 +215,21 @@ var gSearchResultsPane = {
* Shows or hides content according to search input
*
* @param String event
* to search for filted query in
*/
searchFunction(event) {
let query = event.target.value.trim();
this.findSelection.removeAllRanges();
+ // Remove all bubbles
+ [].forEach.call(document.querySelectorAll('.search-bubble'),function(e){
+ e.parentNode.removeChild(e);
+ });
+ this.listSearchBubbles = [];
let srHeader = document.getElementById("header-searchResults");
if (query) {
// Showing the Search Results Tag
gotoPref("paneSearchResults");
this.searchResultsCategory.hidden = false;
@@ -260,16 +267,20 @@ var gSearchResultsPane = {
document.getElementById("sorry-message").textContent =
strings.getFormattedString("searchResults.sorryMessage", [query]);
let brandName = document.getElementById("bundleBrand").getString("brandShortName");
document.getElementById("need-help").innerHTML =
strings.getFormattedString("searchResults.needHelp", [brandName]);
document.getElementById("need-help-link").setAttribute("href", getHelpLinkURL("search"));
+ } else {
+ for (let obj of this.listSearchBubbles){
+ this.createSearchBubble(obj,query);
+ }
}
} else {
this.searchResultsCategory.hidden = true;
document.getElementById("sorry-message").textContent = "";
// Going back to General when cleared
gotoPref("paneGeneral");
}
},
@@ -309,28 +320,53 @@ var gSearchResultsPane = {
}
// Access key are presented
let complexTextNodesResult = this.highlightMatches(accessKeyTextNodes, nodeSizes, allNodeText, searchPhrase);
// Searching some elements, such as xul:button, have a 'label' attribute that contains the user-visible text.
if (nodeObject.getAttribute("label")) {
labelResult = this.stringMatchesFilters(nodeObject.getAttribute("label"), searchPhrase);
+ if (labelResult){
+ this.listSearchBubbles.push(nodeObject);
+ }
}
// Searching some elements, such as xul:label, store their user-visible text in a "value" attribute.
if (nodeObject.getAttribute("value")) {
valueResult = this.stringMatchesFilters(nodeObject.getAttribute("value"), searchPhrase);
+ if(valueResult){
+ this.listSearchBubbles.push(nodeObject);
+ }
}
matchesFound = matchesFound || complexTextNodesResult || labelResult || valueResult;
}
for (let i = 0; i < nodeObject.childNodes.length; i++) {
// Search only if child node is not hidden
if (!nodeObject.childNodes[i].hidden) {
let result = this.searchWithinNode(nodeObject.childNodes[i], searchPhrase);
matchesFound = matchesFound || result;
}
}
return matchesFound;
+ },
+
+ createSearchBubble(currentNode,searchPhrase) {
+ // Getting position of the current node
+ var rect = currentNode.getBoundingClientRect();
+
+ currentNode.parentElement.style.cssText = "position:relative";
+ currentNode.style.cssText = "z-index:1";
+ var searchBubble = document.createElement("div");
+ searchBubble.setAttribute("class", "search-bubble");
+ searchBubble.style.cssText = "top:"+(rect.height+10).toString()+"px; left:"+(rect.left-224).toString()+"px; z-index:2";
+
+ var searchContent = document.createElement("div");
+ searchContent.setAttribute("class", "search-bubble-innards");
+ searchContent.innerHTML = searchPhrase;
+
+ searchBubble.appendChild(searchContent);
+
+ currentNode.parentElement.insertBefore(searchBubble,currentNode);
}
}
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -563,17 +563,17 @@ description > html|a {
}
.iOSLink {
background-image: url("chrome://browser/skin/fxa/ios@2x.png");
}
.fxaFirefoxLogo {
list-style-image: url(chrome://browser/skin/fxa/logo@2x.png);
}
}
-
+/* Copy from chrome to test. Need to change this entire model */
/* Container for the elements that make up the search bubble. */
.search-bubble {
left: -30px;
position: absolute;
top: -1000px; /* Minor hack: position off-screen by default. */
/* Create a z-context for search-bubble-innards, its after and before. */
z-index: 1;
}