222 lines
5.9 KiB
JavaScript
222 lines
5.9 KiB
JavaScript
/*
|
|
* JS doesn't support directly declaring objects
|
|
* with '--' and '-' in their properties.
|
|
*
|
|
* Well technically it deos using bracket-notation like this:
|
|
* foo['--bar'] =42;
|
|
* But that's not that much better.
|
|
*
|
|
* So instead this JSON.parse is used.
|
|
*/
|
|
|
|
window.themes = JSON.parse('{\
|
|
"white": {\
|
|
"--main-highlight-color": "#EF940B",\
|
|
"--main-bg-color": "white", \
|
|
"--secondary-bg-color": "white", \
|
|
"--main-text-color": "black",\
|
|
"--main-link-color": "#106BF4",\
|
|
"--shadow-color": "#888",\
|
|
"--gray-light": "#cacaca",\
|
|
"--gray-medium": "#e0e0e0",\
|
|
"--gray-dark": "#4c4c4c",\
|
|
"--red": "red",\
|
|
"--green": "green"\
|
|
},\
|
|
"black": {\
|
|
"--main-highlight-color": "#EE6E1F",\
|
|
"--main-link-color": "#1191e0",\
|
|
"--main-bg-color": "black",\
|
|
"--secondary-bg-color": "black", \
|
|
"--main-text-color": "white",\
|
|
"--shadow-color": "#777",\
|
|
"--gray-light": "#4c4c4c",\
|
|
"--gray-medium": "#333",\
|
|
"--gray-dark": "#cacaca",\
|
|
"--red": "#ef0000",\
|
|
"--green": "#00ab00"\
|
|
},\
|
|
"ash": {\
|
|
"--main-highlight-color": "#EE6E1F",\
|
|
"--main-link-color": "#1191e0",\
|
|
"--main-bg-color": "#333",\
|
|
"--secondary-bg-color": "#333", \
|
|
"--main-text-color": "#d0d0d0",\
|
|
"--shadow-color": "#656565",\
|
|
"--gray-light": "#4c4c4c",\
|
|
"--gray-medium": "#3b3b3b",\
|
|
"--gray-dark": "#cacaca",\
|
|
"--red": "#e4053e",\
|
|
"--green": "#04c446"\
|
|
},\
|
|
"midnight": {\
|
|
"--main-highlight-color": "#1caff6",\
|
|
"--main-link-color": "#1caff6",\
|
|
"--main-bg-color": "#111",\
|
|
"--secondary-bg-color": "#045d89", \
|
|
"--main-text-color": "#d0d0d0",\
|
|
"--shadow-color": "#656565",\
|
|
"--gray-light": "#3f3f3f",\
|
|
"--gray-medium": "#3b3b3b",\
|
|
"--gray-dark": "#cacaca",\
|
|
"--red": "#f72900",\
|
|
"--green": "#82dd00"\
|
|
}\
|
|
}');
|
|
window.IS_TOUCH_DEVICE = false;
|
|
window.addEventListener('touchstart', function() {
|
|
window.IS_TOUCH_DEVICE = true;
|
|
});
|
|
|
|
window.queries = getQueries();
|
|
setTheme(queries.theme);
|
|
if (queries.debugTouch) {
|
|
IS_TOUCH_DEVICE = true;
|
|
console.log("Touch device mode set");
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
displayThemeChooser();
|
|
});
|
|
|
|
function setTheme(t, save = true, element = null) {
|
|
let themeName = 'white';
|
|
if (!!t && (t in themes)) {
|
|
themeName = t;
|
|
} else {
|
|
const ls = localStorage.getItem('theme');
|
|
if (!!ls && (ls in themes)) {
|
|
themeName = ls;
|
|
} else {
|
|
save = false;
|
|
// Use default. Switch to ash if dark mode and don't save
|
|
if (matchMedia("(prefers-color-scheme: dark)")) {
|
|
themeName = 'ash';
|
|
}
|
|
}
|
|
}
|
|
if (save) {
|
|
localStorage.setItem('theme', themeName);
|
|
}
|
|
const theme = themes[themeName];
|
|
const doc = element || document.querySelector(':root');
|
|
Object.keys(theme).forEach(varName => {
|
|
doc.style.setProperty(varName, theme[varName]);
|
|
});
|
|
}
|
|
|
|
function displayThemeChooser() {
|
|
const wrapper = document.getElementById('themeChooser');
|
|
if (!wrapper) {
|
|
return;
|
|
}
|
|
const themeNames = Object.keys(themes);
|
|
if (themeNames.length < 2) {
|
|
return;
|
|
}
|
|
const list = document.createElement('ul');
|
|
list.classList.add('theme-chooser-list');
|
|
themeNames.forEach(t => {
|
|
const link = document.createElement('a');
|
|
link.style.position = 'relative';
|
|
link.href = `?theme=${t}`;
|
|
link.onclick = function (e) {
|
|
const t = this.href.split('theme=')[1];
|
|
e.preventDefault();
|
|
if (!IS_TOUCH_DEVICE) {
|
|
setTheme(t);
|
|
return;
|
|
}
|
|
const callout = document.querySelector('.theme-preview');
|
|
if (callout && callout.getAttribute('currentTheme') == t) {
|
|
// Clicked on already seelcted theme - apply!
|
|
callout.style.display = "none";
|
|
document.querySelector('.themelist').style.filter = '';
|
|
try {
|
|
let d = document.querySelector('.dimmer').remove();
|
|
} catch (err) {
|
|
// Do nothing
|
|
}
|
|
setTheme(t);
|
|
return;
|
|
} else {
|
|
const rect = list.getBoundingClientRect();
|
|
setTheme(t, false, callout);
|
|
callout.setAttribute('currentTheme', t);
|
|
callout.style.display = "inherit";
|
|
callout.style.bottom = document.querySelector('.theme-chooser-list').getBoundingClientRect().top + "px";
|
|
console.log(callout, callout.style);
|
|
document.querySelector('.themelist').style.filter = 'blur(5px)';
|
|
if (!document.querySelector('.dimmer')) {
|
|
let dimmer = document.createElement('div');
|
|
dimmer.classList.add('dimmer');
|
|
document.body.appendChild(dimmer);
|
|
}
|
|
}
|
|
};
|
|
link.onmouseenter = function (e) {
|
|
if (!IS_TOUCH_DEVICE) {
|
|
const t = this.href.split('theme=')[1];
|
|
setTheme(t, false);
|
|
}
|
|
};
|
|
link.onmouseleave = function (e) {
|
|
if (!IS_TOUCH_DEVICE) {
|
|
setTheme(null, false);
|
|
}
|
|
};
|
|
const container = document.createElement('li');
|
|
container.classList.add('theme-chooser-list-item');
|
|
const textContainer = document.createElement('span');
|
|
link.appendChild(container);
|
|
textContainer.innerText = t;
|
|
container.appendChild(textContainer);
|
|
list.appendChild(link);
|
|
});
|
|
wrapper.appendChild(list);
|
|
}
|
|
|
|
function getQueries() {
|
|
const query = window.location.search.substring(1);
|
|
const vars = query.split('&');
|
|
const queries = {};
|
|
vars.forEach(v => {
|
|
const pair = v.split('=');
|
|
if (pair.length > 1) {
|
|
queries[pair[0]] = decodeURIComponent(pair[1]);
|
|
} else {
|
|
queries[pair[0]] = null;
|
|
}
|
|
});
|
|
return queries;
|
|
}
|
|
function get(url) {
|
|
// Return a new promise.
|
|
return new Promise(function(resolve, reject) {
|
|
// Do the usual XHR stuff
|
|
let req = new XMLHttpRequest();
|
|
req.open('GET', url);
|
|
|
|
req.onload = function() {
|
|
// This is called even on 404 etc
|
|
// so check the status
|
|
if (req.status == 200) {
|
|
// Resolve the promise with the response text
|
|
resolve(req.response);
|
|
}
|
|
else {
|
|
// Otherwise reject with the status text
|
|
// which will hopefully be a meaningful error
|
|
reject(Error(req.statusText));
|
|
}
|
|
};
|
|
|
|
// Handle network errors
|
|
req.onerror = function() {
|
|
reject(Error('Network Error'));
|
|
};
|
|
|
|
// Make the request
|
|
req.send();
|
|
});
|
|
} |