File indexing completed on 2024-04-28 05:32:50
0001 /* 0002 Copyright (C) 2017 Kai Uwe Broulik <kde@privat.broulik.de> 0003 Copyright (C) 2018 David Edmundson <davidedmundson@kde.org> 0004 0005 This program is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU General Public License as 0007 published by the Free Software Foundation; either version 3 of 0008 the License, or (at your option) any later version. 0009 0010 This program is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 GNU General Public License for more details. 0014 0015 You should have received a copy of the GNU General Public License 0016 along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 0019 function tabClicked(tabbar, tabbutton) { 0020 tabbar.buttons.forEach(function (button) { 0021 var tablink = button.dataset.tabLink 0022 0023 var tabtarget = document.querySelector("[data-tab-id=" + tablink + "]"); 0024 0025 if (tabbutton == button) { 0026 button.classList.add("active"); 0027 tabtarget.classList.add("active"); 0028 } else { 0029 button.classList.remove("active"); 0030 tabtarget.classList.remove("active"); 0031 } 0032 }); 0033 } 0034 0035 function loadSettings() { 0036 SettingsUtils.get().then((items) => { 0037 for (let key in items) { 0038 if (!items.hasOwnProperty(key)) { 0039 continue; 0040 } 0041 0042 let controls = document.querySelectorAll("[data-extension=" + key + "]"); 0043 for (let control of controls) { 0044 let settingsKey = control.dataset.settingsKey; 0045 if (!settingsKey) { 0046 console.warn("Invalid settings key in", control, "cannot load this"); 0047 continue; 0048 } 0049 0050 let value = items[key][settingsKey] 0051 0052 if (control.type === "checkbox") { 0053 control.checked = !!value; 0054 } else { 0055 if (value === true) { 0056 control.value = "TRUE"; 0057 } else if (value === false) { 0058 control.value = "FALSE"; 0059 } else { 0060 control.value = value; 0061 } 0062 } 0063 0064 updateDependencies(control, key, settingsKey); 0065 0066 control.addEventListener("change", () => { 0067 let saveFailureInfoElement = document.getElementById("save-failure-info"); 0068 saveFailureInfoElement.classList.add("hidden"); 0069 0070 updateDependencies(control, key, settingsKey); 0071 0072 saveSettings((error) => { 0073 if (error) { 0074 saveFailureInfoElement.classList.remove("hidden"); 0075 0076 let saveMessageElement = document.getElementById("save-message"); 0077 try { 0078 saveMessageElement.innerText = chrome.i18n.getMessage("options_save_failed"); 0079 } catch (e) { 0080 // When the extension is reloaded, any call to extension APIs throws, make sure we show at least some form of error 0081 saveMessageElement.innerText = "Saving settings failed (" + (error || e) + ")"; 0082 } 0083 return; 0084 } 0085 }); 0086 }); 0087 } 0088 } 0089 }); 0090 } 0091 0092 function saveSettings(cb) { 0093 var settings = {}; 0094 0095 let controls = document.querySelectorAll("[data-extension]"); 0096 for (let control of controls) { 0097 let extension = control.dataset.extension; 0098 0099 if (!DEFAULT_EXTENSION_SETTINGS.hasOwnProperty(extension)) { 0100 console.warn("Cannot save settings for extension", extension, "which isn't in DEFAULT_EXTENSION_SETTINGS"); 0101 continue; 0102 } 0103 0104 let settingsKey = control.dataset.settingsKey; 0105 if (!settingsKey) { 0106 console.warn("Invalid settings key in", control, "cannot save this"); 0107 continue; 0108 } 0109 0110 if (!settings[extension]) { 0111 settings[extension] = {}; 0112 } 0113 0114 if (!DEFAULT_EXTENSION_SETTINGS[extension].hasOwnProperty(settingsKey)) { 0115 console.warn("Cannot save settings key", settingsKey, "in extension", extension, "which isn't in DEFAULT_EXTENSION_SETTINGS"); 0116 continue; 0117 } 0118 0119 if (control.type === "checkbox") { 0120 settings[extension][settingsKey] = control.checked; 0121 } else { 0122 let value = control.value; 0123 if (value === "TRUE") { 0124 value = true; 0125 } else if (value === "FALSE") { 0126 value = false; 0127 } 0128 settings[extension][settingsKey] = value; 0129 } 0130 } 0131 0132 SettingsUtils.set(settings).then(() => { 0133 cb(); 0134 }, (err) => { 0135 cb(err); 0136 }); 0137 } 0138 0139 function updateDependencies(control, extension, settingsKey) { 0140 // Update all depending controls 0141 let value = control.type === "checkbox" ? control.checked : control.value; 0142 if (value === true) { 0143 value = "TRUE"; 0144 } else if (value === false) { 0145 value = "FALSE"; 0146 } 0147 0148 let dependencies = document.querySelectorAll("[data-depends-extension=" + extension + "][data-depends-settings-key=" + settingsKey + "]"); 0149 for (let dependency of dependencies) { 0150 dependency.disabled = (value != dependency.dataset.dependsSettingsValue); 0151 } 0152 } 0153 0154 function hasPermission(permission) { 0155 return new Promise((resolve, reject) => { 0156 chrome.permissions.contains({ 0157 permissions: [permission] 0158 }, (result) => { 0159 resolve(result); 0160 }); 0161 }); 0162 } 0163 0164 function askPermission(permission) { 0165 return new Promise((resolve, reject) => { 0166 chrome.permissions.request({ 0167 permissions: [permission] 0168 }, (result) => { 0169 resolve(result); 0170 }); 0171 }); 0172 } 0173 0174 document.addEventListener("DOMContentLoaded", function () { 0175 0176 // poor man's tab widget :) 0177 document.querySelectorAll(".tabbar").forEach(function (tabbar) { 0178 tabbar.buttons = []; 0179 0180 tabbar.querySelectorAll("[data-tab-link]").forEach(function (button) { 0181 0182 var tablink = button.dataset.tabLink 0183 0184 var tabtarget = document.querySelector("[data-tab-id=" + tablink + "]"); 0185 if (!tabtarget) { 0186 console.warn("Tab target", tablink, "does not exist!"); 0187 return; 0188 } 0189 0190 button.addEventListener("click", function (event) { 0191 tabClicked(tabbar, button); 0192 event.preventDefault(); 0193 }); 0194 0195 tabbar.buttons.push(button); 0196 0197 // start with the one tab page that is active 0198 if (tabtarget.classList.contains("active")) { 0199 tabClicked(tabbar, button); 0200 } 0201 }); 0202 }); 0203 0204 if (IS_FIREFOX) { 0205 document.querySelectorAll("[data-not-show-in=firefox]").forEach(function (item) { 0206 item.style.display = "none"; 0207 }); 0208 } 0209 0210 // check whether the platform is supported before loading and activating settings 0211 chrome.runtime.getPlatformInfo(function (info) { 0212 if (!SUPPORTED_PLATFORMS.includes(info.os)) { 0213 document.body.classList.add("os-not-supported"); 0214 return; 0215 } 0216 0217 loadSettings(); 0218 0219 // When getSubsystemStatus fails we assume it's an old host without any of the new features 0220 // for which we added the requires-extension attributes. Disable all of them initially 0221 // and then have the supported ones enabled below. 0222 document.querySelectorAll("[data-requires-extension]").forEach((item) => { 0223 item.classList.add("not-supported", "by-host"); 0224 }); 0225 0226 sendMessage("settings", "getSubsystemStatus").then((status) => { 0227 document.querySelectorAll("[data-requires-extension]").forEach((item) => { 0228 let requiresExtension = item.dataset.requiresExtension; 0229 0230 if (requiresExtension && !status.hasOwnProperty(requiresExtension)) { 0231 console.log("Extension", requiresExtension, "is not supported by this version of the host"); 0232 return; // continue 0233 } 0234 0235 let requiresMinimumVersion = Number(item.dataset.requiresExtensionVersionMinimum); 0236 if (requiresMinimumVersion) { 0237 let runningVersion = status[requiresExtension].version; 0238 if (runningVersion < requiresMinimumVersion) { 0239 console.log("Extension", requiresExtension, "of version", requiresMinimumVersion, "is required but only", runningVersion, "is present in the host"); 0240 return; // continue 0241 } 0242 } 0243 0244 item.classList.remove("not-supported", "by-host"); 0245 }); 0246 }).catch((e) => { 0247 // The host is most likely not working correctly 0248 // If we run this against an older host which doesn't support message replies 0249 // this handler is never entered, so we really encountered an error just now! 0250 console.warn("Failed to determine subsystem status", e); 0251 document.body.classList.add("startup-failure"); 0252 }); 0253 0254 Promise.all([ 0255 sendMessage("settings", "getVersion"), 0256 chrome.runtime.getManifest() 0257 ]).then((results) => { 0258 const versionInfo = results[0]; 0259 const manifest = results[1]; 0260 0261 document.getElementById("version-info-host").innerText = chrome.i18n.getMessage("options_about_host_version", 0262 versionInfo.host); 0263 document.getElementById("version-info-extension").innerText = chrome.i18n.getMessage("options_about_extension_version", manifest.version); 0264 0265 document.getElementById("version-info").classList.remove("not-supported"); 0266 }); 0267 }); 0268 0269 document.getElementById("open-krunner-settings").addEventListener("click", function (event) { 0270 sendMessage("settings", "openKRunnerSettings"); 0271 event.preventDefault(); 0272 }); 0273 0274 document.getElementById("request-permission-history").addEventListener("click", (e) => { 0275 hasPermission("history").then((granted) => { 0276 if (granted) { 0277 document.getElementById("historyrunner-description").innerText = chrome.i18n.getMessage("permission_request_already"); 0278 return; 0279 } 0280 0281 return askPermission("history"); 0282 }); 0283 0284 e.preventDefault(); 0285 }); 0286 0287 // When trying to enable historyrunner check if user accepted the permission 0288 const historyRunnerCheckBox = document.querySelector("[data-extension=historyrunner][data-settings-key=enabled]"); 0289 historyRunnerCheckBox.addEventListener("click", (e) => { 0290 if (historyRunnerCheckBox.checked) { 0291 askPermission("history").then((granted) => { 0292 historyRunnerCheckBox.checked = granted; 0293 }); 0294 } 0295 }); 0296 0297 // Make translators credit behave like the one in KAboutData 0298 var translatorsAboutData = ""; 0299 0300 var translators = chrome.i18n.getMessage("options_about_translators"); 0301 if (translators && translators !== "Your names") { 0302 translatorsAboutData = chrome.i18n.getMessage("options_about_translated_by", translators) 0303 } 0304 0305 var translatorsAboutDataItem = document.getElementById("translators-aboutdata"); 0306 if (translatorsAboutData) { 0307 translatorsAboutDataItem.innerText = translatorsAboutData; 0308 } else { 0309 translatorsAboutDataItem.style.display = "none"; 0310 } 0311 0312 // Chrome at some point started not properly opening links on the options page 0313 // Force external links to open in a new tab 0314 document.querySelectorAll("a[href^=http]").forEach((link) => { 0315 if (!link.target) { 0316 link.target = "_blank"; 0317 } 0318 }); 0319 });