mirror of
https://github.com/McShelby/hugo-theme-relearn.git
synced 2025-01-18 10:50:24 +00:00
theme: fix flash of non-default variant, part II #757
adapt the variant generator to previous changes; interestingly, the new mechanism caused the variant generator to be greatly simplified; something, I didn't expect beforehand
This commit is contained in:
parent
0505b36141
commit
deee4ae6b7
22 changed files with 336 additions and 351 deletions
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* blue */
|
||||
--MAIN-TEXT-color: rgba(50, 50, 50, 1); /* Color of text by default */
|
||||
--MAIN-TITLES-TEXT-color: rgba(94, 94, 94, 1); /* Color of titles h2-h3-h4-h5-h6 */
|
||||
--MAIN-TITLES-H1-TEXT-color: rgba(34, 34, 34, 1); /* text color of h1 titles */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* green */
|
||||
--MAIN-TEXT-color: rgba(50, 50, 50, 1); /* Color of text by default */
|
||||
--MAIN-TITLES-TEXT-color: rgba(94, 94, 94, 1); /* Color of titles h2-h3-h4-h5-h6 */
|
||||
--MAIN-TITLES-H1-TEXT-color: rgba(34, 34, 34, 1); /* text color of h1 titles */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* learn */
|
||||
--MAIN-TEXT-color: rgba(50, 50, 50, 1); /* Color of text by default */
|
||||
--MAIN-TITLES-TEXT-color: rgba(94, 94, 94, 1); /* Color of titles h2-h3-h4-h5-h6 */
|
||||
--MAIN-TITLES-H1-TEXT-color: rgba(34, 34, 34, 1); /* text color of h1 titles */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* neon */
|
||||
--PRIMARY-color: rgba(243, 0, 178, 1); /* brand primary color */
|
||||
--SECONDARY-color: rgb(50, 189, 243, 1); /* brand secondary color */
|
||||
--ACCENT-color: rgba(255, 255, 0, 1); /* brand accent color, used for search highlights */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* red */
|
||||
--MAIN-TEXT-color: rgba(50, 50, 50, 1); /* Color of text by default */
|
||||
--MAIN-TITLES-TEXT-color: rgba(94, 94, 94, 1); /* Color of titles h2-h3-h4-h5-h6 */
|
||||
--MAIN-TITLES-H1-TEXT-color: rgba(34, 34, 34, 1); /* text color of h1 titles */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* relearn-bright */
|
||||
--PRIMARY-color: rgba(131, 201, 50, 1); /* brand primary color */
|
||||
--SECONDARY-color: rgba(99, 128, 208, 1); /* brand secondary color */
|
||||
--ACCENT-color: rgb(255, 102, 78, 1); /* brand accent color, used for search highlights */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* relearn-dark */
|
||||
--PRIMARY-color: rgba(125, 201, 3, 1); /* brand primary color */
|
||||
--SECONDARY-color: rgba(108, 140, 227, 1); /* brand secondary color */
|
||||
--ACCENT-color: rgb(255, 102, 78, 1); /* brand accent color, used for search highlights */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* relearn-light */
|
||||
--PRIMARY-color: rgba(125, 201, 3, 1); /* brand primary color */
|
||||
--SECONDARY-color: rgba(72, 106, 201, 1); /* brand secondary color */
|
||||
--ACCENT-color: rgb(255, 102, 78); /* brand accent color, used for search highlights */
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* zen-dark */
|
||||
--PRIMARY-color: rgba(47, 129, 235, 1); /* brand primary color */
|
||||
--SECONDARY-color: rgba(47, 129, 235, 1); /* brand secondary color */
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
:root {
|
||||
/* zen-light */
|
||||
--PRIMARY-color: rgba(26, 115, 232, 1); /* brand primary color */
|
||||
--SECONDARY-color: rgba(26, 115, 232, 1); /* brand secondary color */
|
||||
|
||||
|
|
|
@ -246,3 +246,10 @@ summaryLength = 10
|
|||
siteparam.test.text = 'A **nested** option <b>with</b> formatting'
|
||||
# Extension to the image effects only for the docs.
|
||||
imageEffects.bg-white = true
|
||||
# This is for support of the variantgenerator in the exampleSite, you don't need this!
|
||||
variantgenerator.force = true
|
||||
|
||||
[params.relearn.dependencies]
|
||||
# This is for support of the variantgenerator in the exampleSite, you don't need this!
|
||||
[params.relearn.dependencies.variantgenerator]
|
||||
name = 'VariantGenerator'
|
||||
|
|
|
@ -80,7 +80,7 @@ themeVariant = [
|
|||
# If set to `true`, further theme asset files besides the generated HTML files
|
||||
# will be minified during build. If no value is set, the theme will avoid
|
||||
# minification if you have started with `hugo server` and otherwise will minify.
|
||||
minify = true
|
||||
minify = ""
|
||||
|
||||
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
# General
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
+++
|
||||
categories = ["tutorial"]
|
||||
description = "An interactive tool to generate color variant stylesheets"
|
||||
mermaid.force = true
|
||||
options = ["themeVariant"]
|
||||
title = "Stylesheet Generator"
|
||||
weight = 4
|
||||
|
@ -27,14 +26,4 @@ Once you are satisfied, you can download the new variants file and copy it into
|
|||
See the docs for [further configuration options](configuration/branding/colors).
|
||||
{{% /expand %}}
|
||||
|
||||
{{% button style="secondary" icon="download" href="javascript:window.variants&&variants.getStylesheet();this.blur();" %}}Download variant{{% /button %}}
|
||||
{{% button style="warning" icon="trash" href="javascript:window.variants&&variants.resetVariant();this.blur();" %}}Reset variant{{% /button %}}
|
||||
|
||||
<div id="R-vargenerator" class="mermaid zoomable" style="background-color: var(--INTERNAL-MAIN-TEXT-color);">Graph</div>
|
||||
|
||||
{{% button style="secondary" icon="download" href="javascript:window.variants&&variants.getStylesheet();this.blur();" %}}Download variant{{% /button %}}
|
||||
{{% button style="warning" icon="trash" href="javascript:window.variants&&variants.resetVariant();this.blur();" %}}Reset variant{{% /button %}}
|
||||
|
||||
<script>
|
||||
window.variants && variants.generator( '#R-vargenerator' );
|
||||
</script>
|
||||
{{% variantgenerator %}}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
+++
|
||||
categories = ["tutorial"]
|
||||
description = "An interactive tool to generate color variant stylesheets"
|
||||
mermaid.force = true
|
||||
options = ["themeVariant"]
|
||||
title = "Stylesheet Generrrat'r"
|
||||
weight = 4
|
||||
|
|
|
@ -16,6 +16,12 @@ weight = -2
|
|||
|
||||
Due to these changes, `expand` and `notice` with `style=transparent` will now generate slightly different margins.
|
||||
|
||||
- {{% badge style="note" title=" " %}}Change{{% /badge %}} This release fixes a bug, where the selection of a non-default variant may caused the page to flicker on load.
|
||||
|
||||
To achieve this, generation and handling of the theme variant stylesheets and the variant generator were completely rewritten. There are no changes required by you.
|
||||
|
||||
Anyways, please note that now the [variant generator](configuration/branding/generator) is not included in the theme release anymore but is only available in the exampleSite docs. As a sideeffect, less JavaScript will be loaded on your site.
|
||||
|
||||
### New
|
||||
|
||||
- {{% badge style="info" icon="plus-circle" title=" " %}}New{{% /badge %}} This release fixes a long standing issue, where loading a page with a non-default variant may caused screen flashing.
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{{- $page := .page }}
|
||||
{{- $location := .location }}
|
||||
{{- if eq $location "header" }}
|
||||
{{- with $page }}
|
||||
{{- $assetBusting := partialCached "assetbusting.gotmpl" . }}
|
||||
<script src="{{"js/variant.js" | relURL}}{{ $assetBusting }}"></script>
|
||||
{{- end }}
|
||||
{{- end }}
|
45
exampleSite/layouts/shortcodes/variantgenerator.html
Normal file
45
exampleSite/layouts/shortcodes/variantgenerator.html
Normal file
|
@ -0,0 +1,45 @@
|
|||
{{ partial "shortcodes/notice.html" (dict
|
||||
"page" .Page
|
||||
"style" "note"
|
||||
"content" "The <code>CODE-theme</code> parameter can be changed in the generator but the change will not be reflected dynamically in the page preview."
|
||||
)}}
|
||||
{{ partial "shortcodes/button.html" (dict
|
||||
"page" .Page
|
||||
"href" "javascript:window.variants&&variants.getStylesheet();this.blur();"
|
||||
"style" "secondary"
|
||||
"icon" "download"
|
||||
"content" "Download variant"
|
||||
)}}
|
||||
{{ partial "shortcodes/button.html" (dict
|
||||
"page" .Page
|
||||
"href" "javascript:window.variants&&variants.resetVariant();this.blur();"
|
||||
"style" "warning"
|
||||
"icon" "trash"
|
||||
"content" "Reset variant"
|
||||
)}}
|
||||
<div id="R-vargenerator" class="mermaid zoomable" style="background-color: var(--INTERNAL-MAIN-TEXT-color);">
|
||||
Graph
|
||||
</div>
|
||||
{{ partial "shortcodes/button.html" (dict
|
||||
"page" .Page
|
||||
"href" "javascript:window.variants&&variants.getStylesheet();this.blur();"
|
||||
"style" "secondary"
|
||||
"icon" "download"
|
||||
"content" "Download variant"
|
||||
)}}
|
||||
{{ partial "shortcodes/button.html" (dict
|
||||
"page" .Page
|
||||
"href" "javascript:window.variants&&variants.resetVariant();this.blur();"
|
||||
"style" "warning"
|
||||
"icon" "trash"
|
||||
"content" "Reset variant"
|
||||
)}}
|
||||
<script>
|
||||
window.variants && variants.generator( '#R-vargenerator' );
|
||||
</script>
|
||||
{{- /* the variant generator also requires Mermaid; so as there is no Mermaid
|
||||
shortcode involved here to create the graph, we have to take care
|
||||
to load it our self; the quickest way to do this is, to set the
|
||||
Mermaid dependency as well */}}
|
||||
{{- .Page.Store.Set "hasMermaid" true }}
|
||||
{{- .Page.Store.Set "hasVariantGenerator" true }}
|
|
@ -1,9 +1,9 @@
|
|||
{{- $page := . }}
|
||||
{{- $nonautothemevariants := slice }}
|
||||
{{- $formathtmlpre := ":root:not([data-r-output-format='print'])" }}
|
||||
{{- $formathtmlpre := ":root:not([data-r-output-format='print']):not([data-r-theme-variant='my-custom-variant'])" }}
|
||||
{{- $formathtml := "" }}
|
||||
{{- $minify := not hugo.IsServer }}
|
||||
{{- if isset site.Params "minify" }}
|
||||
{{- if and (isset site.Params "minify") (ne site.Params.minify "") }}
|
||||
{{- $minify = site.Params.minify }}
|
||||
{{- end }}
|
||||
|
||||
|
@ -30,6 +30,9 @@ Unification run:
|
|||
{{- if not (isset $themevariant "auto") }}
|
||||
{{- $nonautothemevariants = $nonautothemevariants | append $themevariant.identifier }}
|
||||
{{- end }}
|
||||
{{- if eq $themevariant.identifier "my-custom-variant" }}
|
||||
{{- errorf "\"theme-%s.css\": the variant identifier '%s' is reserved for the theme's variant generator, instead rename it to something different" "my-custom-variant" "my-custom-variant" }}
|
||||
{{- end }}
|
||||
{{- $themevariants = $themevariants | append $themevariant }}
|
||||
{{- end }}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<script>window.relearn.initVariant();</script>
|
||||
<script>window.relearn.markVariant();</script>
|
||||
</li>
|
||||
<li class="footerVisitedLinks{{if $showvisitedlinks}} showVisitedLinks{{end}}">
|
||||
<div class="padding menu-control">
|
||||
|
|
|
@ -11,12 +11,12 @@
|
|||
<link href="{{"css/perfect-scrollbar.min.css" | relURL}}{{ $assetBusting }}" rel="stylesheet">
|
||||
{{- $themevariants := partialCached "_relearn/themeVariants.gotmpl" . }}
|
||||
{{- $minify := not hugo.IsServer }}
|
||||
{{- if isset site.Params "minify" }}
|
||||
{{- if and (isset site.Params "minify") (ne site.Params.minify "") }}
|
||||
{{- $minify = site.Params.minify }}
|
||||
{{- end }}
|
||||
{{- $min := cond $minify ".min" "" }}
|
||||
<link href="{{(printf "css/theme%s.css" $min) | relURL}}{{ $assetBusting }}" rel="stylesheet">
|
||||
<link href="{{(printf "css/format-%s%s.css" $outputFormat $min) | relURL}}{{ $assetBusting }}" rel="stylesheet">
|
||||
<link href="{{(printf "css/format-%s%s.css" $outputFormat $min) | relURL}}{{ $assetBusting }}" rel="stylesheet" id="R-format-style">
|
||||
<script>
|
||||
window.relearn = window.relearn || {};
|
||||
window.relearn.relBasePath='{{ partial "_relearn/relBasePath.gotmpl" . | safeJS }}';
|
||||
|
@ -30,32 +30,34 @@
|
|||
{{- range $themevariants }}
|
||||
{{- $quotedthemevariants = $quotedthemevariants | append (printf "'%s'" .identifier) }}
|
||||
{{- end }}
|
||||
window.variants && variants.init( [ {{ delimit $quotedthemevariants ", " | safeJS }} ] );
|
||||
window.relearn.themevariants = [ {{ delimit $quotedthemevariants ", " | safeJS }} ];
|
||||
window.relearn.customvariantname = "my-custom-variant";
|
||||
window.relearn.changeVariant = function(variant) {
|
||||
var oldVariant = document.documentElement.dataset.rThemeVariant;
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + "/variant", variant);
|
||||
document.documentElement.dataset.rThemeVariant = variant;
|
||||
var old_variant = window.localStorage.getItem("R-theme-variant");
|
||||
if (old_variant != variant) {
|
||||
window.localStorage.setItem("R-theme-variant", variant);
|
||||
document.dispatchEvent( new CustomEvent('themeVariantLoaded', { detail: { variant: variant } }) );
|
||||
if (oldVariant != variant) {
|
||||
document.dispatchEvent( new CustomEvent('themeVariantLoaded', { detail: { variant, oldVariant } }) );
|
||||
}
|
||||
}
|
||||
window.relearn.markVariant = function() {
|
||||
var variant = window.localStorage.getItem(window.relearn.absBaseUri + "/variant");
|
||||
var select = document.querySelector("#R-select-variant");
|
||||
if (select) {
|
||||
select.value = variant;
|
||||
}
|
||||
}
|
||||
window.relearn.initVariant = function() {
|
||||
var variant = window.localStorage.getItem("R-theme-variant") ?? "";
|
||||
var el = document.querySelector("#R-select-variant");
|
||||
if (variant && el) {
|
||||
var options = Array.from(el.options);
|
||||
if( options.some(option => option.value == variant) ){
|
||||
el.value = variant;
|
||||
}
|
||||
else {
|
||||
variant = options[0]?.value ?? "";
|
||||
el.value = variant;
|
||||
window.localStorage.setItem("R-theme-variant", variant);
|
||||
}
|
||||
var variant = window.localStorage.getItem(window.relearn.absBaseUri + "/variant") ?? "";
|
||||
if( variant == window.relearn.customvariantname ){
|
||||
}else if( !variant || !window.relearn.themevariants.includes(variant) ){
|
||||
variant = window.relearn.themevariants[0];
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + "/variant", variant);
|
||||
}
|
||||
document.documentElement.dataset.rThemeVariant = variant;
|
||||
}
|
||||
window.relearn.initVariant();
|
||||
window.relearn.markVariant();
|
||||
{{ "// translations" | safeJS }}
|
||||
{{ printf "window.T_Copy_to_clipboard = `%s`;" (T `Copy-to-clipboard`) | safeJS }}
|
||||
{{ printf "window.T_Copied_to_clipboard = `%s`;" (T `Copied-to-clipboard`) | safeJS }}
|
||||
|
|
|
@ -1 +1 @@
|
|||
7.1.1+2c5ac2b60022b3ec8e9e275bfeb2d5ebc77d9bc0
|
||||
7.1.1+0505b36141f2a69dc36be8589c0678783cad98a9
|
|
@ -12,89 +12,47 @@ function ready(fn) {
|
|||
}
|
||||
|
||||
var variants = {
|
||||
variant: '',
|
||||
variants: [],
|
||||
customvariantname: 'my-custom-variant',
|
||||
variants: window.relearn.themevariants,
|
||||
customvariantname: window.relearn.customvariantname,
|
||||
isstylesheetloaded: true,
|
||||
|
||||
init: function (variants) {
|
||||
this.variants = variants;
|
||||
var variant = window.localStorage.getItem(window.relearn.absBaseUri + '/variant') || (this.variants.length ? this.variants[0] : '');
|
||||
this.changeVariant(variant);
|
||||
document.addEventListener(
|
||||
'readystatechange',
|
||||
function () {
|
||||
if (document.readyState == 'interactive') {
|
||||
this.markSelectedVariant();
|
||||
setup: function () {
|
||||
this.addCustomVariantStyles();
|
||||
|
||||
var customvariantstylesheet = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariantstylesheet');
|
||||
var customvariant = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariant');
|
||||
if (!customvariantstylesheet || !customvariant) {
|
||||
customvariantstylesheet = '';
|
||||
window.localStorage.removeItem(window.relearn.absBaseUri + '/customvariantstylesheet');
|
||||
customvariant = '';
|
||||
window.localStorage.removeItem(window.relearn.absBaseUri + '/customvariant');
|
||||
} else if (customvariant && !window.relearn.themevariants.includes(customvariant)) {
|
||||
// this can only happen on initial load, if a previously selected variant is not available anymore
|
||||
customvariant = window.relearn.themevariants[0];
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + '/customvariant', customvariant);
|
||||
}
|
||||
}.bind(this)
|
||||
);
|
||||
this.updateCustomVariantStyles(customvariantstylesheet);
|
||||
|
||||
this.init();
|
||||
ready(this.init.bind(this));
|
||||
},
|
||||
|
||||
getVariant: function () {
|
||||
return this.variant;
|
||||
},
|
||||
|
||||
setVariant: function (variant) {
|
||||
this.variant = variant;
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + '/variant', variant);
|
||||
},
|
||||
|
||||
isVariantLoaded: function () {
|
||||
return window.theme && this.isstylesheetloaded;
|
||||
},
|
||||
|
||||
markSelectedVariant: function () {
|
||||
var variant = this.getVariant();
|
||||
var select = document.querySelector('#R-select-variant');
|
||||
if (!select) {
|
||||
return;
|
||||
}
|
||||
init: function (variant, old_path) {
|
||||
this.addCustomVariantOption();
|
||||
if (variant && select.value != variant) {
|
||||
select.value = variant;
|
||||
}
|
||||
var interval_id = setInterval(
|
||||
function () {
|
||||
if (this.isVariantLoaded()) {
|
||||
clearInterval(interval_id);
|
||||
updateTheme({ variant: variant });
|
||||
}
|
||||
}.bind(this),
|
||||
25
|
||||
);
|
||||
// remove selection, because if some uses an arrow navigation"
|
||||
// by pressing the left or right cursor key, we will automatically
|
||||
// select a different style
|
||||
if (document.activeElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
},
|
||||
|
||||
generateVariantPath: function (variant, old_path) {
|
||||
var new_path = old_path.replace(new RegExp(`^(.*\/theme-).*?(\.css.*)$`), '$1' + variant + '$2');
|
||||
return new_path;
|
||||
window.relearn.markVariant();
|
||||
window.relearn.changeVariant(window.localStorage.getItem(window.relearn.absBaseUri + '/variant'));
|
||||
},
|
||||
|
||||
addCustomVariantOption: function () {
|
||||
var variantbase = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariantbase');
|
||||
if (this.variants.indexOf(variantbase) < 0) {
|
||||
variantbase = '';
|
||||
}
|
||||
if (!window.localStorage.getItem(window.relearn.absBaseUri + '/customvariant')) {
|
||||
variantbase = '';
|
||||
}
|
||||
if (!variantbase) {
|
||||
return;
|
||||
}
|
||||
var customvariant = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariant');
|
||||
var select = document.querySelector('#R-select-variant');
|
||||
if (!select) {
|
||||
if (!customvariant || !select) {
|
||||
return;
|
||||
}
|
||||
var option = document.querySelector('#' + this.customvariantname);
|
||||
var option = document.querySelector('#R-select-variant-' + this.customvariantname);
|
||||
if (!option) {
|
||||
option = document.createElement('option');
|
||||
option.id = this.customvariantname;
|
||||
option.id = 'R-select-variant-' + this.customvariantname;
|
||||
option.value = this.customvariantname;
|
||||
option.text = this.customvariantname.replace(/-/g, ' ').replace(/\w\S*/g, function (w) {
|
||||
return w.replace(/^\w/g, function (c) {
|
||||
|
@ -109,116 +67,225 @@ var variants = {
|
|||
},
|
||||
|
||||
removeCustomVariantOption: function () {
|
||||
var option = document.querySelector('#' + this.customvariantname);
|
||||
var option = document.querySelector('#R-select-variant-' + this.customvariantname);
|
||||
if (option) {
|
||||
option.remove();
|
||||
}
|
||||
if (this.variants.length <= 1) {
|
||||
document.querySelectorAll('.footerVariantSwitch').forEach(function (e) {
|
||||
e.classList.remove('showVariantSwitch');
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addCustomVariantStyles: function () {
|
||||
var head = document.querySelector('head');
|
||||
var style = document.createElement('style');
|
||||
style.id = 'R-variant-styles-' + this.customvariantname;
|
||||
head.appendChild(style);
|
||||
},
|
||||
|
||||
updateCustomVariantStyles: function (stylesheet) {
|
||||
stylesheet = ":root:not([data-r-output-format='print'])[data-r-theme-variant='" + this.customvariantname + "'] {" + '\n&' + stylesheet + '\n}';
|
||||
var style = document.querySelector('#R-variant-styles-' + this.customvariantname);
|
||||
if (style) {
|
||||
style.textContent = stylesheet;
|
||||
}
|
||||
},
|
||||
|
||||
saveCustomVariant: function () {
|
||||
if (this.getVariant() != this.customvariantname) {
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + '/customvariantbase', this.getVariant());
|
||||
var variant = window.localStorage.getItem(window.relearn.absBaseUri + '/variant');
|
||||
if (variant != this.customvariantname) {
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + '/customvariant', variant);
|
||||
}
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + '/customvariant', this.generateStylesheet());
|
||||
this.setVariant(this.customvariantname);
|
||||
this.markSelectedVariant();
|
||||
var stylesheet = this.generateStylesheet();
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + '/variant', this.customvariantname);
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + '/customvariantstylesheet', stylesheet);
|
||||
this.updateCustomVariantStyles(stylesheet);
|
||||
|
||||
this.addCustomVariantOption();
|
||||
window.relearn.markVariant();
|
||||
window.relearn.changeVariant(this.customvariantname);
|
||||
},
|
||||
|
||||
loadCustomVariant: function () {
|
||||
var stylesheet = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariant');
|
||||
normalizeColor: function (c) {
|
||||
if (!c || !c.trim) {
|
||||
return c;
|
||||
}
|
||||
c = c.trim();
|
||||
c = c.replace(/\s*\(\s*/g, '( ');
|
||||
c = c.replace(/\s*\)\s*/g, ' )');
|
||||
c = c.replace(/\s*,\s*/g, ', ');
|
||||
c = c.replace(/0*\./g, '.');
|
||||
c = c.replace(/ +/g, ' ');
|
||||
return c;
|
||||
},
|
||||
|
||||
// temp styles to document
|
||||
var head = document.querySelector('head');
|
||||
var style = document.createElement('style');
|
||||
style.id = 'R-custom-variant-style';
|
||||
style.appendChild(document.createTextNode(stylesheet));
|
||||
head.appendChild(style);
|
||||
getColorValue: function (c) {
|
||||
return this.normalizeColor(getComputedStyle(document.documentElement).getPropertyValue('--INTERNAL-' + c));
|
||||
},
|
||||
|
||||
var interval_id = setInterval(
|
||||
function () {
|
||||
if (this.findLoadedStylesheet('R-variant-style')) {
|
||||
clearInterval(interval_id);
|
||||
// save the styles to the current variant stylesheet
|
||||
this.variantvariables.forEach(
|
||||
function (e) {
|
||||
this.changeColor(e.name, true);
|
||||
}.bind(this)
|
||||
);
|
||||
getColorProperty: function (c, read_style) {
|
||||
var e = this.findColor(c);
|
||||
var p = this.normalizeColor(read_style.getPropertyValue('--' + c)).replace('--INTERNAL-', '--');
|
||||
return p;
|
||||
},
|
||||
|
||||
// remove temp styles
|
||||
style.remove();
|
||||
findRootRule: function (rules, parentSelectors) {
|
||||
for (let rule of rules ?? []) {
|
||||
if ((rule.conditionText && rule.conditionText != 'screen') || (rule.selectorText && !rule.selectorText.startsWith(':root:not'))) {
|
||||
return null;
|
||||
}
|
||||
if (parentSelectors.some((selector) => rule.selectorText === selector)) {
|
||||
// Search nested rules for &:root
|
||||
for (let nestedRule of rule.cssRules ?? []) {
|
||||
if (nestedRule.selectorText === '&:root') {
|
||||
return nestedRule.style;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
let result = this.findRootRule(rule.cssRules, parentSelectors);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
findLoadedStylesheet: function (id, parentSelectors) {
|
||||
for (let sheet of document.styleSheets) {
|
||||
if (sheet.ownerNode.id === id) {
|
||||
return this.findRootRule(sheet.cssRules, parentSelectors);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
findColor: function (name) {
|
||||
var f = this.variantvariables.find(function (x) {
|
||||
return x.name == name;
|
||||
});
|
||||
return f;
|
||||
},
|
||||
|
||||
generateColorVariable: function (e, read_style) {
|
||||
var v = '';
|
||||
var gen = this.getColorProperty(e.name, read_style);
|
||||
if (gen) {
|
||||
v += ' --' + e.name + ': ' + gen + '; /* ' + e.tooltip + ' */\n';
|
||||
}
|
||||
return v;
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// CSS download
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
generateStylesheet: function () {
|
||||
var customvariantbase = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariant') ?? window.localStorage.getItem(window.relearn.absBaseUri + '/variant');
|
||||
var base_style = this.findLoadedStylesheet('R-format-style', [':root:not([data-r-output-format="print"])[data-r-theme-variant="' + customvariantbase + '"]']);
|
||||
if (!base_style) {
|
||||
alert('There is nothing to be generated as auto mode variants will be generated by Hugo');
|
||||
return;
|
||||
}
|
||||
|
||||
var variant = this.customvariantname;
|
||||
var custom_style = this.findLoadedStylesheet('R-variant-styles-' + variant, [':root:not([data-r-output-format="print"])[data-r-theme-variant="' + variant + '"]']);
|
||||
if (!custom_style) {
|
||||
variant = customvariantbase;
|
||||
custom_style = base_style;
|
||||
}
|
||||
|
||||
var style =
|
||||
':root {\n' +
|
||||
' /* ' +
|
||||
variant +
|
||||
' */\n' +
|
||||
this.variantvariables.reduce(
|
||||
function (a, e) {
|
||||
return a + this.generateColorVariable(e, custom_style);
|
||||
}.bind(this),
|
||||
''
|
||||
) +
|
||||
'}\n';
|
||||
return style;
|
||||
},
|
||||
|
||||
download: function (data, mimetype, filename) {
|
||||
var blob = new Blob([data], { type: mimetype });
|
||||
var url = window.URL.createObjectURL(blob);
|
||||
var a = document.createElement('a');
|
||||
a.setAttribute('href', url);
|
||||
a.setAttribute('download', filename);
|
||||
a.click();
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// external API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
changeColor: function (c) {
|
||||
var customvariantbase = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariant') ?? window.localStorage.getItem(window.relearn.absBaseUri + '/variant');
|
||||
var base_style = this.findLoadedStylesheet('R-format-style', [':root:not([data-r-output-format="print"])[data-r-theme-variant="' + customvariantbase + '"]']);
|
||||
if (!base_style) {
|
||||
alert('An auto mode variant can not be changed. Please select its light/dark variant directly to make changes');
|
||||
return;
|
||||
}
|
||||
|
||||
var custom_style = this.findLoadedStylesheet('R-variant-styles-' + this.customvariantname, [':root:not([data-r-output-format="print"])[data-r-theme-variant="' + this.customvariantname + '"]']);
|
||||
if (!custom_style) {
|
||||
this.saveCustomVariant();
|
||||
custom_style = this.findLoadedStylesheet('R-variant-styles-' + this.customvariantname, [':root:not([data-r-output-format="print"])[data-r-theme-variant="' + this.customvariantname + '"]']);
|
||||
}
|
||||
|
||||
var e = this.findColor(c);
|
||||
var v = this.getColorProperty(c, custom_style);
|
||||
var t = c + '\n\n' + e.tooltip + '\n';
|
||||
if (e.fallback) {
|
||||
t += '\nInherits value "' + this.getColorValue(e.fallback) + '" from ' + e.fallback + ' if not set\n';
|
||||
} else if (e.default) {
|
||||
t += '\nDefaults to value "' + this.normalizeColor(e.default) + '" if not set\n';
|
||||
}
|
||||
var n = prompt(t, v);
|
||||
if (n === null) {
|
||||
// user canceld operation
|
||||
return;
|
||||
}
|
||||
|
||||
if (n) {
|
||||
// value set to specific value
|
||||
n = this.normalizeColor(n).replace('--INTERNAL-', '--').replace('--', '--INTERNAL-');
|
||||
if (n != v) {
|
||||
custom_style.setProperty('--' + c, n);
|
||||
}
|
||||
} else {
|
||||
// value emptied, so delete it
|
||||
custom_style.removeProperty('--' + c);
|
||||
}
|
||||
|
||||
this.saveCustomVariant();
|
||||
}
|
||||
}.bind(this),
|
||||
25
|
||||
);
|
||||
},
|
||||
|
||||
resetVariant: function () {
|
||||
var variantbase = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariantbase');
|
||||
if (variantbase && confirm('You have made changes to your custom variant. Are you sure you want to reset all changes?')) {
|
||||
window.localStorage.removeItem(window.relearn.absBaseUri + '/customvariantbase');
|
||||
var customvariant = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariant');
|
||||
if (customvariant && confirm('You have made changes to your custom variant. Are you sure you want to reset all changes?')) {
|
||||
window.localStorage.removeItem(window.relearn.absBaseUri + '/customvariant');
|
||||
window.localStorage.removeItem(window.relearn.absBaseUri + '/customvariantstylesheet');
|
||||
window.localStorage.setItem(window.relearn.absBaseUri + '/variant', customvariant);
|
||||
this.updateCustomVariantStyles('');
|
||||
|
||||
this.removeCustomVariantOption();
|
||||
if (this.getVariant() == this.customvariantname) {
|
||||
this.changeVariant(variantbase);
|
||||
}
|
||||
window.relearn.markVariant();
|
||||
window.relearn.changeVariant(customvariant);
|
||||
}
|
||||
},
|
||||
|
||||
onLoadStylesheet: function () {
|
||||
variants.isstylesheetloaded = true;
|
||||
},
|
||||
|
||||
switchStylesheet: function (variant, without_check) {
|
||||
var link = document.querySelector('#R-variant-style');
|
||||
if (!link) {
|
||||
return;
|
||||
}
|
||||
var old_path = link.getAttribute('href');
|
||||
var new_path = this.generateVariantPath(variant, old_path);
|
||||
this.isstylesheetloaded = false;
|
||||
|
||||
// Chrome needs a new element to trigger the load callback again
|
||||
var new_link = document.createElement('link');
|
||||
new_link.id = 'R-variant-style';
|
||||
new_link.rel = 'stylesheet';
|
||||
new_link.onload = this.onLoadStylesheet;
|
||||
new_link.setAttribute('href', new_path);
|
||||
link.parentNode.replaceChild(new_link, link);
|
||||
},
|
||||
|
||||
changeVariant: function (variant) {
|
||||
if (variant == this.customvariantname) {
|
||||
var variantbase = window.localStorage.getItem(window.relearn.absBaseUri + '/customvariantbase');
|
||||
if (this.variants.indexOf(variantbase) < 0) {
|
||||
variant = '';
|
||||
}
|
||||
if (!window.localStorage.getItem(window.relearn.absBaseUri + '/customvariant')) {
|
||||
variant = '';
|
||||
}
|
||||
this.setVariant(variant);
|
||||
if (!variant) {
|
||||
return;
|
||||
}
|
||||
this.switchStylesheet(variantbase);
|
||||
this.loadCustomVariant();
|
||||
} else {
|
||||
if (this.variants.indexOf(variant) < 0) {
|
||||
variant = this.variants.length ? this.variants[0] : '';
|
||||
}
|
||||
this.setVariant(variant);
|
||||
if (!variant) {
|
||||
return;
|
||||
}
|
||||
this.switchStylesheet(variant);
|
||||
this.markSelectedVariant();
|
||||
getStylesheet: function () {
|
||||
var style = this.generateStylesheet();
|
||||
if (style) {
|
||||
console.log(style);
|
||||
this.download(style, 'text/css', 'theme-' + this.customvariantname + '.css');
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -240,23 +307,9 @@ var variants = {
|
|||
);
|
||||
},
|
||||
|
||||
download: function (data, mimetype, filename) {
|
||||
var blob = new Blob([data], { type: mimetype });
|
||||
var url = window.URL.createObjectURL(blob);
|
||||
var a = document.createElement('a');
|
||||
a.setAttribute('href', url);
|
||||
a.setAttribute('download', filename);
|
||||
a.click();
|
||||
},
|
||||
|
||||
getStylesheet: function () {
|
||||
var style = this.generateStylesheet();
|
||||
if (!style) {
|
||||
alert('There is nothing to be generated as auto mode variants will be generated by Hugo');
|
||||
return;
|
||||
}
|
||||
this.download(style, 'text/css', 'theme-' + this.customvariantname + '.css');
|
||||
},
|
||||
// ------------------------------------------------------------------------
|
||||
// Mermaid graph stuff
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
adjustCSSRules: function (selector, props, sheets) {
|
||||
// get stylesheet(s)
|
||||
|
@ -291,145 +344,6 @@ var variants = {
|
|||
}
|
||||
},
|
||||
|
||||
normalizeColor: function (c) {
|
||||
if (!c || !c.trim) {
|
||||
return c;
|
||||
}
|
||||
c = c.trim();
|
||||
c = c.replace(/\s*\(\s*/g, '( ');
|
||||
c = c.replace(/\s*\)\s*/g, ' )');
|
||||
c = c.replace(/\s*,\s*/g, ', ');
|
||||
c = c.replace(/0*\./g, '.');
|
||||
c = c.replace(/ +/g, ' ');
|
||||
return c;
|
||||
},
|
||||
|
||||
getColorValue: function (c) {
|
||||
return this.normalizeColor(getComputedStyle(document.documentElement).getPropertyValue('--INTERNAL-' + c));
|
||||
},
|
||||
|
||||
getColorProperty: function (c, read_style) {
|
||||
var e = this.findColor(c);
|
||||
var p = this.normalizeColor(read_style.getPropertyValue('--' + c)).replace('--INTERNAL-', '--');
|
||||
return p;
|
||||
},
|
||||
|
||||
findLoadedStylesheet: function (id) {
|
||||
for (var n = 0; n < document.styleSheets.length; ++n) {
|
||||
if (document.styleSheets[n].ownerNode.id == id) {
|
||||
var s = document.styleSheets[n];
|
||||
if (s.rules && s.rules.length) {
|
||||
for (var m = 0; m < s.rules.length; ++m) {
|
||||
if (s.rules[m].selectorText == ':root') {
|
||||
return s.rules[m].style;
|
||||
}
|
||||
if (s.rules[m].cssRules && s.rules[m].cssRules.length) {
|
||||
for (var o = 0; o < s.rules[m].cssRules.length; ++o) {
|
||||
if (s.rules[m].cssRules[o].selectorText == ':root') {
|
||||
return s.rules[m].cssRules[o].style;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
changeColor: function (c, without_prompt) {
|
||||
var with_prompt = !(without_prompt || false);
|
||||
|
||||
var read_style = this.findLoadedStylesheet('R-custom-variant-style');
|
||||
var write_style = this.findLoadedStylesheet('R-variant-style');
|
||||
if (!read_style) {
|
||||
read_style = write_style;
|
||||
}
|
||||
if (!read_style) {
|
||||
if (with_prompt) {
|
||||
alert('An auto mode variant can not be changed. Please select its light/dark variant directly to make changes');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var e = this.findColor(c);
|
||||
var v = this.getColorProperty(c, read_style);
|
||||
var n = '';
|
||||
if (!with_prompt) {
|
||||
n = v;
|
||||
} else {
|
||||
var t = c + '\n\n' + e.tooltip + '\n';
|
||||
if (e.fallback) {
|
||||
t += '\nInherits value "' + this.getColorValue(e.fallback) + '" from ' + e.fallback + ' if not set\n';
|
||||
} else if (e.default) {
|
||||
t += '\nDefaults to value "' + this.normalizeColor(e.default) + '" if not set\n';
|
||||
}
|
||||
n = prompt(t, v);
|
||||
if (n === null) {
|
||||
// user canceld operation
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (n) {
|
||||
// value set to specific value
|
||||
n = this.normalizeColor(n).replace('--INTERNAL-', '--').replace('--', '--INTERNAL-');
|
||||
if (!with_prompt || n != v) {
|
||||
write_style.setProperty('--' + c, n);
|
||||
}
|
||||
} else {
|
||||
// value emptied, so delete it
|
||||
write_style.removeProperty('--' + c);
|
||||
}
|
||||
|
||||
if (with_prompt) {
|
||||
this.saveCustomVariant();
|
||||
}
|
||||
},
|
||||
|
||||
findColor: function (name) {
|
||||
var f = this.variantvariables.find(function (x) {
|
||||
return x.name == name;
|
||||
});
|
||||
return f;
|
||||
},
|
||||
|
||||
generateColorVariable: function (e, read_style) {
|
||||
var v = '';
|
||||
var gen = this.getColorProperty(e.name, read_style);
|
||||
if (gen) {
|
||||
v += ' --' + e.name + ': ' + gen + '; /* ' + e.tooltip + ' */\n';
|
||||
}
|
||||
return v;
|
||||
},
|
||||
|
||||
generateStylesheet: function () {
|
||||
var read_style = this.findLoadedStylesheet('R-custom-variant-style');
|
||||
var write_style = this.findLoadedStylesheet('R-variant-style');
|
||||
if (!read_style) {
|
||||
read_style = write_style;
|
||||
}
|
||||
if (!read_style) {
|
||||
return;
|
||||
}
|
||||
|
||||
var style =
|
||||
'/* ' +
|
||||
this.customvariantname +
|
||||
' */\n' +
|
||||
':root {\n' +
|
||||
this.variantvariables.reduce(
|
||||
function (a, e) {
|
||||
return a + this.generateColorVariable(e, read_style);
|
||||
}.bind(this),
|
||||
''
|
||||
) +
|
||||
'}\n';
|
||||
console.log(style);
|
||||
return style;
|
||||
},
|
||||
|
||||
styleGraphGroup: function (selector, colorvar) {
|
||||
this.adjustCSSRules('#R-body svg ' + selector + ' > rect', 'color: var(--INTERNAL-' + colorvar + '); fill: var(--INTERNAL-' + colorvar + '); stroke: #80808080;');
|
||||
this.adjustCSSRules('#R-body svg ' + selector + ' > .label .nodeLabel', 'color: var(--INTERNAL-' + colorvar + '); fill: var(--INTERNAL-' + colorvar + '); stroke: #80808080;');
|
||||
|
@ -688,3 +602,5 @@ var variants = {
|
|||
{ name: 'BOX-WARNING-TEXT-color', group: 'colored boxes', fallback: 'BOX-RED-TEXT-color', tooltip: 'text color of warning boxes' },
|
||||
],
|
||||
};
|
||||
|
||||
variants.setup();
|
||||
|
|
Loading…
Reference in a new issue