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/. */
7 var EXPORTED_SYMBOLS = ["AsyncPrefs"];
9 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
11 const kInChildProcess =
12 Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT;
14 const kAllowedPrefs = new Set([
15 // NB: please leave the testing prefs at the top, and sort the rest alphabetically if you add
17 "testing.allowed-prefs.some-bool-pref",
18 "testing.allowed-prefs.some-char-pref",
19 "testing.allowed-prefs.some-int-pref",
26 "reader.color_scheme",
27 "reader.content_width",
30 "security.ssl.errorReporting.automatic",
31 "security.tls.version.enable-deprecated",
34 const kPrefTypeMap = new Map([
35 ["boolean", Services.prefs.PREF_BOOL],
36 ["number", Services.prefs.PREF_INT],
37 ["string", Services.prefs.PREF_STRING],
40 function maybeReturnErrorForReset(pref) {
41 if (!kAllowedPrefs.has(pref)) {
42 return `Resetting pref ${pref} from content is not allowed.`;
47 function maybeReturnErrorForSet(pref, value) {
48 if (!kAllowedPrefs.has(pref)) {
49 return `Setting pref ${pref} from content is not allowed.`;
52 let valueType = typeof value;
53 if (!kPrefTypeMap.has(valueType)) {
54 return `Can't set pref ${pref} to value of type ${valueType}.`;
56 let prefType = Services.prefs.getPrefType(pref);
58 prefType != Services.prefs.PREF_INVALID &&
59 prefType != kPrefTypeMap.get(valueType)
61 return `Can't set pref ${pref} to a value with type ${valueType} that doesn't match the pref's type ${prefType}.`;
67 if (kInChildProcess) {
69 let gMsgMap = new Map();
73 let error = maybeReturnErrorForSet(pref, value);
75 return Promise.reject(error);
78 let msgId = ++gUniqueId;
79 return new Promise((resolve, reject) => {
80 gMsgMap.set(msgId, { resolve, reject });
81 Services.cpmm.sendAsyncMessage("AsyncPrefs:SetPref", {
90 let error = maybeReturnErrorForReset(pref);
92 return Promise.reject(error);
95 let msgId = ++gUniqueId;
96 return new Promise((resolve, reject) => {
97 gMsgMap.set(msgId, { resolve, reject });
98 Services.cpmm.sendAsyncMessage("AsyncPrefs:ResetPref", { pref, msgId });
102 receiveMessage(msg) {
103 let promiseRef = gMsgMap.get(msg.data.msgId);
105 gMsgMap.delete(msg.data.msgId);
106 if (msg.data.success) {
107 promiseRef.resolve();
109 promiseRef.reject(msg.data.message);
115 Services.cpmm.addMessageListener("AsyncPrefs:PrefSetFinished", AsyncPrefs);
116 Services.cpmm.addMessageListener("AsyncPrefs:PrefResetFinished", AsyncPrefs);
120 number: "setIntPref",
121 boolean: "setBoolPref",
122 string: "setCharPref",
126 let error = maybeReturnErrorForSet(pref, value);
128 return Promise.reject(error);
130 let methodToUse = this.methodForType[typeof value];
132 Services.prefs[methodToUse](pref, value);
133 return Promise.resolve(value);
136 return Promise.reject(ex.message);
141 let error = maybeReturnErrorForReset(pref);
143 return Promise.reject(error);
147 Services.prefs.clearUserPref(pref);
148 return Promise.resolve();
151 return Promise.reject(ex.message);
155 receiveMessage(msg) {
156 if (msg.name == "AsyncPrefs:SetPref") {
159 this.onPrefReset(msg);
164 let { pref, msgId } = msg.data;
165 this.reset(pref).then(
167 msg.target.sendAsyncMessage("AsyncPrefs:PrefResetFinished", {
173 msg.target.sendAsyncMessage("AsyncPrefs:PrefResetFinished", {
183 let { pref, value, msgId } = msg.data;
184 this.set(pref, value).then(
186 msg.target.sendAsyncMessage("AsyncPrefs:PrefSetFinished", {
192 msg.target.sendAsyncMessage("AsyncPrefs:PrefSetFinished", {
202 // PLEASE KEEP THIS LIST IN SYNC WITH THE LISTENERS ADDED IN nsBrowserGlue
203 Services.ppmm.addMessageListener("AsyncPrefs:SetPref", this);
204 Services.ppmm.addMessageListener("AsyncPrefs:ResetPref", this);
205 // PLEASE KEEP THIS LIST IN SYNC WITH THE LISTENERS ADDED IN nsBrowserGlue