diff --git a/docs/.pages b/docs/.pages index ff39b93ddb..935044d41e 100644 --- a/docs/.pages +++ b/docs/.pages @@ -1,6 +1,7 @@ nav: - Home: - ... | index*.md + - ... | preferences*.md - zengin - genome - contribute \ No newline at end of file diff --git a/docs/preferences.md b/docs/preferences.md new file mode 100644 index 0000000000..3fec8eb600 --- /dev/null +++ b/docs/preferences.md @@ -0,0 +1,26 @@ +# Preferences + +
+ + + + \ No newline at end of file diff --git a/overrides/assets/javascripts/extra.js b/overrides/assets/javascripts/extra.js index 9e61f2093e..7d4428d19e 100644 --- a/overrides/assets/javascripts/extra.js +++ b/overrides/assets/javascripts/extra.js @@ -100,13 +100,18 @@ window.addEventListener("DOMContentLoaded", _ => { gmcExpandNavigation(); gmcAddVersionToggle(); gmcLinksForVersion(); - if (gGMC_PAGE_LOCALE !== gGMC_DEFAULT_LOCALE && gGMC_PAGE_LOCALE !== gGMC_FILE_LOCALE) { + if (gGMC_PAGE_LOCALE !== gGMC_DEFAULT_LOCALE + && gGMC_PAGE_LOCALE !== gGMC_FILE_LOCALE + && !gGMC_REMOVE_TRANSLATION_PROMPTS) { gmcTranslateButton(); } gmcRemoveCodeLines(); gmcExternalLinks(); - new gMutationObserver(gmcSearchMutationCallback) - .observe(document.querySelector(".md-search-result__list"), {childList: true}); + const searchResults = document.querySelector(".md-search-result__list"); + if (searchResults) { + new gMutationObserver(gmcSearchMutationCallback) + .observe(searchResults, {childList: true}); + } }); window.addEventListener("hashchange", _ => { @@ -402,6 +407,7 @@ const gmcTranslateButton = () => { "*GitHub's file editor doesn't provide `.md` formatting options, if you want those, consider using https://stackedit.io/*", ].join(" \n")); const newAnchor = document.createElement("a"); + newAnchor.id = "gmc-new-translation-button"; newAnchor.classList = anchor.classList; // Weird quirk. The topDirectory needs to be in both, the link and in the filename param to put the file in the correct directory. // -- This quirk stopped quirking with the introduction of the new GitHub UI, sadge. @@ -409,7 +415,7 @@ const gmcTranslateButton = () => { newAnchor.innerHTML = gGMC_TRANSLATE_SVG; newAnchor.title = gGMC_TRANSLATE_CTA; anchor.parentElement.prepend(newAnchor); -} +}; const gmcRemoveCodeLines = () => { const nodesForRemoval = []; @@ -433,7 +439,7 @@ const gmcFadingNavigation = () => { activeNavItems[0].classList.add("gmc-fade-nav"); activeNavItems[activeNavItems.length - 1].classList.add("gmc-fade-nav-off"); -} +}; function gmcDebug(...message) { if (gGMC_LOCAL) diff --git a/overrides/assets/javascripts/preferences.js b/overrides/assets/javascripts/preferences.js new file mode 100644 index 0000000000..b788589284 --- /dev/null +++ b/overrides/assets/javascripts/preferences.js @@ -0,0 +1,129 @@ +/* + * Licence MIT - Copyright (c) 2023 Kamil Krzyśków (HRY) + */ + +const gmcPreferenceHandler = (event) => { + console.debug(event); + const target = event.target; + const option = target.dataset["option"]; + // preferencesKey defined in extrahead template override + let loadedPreferences = __md_get(preferencesKey); + + if (option === "color") { + let prev = loadedPreferences["color"]; + if (!prev) { + loadedPreferences["color"] = {}; + loadedPreferences["__global"] = {}; + } + + // TODO Separate raw css builder from value assignment, perhaps it's time for OOP... + // TODO Implement some HEX to HSL conversion logic + // https://stackoverflow.com/questions/3732046/how-do-you-get-the-hue-of-a-xxxxxx-colour + + loadedPreferences["color"]["value"] = target.value; + loadedPreferences["__global"]["cssRaw"] = `* { --md-typeset-a-color: ${target.value}!important; } + [data-md-color-scheme="slate"] .md-header { border-bottom: .10rem solid ${target.value}; } + [data-md-color-scheme="slate"] .md-tabs { background-color: ${target.value} !important; }`; + } + + __md_set(preferencesKey, loadedPreferences) + // Function defined in extrahead template override + gmcLoadSetPreferences(); +}; + +/** + * Removes the translation prompts from the page. + * Mostly a quick hack for the GMC Preferences page. + * Once this function is used more than 3 times, + * it would be better to have a backend preprocessor solution. + */ +const removeRedundantTranslationIndicator = () => { + const itemsToRemove = [ + document.querySelector("#gmc-new-translation-button"), + document.querySelector(".gmc-announce") + ]; + + for (const item of itemsToRemove) { + console.debug(item) + if (item) { + item.remove(); + } + } +}; + +/* + This is run immediately when loaded to add the elements before the bundle.js + overrides the title tooltip logic. DOMContentLoaded is too late. +*/ +(() => { + + // Defined in extrahead template override + gGMC_REMOVE_TRANSLATION_PROMPTS = true; + removeRedundantTranslationIndicator(); + + let lastElement = document.querySelector("#preferences-start"); + const localizationElement = document.querySelector("#preferences-config-localization"); + + if (!lastElement || !localizationElement) { + console.debug("Preferences management couldn't find specified elements"); + return; + } + + // TODO export into a separate function to keep localization gathering disconnected from rendering + const localizationMatrix = JSON.parse(localizationElement.textContent); + let currentLocalization = localizationMatrix["en"]; + const langCode = location.pathname.split("/")[2]; + const langCodeLocalization = localizationMatrix[langCode]; + + if (langCodeLocalization) { + currentLocalization = {...currentLocalization, ...langCodeLocalization} + } + + console.debug(lastElement) + console.debug(localizationMatrix) + console.debug(langCode) + console.debug(langCodeLocalization) + console.debug(currentLocalization) + + const h1Tag = document.querySelector(".md-content h1"); + if (h1Tag) { + h1Tag.childNodes[0].nodeValue = currentLocalization["h1Content"]; + } + lastElement.innerText = currentLocalization["firstParagraph"]; + + const optionNames = ["color", "headingShadow"]; + + for (let option of optionNames) { + if (option !== "color") { + console.debug("for now only color works") + break; + } + + console.debug(option) + + const title = document.createElement("h2"); + title.innerText = currentLocalization[`${option}Title`]; + lastElement.insertAdjacentElement("afterend", title); + + const description = document.createElement("p"); + description.innerText = currentLocalization[`${option}Description`]; + title.insertAdjacentElement("afterend", description); + + const inputWrapper = document.createElement("p"); + const input = document.createElement("input"); + input.type = "text"; + if (option === "color") { + input.type = option; + } + input.dataset["option"] = option; + input.title = option; + if (option !== "color") { + input.className = "md-input"; + } + input.addEventListener("change", gmcPreferenceHandler); + inputWrapper.appendChild(input); + description.insertAdjacentElement("afterend", inputWrapper); + + lastElement = inputWrapper; + } +})(); \ No newline at end of file diff --git a/overrides/main.html b/overrides/main.html index 22a810cb5e..c346d2b518 100644 --- a/overrides/main.html +++ b/overrides/main.html @@ -1,5 +1,35 @@ {% extends "base.html" %} +{% block extrahead %} + {{ super() }} + +{% endblock %} + {# Extend the last block in the `base.html` before the changes are applicable to avoid any issues with the hacky page.meta