|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 const Cc = Components.classes; |
|
5 const Ci = Components.interfaces; |
|
6 const Cu = Components.utils; |
|
7 |
|
8 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
9 Cu.import("resource://gre/modules/Services.jsm"); |
|
10 |
|
11 XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", |
|
12 "resource://gre/modules/PlacesUtils.jsm"); |
|
13 XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", |
|
14 "resource://gre/modules/NetUtil.jsm"); |
|
15 XPCOMUtils.defineLazyModuleGetter(this, "Task", |
|
16 "resource://gre/modules/Task.jsm"); |
|
17 |
|
18 // Custom factory object to ensure that we're a singleton |
|
19 const BrowserStartupServiceFactory = { |
|
20 _instance: null, |
|
21 createInstance: function (outer, iid) { |
|
22 if (outer != null) |
|
23 throw Components.results.NS_ERROR_NO_AGGREGATION; |
|
24 return this._instance || (this._instance = new BrowserStartup()); |
|
25 } |
|
26 }; |
|
27 |
|
28 function BrowserStartup() { |
|
29 this._init(); |
|
30 } |
|
31 |
|
32 BrowserStartup.prototype = { |
|
33 // for XPCOM |
|
34 classID: Components.ID("{1d542abc-c88b-4636-a4ef-075b49806317}"), |
|
35 |
|
36 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), |
|
37 |
|
38 _xpcom_factory: BrowserStartupServiceFactory, |
|
39 |
|
40 _init: function() { |
|
41 Services.obs.addObserver(this, "places-init-complete", false); |
|
42 Services.obs.addObserver(this, "final-ui-startup", false); |
|
43 }, |
|
44 |
|
45 _initDefaultBookmarks: function() { |
|
46 // We must instantiate the history service since it will tell us if we |
|
47 // need to import or restore bookmarks due to first-run, corruption or |
|
48 // forced migration (due to a major schema change). |
|
49 let histsvc = Cc["@mozilla.org/browser/nav-history-service;1"]. |
|
50 getService(Ci.nsINavHistoryService); |
|
51 |
|
52 // If the database is corrupt or has been newly created we should |
|
53 // import bookmarks. |
|
54 let databaseStatus = histsvc.databaseStatus; |
|
55 let importBookmarks = databaseStatus == histsvc.DATABASE_STATUS_CREATE || |
|
56 databaseStatus == histsvc.DATABASE_STATUS_CORRUPT; |
|
57 |
|
58 if (!importBookmarks) { |
|
59 // Check to see whether "mobile" root already exists. This is to handle |
|
60 // existing profiles created with pre-1.0 builds (which won't have mobile |
|
61 // bookmarks root). We can remove this eventually when we stop |
|
62 // caring about users migrating to current builds with pre-1.0 profiles. |
|
63 let annos = Cc["@mozilla.org/browser/annotation-service;1"]. |
|
64 getService(Ci.nsIAnnotationService); |
|
65 let metroRootItems = annos.getItemsWithAnnotation("metro/bookmarksRoot", {}); |
|
66 if (metroRootItems.length > 0) |
|
67 return; // no need to do initial import |
|
68 } |
|
69 |
|
70 Cu.import("resource://gre/modules/BookmarkJSONUtils.jsm"); |
|
71 |
|
72 Task.spawn(function() { |
|
73 yield BookmarkJSONUtils.importFromURL("chrome://browser/locale/bookmarks.json", false); |
|
74 |
|
75 // Create the new smart bookmark. |
|
76 const MAX_RESULTS = 10; |
|
77 const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark"; |
|
78 |
|
79 // Place the Metro folder at the end of the smart bookmarks list. |
|
80 let maxIndex = Math.max.apply(null, |
|
81 PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO).map(id => { |
|
82 return PlacesUtils.bookmarks.getItemIndex(id); |
|
83 })); |
|
84 let smartBookmarkId = |
|
85 PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarksMenuFolderId, |
|
86 NetUtil.newURI("place:folder=" + |
|
87 PlacesUtils.annotations.getItemsWithAnnotation('metro/bookmarksRoot', {})[0] + |
|
88 "&queryType=" + |
|
89 Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + |
|
90 "&sort=" + |
|
91 Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING + |
|
92 "&maxResults=" + MAX_RESULTS + |
|
93 "&excludeQueries=1"), |
|
94 maxIndex + 1, |
|
95 PlacesUtils.getString("windows8TouchTitle")); |
|
96 PlacesUtils.annotations.setItemAnnotation(smartBookmarkId, |
|
97 SMART_BOOKMARKS_ANNO, |
|
98 "Windows8Touch", 0, |
|
99 PlacesUtils.annotations.EXPIRE_NEVER); |
|
100 }); |
|
101 }, |
|
102 |
|
103 _startupActions: function() { |
|
104 }, |
|
105 |
|
106 // nsIObserver |
|
107 observe: function(aSubject, aTopic, aData) { |
|
108 switch (aTopic) { |
|
109 case "places-init-complete": |
|
110 Services.obs.removeObserver(this, "places-init-complete"); |
|
111 this._initDefaultBookmarks(); |
|
112 break; |
|
113 case "final-ui-startup": |
|
114 Services.obs.removeObserver(this, "final-ui-startup"); |
|
115 this._startupActions(); |
|
116 break; |
|
117 } |
|
118 } |
|
119 }; |
|
120 |
|
121 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([BrowserStartup]); |