1 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* import-globals-from /browser/base/content/utilityOverlay.js */
7 /* import-globals-from /toolkit/content/preferencesBindings.js */
8 /* import-globals-from ../extensionControlled.js */
10 const proxyService = Ci.nsIProtocolProxyService;
12 const PROXY_TYPES_MAP_REVERSE = new Map([
13 [proxyService.PROXYCONFIG_DIRECT, "DIRECT"],
14 [proxyService.PROXYCONFIG_MANUAL, "MANUAL"],
15 [proxyService.PROXYCONFIG_PAC, "PAC"],
16 [proxyService.PROXYCONFIG_WPAD, "WPAD"],
17 [proxyService.PROXYCONFIG_SYSTEM, "SYSTEM"],
21 .getElementById("ConnectionsDialog")
22 .addEventListener("dialoghelp", window.top.openPrefsHelp);
25 // Add network.proxy.autoconfig_url before network.proxy.type so they're
26 // both initialized when network.proxy.type initialization triggers a call to
27 // gConnectionsDialog.updateReloadButton().
28 { id: "network.proxy.autoconfig_url", type: "string" },
29 { id: "network.proxy.system_wpad", type: "bool" },
30 { id: "network.proxy.type", type: "int" },
31 { id: "network.proxy.http", type: "string" },
32 { id: "network.proxy.http_port", type: "int" },
33 { id: "network.proxy.ssl", type: "string" },
34 { id: "network.proxy.ssl_port", type: "int" },
35 { id: "network.proxy.socks", type: "string" },
36 { id: "network.proxy.socks_port", type: "int" },
37 { id: "network.proxy.socks_version", type: "int" },
38 { id: "network.proxy.socks_remote_dns", type: "bool" },
39 { id: "network.proxy.socks5_remote_dns", type: "bool" },
40 { id: "network.proxy.no_proxies_on", type: "string" },
41 { id: "network.proxy.share_proxy_settings", type: "bool" },
42 { id: "signon.autologin.proxy", type: "bool" },
43 { id: "pref.advanced.proxies.disable_button.reload", type: "bool" },
44 { id: "network.proxy.backup.ssl", type: "string" },
45 { id: "network.proxy.backup.ssl_port", type: "int" },
48 window.addEventListener(
51 Preferences.get("network.proxy.type").on(
53 gConnectionsDialog.proxyTypeChanged.bind(gConnectionsDialog)
55 Preferences.get("network.proxy.socks_version").on(
57 gConnectionsDialog.updateDNSPref.bind(gConnectionsDialog)
61 .getElementById("key_close")
62 .addEventListener("command", event => Preferences.close(event));
65 .getElementById("disableProxyExtension")
68 makeDisableControllingExtension(PREF_SETTING_TYPE, PROXY_KEY).bind(
73 .getElementById("networkProxyAutoconfigURL")
74 .addEventListener("input", () => gConnectionsDialog.updateReloadButton());
76 .getElementById("autoReload")
77 .addEventListener("command", () => gConnectionsDialog.reloadPAC());
79 gConnectionsDialog.checkForSystemProxy();
80 gConnectionsDialog.updateProxySettingsUI();
81 initializeProxyUI(gConnectionsDialog);
82 gConnectionsDialog.registerSyncPrefListeners();
84 .getElementById("ConnectionsDialog")
85 .addEventListener("beforeaccept", e =>
86 gConnectionsDialog.beforeAccept(e)
89 { once: true, capture: true }
92 var gConnectionsDialog = {
94 var proxyTypePref = Preferences.get("network.proxy.type");
96 // collect "network.proxy.type" to glean metrics
97 let proxyTypePrefStr =
98 PROXY_TYPES_MAP_REVERSE.get(proxyTypePref.value) || "OTHER";
99 Glean.networkProxySettings.proxyTypePreference.record({
100 value: proxyTypePrefStr,
103 if (proxyTypePref.value == 2) {
104 this.doAutoconfigURLFixup();
108 if (proxyTypePref.value != 1) {
112 var httpProxyURLPref = Preferences.get("network.proxy.http");
113 var httpProxyPortPref = Preferences.get("network.proxy.http_port");
114 var shareProxiesPref = Preferences.get(
115 "network.proxy.share_proxy_settings"
118 // If the proxy server (when specified) is invalid or the port is set to 0 then cancel submission.
119 for (let prefName of ["http", "ssl", "socks"]) {
120 let proxyPortPref = Preferences.get(
121 "network.proxy." + prefName + "_port"
123 let proxyPref = Preferences.get("network.proxy." + prefName);
124 // Only worry about ports which are currently active. If the share option is on, then ignore
125 // all ports except the HTTP and SOCKS port
127 proxyPref.value != "" &&
128 (prefName == "http" || prefName == "socks" || !shareProxiesPref.value)
130 if (proxyPortPref.value == 0) {
132 .getElementById("networkProxy" + prefName.toUpperCase() + "_Port")
134 event.preventDefault();
136 } else if (!Services.io.isValidHostname(proxyPref.value)) {
138 .getElementById("networkProxy" + prefName.toUpperCase())
140 event.preventDefault();
146 // In the case of a shared proxy preference, backup the current values and update with the HTTP value
147 if (shareProxiesPref.value) {
148 var proxyServerURLPref = Preferences.get("network.proxy.ssl");
149 var proxyPortPref = Preferences.get("network.proxy.ssl_port");
150 var backupServerURLPref = Preferences.get("network.proxy.backup.ssl");
151 var backupPortPref = Preferences.get("network.proxy.backup.ssl_port");
152 backupServerURLPref.value =
153 backupServerURLPref.value || proxyServerURLPref.value;
154 backupPortPref.value = backupPortPref.value || proxyPortPref.value;
155 proxyServerURLPref.value = httpProxyURLPref.value;
156 proxyPortPref.value = httpProxyPortPref.value;
159 this.sanitizeNoProxiesPref();
162 checkForSystemProxy() {
163 if ("@mozilla.org/system-proxy-settings;1" in Cc) {
164 document.getElementById("systemPref").removeAttribute("hidden");
166 var systemWpadAllowed = Services.prefs.getBoolPref(
167 "network.proxy.system_wpad.allowed",
170 if (systemWpadAllowed && AppConstants.platform == "win") {
171 document.getElementById("systemWpad").removeAttribute("hidden");
177 var proxyTypePref = Preferences.get("network.proxy.type");
178 var systemWpadPref = Preferences.get("network.proxy.system_wpad");
179 systemWpadPref.updateControlDisabledState(proxyTypePref.value != 5);
182 var httpProxyURLPref = Preferences.get("network.proxy.http");
183 httpProxyURLPref.updateControlDisabledState(proxyTypePref.value != 1);
184 var httpProxyPortPref = Preferences.get("network.proxy.http_port");
185 httpProxyPortPref.updateControlDisabledState(proxyTypePref.value != 1);
187 // Now update the other protocols
188 this.updateProtocolPrefs();
190 var shareProxiesPref = Preferences.get(
191 "network.proxy.share_proxy_settings"
193 shareProxiesPref.updateControlDisabledState(proxyTypePref.value != 1);
194 var autologinProxyPref = Preferences.get("signon.autologin.proxy");
195 autologinProxyPref.updateControlDisabledState(proxyTypePref.value == 0);
196 var noProxiesPref = Preferences.get("network.proxy.no_proxies_on");
197 noProxiesPref.updateControlDisabledState(proxyTypePref.value == 0);
199 var autoconfigURLPref = Preferences.get("network.proxy.autoconfig_url");
200 autoconfigURLPref.updateControlDisabledState(proxyTypePref.value != 2);
202 this.updateReloadButton();
204 document.getElementById("networkProxyNoneLocalhost").hidden =
205 Services.prefs.getBoolPref(
206 "network.proxy.allow_hijacking_localhost",
212 var socksVersionPref = Preferences.get("network.proxy.socks_version");
213 var socks4DNSPref = Preferences.get("network.proxy.socks_remote_dns");
214 var socks5DNSPref = Preferences.get("network.proxy.socks5_remote_dns");
215 var proxyTypePref = Preferences.get("network.proxy.type");
216 var isDefinitelySocks4 =
217 proxyTypePref.value == 1 && socksVersionPref.value == 4;
218 socks5DNSPref.updateControlDisabledState(
219 isDefinitelySocks4 || proxyTypePref.value == 0
221 var isDefinitelySocks5 =
222 proxyTypePref.value == 1 && socksVersionPref.value == 5;
223 socks4DNSPref.updateControlDisabledState(
224 isDefinitelySocks5 || proxyTypePref.value == 0
229 updateReloadButton() {
230 // Disable the "Reload PAC" button if the selected proxy type is not PAC or
231 // if the current value of the PAC input does not match the value stored
232 // in prefs. Likewise, disable the reload button if PAC is not configured
235 var typedURL = document.getElementById("networkProxyAutoconfigURL").value;
236 var proxyTypeCur = Preferences.get("network.proxy.type").value;
238 var pacURL = Services.prefs.getCharPref("network.proxy.autoconfig_url");
239 var proxyType = Services.prefs.getIntPref("network.proxy.type");
241 var disableReloadPref = Preferences.get(
242 "pref.advanced.proxies.disable_button.reload"
244 disableReloadPref.updateControlDisabledState(
245 proxyTypeCur != 2 || proxyType != 2 || typedURL != pacURL
250 this.proxyTypeChanged();
254 updateProtocolPrefs() {
255 var proxyTypePref = Preferences.get("network.proxy.type");
256 var shareProxiesPref = Preferences.get(
257 "network.proxy.share_proxy_settings"
259 var proxyPrefs = ["ssl", "socks"];
260 for (var i = 0; i < proxyPrefs.length; ++i) {
261 var proxyServerURLPref = Preferences.get(
262 "network.proxy." + proxyPrefs[i]
264 var proxyPortPref = Preferences.get(
265 "network.proxy." + proxyPrefs[i] + "_port"
268 // Restore previous per-proxy custom settings, if present.
269 if (proxyPrefs[i] != "socks" && !shareProxiesPref.value) {
270 var backupServerURLPref = Preferences.get(
271 "network.proxy.backup." + proxyPrefs[i]
273 var backupPortPref = Preferences.get(
274 "network.proxy.backup." + proxyPrefs[i] + "_port"
276 if (backupServerURLPref.hasUserValue) {
277 proxyServerURLPref.value = backupServerURLPref.value;
278 backupServerURLPref.reset();
280 if (backupPortPref.hasUserValue) {
281 proxyPortPref.value = backupPortPref.value;
282 backupPortPref.reset();
286 proxyServerURLPref.updateElements();
287 proxyPortPref.updateElements();
288 let prefIsShared = proxyPrefs[i] != "socks" && shareProxiesPref.value;
289 proxyServerURLPref.updateControlDisabledState(
290 proxyTypePref.value != 1 || prefIsShared
292 proxyPortPref.updateControlDisabledState(
293 proxyTypePref.value != 1 || prefIsShared
296 var socksVersionPref = Preferences.get("network.proxy.socks_version");
297 socksVersionPref.updateControlDisabledState(proxyTypePref.value != 1);
298 this.updateDNSPref();
302 readProxyProtocolPref(aProtocol, aIsPort) {
303 if (aProtocol != "socks") {
304 var shareProxiesPref = Preferences.get(
305 "network.proxy.share_proxy_settings"
307 if (shareProxiesPref.value) {
308 var pref = Preferences.get(
309 "network.proxy.http" + (aIsPort ? "_port" : "")
314 var backupPref = Preferences.get(
315 "network.proxy.backup." + aProtocol + (aIsPort ? "_port" : "")
317 return backupPref.hasUserValue ? backupPref.value : undefined;
323 Cc["@mozilla.org/network/protocol-proxy-service;1"]
328 doAutoconfigURLFixup() {
329 var autoURL = document.getElementById("networkProxyAutoconfigURL");
330 var autoURLPref = Preferences.get("network.proxy.autoconfig_url");
332 autoURLPref.value = autoURL.value = Services.uriFixup.getFixupURIInfo(
338 sanitizeNoProxiesPref() {
339 var noProxiesPref = Preferences.get("network.proxy.no_proxies_on");
340 // replace substrings of ; and \n with commas if they're neither immediately
341 // preceded nor followed by a valid separator character
342 noProxiesPref.value = noProxiesPref.value.replace(
343 /([^, \n;])[;\n]+(?![,\n;])/g,
346 // replace any remaining ; and \n since some may follow commas, etc.
347 noProxiesPref.value = noProxiesPref.value.replace(/[;\n]/g, "");
350 readHTTPProxyServer() {
351 var shareProxiesPref = Preferences.get(
352 "network.proxy.share_proxy_settings"
354 if (shareProxiesPref.value) {
355 this.updateProtocolPrefs();
360 readHTTPProxyPort() {
361 var shareProxiesPref = Preferences.get(
362 "network.proxy.share_proxy_settings"
364 if (shareProxiesPref.value) {
365 this.updateProtocolPrefs();
371 let controlGroup = document.getElementById("networkProxyType");
373 ...controlGroup.querySelectorAll(":scope > radio"),
374 ...controlGroup.querySelectorAll("label"),
375 ...controlGroup.querySelectorAll("input"),
376 ...controlGroup.querySelectorAll("checkbox"),
377 ...document.querySelectorAll("#networkProxySOCKSVersion > radio"),
378 ...document.querySelectorAll("#ConnectionsDialogPane > checkbox"),
382 // Update the UI to show/hide the extension controlled message for
384 async updateProxySettingsUI() {
385 let isLocked = API_PROXY_PREFS.some(pref =>
386 Services.prefs.prefIsLocked(pref)
389 function setInputsDisabledState(isControlled) {
390 for (let element of gConnectionsDialog.getProxyControls()) {
391 element.disabled = isControlled;
393 gConnectionsDialog.proxyTypeChanged();
397 // An extension can't control this setting if any pref is locked.
398 hideControllingExtension(PROXY_KEY);
400 handleControllingExtension(PREF_SETTING_TYPE, PROXY_KEY).then(
401 setInputsDisabledState
406 registerSyncPrefListeners() {
407 function setSyncFromPrefListener(element_id, callback) {
408 Preferences.addSyncFromPrefListener(
409 document.getElementById(element_id),
413 setSyncFromPrefListener("networkProxyType", () => this.readProxyType());
414 setSyncFromPrefListener("networkProxyHTTP", () =>
415 this.readHTTPProxyServer()
417 setSyncFromPrefListener("networkProxyHTTP_Port", () =>
418 this.readHTTPProxyPort()
420 setSyncFromPrefListener("shareAllProxies", () =>
421 this.updateProtocolPrefs()
423 setSyncFromPrefListener("networkProxySSL", () =>
424 this.readProxyProtocolPref("ssl", false)
426 setSyncFromPrefListener("networkProxySSL_Port", () =>
427 this.readProxyProtocolPref("ssl", true)
429 setSyncFromPrefListener("networkProxySOCKS", () =>
430 this.readProxyProtocolPref("socks", false)
432 setSyncFromPrefListener("networkProxySOCKS_Port", () =>
433 this.readProxyProtocolPref("socks", true)