Files
tubestation/waterfox/browser/components/preferences/content/general.js
Alex Kontos 732b2a4624 refactor: about:preferences
* feat: Waterfox custom CSS on non-default themes by default
* feat: Table of Contents to preferences
* feat: DoOH checkbox to privacy preferences
* feat panel and menu transparency options
* feat: Look & Feel about:preferences item
2025-11-06 14:13:29 +00:00

242 lines
7.1 KiB
JavaScript

const _gMainPaneOverlay = {
init() {
// Initialize prefs
window.Preferences.addAll(this.preferences);
// Delayed initialization for Overlay dependent code
this.delayedInit();
},
get preferences() {
return [
// Tab Toolbar Position
{ id: "browser.tabs.toolbarposition", type: "wstring" },
// Tab Context Menu
{ id: "browser.tabs.duplicateTab", type: "bool" },
{ id: "browser.tabs.copyurl", type: "bool" },
{ id: "browser.tabs.activetab", type: "bool" },
{ id: "browser.tabs.copyallurls", type: "bool" },
{ id: "browser.tabs.unloadTab", type: "bool" },
// Additional Tab Prefs
{ id: "browser.tabs.pinnedIconOnly", type: "bool" },
{ id: "browser.tabs.insertAfterCurrent", type: "bool" },
{ id: "browser.tabs.insertRelatedAfterCurrent", type: "bool" },
// Dark Theme
{ id: "ui.systemUsesDarkTheme", type: "int" },
// Restart Menu Item
{ id: "browser.restart_menu.purgecache", type: "bool" },
{ id: "browser.restart_menu.requireconfirm", type: "bool" },
{ id: "browser.restart_menu.showpanelmenubtn", type: "bool" },
// Status Bar
{ id: "browser.statusbar.enabled", type: "bool" },
{ id: "browser.statusbar.appendStatusText", type: "bool" },
// Bookmarks Toolbar Position
{ id: "browser.bookmarks.toolbarposition", type: "wstring" },
// Geolocation API
{ id: "geo.provider.network.url", type: "wstring" },
// Referer
{ id: "network.http.sendRefererHeader", type: "int" },
// WebRTC P2P
{ id: "media.peerconnection.enabled", type: "bool" },
// Images
{ id: "permissions.default.image", type: "int" },
// Scripts
{ id: "javascript.enabled", type: "bool" },
// DoOH
{ id: "network.trr.use_ohttp", type: "bool" },
];
},
delayedInit() {
if (!window.initialized) {
setTimeout(() => {
this.delayedInit();
}, 500);
} else if (!document.initialized) {
// Select the correct radio button based on current pref value
this.showRelevantElements();
this.setDynamicThemeGroupValue();
this.setEventListener("dynamicThemeGroup", "command", (event) => {
this.updateDynamicThemePref(event.target.value);
});
if (document.readyState === "complete") {
this.tocGenerate();
} else {
document.addEventListener("readystatechange", () => {
if (document.readyState === "complete") {
this.tocGenerate();
}
});
}
document.initialized = true;
}
this.setEventListener("enableObliviousDns", "click", () => {
const value = document.getElementById("enableObliviousDns").checked ? 2 : 0;
Services.prefs.setIntPref("network.trr.mode", value);
});
},
tocGenerate() {
const contentSelector = "#mainPrefPane";
const headingSelector =
"#mainPrefPane > hbox:not([hidden]) > h1, #mainPrefPane > groupbox:not([hidden]) > h2, #mainPrefPane > groupbox:not([hidden]) label:not([hidden]) > h2";
const headerTarget = headingSelector.replaceAll(":not([hidden])", "");
const specialCharRegex = /[!@#$%^&*():]/gi;
const createHeadingId = () => {
const content = document.querySelector(contentSelector);
const headings = content?.querySelectorAll(headerTarget);
const headingMap = {};
let count = 0;
/**
* @param {Element} heading
* @returns {string}
*/
const getHeadingId = (heading) => {
const id = heading.id;
if (id) {
return id;
}
if (heading instanceof HTMLElement) {
const i18nId = heading.dataset.l10nId;
if (i18nId) {
return i18nId;
}
}
return (
heading.textContent
?.trim()
.toLowerCase()
.split(" ")
.join("-")
.replace(specialCharRegex, "") ?? `${count++}`
);
};
/**
* @param {string} headingText
* @param {number} count
* @returns {string}
*/
const createId = (headingText, count) =>
`${headingText}${count > 0 ? `-${count}` : ""}`;
if (headings) {
for (const heading of headings) {
const id = getHeadingId(heading);
headingMap[id] = !Number.isNaN(headingMap[id]) ? ++headingMap[id] : 0;
heading.id = createId(id, headingMap[id]);
}
}
};
createHeadingId();
tocbot.init({
tocSelector: ".toc",
contentSelector,
headingSelector,
scrollContainer: ".main-content",
headingsOffset: 100, // 90 + margins
hasInnerContainers: false,
/**
* @param {MouseEvent} e
*/
onClick(e) {
e.preventDefault();
/** @type {HTMLLinkElement} */
const link = e.target;
const targetSelector = link?.getAttribute("href");
if (targetSelector) {
const target = document.querySelector(targetSelector);
if (target) {
target.scrollIntoView({ behavior: "smooth", block: "start" });
}
}
},
});
const tocRefresh = () => {
createHeadingId();
tocbot.refresh();
};
window.addEventListener("hashchange", tocRefresh);
},
showRelevantElements() {
const idsGeneral = [
"dynamicThemeGroup",
"restartGroup",
"statusBarGroup",
"bookmarksBarPositionGroup",
"geolocationGroup",
];
const idsPrivacy = ["webrtc", "refheader", "dohBox"];
const win = Services.wm.getMostRecentWindow("navigator:browser");
const uri = win.gBrowser.currentURI.spec;
if (
(uri === "about:preferences" || uri === "about:preferences#general") &&
document.visibilityState === "visible"
) {
for (const id of idsGeneral) {
const el = document.getElementById(id);
if (el) {
el.removeAttribute("hidden");
}
}
} else if (
uri === "about:preferences#privacy" &&
document.visibilityState === "visible"
) {
for (const id of idsPrivacy) {
const el = document.getElementById(id);
if (el) {
el.removeAttribute("hidden");
}
}
}
},
setEventListener(aId, aEventType, aCallback) {
document
.getElementById(aId)
?.addEventListener(aEventType, aCallback.bind(_gMainPaneOverlay));
},
async setDynamicThemeGroupValue() {
const radiogroup = document.getElementById("dynamicThemeRadioGroup");
radiogroup.disabled = true;
radiogroup.value = Services.prefs.getIntPref("ui.systemUsesDarkTheme", -1);
radiogroup.disabled = false;
},
async updateDynamicThemePref(value) {
switch (value) {
case "1":
Services.prefs.setIntPref("ui.systemUsesDarkTheme", 1);
break;
case "0":
Services.prefs.setIntPref("ui.systemUsesDarkTheme", 0);
break;
case "-1":
Services.prefs.clearUserPref("ui.systemUsesDarkTheme");
break;
}
},
};