Bug 1336946 - store the list of top URLs in a file, r?gijs draft
authorSvetlana Orlik <sveta.orlik.code@gmail.com>
Fri, 17 Feb 2017 12:40:31 +0300
changeset 487049 b28a89f970be526f731239e45fa3d6f20e87fd46
parent 483488 c08dd938d988b6163e920a09dceca973d7b96894
child 487091 15cd742545d0ddef12c6760cd3db0c7f6c91ac2b
child 487094 92add5fad043d3f724dff94c37128ea328b023c7
child 489218 7a189c2cff1267340457edbcfcce9de866caa82d
push id46112
push userbmo:sveta.orlik.code@gmail.com
push dateMon, 20 Feb 2017 11:56:40 +0000
reviewersgijs
bugs1336946
milestone54.0a1
Bug 1336946 - store the list of top URLs in a file, r?gijs MozReview-Commit-ID: DB5gKNhRmku
toolkit/components/places/UnifiedComplete.js
toolkit/components/places/jar.mn
toolkit/components/places/moz.build
toolkit/components/places/mozIPlacesAutoComplete.idl
toolkit/components/places/tests/unifiedcomplete/test_prefill_sites.js
toolkit/components/places/unifiedcomplete-top-urls.json
--- a/toolkit/components/places/UnifiedComplete.js
+++ b/toolkit/components/places/UnifiedComplete.js
@@ -260,16 +260,18 @@ const SQL_BOOKMARKED_URL_QUERY = urlQuer
 
 const SQL_BOOKMARKED_TYPED_URL_QUERY = urlQuery("AND bookmarked AND h.typed = 1");
 
 // Getters
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
+Cu.importGlobalProperties(["fetch"]);
+
 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
                                   "resource://gre/modules/PlacesUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
                                   "resource://gre/modules/TelemetryStopwatch.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
                                   "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
                                   "resource://gre/modules/Preferences.jsm");
@@ -554,34 +556,31 @@ function PrefillSite(url, title) {
   this.uri = NetUtil.newURI(url);
   this.title = title;
   this._matchTitle = title.toLowerCase();
 }
 
 /**
  * Storage object for Prefill Sites.
  *   add(url, title): adds a site to storage
- *   populate() : populates the  storage with data (hard-coded for now)
+ *   populate(sites) : populates the  storage with array of [url,title]
  *   sites[]: resulting array of sites (PrefillSite objects)
  */
 XPCOMUtils.defineLazyGetter(this, "PrefillSiteStorage", () => Object.seal({
   sites: [],
 
   add(url, title) {
     let site = new PrefillSite(url, title);
     this.sites.push(site);
   },
 
-  populate() {
-    this.add("https://google.com/", "Google");
-    this.add("https://youtube.com/", "YouTube");
-    this.add("https://facebook.com/", "Facebook");
-    this.add("https://baidu.com/", "\u767E\u5EA6\u4E00\u4E0B\uFF0C\u4F60\u5C31\u77E5\u9053");
-    this.add("https://wikipedia.org/", "Wikipedia");
-    this.add("https://yahoo.com/", "Yahoo");
+  populate(sites) {
+    for (let site of sites) {
+      this.add(site[0], site[1]);
+    }
   },
 }));
 
 XPCOMUtils.defineLazyGetter(this, "ProfileAgeCreatedPromise", () => {
   return (new ProfileAge(null, null)).created;
 });
 
 // Helper functions
@@ -2058,17 +2057,21 @@ function UnifiedComplete() {
   // open pages should be set to false.
   Prefs;
 
   if (Prefs.prefillSitesEnabled) {
     // force initializing the profile age check
     // to ensure the off-main-thread-IO happens ASAP
     // and we don't have to wait for it when doing an autocomplete lookup
     ProfileAgeCreatedPromise;
-    PrefillSiteStorage.populate(); // with hard-coded data for now
+
+    fetch("chrome://global/content/unifiedcomplete-top-urls.json")
+      .then(response => response.json())
+      .then(sites => PrefillSiteStorage.populate(sites))
+      .catch(ex => Cu.reportError(ex));
   }
 }
 
 UnifiedComplete.prototype = {
   // Database handling
 
   /**
    * Promise resolved when the database initialization has completed, or null
@@ -2129,16 +2132,20 @@ UnifiedComplete.prototype = {
   unregisterOpenPage(uri, userContextId) {
     SwitchToTabStorage.delete(uri, userContextId);
   },
 
   addPrefillSite(url, title) {
     PrefillSiteStorage.add(url, title);
   },
 
+  populatePrefillSiteStorage(json) {
+    PrefillSiteStorage.populate(json);
+  },
+
   // nsIAutoCompleteSearch
 
   startSearch(searchString, searchParam, previousResult, listener) {
     // Stop the search in case the controller has not taken care of it.
     if (this._currentSearch) {
       this.stopSearch();
     }
 
new file mode 100644
--- /dev/null
+++ b/toolkit/components/places/jar.mn
@@ -0,0 +1,2 @@
+toolkit.jar:
+  content/global/unifiedcomplete-top-urls.json
--- a/toolkit/components/places/moz.build
+++ b/toolkit/components/places/moz.build
@@ -90,8 +90,10 @@ if CONFIG['MOZ_PLACES']:
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 with Files('**'):
     BUG_COMPONENT = ('Toolkit', 'Places')
 
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wno-error=shadow']
+
+JAR_MANIFESTS += ['jar.mn']
--- a/toolkit/components/places/mozIPlacesAutoComplete.idl
+++ b/toolkit/components/places/mozIPlacesAutoComplete.idl
@@ -140,9 +140,17 @@ interface mozIPlacesAutoComplete : nsISu
    * Add a site to list of Prefill Sites.
    *
    * @param url
    *        The URL of added site.
    * @param title
    *        The title of added site.
    */
   void addPrefillSite(in AUTF8String url, in AUTF8String title);
+
+  /**
+   * Populate list of Prefill Sites from JSON.
+   *
+   * @param sites
+   *        Array of [url,title] to populate from.
+   */
+  void populatePrefillSiteStorage(in jsval sites);
 };
--- a/toolkit/components/places/tests/unifiedcomplete/test_prefill_sites.js
+++ b/toolkit/components/places/tests/unifiedcomplete/test_prefill_sites.js
@@ -4,16 +4,18 @@
  */
 
 const PREF_FEATURE_ENABLED = "browser.urlbar.usepreloadedtopurls.enabled";
 const PREF_FEATURE_EXPIRE_DAYS = "browser.urlbar.usepreloadedtopurls.expire_days";
 
 const autocompleteObject = Cc["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
                              .getService(Ci.mozIPlacesAutoComplete);
 
+Cu.importGlobalProperties(["fetch"]);
+
 // With or without trailing slash - no matter. URI.spec does have it always.
 // Then, check_autocomplete() doesn't cut it off (uses stripPrefix()).
 let yahoooURI = NetUtil.newURI("https://yahooo.com/");
 let gooogleURI = NetUtil.newURI("https://gooogle.com/");
 
 autocompleteObject.addPrefillSite(yahoooURI.spec, "Yahooo");
 autocompleteObject.addPrefillSite(gooogleURI.spec, "Gooogle");
 
@@ -109,8 +111,32 @@ add_task(function* test_sorting_against_
       { uri: yahoooURI, title: "Yahooo",  style: ["prefill-site"] },
       { uri: gooogleURI, title: "Gooogle", style: ["prefill-site"] },
     ],
   });
 
   yield cleanup();
 });
 
+add_task(function* test_data_file() {
+  let response = yield fetch("chrome://global/content/unifiedcomplete-top-urls.json");
+
+  do_print("Source file is supplied and fetched OK");
+  Assert.ok(response.ok);
+
+  do_print("The JSON is parsed");
+  let sites = yield response.json();
+
+  do_print("Storage is populated");
+  autocompleteObject.populatePrefillSiteStorage(sites);
+
+  let lastSite = sites.pop();
+  let uri = NetUtil.newURI(lastSite[0]);
+  let title = lastSite[1];
+
+  do_print("Storage is populated from JSON correctly");
+  yield check_autocomplete({
+    search: uri.host.slice(1), // omit 1st letter to avoid style:"autofill" result
+    matches: [ { uri, title,  style: ["prefill-site"] } ],
+  });
+
+  yield cleanup();
+});
new file mode 100644
--- /dev/null
+++ b/toolkit/components/places/unifiedcomplete-top-urls.json
@@ -0,0 +1,8 @@
+[
+  ["https://google.com/", "Google"],
+  ["https://youtube.com/", "YouTube"],
+  ["https://facebook.com/", "Facebook"],
+  ["https://baidu.com/", "\u767E\u5EA6\u4E00\u4E0B\uFF0C\u4F60\u5C31\u77E5\u9053"],
+  ["https://wikipedia.org/", "Wikipedia"],
+  ["https://yahoo.com/", "Yahoo"]
+]
\ No newline at end of file