177 lines
6.5 KiB
JavaScript
177 lines
6.5 KiB
JavaScript
/* eslint-disable no-bitwise, no-nested-ternary, no-mutable-exports, comma-dangle, strict */
|
|
|
|
((Drupal, drupalSettings, once) => {
|
|
Drupal.behaviors.ginAccent = {
|
|
attach: function attach(context) {
|
|
once('ginAccent', 'body', context).forEach(() => {
|
|
// Check Darkmode.
|
|
Drupal.ginAccent.checkDarkmode();
|
|
|
|
// Set accent color.
|
|
Drupal.ginAccent.setAccentColor();
|
|
|
|
// Set focus color.
|
|
Drupal.ginAccent.setFocusColor();
|
|
});
|
|
},
|
|
};
|
|
|
|
Drupal.ginAccent = {
|
|
setAccentColor: function setAccentColor(preset = null, color = null) {
|
|
const accentColorPreset = preset != null ? preset : drupalSettings.gin.preset_accent_color;
|
|
document.body.setAttribute('data-gin-accent', accentColorPreset);
|
|
|
|
if (accentColorPreset === 'custom') {
|
|
this.setCustomAccentColor(color);
|
|
}
|
|
},
|
|
|
|
setCustomAccentColor: function setCustomAccentColor(color = null, element = document.body) {
|
|
// If custom color is set, generate colors through JS.
|
|
const accentColor = color != null ? color : drupalSettings.gin.accent_color;
|
|
if (accentColor) {
|
|
this.clearAccentColor(element);
|
|
|
|
const strippedAccentColor = accentColor.replace('#', '');
|
|
const darkAccentColor = this.mixColor('ffffff', strippedAccentColor, 65).replace('#', '');
|
|
const style = document.createElement('style');
|
|
style.className = 'gin-custom-colors';
|
|
style.innerHTML = `
|
|
[data-gin-accent="custom"] {\n\
|
|
--gin-color-primary-rgb: ${this.hexToRgb(accentColor)};\n\
|
|
--gin-color-primary-hover: ${this.shadeColor(accentColor, -10)};\n\
|
|
--gin-color-primary-active: ${this.shadeColor(accentColor, -15)};\n\
|
|
--gin-bg-app-rgb: ${this.hexToRgb(this.mixColor('ffffff', strippedAccentColor, 97))};\n\
|
|
--gin-bg-header: ${this.mixColor('ffffff', strippedAccentColor, 85)};\n\
|
|
--gin-color-sticky-rgb: ${this.hexToRgb(this.mixColor('ffffff', strippedAccentColor, 92))};\n\
|
|
}\n\
|
|
.gin--dark-mode[data-gin-accent="custom"],\n\
|
|
.gin--dark-mode [data-gin-accent="custom"] {\n\
|
|
--gin-color-primary-rgb: ${this.hexToRgb(darkAccentColor)};\n\
|
|
--gin-color-primary-hover: ${this.mixColor('ffffff', strippedAccentColor, 55)};\n\
|
|
--gin-color-primary-active: ${this.mixColor('ffffff', strippedAccentColor, 50)};\n\
|
|
--gin-bg-header: ${this.mixColor('2A2A2D', darkAccentColor, 88)};\n\
|
|
}\n\
|
|
`;
|
|
|
|
element.append(style);
|
|
}
|
|
},
|
|
|
|
clearAccentColor: (element = document.body) => {
|
|
if (element.querySelectorAll('.gin-custom-colors').length > 0) {
|
|
const removeElement = element.querySelector('.gin-custom-colors');
|
|
removeElement.parentNode.removeChild(removeElement);
|
|
}
|
|
},
|
|
|
|
setFocusColor: function setFocusColor(preset = null, color = null) {
|
|
const focusColorPreset = preset != null ? preset : drupalSettings.gin.preset_focus_color;
|
|
document.body.setAttribute('data-gin-focus', focusColorPreset);
|
|
|
|
if (focusColorPreset === 'custom') {
|
|
this.setCustomFocusColor(color);
|
|
}
|
|
},
|
|
|
|
setCustomFocusColor: function setCustomFocusColor(color = null, element = document.body) {
|
|
const accentColor = color != null ? color : drupalSettings.gin.focus_color;
|
|
|
|
// Set preset color.
|
|
if (accentColor) {
|
|
this.clearFocusColor(element);
|
|
|
|
const strippedAccentColor = accentColor.replace('#', '');
|
|
const darkAccentColor = this.mixColor('ffffff', strippedAccentColor, 65);
|
|
const style = document.createElement('style');
|
|
style.className = 'gin-custom-focus';
|
|
style.innerHTML = `
|
|
[data-gin-focus="custom"] {\n\
|
|
--gin-color-focus: ${accentColor};\n\
|
|
}\n\
|
|
.gin--dark-mode[data-gin-focus="custom"],\n\
|
|
.gin--dark-mode [data-gin-focus="custom"] {\n\
|
|
--gin-color-focus: ${darkAccentColor};\n\
|
|
}`;
|
|
|
|
element.append(style);
|
|
}
|
|
},
|
|
|
|
clearFocusColor: (element = document.body) => {
|
|
if (element.querySelectorAll('.gin-custom-focus').length > 0) {
|
|
const removeElement = element.querySelector('.gin-custom-focus');
|
|
removeElement.parentNode.removeChild(removeElement);
|
|
}
|
|
},
|
|
|
|
checkDarkmode: () => {
|
|
const darkmodeClass = drupalSettings.gin.darkmode_class;
|
|
|
|
// Change to Darkmode.
|
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
|
|
if (e.matches && localStorage.getItem('Drupal.gin.darkmode') === 'auto') {
|
|
document.querySelector('html').classList.add(darkmodeClass);
|
|
}
|
|
});
|
|
|
|
// Change to Lightmode.
|
|
window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', e => {
|
|
if (e.matches && localStorage.getItem('Drupal.gin.darkmode') === 'auto') {
|
|
document.querySelector('html').classList.remove(darkmodeClass);
|
|
}
|
|
});
|
|
},
|
|
|
|
// https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
|
|
hexToRgb: (hex) => {
|
|
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
|
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
|
|
return r + r + g + g + b + b;
|
|
});
|
|
|
|
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
return result ? `${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}` : null;
|
|
},
|
|
|
|
// https://gist.github.com/jedfoster/7939513
|
|
mixColor: (color_1, color_2, weight) => {
|
|
function d2h(d) { return d.toString(16); }
|
|
function h2d(h) { return parseInt(h, 16); }
|
|
|
|
weight = (typeof(weight) !== 'undefined') ? weight : 50;
|
|
|
|
var color = "#";
|
|
|
|
for (var i = 0; i <= 5; i += 2) {
|
|
var v1 = h2d(color_1.substr(i, 2)),
|
|
v2 = h2d(color_2.substr(i, 2)),
|
|
val = d2h(Math.floor(v2 + (v1 - v2) * (weight / 100.0)));
|
|
|
|
while(val.length < 2) { val = '0' + val; }
|
|
color += val;
|
|
}
|
|
|
|
return color;
|
|
},
|
|
|
|
shadeColor: (color, percent) => {
|
|
const num = parseInt(color.replace('#', ''), 16);
|
|
const amt = Math.round(2.55 * percent);
|
|
const R = (num >> 16) + amt;
|
|
const B = ((num >> 8) & 0x00ff) + amt;
|
|
const G = (num & 0x0000ff) + amt;
|
|
|
|
return `#${(
|
|
0x1000000
|
|
+ (R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000
|
|
+ (B < 255 ? (B < 1 ? 0 : B) : 255) * 0x100
|
|
+ (G < 255 ? (G < 1 ? 0 : G) : 255)
|
|
)
|
|
.toString(16)
|
|
.slice(1)}`;
|
|
},
|
|
|
|
};
|
|
})(Drupal, drupalSettings, once);
|