258 lines, 150 LOC, 57 covered (38%)
2 | 1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
|
3 | * |
|
4 | * The contents of this file are subject to the Mozilla Public License Version |
|
5 | * 1.1 (the "License"); you may not use this file except in compliance with |
|
6 | * the License. You may obtain a copy of the License at |
|
7 | * http://www.mozilla.org/MPL/ |
|
8 | * |
|
9 | * Software distributed under the License is distributed on an "AS IS" basis, |
|
10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
|
11 | * for the specific language governing rights and limitations under the |
|
12 | * License. |
|
13 | * |
|
14 | * The Original Code is Bookmarks Sync. |
|
15 | * |
|
16 | * The Initial Developer of the Original Code is Mozilla. |
|
17 | * Portions created by the Initial Developer are Copyright (C) 2008 |
|
18 | * the Initial Developer. All Rights Reserved. |
|
19 | * |
|
20 | * Contributor(s): |
|
21 | * Anant Narayanan <anant@kix.in> |
|
22 | * |
|
23 | * Alternatively, the contents of this file may be used under the terms of |
|
24 | * either the GNU General Public License Version 2 or later (the "GPL"), or |
|
25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|
26 | * in which case the provisions of the GPL or the LGPL are applicable instead |
|
27 | * of those above. If you wish to allow use of your version of this file only |
|
28 | * under the terms of either the GPL or the LGPL, and not to allow others to |
|
29 | * use your version of this file under the terms of the MPL, indicate your |
|
30 | * decision by deleting the provisions above and replace them with the notice |
|
31 | * and other provisions required by the GPL or the LGPL. If you do not delete |
|
32 | * the provisions above, a recipient may use your version of this file under |
|
33 | * the terms of any one of the MPL, the GPL or the LGPL. |
|
34 | * |
|
35 | * ***** END LICENSE BLOCK ***** */ |
|
36 | ||
14 | 37 | const EXPORTED_SYMBOLS = ['PrefsEngine']; |
38 | ||
8 | 39 | const Cc = Components.classes; |
8 | 40 | const Ci = Components.interfaces; |
8 | 41 | const Cu = Components.utils; |
42 | ||
6 | 43 | const WEAVE_SYNC_PREFS = "extensions.weave.prefs.sync."; |
6 | 44 | const WEAVE_PREFS_GUID = "preferences"; |
45 | ||
10 | 46 | Cu.import("resource://weave/util.js"); |
10 | 47 | Cu.import("resource://weave/engines.js"); |
10 | 48 | Cu.import("resource://weave/stores.js"); |
10 | 49 | Cu.import("resource://weave/trackers.js"); |
10 | 50 | Cu.import("resource://weave/type_records/prefs.js"); |
51 | ||
6 | 52 | function PrefsEngine() { |
14 | 53 | SyncEngine.call(this, "Prefs"); |
54 | } |
|
4 | 55 | PrefsEngine.prototype = { |
6 | 56 | __proto__: SyncEngine.prototype, |
4 | 57 | _storeObj: PrefStore, |
4 | 58 | _trackerObj: PrefTracker, |
4 | 59 | _recordObj: PrefRec, |
60 | ||
4 | 61 | _wipeClient: function _wipeClient() { |
62 | SyncEngine.prototype._wipeClient.call(this); |
|
63 | this.justWiped = true; |
|
64 | }, |
|
65 | ||
10 | 66 | _reconcile: function _reconcile(item) { |
67 | // Apply the incoming item if we don't care about the local data |
|
68 | if (this.justWiped) { |
|
69 | this.justWiped = false; |
|
70 | return true; |
|
71 | } |
|
72 | return SyncEngine.prototype._reconcile.call(this, item); |
|
73 | } |
|
74 | }; |
|
75 | ||
76 | ||
4 | 77 | function PrefStore(name) { |
78 | Store.call(this, name); |
|
79 | } |
|
4 | 80 | PrefStore.prototype = { |
6 | 81 | __proto__: Store.prototype, |
82 | ||
4 | 83 | get _prefs() { |
84 | let prefs = Cc["@mozilla.org/preferences-service;1"]. |
|
85 | getService(Ci.nsIPrefBranch); |
|
86 | ||
87 | this.__defineGetter__("_prefs", function() prefs); |
|
88 | return prefs; |
|
89 | }, |
|
90 | ||
4 | 91 | get _syncPrefs() { |
92 | let service = Cc["@mozilla.org/preferences-service;1"]. |
|
93 | getService(Ci.nsIPrefService); |
|
94 | let syncPrefs = service.getBranch(WEAVE_SYNC_PREFS).getChildList("", {}); |
|
95 | ||
96 | this.__defineGetter__("_syncPrefs", function() syncPrefs); |
|
97 | return syncPrefs; |
|
98 | }, |
|
99 | ||
4 | 100 | _getAllPrefs: function PrefStore__getAllPrefs() { |
101 | let values = []; |
|
102 | let toSync = this._syncPrefs; |
|
103 | ||
104 | let pref; |
|
105 | for (let i = 0; i < toSync.length; i++) { |
|
106 | if (!this._prefs.getBoolPref(WEAVE_SYNC_PREFS + toSync[i])) |
|
107 | continue; |
|
108 | ||
109 | pref = {}; |
|
110 | pref["name"] = toSync[i]; |
|
111 | ||
112 | switch (this._prefs.getPrefType(toSync[i])) { |
|
113 | case Ci.nsIPrefBranch.PREF_INT: |
|
114 | pref["type"] = "int"; |
|
115 | pref["value"] = this._prefs.getIntPref(toSync[i]); |
|
116 | break; |
|
117 | case Ci.nsIPrefBranch.PREF_STRING: |
|
118 | pref["type"] = "string"; |
|
119 | pref["value"] = this._prefs.getCharPref(toSync[i]); |
|
120 | break; |
|
121 | case Ci.nsIPrefBranch.PREF_BOOL: |
|
122 | pref["type"] = "boolean"; |
|
123 | pref["value"] = this._prefs.getBoolPref(toSync[i]); |
|
124 | break; |
|
125 | default: |
|
126 | this._log.trace("Unsupported pref type for " + toSync[i]); |
|
127 | } |
|
128 | if ("value" in pref) |
|
129 | values[values.length] = pref; |
|
130 | } |
|
131 | ||
132 | return values; |
|
133 | }, |
|
134 | ||
4 | 135 | _setAllPrefs: function PrefStore__setAllPrefs(values) { |
136 | // cache |
|
137 | let ltmExists = true; |
|
138 | let ltm = {}; |
|
139 | let enabledBefore = false; |
|
140 | let prevTheme = ""; |
|
141 | try { |
|
142 | Cu.import("resource://gre/modules/LightweightThemeManager.jsm", ltm); |
|
143 | ltm = ltm.LightweightThemeManager; |
|
144 | enabledBefore = this._prefs.getBoolPref("lightweightThemes.isThemeSelected"); |
|
145 | prevTheme = ltm.currentTheme; |
|
146 | } catch(ex) { |
|
147 | ltmExists = false; |
|
148 | } // LightweightThemeManager only exists in Firefox 3.6+ |
|
149 | ||
150 | for (let i = 0; i < values.length; i++) { |
|
151 | switch (values[i]["type"]) { |
|
152 | case "int": |
|
153 | this._prefs.setIntPref(values[i]["name"], values[i]["value"]); |
|
154 | break; |
|
155 | case "string": |
|
156 | this._prefs.setCharPref(values[i]["name"], values[i]["value"]); |
|
157 | break; |
|
158 | case "boolean": |
|
159 | this._prefs.setBoolPref(values[i]["name"], values[i]["value"]); |
|
160 | break; |
|
161 | default: |
|
162 | this._log.trace("Unexpected preference type: " + values[i]["type"]); |
|
163 | } |
|
164 | } |
|
165 | ||
166 | // Notify the lightweight theme manager of all the new values |
|
167 | if (ltmExists) { |
|
168 | let enabledNow = this._prefs.getBoolPref("lightweightThemes.isThemeSelected"); |
|
169 | if (enabledBefore && !enabledNow) |
|
170 | ltm.currentTheme = null; |
|
171 | else if (enabledNow && ltm.usedThemes[0] != prevTheme) { |
|
172 | ltm.currentTheme = null; |
|
173 | ltm.currentTheme = ltm.usedThemes[0]; |
|
174 | } |
|
175 | } |
|
176 | }, |
|
177 | ||
4 | 178 | getAllIDs: function PrefStore_getAllIDs() { |
179 | /* We store all prefs in just one WBO, with just one GUID */ |
|
180 | let allprefs = {}; |
|
181 | allprefs[WEAVE_PREFS_GUID] = this._getAllPrefs(); |
|
182 | return allprefs; |
|
183 | }, |
|
184 | ||
4 | 185 | changeItemID: function PrefStore_changeItemID(oldID, newID) { |
186 | this._log.trace("PrefStore GUID is constant!"); |
|
187 | }, |
|
188 | ||
4 | 189 | itemExists: function FormStore_itemExists(id) { |
190 | return (id === WEAVE_PREFS_GUID); |
|
191 | }, |
|
192 | ||
4 | 193 | createRecord: function createRecord(guid) { |
194 | let record = new PrefRec(); |
|
195 | ||
196 | if (guid == WEAVE_PREFS_GUID) { |
|
197 | record.value = this._getAllPrefs(); |
|
198 | } else { |
|
199 | record.deleted = true; |
|
200 | } |
|
201 | ||
202 | return record; |
|
203 | }, |
|
204 | ||
4 | 205 | create: function PrefStore_create(record) { |
206 | this._log.trace("Ignoring create request"); |
|
207 | }, |
|
208 | ||
4 | 209 | remove: function PrefStore_remove(record) { |
210 | this._log.trace("Ignoring remove request") |
|
211 | }, |
|
212 | ||
4 | 213 | update: function PrefStore_update(record) { |
214 | this._log.trace("Received pref updates, applying..."); |
|
215 | this._setAllPrefs(record.value); |
|
216 | }, |
|
217 | ||
10 | 218 | wipe: function PrefStore_wipe() { |
219 | this._log.trace("Ignoring wipe request"); |
|
220 | } |
|
221 | }; |
|
222 | ||
6 | 223 | function PrefTracker(name) { |
12 | 224 | Tracker.call(this, name); |
18 | 225 | this._prefs.addObserver("", this, false); |
226 | } |
|
4 | 227 | PrefTracker.prototype = { |
6 | 228 | __proto__: Tracker.prototype, |
229 | ||
6 | 230 | get _prefs() { |
6 | 231 | let prefs = Cc["@mozilla.org/preferences-service;1"]. |
8 | 232 | getService(Ci.nsIPrefBranch2); |
233 | ||
12 | 234 | this.__defineGetter__("_prefs", function() prefs); |
4 | 235 | return prefs; |
236 | }, |
|
237 | ||
6 | 238 | get _syncPrefs() { |
6 | 239 | let service = Cc["@mozilla.org/preferences-service;1"]. |
8 | 240 | getService(Ci.nsIPrefService); |
20 | 241 | let syncPrefs = service.getBranch(WEAVE_SYNC_PREFS).getChildList("", {}); |
242 | ||
357 | 243 | this.__defineGetter__("_syncPrefs", function() syncPrefs); |
4 | 244 | return syncPrefs; |
245 | }, |
|
246 | ||
247 | /* 25 points per pref change */ |
|
127 | 248 | observe: function(aSubject, aTopic, aData) { |
351 | 249 | if (aTopic != "nsPref:changed") |
250 | return; |
|
251 | ||
819 | 252 | if (this._syncPrefs.indexOf(aData) != -1) { |
253 | this.score += 1; |
|
254 | this.addChangedID(WEAVE_PREFS_GUID); |
|
255 | this._log.trace("Preference " + aData + " changed"); |
|
117 | 256 | } |
257 | } |
|
2 | 258 | }; |