permissions.js (7335B)
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 /* import-globals-from pageInfo.js */ 6 7 const { SitePermissions } = ChromeUtils.importESModule( 8 "resource:///modules/SitePermissions.sys.mjs" 9 ); 10 11 var gPermPrincipal; 12 13 // List of ids of permissions to hide. 14 const EXCLUDE_PERMS = ["open-protocol-handler"]; 15 16 // Array of permissionIDs sorted alphabetically by label. 17 let gPermissions = SitePermissions.listPermissions() 18 .filter(permissionID => { 19 if (!SitePermissions.getPermissionLabel(permissionID)) { 20 return false; 21 } 22 return !EXCLUDE_PERMS.includes(permissionID); 23 }) 24 .sort((a, b) => { 25 let firstLabel = SitePermissions.getPermissionLabel(a); 26 let secondLabel = SitePermissions.getPermissionLabel(b); 27 return firstLabel.localeCompare(secondLabel); 28 }); 29 30 var permissionObserver = { 31 observe(aSubject, aTopic) { 32 if (aTopic == "perm-changed") { 33 var permission = aSubject.QueryInterface(Ci.nsIPermission); 34 if ( 35 permission.matches(gPermPrincipal, true) && 36 gPermissions.includes(permission.type) 37 ) { 38 initRow(permission.type); 39 } 40 } 41 }, 42 }; 43 44 function getExcludedPermissions() { 45 return EXCLUDE_PERMS; 46 } 47 48 function onLoadPermission(uri, principal) { 49 var permTab = document.getElementById("permTab"); 50 if (SitePermissions.isSupportedPrincipal(principal)) { 51 gPermPrincipal = principal; 52 var hostText = document.getElementById("hostText"); 53 hostText.value = uri.displayPrePath; 54 55 for (var i of gPermissions) { 56 initRow(i); 57 } 58 Services.obs.addObserver(permissionObserver, "perm-changed"); 59 window.addEventListener("unload", onUnloadPermission); 60 permTab.hidden = false; 61 } else { 62 permTab.hidden = true; 63 } 64 } 65 66 function onUnloadPermission() { 67 Services.obs.removeObserver(permissionObserver, "perm-changed"); 68 } 69 70 function initRow(aPartId) { 71 createRow(aPartId); 72 73 var checkbox = document.getElementById(aPartId + "Def"); 74 var command = document.getElementById("cmd_" + aPartId + "Toggle"); 75 var { state, scope } = SitePermissions.getForPrincipal( 76 gPermPrincipal, 77 aPartId 78 ); 79 let defaultState = SitePermissions.getDefault(aPartId); 80 81 // Since cookies preferences have many different possible configuration states 82 // we don't consider any permission except "no permission" to be default. 83 if (aPartId == "cookie") { 84 state = Services.perms.testPermissionFromPrincipal( 85 gPermPrincipal, 86 "cookie" 87 ); 88 89 if (state == SitePermissions.UNKNOWN) { 90 checkbox.checked = true; 91 command.setAttribute("disabled", "true"); 92 // Don't select any item in the radio group, as we can't 93 // confidently say that all cookies on the site will be allowed. 94 let radioGroup = document.getElementById("cookieRadioGroup"); 95 radioGroup.selectedItem = null; 96 } else { 97 checkbox.checked = false; 98 command.removeAttribute("disabled"); 99 } 100 101 setRadioState(aPartId, state); 102 103 checkbox.disabled = Services.prefs.prefIsLocked( 104 "network.cookie.cookieBehavior" 105 ); 106 107 return; 108 } 109 110 if (state != defaultState) { 111 checkbox.checked = false; 112 command.removeAttribute("disabled"); 113 } else { 114 checkbox.checked = true; 115 command.setAttribute("disabled", "true"); 116 } 117 118 if ( 119 [SitePermissions.SCOPE_POLICY, SitePermissions.SCOPE_GLOBAL].includes(scope) 120 ) { 121 checkbox.setAttribute("disabled", "true"); 122 command.setAttribute("disabled", "true"); 123 } 124 125 setRadioState(aPartId, state); 126 127 switch (aPartId) { 128 case "install": 129 checkbox.disabled = !Services.policies.isAllowed("xpinstall"); 130 break; 131 case "popup": 132 checkbox.disabled = Services.prefs.prefIsLocked( 133 "dom.disable_open_during_load" 134 ); 135 break; 136 case "autoplay-media": 137 checkbox.disabled = Services.prefs.prefIsLocked("media.autoplay.default"); 138 break; 139 case "geo": 140 case "desktop-notification": 141 case "camera": 142 case "microphone": 143 case "xr": 144 case "screen": 145 checkbox.disabled = Services.prefs.prefIsLocked( 146 "permissions.default." + aPartId 147 ); 148 break; 149 } 150 } 151 152 function createRow(aPartId) { 153 let rowId = "perm-" + aPartId + "-row"; 154 if (document.getElementById(rowId)) { 155 return; 156 } 157 158 let commandId = "cmd_" + aPartId + "Toggle"; 159 let labelId = "perm-" + aPartId + "-label"; 160 let radiogroupId = aPartId + "RadioGroup"; 161 162 let command = document.createXULElement("command"); 163 command.setAttribute("id", commandId); 164 command.addEventListener("command", () => onRadioClick(aPartId)); 165 document.getElementById("pageInfoCommandSet").appendChild(command); 166 167 let row = document.createXULElement("vbox"); 168 row.setAttribute("id", rowId); 169 row.setAttribute("class", "permission"); 170 171 let label = document.createXULElement("label"); 172 label.setAttribute("id", labelId); 173 label.setAttribute("control", radiogroupId); 174 label.setAttribute("value", SitePermissions.getPermissionLabel(aPartId)); 175 label.setAttribute("class", "permissionLabel"); 176 row.appendChild(label); 177 178 let controls = document.createXULElement("hbox"); 179 controls.setAttribute("role", "group"); 180 controls.setAttribute("aria-labelledby", labelId); 181 182 let checkbox = document.createXULElement("checkbox"); 183 checkbox.setAttribute("id", aPartId + "Def"); 184 checkbox.setAttribute("native", true); 185 document.l10n.setAttributes(checkbox, "permissions-use-default"); 186 checkbox.addEventListener("command", () => onCheckboxClick(aPartId)); 187 controls.appendChild(checkbox); 188 189 let spacer = document.createXULElement("spacer"); 190 spacer.setAttribute("flex", "1"); 191 controls.appendChild(spacer); 192 193 let radiogroup = document.createXULElement("radiogroup"); 194 radiogroup.setAttribute("id", radiogroupId); 195 radiogroup.setAttribute("orient", "horizontal"); 196 for (let state of SitePermissions.getAvailableStates(aPartId)) { 197 let radio = document.createXULElement("radio"); 198 radio.setAttribute("id", aPartId + "#" + state); 199 radio.setAttribute( 200 "label", 201 SitePermissions.getMultichoiceStateLabel(aPartId, state) 202 ); 203 radio.setAttribute("command", commandId); 204 radiogroup.appendChild(radio); 205 } 206 controls.appendChild(radiogroup); 207 208 row.appendChild(controls); 209 210 document.getElementById("permList").appendChild(row); 211 } 212 213 function onCheckboxClick(aPartId) { 214 var command = document.getElementById("cmd_" + aPartId + "Toggle"); 215 var checkbox = document.getElementById(aPartId + "Def"); 216 if (checkbox.checked) { 217 SitePermissions.removeFromPrincipal(gPermPrincipal, aPartId); 218 command.setAttribute("disabled", "true"); 219 } else { 220 onRadioClick(aPartId); 221 command.removeAttribute("disabled"); 222 } 223 } 224 225 function onRadioClick(aPartId) { 226 var radioGroup = document.getElementById(aPartId + "RadioGroup"); 227 let permission; 228 if (radioGroup.selectedItem) { 229 permission = parseInt(radioGroup.selectedItem.id.split("#")[1]); 230 } else { 231 permission = SitePermissions.getDefault(aPartId); 232 } 233 SitePermissions.setForPrincipal(gPermPrincipal, aPartId, permission); 234 } 235 236 function setRadioState(aPartId, aValue) { 237 var radio = document.getElementById(aPartId + "#" + aValue); 238 if (radio) { 239 radio.radioGroup.selectedItem = radio; 240 } 241 }