2020-06-09 04:02:03 +02:00
|
|
|
class ThemeEngine {
|
2020-06-09 12:13:12 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
constructor() {
|
|
|
|
this._localStorage = window.localStorage;
|
|
|
|
|
|
|
|
this._backgroundTextBox = document.querySelector('#backgroundSet');
|
|
|
|
this._backgroundOpacityTextBox = document.querySelector('#backgroundOpacitySet');
|
|
|
|
this._foregroundTextBox = document.querySelector('#foregroundSet');
|
|
|
|
this._foregroundOpacityTextBox = document.querySelector('#foregroundOpacitySet');
|
|
|
|
|
|
|
|
this._blurTextBox = document.querySelector('#blurSet');
|
2020-06-10 10:35:39 +02:00
|
|
|
this._animSpeedTextBox = document.querySelector('#animSpeedSet');
|
2020-06-09 04:02:03 +02:00
|
|
|
this._applyTheme = document.querySelector('#themeEngineAsDefault');
|
|
|
|
this._resetTheme = document.querySelector('#themeEngineReset');
|
|
|
|
|
|
|
|
this._init();
|
|
|
|
}
|
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Get CSS variable value
|
|
|
|
_getCSSProperty = variable => {
|
|
|
|
let cssValue = window.getComputedStyle(document.documentElement).getPropertyValue(String(variable));
|
|
|
|
|
|
|
|
// Remove whitespaces
|
|
|
|
// I don't know why getProperty value adds a whitespace(i'm really noob at js)
|
|
|
|
cssValue = cssValue.replace(/ /g,'');
|
|
|
|
|
|
|
|
return cssValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get localStorage item value
|
|
|
|
_getStorageItem = item => {
|
|
|
|
return this._localStorage.getItem(String(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set localStorage item value
|
|
|
|
_setStorageItem = (item, value) => {
|
|
|
|
this._localStorage.setItem(
|
|
|
|
String(item),
|
|
|
|
this._getCSSProperty(String(value))
|
|
|
|
);
|
2020-06-04 05:33:17 +02:00
|
|
|
}
|
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Set/Save original CSS Value, useful when reseting theme engine
|
|
|
|
_saveOriginalDefaultCSS = () => {
|
|
|
|
|
|
|
|
// Check original default CSS values
|
|
|
|
const defaultValues = {
|
|
|
|
'origBaseBG': {
|
|
|
|
value: this._getStorageItem('origBaseBG'),
|
|
|
|
cssVariable: '--base-bg'
|
|
|
|
},
|
|
|
|
'origBaseColor': {
|
|
|
|
value: this._getStorageItem('origBaseColor'),
|
|
|
|
cssVariable: '--base-color'
|
|
|
|
},
|
|
|
|
'origBlurStrength': {
|
|
|
|
value: this._getStorageItem('origBlurStrength'),
|
|
|
|
cssVariable: '--blur-strength'
|
|
|
|
},
|
|
|
|
'origAnimSpeed': {
|
|
|
|
value: this._getStorageItem('origAnimSpeed'),
|
|
|
|
cssVariable: '--transition-speed'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// If original css variable has has no value, set it
|
|
|
|
Object.keys(defaultValues)
|
|
|
|
.forEach(item => {
|
|
|
|
const itemName = item;
|
|
|
|
const itemValue = defaultValues[String(item)].value;
|
|
|
|
|
|
|
|
// If value is null, set
|
|
|
|
if (!itemValue) {
|
|
|
|
this._setStorageItem(itemName, defaultValues[String(item)].cssVariable);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate color
|
2020-06-09 04:02:03 +02:00
|
|
|
_checkColorValidity = colorStr => {
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
// Check if RGBA - (#RRGGBBAA)
|
2020-06-17 13:03:27 +02:00
|
|
|
const colorRGBA = /^#[0-9a-fA-F]{8}$/i.test(colorStr);
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
// If not RGBA
|
|
|
|
if (!colorRGBA) {
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
// If RGB - (#RRGGBB)
|
2020-06-17 13:03:27 +02:00
|
|
|
if (/^#[0-9a-fA-F]{3}$/i.test(colorStr)) {
|
2020-06-09 04:02:03 +02:00
|
|
|
|
|
|
|
// Add completely opaque alpha
|
|
|
|
return colorStr + 'FF';
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
// If three-charactered HEX color - (#RGB)
|
2020-06-17 13:03:27 +02:00
|
|
|
// I feel that this is never used lol
|
|
|
|
} else if (/^#[0-9a-fA-F]{3}$/i.test(colorStr)) {
|
2020-06-09 04:02:03 +02:00
|
|
|
|
|
|
|
// Convert it to RRGGBB
|
|
|
|
return colorStr.replace(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/, '#$1$1$2$2$3$3');
|
|
|
|
|
|
|
|
// If three-charactered HEX Color(#RGB) with AA - (#RGBAA)
|
2020-06-17 13:03:27 +02:00
|
|
|
} else if (/^#[0-9a-fA-F]{3}[0-9a-fA-F]{2}$/i.test(colorStr)) {
|
2020-06-09 04:02:03 +02:00
|
|
|
|
|
|
|
const bg = colorStr.slice(0, -2);
|
|
|
|
const op = colorStr.slice(-2);
|
|
|
|
|
|
|
|
return bg.replace(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/, '#$1$1$2$2$3$3') + op;
|
|
|
|
|
|
|
|
} else {
|
2020-06-17 13:03:27 +02:00
|
|
|
return null;
|
2020-06-09 04:02:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// It's RGBA and a valid color so just return it
|
|
|
|
return colorStr;
|
|
|
|
}
|
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Validate color
|
|
|
|
_checkBlurValidity = blurStr => {
|
|
|
|
|
|
|
|
let blurStrength = parseInt(blurStr, 10);
|
|
|
|
|
|
|
|
if (String(blurStrength) === 'NaN') {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
return String(blurStrength) + 'px';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_checkAnimSpeedValidity = speedStr => {
|
|
|
|
|
|
|
|
let animSpeed = parseInt(speedStr, 10);
|
|
|
|
let timeSuffix;
|
|
|
|
|
|
|
|
if (speedStr.endsWith('ms')) {
|
|
|
|
timeSuffix = 'ms';
|
|
|
|
} else if (speedStr.endsWith('s')) {
|
|
|
|
timeSuffix = 's';
|
|
|
|
}
|
|
|
|
|
|
|
|
if(String(animSpeed) === 'NaN') {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
if (timeSuffix) {
|
|
|
|
return String(animSpeed) + timeSuffix;
|
|
|
|
} else {
|
|
|
|
return String(animSpeed) + 'ms';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update textboxes value
|
2020-06-10 10:35:39 +02:00
|
|
|
_updateTextBoxValues = (bgColor, bgOpacity, fgColor, fgOpacity, blurPower, animSpeed) => {
|
2020-06-09 04:02:03 +02:00
|
|
|
|
|
|
|
// Set placeholders
|
|
|
|
this._backgroundTextBox.value = '';
|
|
|
|
this._backgroundTextBox.placeholder = bgColor;
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
this._backgroundOpacityTextBox.value = '';
|
|
|
|
this._backgroundOpacityTextBox.placeholder = bgOpacity;
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
this._foregroundTextBox.value = '';
|
|
|
|
this._foregroundTextBox.placeholder = fgColor;
|
|
|
|
this._foregroundOpacityTextBox.value = '';
|
|
|
|
this._foregroundOpacityTextBox.placeholder = fgOpacity;
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
this._blurTextBox.value = '';
|
|
|
|
this._blurTextBox.placeholder = blurPower;
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-10 10:35:39 +02:00
|
|
|
this._animSpeedTextBox.value = '';
|
|
|
|
this._animSpeedTextBox.placeholder = animSpeed;
|
2020-06-09 04:02:03 +02:00
|
|
|
}
|
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Get/Update current css value
|
|
|
|
_getCurrentCSSValues = () => {
|
|
|
|
|
|
|
|
// Retrieve current css values
|
|
|
|
let currentValues = {
|
|
|
|
'baseBG': {
|
|
|
|
value: this._getStorageItem('baseBG'),
|
|
|
|
origVariable: 'origBaseBG'
|
|
|
|
},
|
|
|
|
'baseColor': {
|
|
|
|
value: this._getStorageItem('baseColor'),
|
|
|
|
origVariable: 'origBaseColor'
|
|
|
|
},
|
|
|
|
'blurStrength': {
|
|
|
|
value: this._getStorageItem('blurStrength'),
|
|
|
|
origVariable: 'origBlurStrength'
|
|
|
|
},
|
|
|
|
'animSpeed': {
|
|
|
|
value: this._getStorageItem('animSpeed'),
|
|
|
|
origVariable: 'origAnimSpeed'
|
|
|
|
}
|
|
|
|
};
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// If current css variable has has no value, set it
|
|
|
|
Object.keys(currentValues)
|
|
|
|
.forEach(key => {
|
|
|
|
const cssVar = key;
|
|
|
|
const cssValue = currentValues[String(cssVar)].value;
|
2020-06-09 04:02:03 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// If value is null, set
|
|
|
|
if (!cssValue) {
|
|
|
|
currentValues[String(cssVar)].value = this._getStorageItem(currentValues[String(cssVar)].origVariable);
|
|
|
|
}
|
|
|
|
});
|
2020-06-09 04:02:03 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
return currentValues;
|
|
|
|
}
|
2020-06-10 10:35:39 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Process css variables to update input fields
|
|
|
|
_processCurrentCSSValues = () => {
|
2020-06-09 04:02:03 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Get current css values
|
|
|
|
const themeObj = this._getCurrentCSSValues();
|
2020-06-09 04:02:03 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
const baseBG = themeObj['baseBG'].value;
|
2020-06-09 04:02:03 +02:00
|
|
|
const backgroundColor = baseBG.slice(0, -2);
|
|
|
|
const backgroundOpacity = baseBG.slice(-2);
|
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
const baseColor = themeObj['baseColor'].value;
|
2020-06-09 04:02:03 +02:00
|
|
|
const foregroundColor = baseColor.slice(0, -2);
|
|
|
|
const foregroundOpacity = baseColor.slice(-2);
|
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
const blurStrength = themeObj['blurStrength'].value;
|
|
|
|
const animSpeed = themeObj['animSpeed'].value;
|
|
|
|
|
|
|
|
// Pass value to update textboxes
|
2020-06-09 04:02:03 +02:00
|
|
|
this._updateTextBoxValues(
|
|
|
|
backgroundColor,
|
|
|
|
backgroundOpacity,
|
|
|
|
foregroundColor,
|
|
|
|
foregroundOpacity,
|
2020-06-10 10:35:39 +02:00
|
|
|
blurStrength,
|
|
|
|
animSpeed
|
2020-06-16 14:07:54 +02:00
|
|
|
);
|
2020-06-04 05:33:17 +02:00
|
|
|
}
|
2020-06-17 13:03:27 +02:00
|
|
|
|
|
|
|
// Get input fields values
|
|
|
|
_getInputFieldsValue = () => {
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Get value from the input fields
|
|
|
|
const backgroundColor = (this._backgroundTextBox.value || this._backgroundTextBox.placeholder) +
|
2020-06-09 04:02:03 +02:00
|
|
|
(this._backgroundOpacityTextBox.value || this._backgroundOpacityTextBox.placeholder);
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
const foregroundColor = (this._foregroundTextBox.value || this._foregroundTextBox.placeholder) +
|
2020-06-09 04:02:03 +02:00
|
|
|
(this._foregroundOpacityTextBox.value || this._foregroundOpacityTextBox.placeholder);
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
const blurStrength = (this._blurTextBox.value || this._blurTextBox.placeholder);
|
|
|
|
const transitionSpeed = (this._animSpeedTextBox.value || this._animSpeedTextBox.placeholder);
|
2020-06-10 10:35:39 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
const inputFieldValues = {
|
|
|
|
'background': backgroundColor,
|
|
|
|
'foreground': foregroundColor,
|
|
|
|
'blurPower': blurStrength,
|
|
|
|
'animSpeed': transitionSpeed
|
|
|
|
};
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
return inputFieldValues;
|
|
|
|
}
|
|
|
|
|
|
|
|
_updateCSSColors = (bgColor, fgColor, blurPower, animSpeed) => {
|
2020-06-09 04:02:03 +02:00
|
|
|
// Change CSS colors
|
|
|
|
document.documentElement.style.setProperty('--base-bg', bgColor);
|
|
|
|
document.documentElement.style.setProperty('--base-color', fgColor);
|
|
|
|
document.documentElement.style.setProperty('--blur-strength', blurPower);
|
2020-06-10 10:35:39 +02:00
|
|
|
document.documentElement.style.setProperty('--transition-speed', animSpeed);
|
2020-06-17 13:03:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update css variables and set theme
|
|
|
|
_updateCSSVariables = () => {
|
|
|
|
|
|
|
|
const inputValueObj = this._getInputFieldsValue();
|
|
|
|
|
|
|
|
const bgColorRaw = inputValueObj['background'];
|
|
|
|
const fgColorRaw = inputValueObj['foreground'];
|
|
|
|
const blurPowerRaw = inputValueObj['blurPower'];
|
|
|
|
const animSpeedRaw = inputValueObj['animSpeed'];
|
|
|
|
|
|
|
|
// Colors data obj
|
|
|
|
let validatedColorValues = {
|
|
|
|
'bgColor': {
|
|
|
|
value: this._checkColorValidity(String(bgColorRaw)),
|
|
|
|
fallbackVar: 'baseBG',
|
|
|
|
fallbackOrigVar: 'origBaseBG'
|
|
|
|
},
|
|
|
|
'fgColor': {
|
|
|
|
value: this._checkColorValidity(String(fgColorRaw)),
|
|
|
|
fallbackVar: 'baseColor',
|
|
|
|
fallbackOrigVar: 'origBaseColor'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Check color validity
|
|
|
|
Object.keys(validatedColorValues)
|
|
|
|
.forEach(key => {
|
|
|
|
|
|
|
|
let colorVar = key;
|
|
|
|
let colorValue = validatedColorValues[String(key)].value;
|
|
|
|
|
|
|
|
if (!colorValue) {
|
|
|
|
validatedColorValues[String(key)].value =
|
|
|
|
this._getStorageItem(validatedColorValues[String(key)].fallbackVar) ||
|
|
|
|
this._getStorageItem(validatedColorValues[String(key)].fallbackOrigVar);
|
|
|
|
|
|
|
|
// console.log('Invalid Color! Will use previous one...')
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Set valid color to variables
|
|
|
|
const bgColor = validatedColorValues['bgColor'].value;
|
|
|
|
const fgColor = validatedColorValues['fgColor'].value;
|
|
|
|
|
|
|
|
// Blur data obj
|
|
|
|
let validatedBlurValue = {
|
|
|
|
'blurStrength': {
|
|
|
|
value: this._checkBlurValidity(blurPowerRaw),
|
|
|
|
fallbackVar: 'blurStrength',
|
|
|
|
fallbackOrigVar: 'origBlurStrength'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Validate and set blur strength
|
|
|
|
const blurPower = this._checkBlurValidity(blurPowerRaw) ||
|
|
|
|
this._getStorageItem(validatedBlurValue['blurStrength'].fallbackVar) ||
|
|
|
|
this._getStorageItem(validatedBlurValue['blurStrength'].fallbackOrigVar);
|
|
|
|
|
|
|
|
// Anim speed data obj
|
|
|
|
let validatedSpeedValue = {
|
|
|
|
'transitionSpeed' : {
|
|
|
|
value: this._checkBlurValidity(animSpeedRaw),
|
|
|
|
fallbackVar: 'animSpeed',
|
|
|
|
fallbackOrigVar: 'origAnimSpeed'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Valudate and set anim speed
|
|
|
|
const animSpeed = this._checkAnimSpeedValidity(animSpeedRaw) ||
|
|
|
|
this._getStorageItem(validatedSpeedValue['transitionSpeed'].fallbackVar) ||
|
|
|
|
this._getStorageItem(validatedSpeedValue['transitionSpeed'].fallbackOrigVar);
|
|
|
|
|
|
|
|
// console.log('bg: '+bgColor+'\nfg: '+fgColor+'\nblur: '+blurPower+'\nspeed: '+animSpeed);
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
// Save custom color
|
|
|
|
this._localStorage.setItem('baseBG', bgColor);
|
|
|
|
this._localStorage.setItem('baseColor', fgColor);
|
|
|
|
this._localStorage.setItem('blurStrength', blurPower);
|
2020-06-10 10:35:39 +02:00
|
|
|
this._localStorage.setItem('animSpeed', animSpeed);
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Update css colors
|
|
|
|
this._updateCSSColors(bgColor, fgColor, blurPower, animSpeed);
|
|
|
|
this._processCurrentCSSValues();
|
|
|
|
}
|
|
|
|
|
|
|
|
_reApplyTheme = () => {
|
|
|
|
this._updateCSSColors(
|
|
|
|
this._getStorageItem('baseBG') || this._getStorageItem('origBaseBG'),
|
|
|
|
this._getStorageItem('baseColor') || this._getStorageItem('origBaseColor'),
|
|
|
|
this._getStorageItem('blurStrength') || this._getStorageItem('origBlurStrength'),
|
|
|
|
this._getStorageItem('animSpeed') || this._getStorageItem('origAnimSpeed')
|
|
|
|
);
|
|
|
|
|
|
|
|
this._processCurrentCSSValues();
|
2020-06-09 04:02:03 +02:00
|
|
|
}
|
2020-06-04 05:33:17 +02:00
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
_applyOnClickEvent = e => {
|
2020-06-17 13:03:27 +02:00
|
|
|
this._updateCSSVariables();
|
2020-06-04 05:33:17 +02:00
|
|
|
}
|
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
_registerApplyOnClickEvent = () => {
|
|
|
|
this._applyTheme.onclick = this._applyOnClickEvent;
|
2020-06-04 05:33:17 +02:00
|
|
|
}
|
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
_resetOnClickEvent = e => {
|
|
|
|
this._localStorage.removeItem('baseBG');
|
|
|
|
this._localStorage.removeItem('baseColor');
|
|
|
|
this._localStorage.removeItem('blurStrength');
|
2020-06-10 10:35:39 +02:00
|
|
|
this._localStorage.removeItem('animSpeed');
|
2020-06-09 04:02:03 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
this._saveOriginalDefaultCSS();
|
|
|
|
this._reApplyTheme();
|
2020-06-09 04:02:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
_registerResetOnClickEvent = () => {
|
|
|
|
this._resetTheme.onclick = this._resetOnClickEvent;
|
|
|
|
}
|
|
|
|
|
|
|
|
_init = () => {
|
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Save original css variables value
|
|
|
|
this._saveOriginalDefaultCSS();
|
2020-06-09 04:02:03 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Process theme
|
|
|
|
this._reApplyTheme();
|
2020-06-09 04:02:03 +02:00
|
|
|
|
2020-06-17 13:03:27 +02:00
|
|
|
// Register events
|
2020-06-09 04:02:03 +02:00
|
|
|
this._registerApplyOnClickEvent();
|
|
|
|
this._registerResetOnClickEvent();
|
2020-06-04 05:33:17 +02:00
|
|
|
}
|
|
|
|
|
2020-06-09 04:02:03 +02:00
|
|
|
}
|