Bug 1335905 -adding testing files for toggle search elements draft
authorFirefox <herrickz@msu.edu>
Sun, 12 Feb 2017 12:33:42 -0500
changeset 482428 d0df068094c63b1cb0789d610fbf160c394d9d40
parent 468005 f7e1982a2582b14c5885d787b530f879da3a040e
child 545429 206b7997e40aea72a7695208c7198d52d023a816
push id45078
push userbmo:xfergusi@gmail.com
push dateSun, 12 Feb 2017 17:42:12 +0000
bugs1335905
milestone54.0a1
Bug 1335905 -adding testing files for toggle search elements MozReview-Commit-ID: AF1I1dGowAK
browser/app/profile/firefox.js
browser/components/preferences/in-content/SearchEach.js
browser/components/preferences/in-content/jar.mn
browser/components/preferences/in-content/preferences.xul
browser/components/preferences/in-content/tests/browser.ini
browser/components/preferences/in-content/tests/browser_search_within_preferences.js
browser/themes/shared/incontentprefs/preferences.inc.css
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1578,8 +1578,10 @@ pref("services.sync.validation.enabled",
 // Preferences for the form autofill system extension
 pref("browser.formautofill.experimental", false);
 
 // Enable safebrowsing v4 tables (suffixed by "-proto") update.
 #ifdef NIGHTLY_BUILD
 pref("urlclassifier.malwareTable", "goog-malware-shavar,goog-unwanted-shavar,goog-malware-proto,goog-unwanted-proto,test-malware-simple,test-unwanted-simple");
 pref("urlclassifier.phishTable", "goog-phish-shavar,goog-phish-proto,test-phish-simple");
 #endif
+
+pref("browser.preference.search",false);
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/SearchEach.js
@@ -0,0 +1,233 @@
+console.log('in the SearchEach file');
+
+let mainSeachEmelemt = document.querySelectorAll('#searchTextIMF');
+
+function hideShowSearch () {
+
+    let mainSearchEnable = Services.prefs.getBoolPref('browser.preference.search')
+
+    mainSeachEmelemt.forEach(function (node){
+        let vis = node.style;
+
+        if (mainSearchEnable)
+        {
+            vis.display = 'block';
+        }
+        else
+        {
+            vis.display = 'none';
+        }
+    });
+    
+
+}
+
+function searchFunc(element) {
+    if(mainSeachEmelemt[0].value){
+        console.time('SearchTime');
+
+        //Controller
+        let controller = getSelectionController();
+        let findSelection = controller.getSelection(Ci.nsISelectionController.SELECTION_FIND);
+        findSelection.removeAllRanges()
+
+        //Building the range for highlighted areas
+        let rootPreferences = document.getElementById('mainPrefPane')//.querySelectorAll('*')
+        let rootPreferencesChildren = rootPreferences.childNodes
+        //Remove later, used for the debugs
+        let foundCounter = 0;
+
+        for (let i = 0; i<rootPreferences.childElementCount; i++){
+            if(nodeRecursion(rootPreferencesChildren[i], mainSeachEmelemt[0].value, findSelection)){
+                foundCounter++; //<Remove this 
+                rootPreferencesChildren[i].setAttribute('hidden', 'false');
+            }else{
+                rootPreferencesChildren[i].setAttribute('hidden', 'true');
+            }
+        }
+        console.log('found and highlighted: ', foundCounter) //<Remove later
+        console.timeEnd('SearchTime')
+    } else{
+        console.log("Empty string not searching")
+    }
+
+}
+
+mainSeachEmelemt.innerHTML = ''
+hideShowSearch();
+
+
+  /**
+   * Check that the passed string matches the filter arguments.
+   *
+   * @param String str
+   *        to search for filter words in.
+   * @param String filter
+   *        is a string containing all of the words to filter on.
+   * @returns boolean
+   */
+  function stringMatchesFilters (str, filter) {
+    if (!filter || !str) {
+      return true;
+    }
+
+    let searchStr = str.toLowerCase();
+    let filterStrings = filter.toLowerCase().split(/\s+/);
+    return !filterStrings.some(function (f) {
+      return searchStr.indexOf(f) == -1;
+    });
+  }
+
+  function nodeRecursion(nodeObject, searchPhrase, findSelection) {
+      if(nodeObject.childElementCount == 0 && 
+      (getTextContentAttribute(nodeObject,searchPhrase) //|| 
+       //getLabelAttribute(nodeObject,searchPhrase))
+      )) {
+          //Drill down deeper 
+          //if(nodeObject.boxObject){
+          //    getRangeObject(nodeObject.boxObject, searchPhrase.trim().split(), range);
+          //}
+          // Finding Text nodes in leaf node
+          let leaf = textNodesUnder(nodeObject)
+          let listOfWords = searchPhrase.trim().split()
+
+          console.log("Leaf")
+          console.log(leaf)
+          leaf.forEach(function (node) {
+              console.log(node)
+              listOfWords.forEach(function (word){
+                searchWord(node,node.textContent,word,findSelection)
+            });
+          });
+          
+
+          let anonymous = textNodesUnder(nodeObject.boxObject)
+          let anonymousTextContent = ''
+          anonymous.forEach(function (node) {
+              anonymousTextContent += node.textContent
+          });
+          console.log("anonymousTextContent")
+          console.log(anonymousTextContent)
+
+          
+          /*
+          allTextNodes.forEach(function (node) {
+              listOfWords.forEach(function (word){
+                searchWord(node,node.textContent,word,range)
+            });
+          });
+          */
+          
+          return true
+      }
+      let foundInChild = false
+      for (let i = 0; i<nodeObject.childElementCount; i++){
+          foundInChild = foundInChild || nodeRecursion(nodeObject.childNodes[i],searchPhrase, findSelection)
+      }
+
+      return foundInChild
+  }
+
+  //http://stackoverflow.com/questions/10730309/find-all-text-nodes-in-html-page
+  function textNodesUnder(node) {
+    let all = [];
+    for (node=node.firstChild;node;node=node.nextSibling){
+        if (node.nodeType==3) all.push(node);
+        else all = all.concat(textNodesUnder(node));
+    }
+    return all;
+  }
+
+  /*
+  function getRangeObject(elementObject, listOfWords, range){
+    let firstChildElement = elementObject.firstChild
+    if(firstChildElement.nodeType === firstChildElement.TEXT_NODE){
+        listOfWords.forEach(function (word){
+            searchWord(firstChildElement,nodeObject.textContent,word,range)
+        });
+    } else if(firstChildElement.nextSibling){
+        getRangeObject(firstChildElement.nextSibling, listOfWords, range)
+    }
+
+    
+  }
+  */
+
+  //nodeObject.boxObject.firstChild.nextSibling.firstChild.nextSibling.firstChild.textContent.includes("Night")
+
+  function searchWord(textNode, textSearch, word, findSelection){
+      let regExp = new RegExp(word,'gi')
+      let result,indices = []
+
+      while( (result=regExp.exec(textSearch)) ){
+          indices.push(result.index)
+      }
+
+      // Add each found word to range
+      for(let i=0;i<indices.length; i++){
+        let range = document.createRange();
+        range.setStart(textNode, indices[i]);
+        range.setEnd(textNode, (indices[i]+word.length) );
+        findSelection.addRange(range); // Add each range to be highlighted
+      }
+
+      
+
+  }
+
+  function getTextContentAttribute(nodeObject,searchPhrase){
+      if(typeof nodeObject.textContent == 'string' && nodeObject.textContent != ''
+      && stringMatchesFilters(nodeObject.textContent, searchPhrase)){
+          /*
+          words = searchPhrase.trim().split()
+          for(let i=0; i<words.length; i++){
+            searchWord(nodeObject,nodeObject.textContent,words[i],range)
+          }
+          */
+          return true
+      }
+      return false
+  }
+
+  function getLabelAttribute(nodeObject,searchPhrase){
+      if(typeof nodeObject.label == 'string' && nodeObject.label != ''
+      && stringMatchesFilters(nodeObject.label, searchPhrase)){
+          /*
+          words = searchPhrase.trim().split()
+          for(let i=0; i<words.length; i++){
+            searchWord(nodeObject,nodeObject.label,words[i],range)
+          }
+          */
+          return true
+      }
+      return false
+  }
+
+  /*
+  function replaceText(originalText,words){
+      words = words.replace(/ /g,'|')
+      let regExp = new RegExp(words,'gi')
+      originalText = originalText.replace(regExp, function subFunction(x){return '<span class=\'search-highlighted\'>'+x+'</span>';});
+      return originalText
+}
+
+function removeHighlightedSearch() {
+    let x = document.getElementsByClassName('search-highlighted');
+    while(x.length){
+        x[0].outerHTML = x[0].textContent
+    }
+    
+}
+*/
+function getSelectionController() {
+    // Yuck. See bug 138068.
+    let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                          .getInterface(Ci.nsIWebNavigation)
+                          .QueryInterface(Ci.nsIDocShell);
+
+    let controller = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
+                             .getInterface(Ci.nsISelectionDisplay)
+                             .QueryInterface(Ci.nsISelectionController);
+
+    return controller
+} 
--- a/browser/components/preferences/in-content/jar.mn
+++ b/browser/components/preferences/in-content/jar.mn
@@ -11,8 +11,9 @@ browser.jar:
    content/browser/preferences/in-content/privacy.js
    content/browser/preferences/in-content/containers.js
    content/browser/preferences/in-content/advanced.js
    content/browser/preferences/in-content/applications.js
    content/browser/preferences/in-content/content.js
    content/browser/preferences/in-content/sync.js
    content/browser/preferences/in-content/security.js
    content/browser/preferences/in-content/search.js
+   content/browser/preferences/in-content/SearchEach.js
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -70,16 +70,17 @@
 
   <html:link rel="shortcut icon"
               href="chrome://browser/skin/preferences/in-content/favicon.ico"/>
 
   <script type="application/javascript"
           src="chrome://browser/content/utilityOverlay.js"/>
   <script type="application/javascript"
           src="chrome://browser/content/preferences/in-content/preferences.js"/>
+
   <script src="chrome://browser/content/preferences/in-content/subdialogs.js"/>
 
   <stringbundle id="bundleBrand"
                 src="chrome://branding/locale/brand.properties"/>
   <stringbundle id="bundlePreferences"
                 src="chrome://browser/locale/preferences/preferences.properties"/>
 
   <stringbundleset id="appManagerBundleset">
@@ -181,30 +182,35 @@
 
     <keyset>
       <!-- Disable the findbar because it doesn't work properly.
            Remove this keyset once bug 1094240 ("disablefastfind" attribute
            broken in e10s mode) is fixed. -->
       <key key="&focusSearch1.key;" modifiers="accel" id="focusSearch1" oncommand=";"/>
     </keyset>
 
+
     <vbox class="main-content" flex="1">
+      <div align="right">  
+        <input xmlns="http://www.w3.org/1999/xhtml" name="q" value="" id="searchTextIMF" maxlength="500" 
+        placeholder="Search" type="text"></input>
+        <button id="searchTextIMF" onclick="searchFunc(this)" type="button">Click Me!</button>
+      </div>
       <prefpane id="mainPrefPane">
 #include main.xul
 #include search.xul
 #include privacy.xul
 #include containers.xul
 #include advanced.xul
 #include applications.xul
 #include content.xul
 #include security.xul
 #include sync.xul
       </prefpane>
     </vbox>
-
   </hbox>
 
     <vbox id="dialogOverlay" align="center" pack="center">
       <groupbox id="dialogBox"
                 orient="vertical"
                 pack="end"
                 role="dialog"
                 aria-labelledby="dialogTitle">
@@ -216,9 +222,13 @@
         </caption>
         <browser id="dialogFrame"
                  name="dialogFrame"
                  autoscroll="false"
                  disablehistory="true"/>
       </groupbox>
     </vbox>
   </stack>
+
+    <script src="chrome://browser/content/preferences/in-content/SearchEach.js"/>
+
 </page>
+
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -30,16 +30,17 @@ skip-if = true || !healthreport # Bug 11
 [browser_permissions_urlFieldHidden.js]
 [browser_proxy_backup.js]
 [browser_privacypane_1.js]
 [browser_privacypane_3.js]
 [browser_privacypane_4.js]
 [browser_privacypane_5.js]
 [browser_privacypane_8.js]
 [browser_sanitizeOnShutdown_prefLocked.js]
+[browser_search_within_preferences.js]
 [browser_searchsuggestions.js]
 [browser_security.js]
 [browser_subdialogs.js]
 support-files =
   subdialog.xul
   subdialog2.xul
 [browser_telemetry.js]
 # Skip this test on Android as FHR and Telemetry are separate systems there.
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser_search_within_preferences.js
@@ -0,0 +1,19 @@
+add_task(function*(){
+	Services.prefs.setBoolPref("browser.preference.search",false);
+	yield openPreferencesViaOpenPreferencesAPI("paneGeneral", undefined, {leaveOpen: true});
+	let mainSeachEmelemt = gBrowser.contentDocument.querySelectorAll('#searchTextIMF');
+	is(mainSeachEmelemt.length, 2, "there should be two elements returned by querySelectorAll");
+	ok(is_hidden(mainSeachEmelemt[0]), "Search box should be hidden");
+	ok(is_hidden(mainSeachEmelemt[1]), "Search button should be hidden");
+	yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
+add_task(function*(){
+	Services.prefs.setBoolPref("browser.preference.search",true);
+	yield openPreferencesViaOpenPreferencesAPI("paneGeneral", undefined, {leaveOpen: true});
+	let mainSeachEmelemt = gBrowser.contentDocument.querySelectorAll('#searchTextIMF');
+	is(mainSeachEmelemt.length, 2, "there should be two elements returned by querySelectorAll");
+	ok(!is_hidden(mainSeachEmelemt[0]), "Search box should be shown");
+	ok(!is_hidden(mainSeachEmelemt[1]), "Search button should be shown");
+	yield BrowserTestUtils.removeTab(gBrowser.selectedTab);	
+});
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -559,8 +559,47 @@ description > html|a {
   }
   .fxaSyncIllustration {
     list-style-image: url(chrome://browser/skin/fxa/sync-illustration@2x.png)
   }
   .fxaFirefoxLogo {
     list-style-image: url(chrome://browser/skin/fxa/logo@2x.png);
   }
 }
+
+.search-highlighted {
+  background-color: yellow;
+}
+
+.search-bubble {
+  position: relative;
+  display: inline-block;
+  border-bottom: 1px dotted black;
+}
+
+.search-bubble .search-bubble-text {
+    visibility: visible;
+    width: 120px;
+    background-color: #555;
+    color: #fff;
+    text-align: center;
+    border-radius: 6px;
+    padding: 5px 0;
+    position: absolute;
+    z-index: 1;
+    bottom: 125%;
+    left: 50%;
+    margin-left: -60px;
+    opacity: 0;
+    transition: opacity 1s;
+    opacity: 1;
+}
+
+.search-bubble .search-bubble-text::after {
+    content: "";
+    position: absolute;
+    top: 100%;
+    left: 50%;
+    margin-left: -5px;
+    border-width: 5px;
+    border-style: solid;
+    border-color: yellow transparent transparent transparent;
+}