Bug 1352481 - Finding content and highlights in popups. draft
authormanotejmeka <manotejmeka@gmail.com>
Mon, 10 Apr 2017 14:43:32 -0400
changeset 561057 37307ef234b1055ccb132cf7970a3d4488d99c4d
parent 561056 aeb201ae7d0537ac5c209b6bdd6af648ba016244
child 623867 2a4e0e13021dd90b1bb1496ed5a74f8864e5dd27
push id53614
push userbmo:manotejmeka@gmail.com
push dateWed, 12 Apr 2017 06:08:13 +0000
bugs1352481
milestone55.0a1
Bug 1352481 - Finding content and highlights in popups. MozReview-Commit-ID: 3OS4msNjbER
browser/components/preferences/in-content/findInPage.js
browser/components/preferences/in-content/main.js
browser/components/preferences/in-content/subdialogs.js
--- a/browser/components/preferences/in-content/findInPage.js
+++ b/browser/components/preferences/in-content/findInPage.js
@@ -10,17 +10,22 @@ Components.utils.import("resource://gre/
 var gSearchResultsPane = {
   findSelection: null,
   searchResultsCategory: null,
   searchInput: null,
   listSearchBubbles: [],
   initialSearch: true,
   trie: null,
   timer: null,
-
+  dialogBoxs: {},
+	totalSubDialogs: 0,
+	counterDialog: 0,
+  dialogeInit: true,
+  searchQuery: "",
+ 
   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");
     
@@ -80,16 +85,22 @@ var gSearchResultsPane = {
       this.initializeCategories();
       if (!this.categoriesInitialized) {
         // Initial search to load tries tree
         this.searchInput.value = "testing search";
         this.searchFunction(event.target.value.trim().toLowerCase());
         this.searchInput.value = "";
         this.searchFunction(event.target.value.trim().toLowerCase());
       }
+      // Taking care of dialogs
+			this.openSubDialogBox();
+			if (this.initialSearch) {
+				this.initialSearch = false;
+			}
+
       this.categoriesInitialized = true;
 
     } else if (event.type === "input") {
       let query = event.target.value.trim().toLowerCase();
       // Adding a class to show the close button
       this.classManipulation(query, "closeButton");
       let overlayClose = document.getElementById("close-button-overlay");
       overlayClose.hidden = false;
@@ -186,16 +197,29 @@ var gSearchResultsPane = {
     //  Initializing all the JS for all the tabs
     if (!this.categoriesInitialized) {
       // Each element of gCategoryInits is a name
       for (let [/* name */, category] of gCategoryInits) {
         if (!category.inited) {
           category.init();
         }
       }
+      this.subDialogInit();
+    }
+  },
+
+  subDialogInit() {
+    // Mighting be missing some just a list of all visibile during inspect element
+    let ids = ["useBookmark","chooseLanguage","translateButton",
+               "advancedFonts","colors","passwordExceptions","showPasswords",
+               "popupPolicyButton","notificationsPolicyButton","addonExceptions",
+               "connectionSettings","offlineNotifyExceptions","showUpdateHistory"];
+    for (let id of ids){
+      console.log("id",id);
+      document.getElementById(id).setAttribute("subDialog","true");
     }
   },
 
   /**
    * Finds and returns text nodes within node and all descendants
    * Iterates through all the sibilings of the node object and adds the sibilings
    * to an array if sibiling is a TEXT_NODE else checks the text nodes with in current node
    * Source - http://stackoverflow.com/questions/10730309/find-all-text-nodes-in-html-page
@@ -329,16 +353,17 @@ var gSearchResultsPane = {
       searchBubble.remove();
     }
 		this.listSearchBubbles = [];
 
 
     let srHeader = document.getElementById("header-searchResults");
 
     if (query) {
+      this.searchQuery = query;
       // Showing the Search Results Tag
       gotoPref("paneSearchResults");
 
       this.searchResultsCategory.hidden = false;
 
       let resultsFound = false;
 
       // Building the range for highlighted areas
@@ -392,31 +417,43 @@ var gSearchResultsPane = {
       overlayClose.hidden = true;
       overlayClose.removeEventListener("click",this);
       this.classManipulation(false, "closeButton");
     }
 
     if (this.initialSearch) {
       this.initialSearch = false;
     }
+    
   },
 
   /**
    * Finding leaf nodes and checking their content for words to search,
    * It is a recursive function
    *
    * @param Node nodeObject
    *    DOM Element
    * @param String searchPhrase
    * @returns boolean
    *    Returns true when found in at least one childNode, false otherwise
    */
-  searchWithinNode(nodeObject, searchPhrase) {
+  searchWithinNode(nodeObject, searchPhrase, test = false) {
     let matchesFound = false;
-    if (nodeObject.childElementCount == 0) {
+    if (nodeObject.childNodes.length == 0) {
+
+      if (test && nodeObject.textContent) {
+        this.highlightMatches([nodeObject],[nodeObject.textContent.length],nodeObject.textContent.toLowerCase(), searchPhrase);
+      }
+      if (this.initialSearch && nodeObject.tagName) {
+        if (nodeObject.getAttribute("subDialog")) {
+          this.dialogBoxs[this.totalSubDialogs] = [nodeObject.id,""];
+          this.totalSubDialogs += 1;
+			  }
+      }
+
       let simpleTextNodes = this.textNodeDescendants(nodeObject);
 
       for (let node of simpleTextNodes) {
         let result = this.highlightMatches([node], [node.length], node.textContent.toLowerCase(), searchPhrase);
         matchesFound = matchesFound || result;
       }
 
       //  Collecting data from boxObject
@@ -432,55 +469,74 @@ var gSearchResultsPane = {
         allNodeText += node.textContent;
         nodeSizes.push(runningSize);
       }
 
       // Access key are presented
       let complexTextNodesResult = this.highlightMatches(accessKeyTextNodes, nodeSizes, allNodeText.toLowerCase(), searchPhrase);
 
       //  Searching some elements, such as xul:button, have a "label" attribute that contains the user-visible text.
-      let labelContent = nodeObject.getAttribute("label");
-      if (labelContent) {
-				if (this.initialSearch) {
-          this.addToTries(labelContent);
-				}
+      if (nodeObject.tagName) {
+
+        let labelContent = nodeObject.getAttribute("label");
+        if (labelContent) {
+          if (this.initialSearch) {
+            this.addToTries(labelContent);
+          }
+
+          labelResult = this.stringMatchesFilters(labelContent, searchPhrase);
+          // Creating tooltips for buttons
+          // if (labelResult && nodeObject.tagName == "button") {
+          //   this.listSearchBubbles.push(nodeObject);
+          // }
+        }
 
-        labelResult = this.stringMatchesFilters(labelContent, searchPhrase);
-				// Creating tooltips for buttons
-				if (labelResult && nodeObject.tagName == "button") {
+        //  Searching some elements, such as xul:label, store their user-visible text in a "value" attribute.
+        let valueContent = nodeObject.getAttribute("value");
+        if (valueContent) {
+          if (this.initialSearch) {
+            this.addToTries(valueContent);
+          }
+
+          valueResult = this.stringMatchesFilters(valueContent, searchPhrase);
+          // Creating tooltips for buttons
+          // if (valueResult && nodeObject.tagName == "button") {
+          //   this.listSearchBubbles.push(nodeObject);
+          // }
+        }
+      }
+
+      let subDialog = false;
+      if (nodeObject.tagName == "button") {
+        //console.log("button",nodeObject.getAttribute("id"),searchPhrase);
+        subDialog = this.findInDialogs(nodeObject.getAttribute("id"),searchPhrase);
+        console.log("ans",nodeObject.getAttribute("id"),subDialog);
+        if (subDialog) {
+          //console.log("in dialog",nodeObject,searchPhrase);
           this.listSearchBubbles.push(nodeObject);
         }
       }
 
-      //  Searching some elements, such as xul:label, store their user-visible text in a "value" attribute.
-	    let valueContent = nodeObject.getAttribute("value");
-      if (valueContent) {
-				if (this.initialSearch) {
-          this.addToTries(valueContent);
-				}
-
-        valueResult = this.stringMatchesFilters(valueContent, searchPhrase);
-				// Creating tooltips for buttons
-				if (valueResult && nodeObject.tagName == "button") {
-          this.listSearchBubbles.push(nodeObject);
-        }
-      }
-
-      matchesFound = matchesFound || complexTextNodesResult || labelResult || valueResult;
+      matchesFound = matchesFound || complexTextNodesResult || labelResult || valueResult || subDialog;
     }
 
     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);
+        let result = this.searchWithinNode(nodeObject.childNodes[i], searchPhrase, test);
         // Creating tooltips/bubbles for menulist element
         if (result && nodeObject.tagName == "menulist") {
           this.listSearchBubbles.push(nodeObject);
         }
-        matchesFound = matchesFound || result;
+      
+        let subRes = false;
+        if (nodeObject.childNodes[i].contentDocument) {
+          subRes = this.searchWithinNode(nodeObject.childNodes[i].contentDocument, searchPhrase, test);
+        }
+        matchesFound = matchesFound || result || subRes;
       }
     }
     return matchesFound;
   },
 
 	/**
    * Inserting a div structure infront of the DOM element matched textContent.
 	 * Then calculation the offsets to position the tooltip in the correct place.
@@ -549,11 +605,76 @@ var gSearchResultsPane = {
     // then splitting it into list of words
     let listOfWords = phrase.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g, "").removeStopWords().split(" ");
     for (let i = 0; i < listOfWords.length; i++) {
       // Might need a better way to check if it is not just numbers
       if (isNaN(listOfWords[i])) {
         this.trie.insert(listOfWords[i].toLowerCase());
       }
     }
-  }
+  },
+
+  getSubDialogContent() {
+		console.log("getting Sub dialog Contet")
+		let arry = this.dialogBoxs[this.counterDialog];
+		let dialogObj = document.getElementById("dialogBox");
+    //console.log("db",dialogObj,dialogObj.children.length);
+		arry[1] = this.leafNodes(dialogObj);
+    //console.log("ar",arry[1],this.totalSubDialogs,this.counterDialog);
+		if (this.totalSubDialogs != this.counterDialog) {
+			this.counterDialog += 1;
+			this.openSubDialogBox();
+		}
+    document.getElementById("dialogClose").click();
+	},
+
+	openSubDialogBox() {
+		let arry = this.dialogBoxs[this.counterDialog];
+    //console.log("arry",arry)
+    if (arry) {
+		  document.getElementById(arry[0]).click();
+    }
+	},
 
+	leafNodes(nodeObject) {
+    let matchesFound = "";
+    //console.log("fun: ",nodeObject,nodeObject.childNodes.length)
+    if (nodeObject.childNodes.length == 0) {
+			//console.log("leaf",nodeObject, nodeObject.textContent,nodeObject.innerHTML);
+      //console.log("no",nodeObject,nodeObject.textContent, nodeObject.tagName);
+      if (nodeObject.textContent.indexOf("chrome://") == -1) {
+        matchesFound += nodeObject.textContent.trim();
+      } 
+    }
+
+    for (let i = 0; i < nodeObject.childNodes.length; i++) {
+      //console.log("\tchild:",nodeObject.childNodes[i],nodeObject.childNodes[i].childNodes.length);
+      // Search only if child node is not hidden
+      let result = this.leafNodes(nodeObject.childNodes[i]);
+      if (nodeObject.childNodes[i].contentDocument) {
+        result += " " + this.leafNodes(nodeObject.childNodes[i].contentDocument);
+      }
+      //console.log("result",result);
+      matchesFound += " " + result;
+    }
+    return matchesFound;
+  },
+
+  findInDialogs(nodeObjectId,searchPhrase) {
+    for (const key of Object.keys(gSearchResultsPane.dialogBoxs)) {
+      //console.log(key, gSearchResultsPane.dialogBoxs[key]);
+      let dialog = this.dialogBoxs[key];
+      let storeData = dialog[1].toLowerCase();
+      if (dialog[0] == nodeObjectId && storeData.indexOf(searchPhrase) > -1) {
+        return true;
+      }
+    }
+    return false;
+  },
+
+  highlightDialog() {
+    if (this.searchQuery != ""){
+    let dialog = document.getElementById("dialogBox");
+    console.log("hDia",dialog);
+    this.searchWithinNode(dialog, this.searchQuery, true)
+    }
+  }
 }
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -122,30 +122,35 @@ var gMainPane = {
     if (AppConstants.HAVE_SHELL_SERVICE) {
       setEventListener("setDefaultButton", "command",
                        gMainPane.setDefaultBrowser);
     }
     setEventListener("useCurrent", "command",
                      gMainPane.setHomePageToCurrent);
     setEventListener("useBookmark", "command",
                      gMainPane.setHomePageToBookmark);
+    //document.getElementById("useBookmark").setAttribute("subDialog","true");
     setEventListener("restoreDefaultHomePage", "command",
                      gMainPane.restoreDefaultHomePage);
     setEventListener("chooseLanguage", "command",
       gMainPane.showLanguages);
+    //document.getElementById("chooseLanguage").setAttribute("subDialog","true"); 
     setEventListener("translationAttributionImage", "click",
       gMainPane.openTranslationProviderAttribution);
     setEventListener("translateButton", "command",
       gMainPane.showTranslationExceptions);
+    //document.getElementById("translateButton").setAttribute("subDialog","true");
     setEventListener("font.language.group", "change",
       gMainPane._rebuildFonts);
     setEventListener("advancedFonts", "command",
       gMainPane.configureFonts);
+    //document.getElementById("advancedFonts").setAttribute("subDialog","true");
     setEventListener("colors", "command",
       gMainPane.configureColors);
+    //document.getElementById("colors").setAttribute("subDialog","true");
 
     // Initializes the fonts dropdowns displayed in this pane.
     this._rebuildFonts();
 
     // Show translation preferences if we may:
     const prefName = "browser.translation.ui.show";
     if (Services.prefs.getBoolPref(prefName)) {
       let row = document.getElementById("translationBox");
--- a/browser/components/preferences/in-content/subdialogs.js
+++ b/browser/components/preferences/in-content/subdialogs.js
@@ -1,14 +1,15 @@
 /* - 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/. */
 
 /* import-globals-from ../../../base/content/utilityOverlay.js */
 /* import-globals-from preferences.js */
+/* import-globals-from findInPage.js */
 
 "use strict";
 
 var gSubDialog = {
   _closingCallback: null,
   _closingEvent: null,
   _isClosing: false,
   _frame: null,
@@ -289,16 +290,24 @@ var gSubDialog = {
     this._overlay.style.visibility = "visible";
     this._overlay.style.opacity = ""; // XXX: focus hack continued from _onContentLoaded
 
     if (this._box.getAttribute("resizable") == "true") {
       this._resizeObserver = new MutationObserver(this._onResize);
       this._resizeObserver.observe(this._box, {attributes: true});
     }
 
+    console.log("open",gSearchResultsPane.dialogeInit);
+    console.log("numb",gSearchResultsPane.totalSubDialogs,gSearchResultsPane.counterDialog);
+    if (gSearchResultsPane.totalSubDialogs == gSearchResultsPane.counterDialog){
+      gSearchResultsPane.highlightDialog();
+    } else if (gSearchResultsPane.dialogeInit) {
+      gSearchResultsPane.getSubDialogContent();
+    }
+
     this._trapFocus();
   },
 
   _onResize(mutations) {
     let frame = gSubDialog._frame;
     // The width and height styles are needed for the initial
     // layout of the frame, but afterward they need to be removed
     // or their presence will restrict the contents of the <browser>