|
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 |
|
5 Components.utils.import("resource:///modules/SitePermissions.jsm"); |
|
6 |
|
7 const nsIQuotaManager = Components.interfaces.nsIQuotaManager; |
|
8 |
|
9 var gPermURI; |
|
10 var gUsageRequest; |
|
11 |
|
12 var gPermissions = SitePermissions.listPermissions(); |
|
13 gPermissions.push("plugins"); |
|
14 |
|
15 var permissionObserver = { |
|
16 observe: function (aSubject, aTopic, aData) |
|
17 { |
|
18 if (aTopic == "perm-changed") { |
|
19 var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission); |
|
20 if (permission.host == gPermURI.host) { |
|
21 if (gPermissions.indexOf(permission.type) > -1) |
|
22 initRow(permission.type); |
|
23 else if (permission.type.startsWith("plugin")) |
|
24 setPluginsRadioState(); |
|
25 } |
|
26 } |
|
27 } |
|
28 }; |
|
29 |
|
30 function onLoadPermission() |
|
31 { |
|
32 var uri = gDocument.documentURIObject; |
|
33 var permTab = document.getElementById("permTab"); |
|
34 if (SitePermissions.isSupportedURI(uri)) { |
|
35 gPermURI = uri; |
|
36 var hostText = document.getElementById("hostText"); |
|
37 hostText.value = gPermURI.host; |
|
38 |
|
39 for (var i of gPermissions) |
|
40 initRow(i); |
|
41 var os = Components.classes["@mozilla.org/observer-service;1"] |
|
42 .getService(Components.interfaces.nsIObserverService); |
|
43 os.addObserver(permissionObserver, "perm-changed", false); |
|
44 onUnloadRegistry.push(onUnloadPermission); |
|
45 permTab.hidden = false; |
|
46 } |
|
47 else |
|
48 permTab.hidden = true; |
|
49 } |
|
50 |
|
51 function onUnloadPermission() |
|
52 { |
|
53 var os = Components.classes["@mozilla.org/observer-service;1"] |
|
54 .getService(Components.interfaces.nsIObserverService); |
|
55 os.removeObserver(permissionObserver, "perm-changed"); |
|
56 |
|
57 if (gUsageRequest) { |
|
58 gUsageRequest.cancel(); |
|
59 gUsageRequest = null; |
|
60 } |
|
61 } |
|
62 |
|
63 function initRow(aPartId) |
|
64 { |
|
65 if (aPartId == "plugins") { |
|
66 initPluginsRow(); |
|
67 return; |
|
68 } |
|
69 |
|
70 createRow(aPartId); |
|
71 |
|
72 var checkbox = document.getElementById(aPartId + "Def"); |
|
73 var command = document.getElementById("cmd_" + aPartId + "Toggle"); |
|
74 var perm = SitePermissions.get(gPermURI, aPartId); |
|
75 |
|
76 if (perm) { |
|
77 checkbox.checked = false; |
|
78 command.removeAttribute("disabled"); |
|
79 } |
|
80 else { |
|
81 checkbox.checked = true; |
|
82 command.setAttribute("disabled", "true"); |
|
83 perm = SitePermissions.getDefault(aPartId); |
|
84 } |
|
85 setRadioState(aPartId, perm); |
|
86 |
|
87 if (aPartId == "indexedDB") { |
|
88 initIndexedDBRow(); |
|
89 } |
|
90 } |
|
91 |
|
92 function createRow(aPartId) { |
|
93 let rowId = "perm-" + aPartId + "-row"; |
|
94 if (document.getElementById(rowId)) |
|
95 return; |
|
96 |
|
97 let commandId = "cmd_" + aPartId + "Toggle"; |
|
98 let labelId = "perm-" + aPartId + "-label"; |
|
99 let radiogroupId = aPartId + "RadioGroup"; |
|
100 |
|
101 let command = document.createElement("command"); |
|
102 command.setAttribute("id", commandId); |
|
103 command.setAttribute("oncommand", "onRadioClick('" + aPartId + "');"); |
|
104 document.getElementById("pageInfoCommandSet").appendChild(command); |
|
105 |
|
106 let row = document.createElement("vbox"); |
|
107 row.setAttribute("id", rowId); |
|
108 row.setAttribute("class", "permission"); |
|
109 |
|
110 let label = document.createElement("label"); |
|
111 label.setAttribute("id", labelId); |
|
112 label.setAttribute("control", radiogroupId); |
|
113 label.setAttribute("value", SitePermissions.getPermissionLabel(aPartId)); |
|
114 label.setAttribute("class", "permissionLabel"); |
|
115 row.appendChild(label); |
|
116 |
|
117 let controls = document.createElement("hbox"); |
|
118 controls.setAttribute("role", "group"); |
|
119 controls.setAttribute("aria-labelledby", labelId); |
|
120 |
|
121 let checkbox = document.createElement("checkbox"); |
|
122 checkbox.setAttribute("id", aPartId + "Def"); |
|
123 checkbox.setAttribute("oncommand", "onCheckboxClick('" + aPartId + "');"); |
|
124 checkbox.setAttribute("label", gBundle.getString("permissions.useDefault")); |
|
125 controls.appendChild(checkbox); |
|
126 |
|
127 let spacer = document.createElement("spacer"); |
|
128 spacer.setAttribute("flex", "1"); |
|
129 controls.appendChild(spacer); |
|
130 |
|
131 let radiogroup = document.createElement("radiogroup"); |
|
132 radiogroup.setAttribute("id", radiogroupId); |
|
133 radiogroup.setAttribute("orient", "horizontal"); |
|
134 for (let state of SitePermissions.getAvailableStates(aPartId)) { |
|
135 let radio = document.createElement("radio"); |
|
136 radio.setAttribute("id", aPartId + "#" + state); |
|
137 radio.setAttribute("label", SitePermissions.getStateLabel(aPartId, state)); |
|
138 radio.setAttribute("command", commandId); |
|
139 radiogroup.appendChild(radio); |
|
140 } |
|
141 controls.appendChild(radiogroup); |
|
142 |
|
143 row.appendChild(controls); |
|
144 |
|
145 document.getElementById("permList").appendChild(row); |
|
146 } |
|
147 |
|
148 function onCheckboxClick(aPartId) |
|
149 { |
|
150 var command = document.getElementById("cmd_" + aPartId + "Toggle"); |
|
151 var checkbox = document.getElementById(aPartId + "Def"); |
|
152 if (checkbox.checked) { |
|
153 SitePermissions.remove(gPermURI, aPartId); |
|
154 command.setAttribute("disabled", "true"); |
|
155 var perm = SitePermissions.getDefault(aPartId); |
|
156 setRadioState(aPartId, perm); |
|
157 } |
|
158 else { |
|
159 onRadioClick(aPartId); |
|
160 command.removeAttribute("disabled"); |
|
161 } |
|
162 } |
|
163 |
|
164 function onPluginRadioClick(aEvent) { |
|
165 onRadioClick(aEvent.originalTarget.getAttribute("id").split('#')[0]); |
|
166 } |
|
167 |
|
168 function onRadioClick(aPartId) |
|
169 { |
|
170 var radioGroup = document.getElementById(aPartId + "RadioGroup"); |
|
171 var id = radioGroup.selectedItem.id; |
|
172 var permission = id.split('#')[1]; |
|
173 SitePermissions.set(gPermURI, aPartId, permission); |
|
174 } |
|
175 |
|
176 function setRadioState(aPartId, aValue) |
|
177 { |
|
178 var radio = document.getElementById(aPartId + "#" + aValue); |
|
179 radio.radioGroup.selectedItem = radio; |
|
180 } |
|
181 |
|
182 function initIndexedDBRow() |
|
183 { |
|
184 let row = document.getElementById("perm-indexedDB-row"); |
|
185 let extras = document.getElementById("perm-indexedDB-extras"); |
|
186 |
|
187 row.appendChild(extras); |
|
188 |
|
189 var quotaManager = Components.classes["@mozilla.org/dom/quota/manager;1"] |
|
190 .getService(nsIQuotaManager); |
|
191 gUsageRequest = |
|
192 quotaManager.getUsageForURI(gPermURI, onIndexedDBUsageCallback); |
|
193 |
|
194 var status = document.getElementById("indexedDBStatus"); |
|
195 var button = document.getElementById("indexedDBClear"); |
|
196 |
|
197 status.value = ""; |
|
198 status.setAttribute("hidden", "true"); |
|
199 button.setAttribute("hidden", "true"); |
|
200 } |
|
201 |
|
202 function onIndexedDBClear() |
|
203 { |
|
204 Components.classes["@mozilla.org/dom/quota/manager;1"] |
|
205 .getService(nsIQuotaManager) |
|
206 .clearStoragesForURI(gPermURI); |
|
207 |
|
208 SitePermissions.remove(gPermURI, "indexedDB-unlimited"); |
|
209 initIndexedDBRow(); |
|
210 } |
|
211 |
|
212 function onIndexedDBUsageCallback(uri, usage, fileUsage) |
|
213 { |
|
214 if (!uri.equals(gPermURI)) { |
|
215 throw new Error("Callback received for bad URI: " + uri); |
|
216 } |
|
217 |
|
218 if (usage) { |
|
219 if (!("DownloadUtils" in window)) { |
|
220 Components.utils.import("resource://gre/modules/DownloadUtils.jsm"); |
|
221 } |
|
222 |
|
223 var status = document.getElementById("indexedDBStatus"); |
|
224 var button = document.getElementById("indexedDBClear"); |
|
225 |
|
226 status.value = |
|
227 gBundle.getFormattedString("indexedDBUsage", |
|
228 DownloadUtils.convertByteUnits(usage)); |
|
229 status.removeAttribute("hidden"); |
|
230 button.removeAttribute("hidden"); |
|
231 } |
|
232 } |
|
233 |
|
234 // XXX copied this from browser-plugins.js - is there a way to share? |
|
235 function makeNicePluginName(aName) { |
|
236 if (aName == "Shockwave Flash") |
|
237 return "Adobe Flash"; |
|
238 |
|
239 // Clean up the plugin name by stripping off any trailing version numbers |
|
240 // or "plugin". EG, "Foo Bar Plugin 1.23_02" --> "Foo Bar" |
|
241 // Do this by first stripping the numbers, etc. off the end, and then |
|
242 // removing "Plugin" (and then trimming to get rid of any whitespace). |
|
243 // (Otherwise, something like "Java(TM) Plug-in 1.7.0_07" gets mangled) |
|
244 let newName = aName.replace(/[\s\d\.\-\_\(\)]+$/, "").replace(/\bplug-?in\b/i, "").trim(); |
|
245 return newName; |
|
246 } |
|
247 |
|
248 function fillInPluginPermissionTemplate(aPluginName, aPermissionString) { |
|
249 let permPluginTemplate = document.getElementById("permPluginTemplate").cloneNode(true); |
|
250 permPluginTemplate.setAttribute("permString", aPermissionString); |
|
251 let attrs = [ |
|
252 [ ".permPluginTemplateLabel", "value", aPluginName ], |
|
253 [ ".permPluginTemplateRadioGroup", "id", aPermissionString + "RadioGroup" ], |
|
254 [ ".permPluginTemplateRadioDefault", "id", aPermissionString + "#0" ], |
|
255 [ ".permPluginTemplateRadioAsk", "id", aPermissionString + "#3" ], |
|
256 [ ".permPluginTemplateRadioAllow", "id", aPermissionString + "#1" ], |
|
257 [ ".permPluginTemplateRadioBlock", "id", aPermissionString + "#2" ] |
|
258 ]; |
|
259 |
|
260 for (let attr of attrs) { |
|
261 permPluginTemplate.querySelector(attr[0]).setAttribute(attr[1], attr[2]); |
|
262 } |
|
263 |
|
264 return permPluginTemplate; |
|
265 } |
|
266 |
|
267 function clearPluginPermissionTemplate() { |
|
268 let permPluginTemplate = document.getElementById("permPluginTemplate"); |
|
269 permPluginTemplate.hidden = true; |
|
270 permPluginTemplate.removeAttribute("permString"); |
|
271 document.querySelector(".permPluginTemplateLabel").removeAttribute("value"); |
|
272 document.querySelector(".permPluginTemplateRadioGroup").removeAttribute("id"); |
|
273 document.querySelector(".permPluginTemplateRadioAsk").removeAttribute("id"); |
|
274 document.querySelector(".permPluginTemplateRadioAllow").removeAttribute("id"); |
|
275 document.querySelector(".permPluginTemplateRadioBlock").removeAttribute("id"); |
|
276 } |
|
277 |
|
278 function initPluginsRow() { |
|
279 let vulnerableLabel = document.getElementById("browserBundle").getString("pluginActivateVulnerable.label"); |
|
280 let pluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); |
|
281 |
|
282 let permissionMap = Map(); |
|
283 |
|
284 for (let plugin of pluginHost.getPluginTags()) { |
|
285 if (plugin.disabled) { |
|
286 continue; |
|
287 } |
|
288 for (let mimeType of plugin.getMimeTypes()) { |
|
289 let permString = pluginHost.getPermissionStringForType(mimeType); |
|
290 if (!permissionMap.has(permString)) { |
|
291 var name = makeNicePluginName(plugin.name); |
|
292 if (permString.startsWith("plugin-vulnerable:")) { |
|
293 name += " \u2014 " + vulnerableLabel; |
|
294 } |
|
295 permissionMap.set(permString, name); |
|
296 } |
|
297 } |
|
298 } |
|
299 |
|
300 let entries = [{name: item[1], permission: item[0]} for (item of permissionMap)]; |
|
301 entries.sort(function(a, b) { |
|
302 return a.name < b.name ? -1 : (a.name == b.name ? 0 : 1); |
|
303 }); |
|
304 |
|
305 let permissionEntries = [ |
|
306 fillInPluginPermissionTemplate(p.name, p.permission) for (p of entries) |
|
307 ]; |
|
308 |
|
309 let permPluginsRow = document.getElementById("perm-plugins-row"); |
|
310 clearPluginPermissionTemplate(); |
|
311 if (permissionEntries.length < 1) { |
|
312 permPluginsRow.hidden = true; |
|
313 return; |
|
314 } |
|
315 |
|
316 for (let permissionEntry of permissionEntries) { |
|
317 permPluginsRow.appendChild(permissionEntry); |
|
318 } |
|
319 |
|
320 setPluginsRadioState(); |
|
321 } |
|
322 |
|
323 function setPluginsRadioState() { |
|
324 let box = document.getElementById("perm-plugins-row"); |
|
325 for (let permissionEntry of box.childNodes) { |
|
326 if (permissionEntry.hasAttribute("permString")) { |
|
327 let permString = permissionEntry.getAttribute("permString"); |
|
328 let permission = SitePermissions.get(gPermURI, permString); |
|
329 setRadioState(permString, permission); |
|
330 } |
|
331 } |
|
332 } |