Bug 1517308 - Add a search field in about:url-classifier - part 2 - about page, r=dimi, r=flod
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 08 Jan 2019 23:05:41 +0100
changeset 510135 0ab9267646168b00142468dd0d243bef4431455a
parent 510134 543e146f314a1cd3af05bd421067df15df862402
child 510136 76f3be6b25e1398e4fdafd67cd2378f12f668b6f
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdimi, flod
bugs1517308
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1517308 - Add a search field in about:url-classifier - part 2 - about page, r=dimi, r=flod
toolkit/content/aboutUrlClassifier.js
toolkit/content/aboutUrlClassifier.xhtml
toolkit/locales/en-US/toolkit/about/url-classifier.ftl
--- a/toolkit/content/aboutUrlClassifier.js
+++ b/toolkit/content/aboutUrlClassifier.js
@@ -6,31 +6,181 @@ ChromeUtils.import("resource://gre/modul
 
 const UPDATE_BEGIN = "safebrowsing-update-begin";
 const UPDATE_FINISH = "safebrowsing-update-finished";
 const JSLOG_PREF = "browser.safebrowsing.debug";
 
 function unLoad() {
   window.removeEventListener("unload", unLoad);
 
+  Search.uninit();
   Provider.uninit();
   Cache.uninit();
   Debug.uninit();
 }
 
 function onLoad() {
   window.removeEventListener("load", onLoad);
   window.addEventListener("unload", unLoad);
 
+  Search.init();
   Provider.init();
   Cache.init();
   Debug.init();
 }
 
 /*
+ * Search
+ */
+var Search = {
+  init() {
+    let classifier = Cc["@mozilla.org/url-classifier/dbservice;1"]
+                       .getService(Ci.nsIURIClassifier);
+    let featureNames = classifier.getFeatureNames();
+
+    let fragment = document.createDocumentFragment();
+    featureNames.forEach(featureName => {
+      let div = document.createElement("div");
+      fragment.appendChild(div);
+
+      let checkbox = document.createElement("input");
+      checkbox.id = "feature_" + featureName;
+      checkbox.type = "checkbox";
+      checkbox.checked = true;
+      div.appendChild(checkbox);
+
+      let label = document.createElement("label");
+      label.for = checkbox.id;
+      div.appendChild(label);
+
+      let text = document.createTextNode(featureName);
+      label.appendChild(text);
+    });
+
+    let list = document.getElementById("search-features");
+    list.appendChild(fragment);
+
+    let btn = document.getElementById("search-button");
+    btn.addEventListener("click", this.search);
+
+    this.hideError();
+    this.hideResults();
+  },
+
+  uninit() {
+    let list = document.getElementById("search-features");
+    while (list.firstChild) {
+      list.firstChild.remove();
+    }
+
+    let btn = document.getElementById("search-button");
+    btn.removeEventListener("click", this.search);
+  },
+
+  search() {
+    Search.hideError();
+    Search.hideResults();
+
+    let input = document.getElementById("search-input").value;
+
+    let uri;
+    try {
+      uri = Services.io.newURI(input);
+      if (!uri) {
+        Search.reportError("url-classifier-search-error-invalid-url");
+        return;
+      }
+    } catch (ex) {
+      Search.reportError("url-classifier-search-error-invalid-url");
+      return;
+    }
+
+    let classifier = Cc["@mozilla.org/url-classifier/dbservice;1"]
+                       .getService(Ci.nsIURIClassifier);
+
+    let featureNames = classifier.getFeatureNames();
+    let features = [];
+    featureNames.forEach(featureName => {
+      if (document.getElementById("feature_" + featureName).checked) {
+        let feature = classifier.getFeatureByName(featureName);
+        if (feature) {
+          features.push(feature);
+        }
+      }
+    });
+
+    if (!features.length) {
+      Search.reportError("url-classifier-search-error-no-features");
+      return;
+    }
+
+    let listType = document.getElementById("search-listtype").value == 0
+                     ? Ci.nsIUrlClassifierFeature.blacklist
+                     : Ci.nsIUrlClassifierFeature.whitelist;
+    classifier.asyncClassifyLocalWithFeatures(uri, features, listType,
+                                              list => Search.showResults(list));
+
+    Search.hideError();
+  },
+
+  hideError() {
+    let errorMessage = document.getElementById("search-error-message");
+    errorMessage.style.display = "none";
+  },
+
+  reportError(msg) {
+    let errorMessage = document.getElementById("search-error-message");
+    document.l10n.setAttributes(errorMessage, msg);
+    errorMessage.style.display = "";
+  },
+
+  hideResults() {
+    let resultTitle = document.getElementById("result-title");
+    resultTitle.style.display = "none";
+
+    let resultTable = document.getElementById("result-table");
+    resultTable.style.display = "none";
+  },
+
+  showResults(results) {
+    let fragment = document.createDocumentFragment();
+    results.forEach(result => {
+      let tr = document.createElement("tr");
+      fragment.appendChild(tr);
+
+      let th = document.createElement("th");
+      tr.appendChild(th);
+      th.appendChild(document.createTextNode(result.feature.name));
+
+      let td = document.createElement("td");
+      tr.appendChild(td);
+
+      let featureName = document.createElement("div");
+      document.l10n.setAttributes(featureName, "url-classifier-search-result-uri", {uri: result.uri.spec});
+      td.appendChild(featureName);
+
+      let list = document.createElement("div");
+      document.l10n.setAttributes(list, "url-classifier-search-result-list", {list: result.list});
+      td.appendChild(list);
+    });
+
+    let resultTable = document.getElementById("result-table");
+    while (resultTable.firstChild) {
+      resultTable.firstChild.remove();
+    }
+
+    resultTable.appendChild(fragment);
+    resultTable.style.display = "";
+
+    let resultTitle = document.getElementById("result-title");
+    resultTitle.style.display = "";
+  },
+};
+
+/*
  * Provider
  */
 var Provider = {
   providers: null,
 
   updatingProvider: "",
 
   init() {
--- a/toolkit/content/aboutUrlClassifier.xhtml
+++ b/toolkit/content/aboutUrlClassifier.xhtml
@@ -13,16 +13,59 @@
   <title data-l10n-id="url-classifier-title"></title>
   <link rel="stylesheet" href="chrome://global/content/aboutUrlClassifier.css" type="text/css"/>
   <link rel="localization" href="toolkit/about/url-classifier.ftl"/>
   <script type="text/javascript" src="chrome://global/content/aboutUrlClassifier.js"></script>
 </head>
 
 <body onload="onLoad()" class="wide-container">
   <h1 data-l10n-id="url-classifier-title"></h1>
+  <div id="search">
+    <h2 class="major-section" data-l10n-id="url-classifier-search-title"></h2>
+    <div class="options">
+      <table id="search-table">
+        <tbody>
+        <tr>
+          <th class="column" data-l10n-id="url-classifier-search-input"></th>
+          <td>
+            <input id="search-input" type="text" value=""/>
+          </td>
+        </tr>
+        <tr>
+          <th class="column" data-l10n-id="url-classifier-search-listType"></th>
+          <td>
+            <select id="search-listtype">
+              <option value="0">Blacklist</option>
+              <option value="1">Whitelist</option>
+            </select>
+          </td>
+        </tr>
+        <tr>
+          <th class="column" data-l10n-id="url-classifier-search-features"></th>
+          <td id="search-features"></td>
+        </tr>
+        <tr>
+          <th></th>
+          <td>
+            <button id="search-button" data-l10n-id="url-classifier-search-btn"></button>
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <p id="search-error-message"></p>
+      <h2 class="major-section" id="result-title" data-l10n-id="url-classifier-search-result-title"></h2>
+      <table id="result-table">
+        <tr>
+          <td>
+            <input id="search-input" type="text" value=""/>
+          </td>
+        </tr>
+      </table>
+    </div>
+  </div>
   <div id="provider">
     <h2 class="major-section" data-l10n-id="url-classifier-provider-title"></h2>
     <table id="provider-table">
       <thead>
         <tr id="provider-head-row">
           <th id="col-provider" data-l10n-id="url-classifier-provider"></th>
           <th id="col-lastupdatetime" data-l10n-id="url-classifier-provider-last-update-time"></th>
           <th id="col-nextupdatetime" data-l10n-id="url-classifier-provider-next-update-time"></th>
--- a/toolkit/locales/en-US/toolkit/about/url-classifier.ftl
+++ b/toolkit/locales/en-US/toolkit/about/url-classifier.ftl
@@ -1,13 +1,23 @@
 # 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/.
 
 url-classifier-title = URL Classifier Information
+url-classifier-search-title = Search
+url-classifier-search-result-title = Results
+url-classifier-search-result-uri = URI: { $uri }
+url-classifier-search-result-list = Table list: { $list }
+url-classifier-search-input = URL
+url-classifier-search-error-invalid-url = Invalid URL
+url-classifier-search-error-no-features = No features selected
+url-classifier-search-btn = Start searching
+url-classifier-search-features = Features
+url-classifier-search-listType = List type
 url-classifier-provider-title = Provider
 url-classifier-provider = Provider
 url-classifier-provider-last-update-time = Last update time
 url-classifier-provider-next-update-time = Next update time
 url-classifier-provider-back-off-time = Back-off time
 url-classifier-provider-last-update-status = Last update status
 url-classifier-provider-update-btn = Update
 url-classifier-cache-title = Cache