diff --git a/javascript/src/zulma_switchcss.js b/javascript/src/zulma_switchcss.js index 074a7fb..60fc273 100644 --- a/javascript/src/zulma_switchcss.js +++ b/javascript/src/zulma_switchcss.js @@ -1,162 +1,163 @@ -(function (switch_css) { - //Constants - const THEME_KEY = "ZULMA_THEME"; - const STOP_BLINK_CSS_ID = "stop-blink"; - const STYLESHEET_CLASSNAME = "stylesheet" +(function(switch_css) { + //Constants + const THEME_KEY = "ZULMA_THEME"; + const STOP_BLINK_CSS_ID = "stop-blink"; + const STYLESHEET_CLASSNAME = "stylesheet"; - //Variables - //let link = null; - let previousLink = null; - let theme = localStorage.getItem(THEME_KEY); + //Variables + let previousLink = null; + let theme = localStorage.getItem(THEME_KEY); - //Events - /* The function called when the css has finished loading */ - const onLinkLoad = (event) => { - //remove event listeners - let link = event.currentTarget; - link.removeEventListener('load', onLinkLoad); - link.removeEventListener('error', onLinkError); - //remove the previous stylesheet(s) - removeStylesheets(); - //add stylesheet class - link.className += STYLESHEET_CLASSNAME; - //everything is good, so we don't need this - previousLink = null; - //make body visible again if it was hidden - showBody(); + //Events + /* The function called when the css has finished loading */ + const onLinkLoad = event => { + //remove event listeners + let link = event.currentTarget; + link.removeEventListener("load", onLinkLoad); + link.removeEventListener("error", onLinkError); + //remove the previous stylesheet(s) + removeStylesheets(); + //add stylesheet class + link.className += STYLESHEET_CLASSNAME; + //everything is good, so we don't need this + previousLink = null; + //make body visible again if it was hidden + showBody(); + }; + + const onLinkError = event => { + //remove event listeners + let link = event.currentTarget; + link.removeEventListener("load", onLinkLoad); + link.removeEventListener("error", onLinkError); + //remove theme from localstorage + clearTheme(); + //remove theme from dropdown list + updateThemeSelect(link.id, false); + //remove link from page + link.remove(); + //re-add the previous stylesheet (if any) + if (previousLink) { + document.getElementsByTagName("head")[0].appendChild(previousLink); + } + //set the theme select to the previous stylesheet + updateThemeSelect( + document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`)[0].id, + true + ); + //make body visible again if it was hidden + showBody(); + }; + + //Private Methods + /* Called when the theme is changed */ + function changeTheme(themeName, firstLoad) { + //create the css link element + var fileref = document.createElement("link"); + fileref.rel = "stylesheet"; + fileref.type = "text/css"; + fileref.href = `/${themeName}.css`; + fileref.id = themeName; + + //append it to the head + let link = document.getElementsByTagName("head")[0].appendChild(fileref); + + //when it's loaded, call onLinkLoad + link.addEventListener("load", onLinkLoad); + //if it errors, call onLinkError + link.addEventListener("error", onLinkError); + + //if this is the first load of the page, remove the current stylesheet early to avoid flash of wrongly styled content + if (firstLoad) { + //keep the old link in case something goes wrong + previousLink = document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`)[0]; + removeStylesheets(); } - const onLinkError = (event) => { - //remove event listeners - let link = event.currentTarget; - link.removeEventListener('load', onLinkLoad); - link.removeEventListener('error', onLinkError); - //remove theme from localstorage - clearTheme(); - //remove theme from dropdown list - updateThemeSelect(link.id, false); - //remove link from page - link.remove(); - //re-add the previous stylesheet (if any) - if (previousLink) { - document.getElementsByTagName("head")[0].appendChild(previousLink); + saveTheme(themeName); + } + + /* Removes all current stylesheets on the page */ + function removeStylesheets() { + document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`).forEach(el => { + el.remove(); + }); + } + + /* Saves the current theme in localstorage */ + function saveTheme(themeName) { + localStorage.setItem(THEME_KEY, themeName); + } + + /* Clears the current theme in localstorage */ + function clearTheme() { + localStorage.removeItem(THEME_KEY); + } + + /* Hides the body of the page */ + function hideBody() { + let head = document.getElementsByTagName("head")[0]; + let style = document.createElement("style"); + let css = "body{visibility:hidden;}"; + + style.id = STOP_BLINK_CSS_ID; + style.setAttribute("type", "text/css"); + + if (style.styleSheet) { + style.styleSheet.cssText = css; + } else { + style.appendChild(document.createTextNode(css)); + } + head.appendChild(style); + } + + /* Shows the body of the page */ + function showBody() { + let css = document.getElementById(STOP_BLINK_CSS_ID); + if (css) css.remove(); + } + + /* Either sets the theme selection to the given theme, or removes it from the list */ + function updateThemeSelect(theme, setSelected) { + //get all select options + let elements = document.querySelectorAll("#theme-select>option"); + //if there are elements, the page is loaded and continue + if (elements.length) { + elements.forEach(element => { + if (element.value === theme) { + if (setSelected) { + element.selected = "selected"; + } else { + element.remove(); + } } - //set the theme select to the previous stylesheet - updateThemeSelect(document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`)[0].id, true) - //make body visible again if it was hidden - showBody(); + }); + } else { + //if there are no elements, the page is not yet loaded; wait for loaded event and try again. + window.addEventListener("DOMContentLoaded", () => { + updateThemeSelect(theme, setSelected); + }); } + } - //Private Methods - /* Called when the theme is changed */ - function changeTheme(themeName, firstLoad) { - //create the css link element - var fileref = document.createElement("link"); - fileref.rel = "stylesheet"; - fileref.type = "text/css"; - fileref.href = `/${themeName}.css`; - fileref.id = themeName; - - //append it to the head - let link = document.getElementsByTagName("head")[0].appendChild(fileref); - - //when it's loaded, call onLinkLoad - link.addEventListener('load', onLinkLoad); - //if it errors, call onLinkError - link.addEventListener('error', onLinkError); - - //if this is the first load of the page, remove the current stylesheet early to avoid flash of wrongly styled content - if (firstLoad) { - //keep the old link in case something goes wrong - previousLink = document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`)[0]; - removeStylesheets(); - } - - saveTheme(themeName); + //Public Methods + switch_css.init = function() { + //if user has selected and theme and it is not the current theme + if (theme && !document.getElementById(theme)) { + //hide the body to stop FOUC + hideBody(); + //change the theme + changeTheme(theme, true); + //when the DOM is loaded, change the select to their current choice + updateThemeSelect(theme, true); } + //when the DOM is loaded, set the dropdown to trigger the theme change + window.addEventListener("DOMContentLoaded", () => { + document.getElementById("theme-select").onchange = function() { + changeTheme(this.value); + }; + }); + }; +})((switch_css = window.switch_css || {})); // eslint-disable-line - /* Removes all current stylesheets on the page */ - function removeStylesheets() { - document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`).forEach((el) => { - el.remove(); - }); - } - - /* Saves the current theme in localstorage */ - function saveTheme(themeName) { - localStorage.setItem(THEME_KEY, themeName); - } - - /* Clears the current theme in localstorage */ - function clearTheme() { - localStorage.removeItem(THEME_KEY); - } - - /* Hides the body of the page */ - function hideBody() { - let head = document.getElementsByTagName('head')[0]; - let style = document.createElement('style'); - let css = 'body{visibility:hidden;}'; - - style.id = STOP_BLINK_CSS_ID; - style.setAttribute('type', 'text/css'); - - if (style.styleSheet) { - style.styleSheet.cssText = css; - } else { - style.appendChild(document.createTextNode(css)); - } - head.appendChild(style); - } - - /* Shows the body of the page */ - function showBody() { - let css = document.getElementById(STOP_BLINK_CSS_ID); - if (css) - css.remove(); - } - - /* Either sets the theme selection to the given theme, or removes it from the list */ - function updateThemeSelect(theme, setSelected) { - //get all select options - let elements = document.querySelectorAll('#theme-select>option'); - //if there are elements, the page is loaded and continue - if (elements.length) { - elements.forEach(element => { - if (element.value === theme) { - if (setSelected) { - element.selected = 'selected'; - } else { - element.remove(); - } - } - }); - } else { - //if there are no elements, the page is not yet loaded; wait for loaded event and try again. - window.addEventListener('DOMContentLoaded', () => { - updateThemeSelect(theme, setSelected); - }); - } - } - - //Public Methods - switch_css.init = function () { - //if user has selected and theme and it is not the current theme - if (theme && !document.getElementById(theme)) { - //hide the body to stop FOUC - hideBody(); - //change the theme - changeTheme(theme, true); - //when the DOM is loaded, change the select to their current choice - updateThemeSelect(theme, true); - } - //when the DOM is loaded, set the dropdown to trigger the theme change - window.addEventListener('DOMContentLoaded', () => { - document.getElementById('theme-select').onchange = function () { - changeTheme(this.value); - } - }); - } -}(switch_css = window.switch_css || {})); // eslint-disable-line - -switch_css.init(); // eslint-disable-line \ No newline at end of file +switch_css.init(); // eslint-disable-line diff --git a/theme.toml b/theme.toml index 5b77e0a..d378bc1 100644 --- a/theme.toml +++ b/theme.toml @@ -2,6 +2,7 @@ name = "Zulma" description = "A zola theme based off bulma.css" license = "MIT" min_version = "0.6.0" +demo = "https://festive-morse-47d46c.netlify.com/" [extra] zulma_themes = ["default", "darkly", "flatly", "pulse", "simplex", "lux", "slate", "solar", "superhero"]