Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
b6e9ebf100 | |||
d645e29ce5 | |||
291fc9111b | |||
0e8e894056 | |||
add728eb6d | |||
6e30e3f361 | |||
f9e0ffa0eb | |||
9632b008ac | |||
4cd74fd9b4 | |||
5355576443 | |||
975b5d3fb3 | |||
f0847a622f | |||
e69b9fb9c8 | |||
16f23c08c6 | |||
e710c594f1 | |||
e4dc101346 | |||
f99d45e8ab |
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,3 +6,4 @@
|
|||||||
/.sass-cache/
|
/.sass-cache/
|
||||||
/build/
|
/build/
|
||||||
*.scssc
|
*.scssc
|
||||||
|
/Book.html
|
||||||
|
@ -5,12 +5,11 @@ homepage: https://labs.phundrak.com/phundrak/org-website-backend
|
|||||||
author: Lucien Cartier-Tilet <lucien@phundrak.com>
|
author: Lucien Cartier-Tilet <lucien@phundrak.com>
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.7.0 <3.0.0'
|
sdk: '>=2.12.0 <3.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
html: '^0.14.0+3'
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^1.8.0
|
build_runner: ">=1.10.1 <2.0.0"
|
||||||
build_web_compilers: ^2.9.0
|
build_web_compilers: ">=2.9.0 <3.0.0"
|
||||||
pedantic: ^1.9.0
|
pedantic: ">=1.9.0 <2.0.0"
|
||||||
|
@ -4,7 +4,8 @@ import './theme.dart' show enableThemeChanger, setTheme;
|
|||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
await setTheme();
|
await setTheme();
|
||||||
await reorganizeHtml()
|
await reorganizeHtml().then((_) {
|
||||||
.then((_) => enableThemeChanger())
|
enableThemeChanger();
|
||||||
.then((_) => createSitemap());
|
createSitemap();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'dart:html';
|
import 'dart:html' show querySelector, Element, window;
|
||||||
import 'dart:svg';
|
import 'dart:svg' show SvgElement;
|
||||||
|
|
||||||
// You will see here and there some 'tabindex' attributes added to various HTML
|
// You will see here and there some 'tabindex' attributes added to various HTML
|
||||||
// elements, and I’m sure you will ask "Why? They don’t serve any purpose, do
|
// elements, and I’m sure you will ask "Why? They don’t serve any purpose, do
|
||||||
@ -32,16 +32,10 @@ final icons = {
|
|||||||
'<svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M12 2.04C6.5 2.04 2 6.53 2 12.06C2 17.06 5.66 21.21 10.44 21.96V14.96H7.9V12.06H10.44V9.85C10.44 7.34 11.93 5.96 14.22 5.96C15.31 5.96 16.45 6.15 16.45 6.15V8.62H15.19C13.95 8.62 13.56 9.39 13.56 10.18V12.06H16.34L15.89 14.96H13.56V21.96A10 10 0 0 0 22 12.06C22 6.53 17.5 2.04 12 2.04Z" /></svg>'),
|
'<svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M12 2.04C6.5 2.04 2 6.53 2 12.06C2 17.06 5.66 21.21 10.44 21.96V14.96H7.9V12.06H10.44V9.85C10.44 7.34 11.93 5.96 14.22 5.96C15.31 5.96 16.45 6.15 16.45 6.15V8.62H15.19C13.95 8.62 13.56 9.39 13.56 10.18V12.06H16.34L15.89 14.96H13.56V21.96A10 10 0 0 0 22 12.06C22 6.53 17.5 2.04 12 2.04Z" /></svg>'),
|
||||||
'theme': SvgElement.svg(
|
'theme': SvgElement.svg(
|
||||||
'<svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M12,18V6A6,6 0 0,1 18,12A6,6 0 0,1 12,18M20,15.31L23.31,12L20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31Z" /></svg>'),
|
'<svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M12,18V6A6,6 0 0,1 18,12A6,6 0 0,1 12,18M20,15.31L23.31,12L20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31Z" /></svg>'),
|
||||||
'sun': SvgElement.svg(
|
|
||||||
'<svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M3.55,18.54L4.96,19.95L6.76,18.16L5.34,16.74M11,22.45C11.32,22.45 13,22.45 13,22.45V19.5H11M12,5.5A6,6 0 0,0 6,11.5A6,6 0 0,0 12,17.5A6,6 0 0,0 18,11.5C18,8.18 15.31,5.5 12,5.5M20,12.5H23V10.5H20M17.24,18.16L19.04,19.95L20.45,18.54L18.66,16.74M20.45,4.46L19.04,3.05L17.24,4.84L18.66,6.26M13,0.55H11V3.5H13M4,10.5H1V12.5H4M6.76,4.84L4.96,3.05L3.55,4.46L5.34,6.26L6.76,4.84Z" /></svg>'),
|
|
||||||
'lightbulb': SvgElement.svg(
|
|
||||||
'<svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M12,6A6,6 0 0,1 18,12C18,14.22 16.79,16.16 15,17.2V19A1,1 0 0,1 14,20H10A1,1 0 0,1 9,19V17.2C7.21,16.16 6,14.22 6,12A6,6 0 0,1 12,6M14,21V22A1,1 0 0,1 13,23H11A1,1 0 0,1 10,22V21H14M20,11H23V13H20V11M1,11H4V13H1V11M13,1V4H11V1H13M4.92,3.5L7.05,5.64L5.63,7.05L3.5,4.93L4.92,3.5M16.95,5.63L19.07,3.5L20.5,4.93L18.37,7.05L16.95,5.63Z" /></svg>'),
|
|
||||||
'moon': SvgElement.svg(
|
|
||||||
'<svg style="width:24px;height:24px" viewBox="0 0 24 24"><path fill="currentColor" d="M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4L13.5,1L14.56,4L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C19.8,15.87 20.69,17.05 20.16,17.8C19.84,18.25 19.5,18.67 19.08,19.07C15.17,23 8.84,23 4.94,19.07C1.03,15.17 1.03,8.83 4.94,4.93C5.34,4.53 5.76,4.17 6.21,3.85C6.96,3.32 8.14,4.21 8.06,5.04C7.79,7.9 8.75,10.87 10.95,13.06C13.14,15.26 16.1,16.22 18.97,15.95M17.33,17.97C14.5,17.81 11.7,16.64 9.53,14.5C7.36,12.31 6.2,9.5 6.04,6.68C3.23,9.82 3.34,14.64 6.35,17.66C9.37,20.67 14.19,20.78 17.33,17.97Z" /></svg>'),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the current page’s title
|
// Get the current page’s title
|
||||||
String getPageTitle() => querySelector('title').text;
|
String getPageTitle() => querySelector('title')!.text!;
|
||||||
|
|
||||||
// Create the home button
|
// Create the home button
|
||||||
Future<Element> makeHome() async {
|
Future<Element> makeHome() async {
|
||||||
@ -51,29 +45,27 @@ Future<Element> makeHome() async {
|
|||||||
'afterBegin',
|
'afterBegin',
|
||||||
Element.a()
|
Element.a()
|
||||||
..attributes['href'] = '/'
|
..attributes['href'] = '/'
|
||||||
..append(makeIcon(icons['home'])));
|
..append(makeIcon(icons['home']!)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a clickable icon
|
// Create a clickable icon
|
||||||
// `t_elem` must be an SVG declared in the above `icons` variable.
|
// `t_elem` must be an SVG declared in the above `icons` variable.
|
||||||
Element makeIcon(SvgElement t_elem) {
|
Element makeIcon(SvgElement t_elem) {
|
||||||
final icon = t_elem..classes.add('nav-icon');
|
return t_elem..classes.add('nav-icon');
|
||||||
return icon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the dropdown sitemap
|
// Create the dropdown sitemap
|
||||||
Future<Element> makePages() async {
|
Future<Element> makePages() async {
|
||||||
var pages = Element.ul()
|
|
||||||
..attributes['id'] = 'drop-page'
|
|
||||||
..classes.add('dropdown');
|
|
||||||
return Element.li()
|
return Element.li()
|
||||||
..attributes['tabindex'] = '0'
|
..attributes['tabindex'] = '0'
|
||||||
..append(Element.a()
|
..append(Element.a()
|
||||||
..attributes['tabindex'] = '-1'
|
..attributes['tabindex'] = '-1'
|
||||||
..attributes['href'] = 'javascript:void(0)'
|
..attributes['href'] = 'javascript:void(0)'
|
||||||
..append(makeIcon(icons['pages'])))
|
..append(makeIcon(icons['pages']!)))
|
||||||
..classes.addAll(['nav-item', 'has-dropdown'])
|
..classes.addAll(['nav-item', 'has-dropdown'])
|
||||||
..append(pages);
|
..append(Element.ul()
|
||||||
|
..attributes['id'] = 'drop-page'
|
||||||
|
..classes.add('dropdown'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the array of share icons
|
// Create the array of share icons
|
||||||
@ -95,32 +87,34 @@ Future<Element> makeShare() async {
|
|||||||
..append(Element.a()
|
..append(Element.a()
|
||||||
..attributes['href'] = 'javascript:void(0)'
|
..attributes['href'] = 'javascript:void(0)'
|
||||||
..attributes['tabindex'] = '-1'
|
..attributes['tabindex'] = '-1'
|
||||||
..append(makeIcon(icons['share'])))
|
..append(makeIcon(icons['share']!)))
|
||||||
..append(Element.ul()
|
..append(Element.ul()
|
||||||
..classes.add('dropdown')
|
..classes.add('dropdown')
|
||||||
..attributes['id'] = 'drop-share'
|
..attributes['id'] = 'drop-share'
|
||||||
..append(makeShareLink(
|
..append(makeShareLink(
|
||||||
makeIcon(icons['twitter']),
|
makeIcon(icons['twitter']!),
|
||||||
'https://twitter.com/share?text=${getPageTitle()}'
|
'https://twitter.com/share?text=${getPageTitle()}'
|
||||||
'&url=${window.location.href}'))
|
'&url=${window.location.href}'))
|
||||||
..append(makeShareLink(makeIcon(icons['reddit']),
|
..append(makeShareLink(makeIcon(icons['reddit']!),
|
||||||
'https://www.reddit.com/submit?title=${getPageTitle()}s&url=${window.location.href}'))
|
'https://www.reddit.com/submit?title=${getPageTitle()}s&url=${window.location.href}'))
|
||||||
..append(makeShareLink(makeIcon(icons['email']),
|
..append(makeShareLink(makeIcon(icons['email']!),
|
||||||
'mailto:?subject=${getPageTitle}&body=${window.location.href}'))
|
'mailto:?subject=$getPageTitle&body=${window.location.href}'))
|
||||||
..append(makeShareLink(
|
..append(makeShareLink(
|
||||||
makeIcon(icons['linkedin']),
|
makeIcon(icons['linkedin']!),
|
||||||
'https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}'
|
'https://www.linkedin.com/shareArticle?mini=true&url=${window.location.href}'
|
||||||
'&title=${getPageTitle()}'))
|
'&title=${getPageTitle()}'))
|
||||||
..append(makeShareLink(makeIcon(icons['facebook']),
|
..append(makeShareLink(makeIcon(icons['facebook']!),
|
||||||
'https://www.facebook.com/sharer/sharer.php?u=${window.location.href}')));
|
'https://www.facebook.com/sharer/sharer.php?u=${window.location.href}')));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the theme changer
|
// Create the theme changer
|
||||||
Future<Element> makeThemeChanger() async {
|
Future<Element> makeThemeChanger() async {
|
||||||
Element makeThemeItem(String t_btnId, [Element t_icon]) {
|
Element makeThemeItem(String t_btnId) {
|
||||||
return Element.li()
|
return Element.li()
|
||||||
..classes.add('dropdown-item')
|
..classes.add('dropdown-item')
|
||||||
..append(Element.span()..attributes['id'] = t_btnId);
|
..append(Element.span()
|
||||||
|
..attributes['id'] = t_btnId
|
||||||
|
..classes.add('themeBtn'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Element.li()
|
return Element.li()
|
||||||
@ -131,13 +125,13 @@ Future<Element> makeThemeChanger() async {
|
|||||||
..attributes['tabindex'] = '-1'
|
..attributes['tabindex'] = '-1'
|
||||||
..append(Element.span()
|
..append(Element.span()
|
||||||
..style.verticalAlign = 'top'
|
..style.verticalAlign = 'top'
|
||||||
..append(makeIcon(icons['theme']))))
|
..append(makeIcon(icons['theme']!))))
|
||||||
..append(Element.ul()
|
..append(Element.ul()
|
||||||
..classes.add('dropdown')
|
..classes.add('dropdown')
|
||||||
..attributes['id'] = 'theme-dropdown'
|
..attributes['id'] = 'theme-dropdown'
|
||||||
..append(makeThemeItem('lightBtn', makeIcon(icons['sun'])))
|
..append(makeThemeItem('lightBtn'))
|
||||||
..append(makeThemeItem('darkBtn', makeIcon(icons['lightbulb'])))
|
..append(makeThemeItem('darkBtn'))
|
||||||
..append(makeThemeItem('blackBtn', makeIcon(icons['moon']))));
|
..append(makeThemeItem('blackBtn')));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the dropdown table of contents
|
// Create the dropdown table of contents
|
||||||
@ -149,7 +143,7 @@ Future<Element> makeToc() async {
|
|||||||
..append(Element.a()
|
..append(Element.a()
|
||||||
..attributes['tabindex'] = '-1'
|
..attributes['tabindex'] = '-1'
|
||||||
..attributes['href'] = 'javascript:void(0)'
|
..attributes['href'] = 'javascript:void(0)'
|
||||||
..append(makeIcon(icons['toc'])));
|
..append(makeIcon(icons['toc']!)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a navbar atop of the HTML body, containing:
|
// Add a navbar atop of the HTML body, containing:
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import 'dart:html' as html show HttpRequest, Element, querySelector;
|
import 'dart:html' show HttpRequest, Element, querySelector;
|
||||||
|
|
||||||
import 'package:html/parser.dart' show parse;
|
|
||||||
import 'package:html/dom.dart' as dom show Element;
|
|
||||||
|
|
||||||
final excluded_keywords = {'index', 'CONTRIBUTING', 'LICENSE', 'README'};
|
final excluded_keywords = {'index', 'CONTRIBUTING', 'LICENSE', 'README'};
|
||||||
|
|
||||||
@ -9,7 +6,7 @@ final excluded_keywords = {'index', 'CONTRIBUTING', 'LICENSE', 'README'};
|
|||||||
Future<String> fetchRemoteSitemap() async {
|
Future<String> fetchRemoteSitemap() async {
|
||||||
const path = '/sitemap.html';
|
const path = '/sitemap.html';
|
||||||
try {
|
try {
|
||||||
return await html.HttpRequest.getString(path);
|
return await HttpRequest.getString(path);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Couldn’t open $path');
|
print('Couldn’t open $path');
|
||||||
}
|
}
|
||||||
@ -17,47 +14,48 @@ Future<String> fetchRemoteSitemap() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse the list of elements and detect pages from this list
|
// Parse the list of elements and detect pages from this list
|
||||||
Map<String, String> detectPages(List<dom.Element> t_sitemap,
|
Map<String, String> detectPages(List<Element> t_sitemap,
|
||||||
[String t_prefix, Map<String, String> t_links]) {
|
[String? t_prefix, Map<String, String>? t_links]) {
|
||||||
t_links ??= <String, String>{};
|
t_links ??= <String, String>{};
|
||||||
|
|
||||||
// parse each element in sitemap
|
// parse each element in sitemap
|
||||||
for (var elem in t_sitemap) {
|
for (var elem in t_sitemap) {
|
||||||
// if it’s a link
|
// if it’s a link
|
||||||
if (elem.innerHtml.startsWith('<a')) {
|
if (elem.innerHtml!.startsWith('<a')) {
|
||||||
elem = elem.firstChild;
|
elem = elem.children[0];
|
||||||
final url = elem.attributes['href'];
|
final url = elem.attributes['href']!;
|
||||||
final text = elem.firstChild.text;
|
final text = elem.children[0].text;
|
||||||
if (excluded_keywords.contains(text) ||
|
if (excluded_keywords.contains(text) ||
|
||||||
excluded_keywords.contains(url.substring(0, url.length - 5))) {
|
excluded_keywords.contains(url.substring(0, url.length - 5))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
t_links['/$url'] = (t_prefix == null) ? text : '$text ($t_prefix)';
|
t_links!['/$url'] = ((t_prefix == null) ? text : '$text ($t_prefix)')!;
|
||||||
} else {
|
} else {
|
||||||
final prefix = (t_prefix == null)
|
final prefix = (t_prefix == null)
|
||||||
? elem.firstChild.text.replaceAll('\n', '')
|
? elem.firstChild!.text!.replaceAll('\n', '')
|
||||||
: '$t_prefix / ${elem.firstChild.text}'.replaceAll('\n', '');
|
: '$t_prefix / ${elem.firstChild!.text}'.replaceAll('\n', '');
|
||||||
t_links = detectPages(elem.children[0].children, prefix, t_links);
|
t_links = detectPages(elem.children[0].children, prefix, t_links);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return t_links;
|
return t_links!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function returns a Map which contains all links to languages detected
|
// This function returns a Map which contains all links to languages detected
|
||||||
// from the sitemap.
|
// from the sitemap.
|
||||||
Future<Map<String, String>> parseSitemap() async {
|
Future<Map<String, String>> parseSitemap() async {
|
||||||
final content = await fetchRemoteSitemap();
|
final content = await fetchRemoteSitemap();
|
||||||
final sitemap = parse(content).getElementsByClassName('org-ul')[0].children;
|
final sitemap = Element.ul()..innerHtml = content;
|
||||||
return detectPages(sitemap);
|
final sitemapNodes = sitemap.querySelector('ul')!.children;
|
||||||
|
return detectPages(sitemapNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> createSitemap() async {
|
Future<void> createSitemap() async {
|
||||||
final sitemap = await parseSitemap();
|
final sitemap = await parseSitemap();
|
||||||
final pages = html.querySelector('#drop-page');
|
final pages = querySelector('#drop-page')!;
|
||||||
sitemap.forEach((url, name) {
|
sitemap.forEach((url, name) {
|
||||||
final link = html.Element.li()
|
final link = Element.li()
|
||||||
..classes.add('dropdown-item')
|
..classes.add('dropdown-item')
|
||||||
..append(html.Element.a()
|
..append(Element.a()
|
||||||
..attributes['href'] = url
|
..attributes['href'] = url
|
||||||
..innerText = name);
|
..innerText = name);
|
||||||
pages.append(link);
|
pages.append(link);
|
||||||
|
@ -1,8 +1,19 @@
|
|||||||
import 'dart:html';
|
import 'dart:html'
|
||||||
|
show DivElement, Element, querySelector, querySelectorAll, window;
|
||||||
|
|
||||||
import './navbar.dart' show makeNavbar;
|
import './navbar.dart' show makeNavbar;
|
||||||
|
|
||||||
const image_header = '/img/icon.png';
|
const image_header = '/img/icon.webp';
|
||||||
|
|
||||||
|
Future<void> makeDecorativeButtonsOrgSrc() async {
|
||||||
|
for (var pre in querySelectorAll('.org-src-container')) {
|
||||||
|
pre
|
||||||
|
..append(Element.div()..attributes['class'] = 'closeButton')
|
||||||
|
..append(Element.div()..attributes['class'] = 'minButton')
|
||||||
|
..append(Element.div()..attributes['class'] = 'maxButton')
|
||||||
|
..append(Element.div()..attributes['class'] = 'floatButton');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<Element> makeHeader() async {
|
Future<Element> makeHeader() async {
|
||||||
var header = Element.tag('header');
|
var header = Element.tag('header');
|
||||||
@ -10,9 +21,9 @@ Future<Element> makeHeader() async {
|
|||||||
..append(Element.img()
|
..append(Element.img()
|
||||||
..attributes['src'] = image_header
|
..attributes['src'] = image_header
|
||||||
..attributes['alt'] = 'Logo'
|
..attributes['alt'] = 'Logo'
|
||||||
..attributes['heigh'] = '150px'
|
..attributes['height'] = '150px'
|
||||||
..attributes['width'] = '150px')
|
..attributes['width'] = '150px')
|
||||||
..append(querySelector('h1'));
|
..append(querySelector('h1')!);
|
||||||
final subt = header.querySelector('.subtitle');
|
final subt = header.querySelector('.subtitle');
|
||||||
if (subt != null) {
|
if (subt != null) {
|
||||||
header.append(subt);
|
header.append(subt);
|
||||||
@ -31,8 +42,8 @@ Future<void> wrapTables() async {
|
|||||||
// All images that are not nested inside a link will be linkified to themselves.
|
// All images that are not nested inside a link will be linkified to themselves.
|
||||||
Future<void> linkifyImg() async {
|
Future<void> linkifyImg() async {
|
||||||
querySelectorAll('img').forEach((img) {
|
querySelectorAll('img').forEach((img) {
|
||||||
if (img.parent.tagName == 'P') {
|
if (img.parent!.tagName == 'P') {
|
||||||
final link = Element.a()..attributes['href'] = img.attributes['src'];
|
final link = Element.a()..attributes['href'] = img.attributes['src']!;
|
||||||
img.insertAdjacentElement('beforeBegin', link);
|
img.insertAdjacentElement('beforeBegin', link);
|
||||||
link.append(img);
|
link.append(img);
|
||||||
}
|
}
|
||||||
@ -40,12 +51,22 @@ Future<void> linkifyImg() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> reorganizeHtml() async {
|
Future<void> reorganizeHtml() async {
|
||||||
|
final ls = window.localStorage;
|
||||||
|
final lastUpdate = '20210330';
|
||||||
|
if (ls['last-update'] != lastUpdate) {
|
||||||
|
ls['last-update'] = lastUpdate;
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
// Make navbar
|
// Make navbar
|
||||||
final navbar = await makeNavbar();
|
final navbar = await makeNavbar();
|
||||||
|
|
||||||
// Make header
|
// Make header
|
||||||
final header = await makeHeader();
|
final header = await makeHeader();
|
||||||
|
|
||||||
|
// Add decorative divs to source block wrappers
|
||||||
|
await makeDecorativeButtonsOrgSrc();
|
||||||
|
|
||||||
// wrap tables in container for better SCSS display
|
// wrap tables in container for better SCSS display
|
||||||
await wrapTables();
|
await wrapTables();
|
||||||
|
|
||||||
@ -53,10 +74,10 @@ Future<void> reorganizeHtml() async {
|
|||||||
await linkifyImg();
|
await linkifyImg();
|
||||||
|
|
||||||
// Add navbar to page
|
// Add navbar to page
|
||||||
querySelector('body').insertAdjacentElement('afterBegin', navbar);
|
querySelector('body')!.insertAdjacentElement('afterBegin', navbar);
|
||||||
|
|
||||||
// Add headet to page
|
// Add headet to page
|
||||||
querySelector('#content').insertAdjacentElement('beforeBegin', header);
|
querySelector('#content')!.insertAdjacentElement('beforeBegin', header);
|
||||||
|
|
||||||
// Add correct class to TOC
|
// Add correct class to TOC
|
||||||
final toc = (querySelector('#table-of-contents') ??
|
final toc = (querySelector('#table-of-contents') ??
|
||||||
@ -64,7 +85,7 @@ Future<void> reorganizeHtml() async {
|
|||||||
..attributes['id'] = 'table-of-contents'
|
..attributes['id'] = 'table-of-contents'
|
||||||
..innerText = 'Table of Contents Unavailable'))
|
..innerText = 'Table of Contents Unavailable'))
|
||||||
..classes.add('dropdown');
|
..classes.add('dropdown');
|
||||||
navbar.querySelector('#toc-drop').append(toc);
|
navbar.querySelector('#toc-drop')!.append(toc);
|
||||||
|
|
||||||
// Remove all <br> tags from HTML
|
// Remove all <br> tags from HTML
|
||||||
querySelectorAll('br').forEach((br) => br.remove());
|
querySelectorAll('br').forEach((br) => br.remove());
|
||||||
|
@ -1,53 +1,20 @@
|
|||||||
import 'dart:html';
|
import 'dart:html' show window, querySelector;
|
||||||
|
|
||||||
class Theme {
|
|
||||||
String _name;
|
|
||||||
String _icon;
|
|
||||||
|
|
||||||
Theme(String t_name, String t_icon) {
|
|
||||||
_name = t_name;
|
|
||||||
_icon = t_icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
String getIcon() => _icon;
|
|
||||||
String getName() => _name;
|
|
||||||
}
|
|
||||||
|
|
||||||
final themes = {
|
|
||||||
'light': Theme('light', 'fa-sun'),
|
|
||||||
'dark': Theme('dark', 'fa-lightbulb'),
|
|
||||||
'black': Theme('black', 'fa-moon')
|
|
||||||
};
|
|
||||||
|
|
||||||
final localStorage = window.localStorage;
|
final localStorage = window.localStorage;
|
||||||
|
|
||||||
|
Future<void> setTheme([String? theme]) async {
|
||||||
|
theme ??= localStorage['theme'] ??
|
||||||
|
(window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
? 'dark'
|
||||||
|
: 'light');
|
||||||
|
localStorage['theme'] = theme;
|
||||||
|
querySelector('body')!
|
||||||
|
..classes.clear()
|
||||||
|
..classes.add(theme);
|
||||||
|
}
|
||||||
|
|
||||||
void enableThemeChanger() {
|
void enableThemeChanger() {
|
||||||
final darkBtn = querySelector('#darkBtn');
|
final themes = <String>['light', 'dark', 'black'];
|
||||||
final lightBtn = querySelector('#lightBtn');
|
themes.forEach((theme) =>
|
||||||
final blackBtn = querySelector('#blackBtn');
|
querySelector('#${theme}Btn')!.onClick.listen((_) => setTheme(theme)));
|
||||||
|
|
||||||
lightBtn.onClick.listen((_) => switchTheme(themes['light']));
|
|
||||||
darkBtn.onClick.listen((_) => switchTheme(themes['dark']));
|
|
||||||
blackBtn.onClick.listen((_) => switchTheme(themes['black']));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> setTheme() async {
|
|
||||||
final currentTheme = themes[localStorage['theme']] ??
|
|
||||||
() {
|
|
||||||
final devicePrefersDark =
|
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
||||||
return themes[devicePrefersDark ? 'dark' : 'light'];
|
|
||||||
}();
|
|
||||||
querySelector('body')
|
|
||||||
..classes.clear()
|
|
||||||
..classes.add(currentTheme.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
void switchTheme(Theme currentTheme) {
|
|
||||||
// Set HTML theme
|
|
||||||
querySelector('body')
|
|
||||||
..classes.clear()
|
|
||||||
..classes.add(currentTheme.getName());
|
|
||||||
// Set storage theme
|
|
||||||
localStorage['theme'] = currentTheme.getName();
|
|
||||||
}
|
}
|
||||||
|
2
web/style/main.scss
Normal file
2
web/style/main.scss
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@import "themes.scss";
|
||||||
|
@import "style.scss";
|
@ -1,4 +1,4 @@
|
|||||||
/* Variables *****************************************************************/
|
// Variables //////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
$switch-small-screen: "only screen and (max-width: 600px)";
|
$switch-small-screen: "only screen and (max-width: 600px)";
|
||||||
$switch-smaller-screen: "only screen and (max-width: 400px)";
|
$switch-smaller-screen: "only screen and (max-width: 400px)";
|
||||||
@ -6,262 +6,7 @@ $switch-smaller-screen: "only screen and (max-width: 400px)";
|
|||||||
$navbar-height: 70px;
|
$navbar-height: 70px;
|
||||||
$postamble-height: 55px;
|
$postamble-height: 55px;
|
||||||
|
|
||||||
$tooltip-underline-size: 3px;
|
// Style //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Themes /////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
$dark: rgba( 52, 73, 94, 1);
|
|
||||||
$black: rgba( 0, 0, 0, 1);
|
|
||||||
$accent1: rgba( 93, 115, 126, 1);
|
|
||||||
$accent2: rgba( 92, 172, 126, 1);
|
|
||||||
$accent3: rgba(197, 193, 155, 1);
|
|
||||||
$light: #eee;
|
|
||||||
$grey1: #f8f8f8;
|
|
||||||
$grey2: #dbe1e8;
|
|
||||||
$grey3: #b2becd;
|
|
||||||
$grey4: #6c7983;
|
|
||||||
$grey5: #454e56;
|
|
||||||
$grey6: #12181b;
|
|
||||||
|
|
||||||
// Accent 1
|
|
||||||
// Black
|
|
||||||
$gradient-accent1-black-left: linear-gradient(to left, $black, $accent1, $accent1);
|
|
||||||
$gradient-accent1-black-right: linear-gradient(to right, $black, $accent1, $accent1);
|
|
||||||
// Dark
|
|
||||||
$gradient-accent1-dark-left: linear-gradient(to left, $dark, $accent1);
|
|
||||||
$gradient-accent1-dark-right: linear-gradient(to right, $dark, $accent1);
|
|
||||||
// Light
|
|
||||||
$gradient-accent1-light-left: linear-gradient(to left, $light, $accent1);
|
|
||||||
$gradient-accent1-light-right: linear-gradient(to right, $light, $accent1);
|
|
||||||
// Accent 2
|
|
||||||
// Black
|
|
||||||
$gradient-accent2-black-left: linear-gradient(to left, $black, $accent2, $accent2);
|
|
||||||
$gradient-accent2-black-right: linear-gradient(to right, $black, $accent2, $accent2);
|
|
||||||
// Dark
|
|
||||||
$gradient-accent2-dark-left: linear-gradient(to left, $dark, $accent2);
|
|
||||||
$gradient-accent2-dark-right: linear-gradient(to right, $dark, $accent2);
|
|
||||||
// Light
|
|
||||||
$gradient-accent2-light-left: linear-gradient(to left, $light, $accent2);
|
|
||||||
$gradient-accent2-light-right: linear-gradient(to right, $light, $accent2);
|
|
||||||
// Accent 3
|
|
||||||
// Black
|
|
||||||
$gradient-accent3-black-left: linear-gradient(to left, $black, $accent3, $accent3);
|
|
||||||
$gradient-accent3-black-right: linear-gradient(to right, $black, $accent3, $accent3);
|
|
||||||
// Dark
|
|
||||||
$gradient-accent3-dark-left: linear-gradient(to left, $dark, $accent3);
|
|
||||||
$gradient-accent3-dark-right: linear-gradient(to right, $dark, $accent3);
|
|
||||||
// Light
|
|
||||||
$gradient-accent3-light-left: linear-gradient(to left, $light, $accent3);
|
|
||||||
$gradient-accent3-light-right: linear-gradient(to right, $light, $accent3);
|
|
||||||
|
|
||||||
.light {
|
|
||||||
$bg-nav: $gradient-accent3-light-right;
|
|
||||||
$border-color: $accent1;
|
|
||||||
|
|
||||||
color: $dark;
|
|
||||||
background: $light;
|
|
||||||
|
|
||||||
transition: background 500ms ease-in-out, color 1s ease-in-out;
|
|
||||||
|
|
||||||
pre {
|
|
||||||
box-shadow: 3px 5px $dark;
|
|
||||||
border-color: $light;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.src {
|
|
||||||
&::before {
|
|
||||||
background-color: $light;
|
|
||||||
color: $dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar, header {
|
|
||||||
background: $bg-nav;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar svg {
|
|
||||||
fill: $dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
|
||||||
background: $gradient-accent3-light-left;
|
|
||||||
color: $dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip {
|
|
||||||
border-bottom: $tooltip-underline-size dotted $accent3;
|
|
||||||
|
|
||||||
.tooltiptext {
|
|
||||||
background-color: $accent3;
|
|
||||||
color: $dark;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
border-color: $accent3 transparent transparent transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown {
|
|
||||||
background: $accent3;
|
|
||||||
color: $dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content {
|
|
||||||
a {
|
|
||||||
box-shadow: inset 0 -3px 0 $accent3;
|
|
||||||
transition: box-shadow 300ms ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 -23px 0 $accent3;
|
|
||||||
transition: box-shadow 300ms ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
table, th, td {
|
|
||||||
border: 1px solid $dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
background: darken($light, 5%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.gentree {
|
|
||||||
filter: invert(0%);
|
|
||||||
transition: filter 1s ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark, .black {
|
|
||||||
$bg-nav: $gradient-accent2-dark-right;
|
|
||||||
$border-color: $dark;
|
|
||||||
|
|
||||||
color: $light;
|
|
||||||
background: $dark;
|
|
||||||
|
|
||||||
transition: background 500ms ease-in-out, color 1s ease-in-out;
|
|
||||||
|
|
||||||
pre {
|
|
||||||
box-shadow: 3px 3px $dark;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.src {
|
|
||||||
&::before {
|
|
||||||
background-color: $dark;
|
|
||||||
color: $light;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar, header {
|
|
||||||
background: $bg-nav;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar svg {
|
|
||||||
fill: $light;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
|
||||||
background: $gradient-accent2-dark-left;
|
|
||||||
color: $light;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip {
|
|
||||||
border-bottom: $tooltip-underline-size dotted $accent1;
|
|
||||||
|
|
||||||
.tooltiptext {
|
|
||||||
background-color: $accent1;
|
|
||||||
color: $light;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
border-color: $accent1 transparent transparent transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown {
|
|
||||||
background: $dark;
|
|
||||||
color: $light;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content {
|
|
||||||
a {
|
|
||||||
box-shadow: inset 0 -3px 0 $accent2;
|
|
||||||
transition: box-shadow 300ms ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 -23px 0 $accent2;
|
|
||||||
transition: box-shadow 300ms ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
table, th, td {
|
|
||||||
border: 1px solid $accent1;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
background: darken($dark, 2.5%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.gentree {
|
|
||||||
filter: invert(100%);
|
|
||||||
transition: filter 1s ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.black {
|
|
||||||
$bg-nav: $gradient-accent1-black-right;
|
|
||||||
|
|
||||||
background: $black;
|
|
||||||
|
|
||||||
pre {
|
|
||||||
box-shadow: 3px 3px $light;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre.src {
|
|
||||||
&::before {
|
|
||||||
background-color: $black;
|
|
||||||
color: $light;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar, header {
|
|
||||||
background: $bg-nav;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
|
||||||
background: $gradient-accent1-black-left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown {
|
|
||||||
background: $dark;
|
|
||||||
color: $light;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content {
|
|
||||||
a {
|
|
||||||
box-shadow: inset 0 -3px 0 $accent1;
|
|
||||||
transition: box-shadow 300ms ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset 0 -23px 0 $accent1;
|
|
||||||
transition: box-shadow 300ms ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
table, th, td {
|
|
||||||
border: 1px solid $light;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
background: lighten($black, 15%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Style *********************************************************************/
|
|
||||||
|
|
||||||
* {
|
* {
|
||||||
outline: none;
|
outline: none;
|
||||||
@ -343,7 +88,6 @@ header {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
min-height: 3rem;
|
min-height: 3rem;
|
||||||
margin-top: 1rem;
|
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
||||||
@ -363,22 +107,22 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#table-of-contents, #drop-page {
|
#table-of-contents, #drop-page {
|
||||||
top: $navbar-height / 1.3;
|
top: $navbar-height;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
height: 500%;
|
height: 80vh;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#theme-dropdown {
|
#theme-dropdown {
|
||||||
width: 150px;
|
width: 250px;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
transform: translateX(-75%);
|
transform: translateX(-75%);
|
||||||
}
|
}
|
||||||
|
|
||||||
#lightBtn, #darkBtn, #blackBtn {
|
.themeBtn {
|
||||||
content: ' ';
|
content: ' ';
|
||||||
border: 2px solid white;
|
border: 2px solid white;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@ -389,18 +133,6 @@ header {
|
|||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#lightBtn {
|
|
||||||
background: $light;
|
|
||||||
}
|
|
||||||
|
|
||||||
#darkBtn {
|
|
||||||
background: $dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
#blackBtn {
|
|
||||||
background: $black;
|
|
||||||
}
|
|
||||||
|
|
||||||
#drop-page, #table-of-contents {
|
#drop-page, #table-of-contents {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@ -420,7 +152,7 @@ header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#drop-share, #drop-page {
|
#drop-share {
|
||||||
li {
|
li {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
@ -507,7 +239,10 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
h1, h2, h3, h4, h5, h6 {
|
||||||
text-align: center;
|
font-family: serif;
|
||||||
|
font-style: italic;
|
||||||
|
margin-left: 2em;
|
||||||
|
margin-right: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
@ -597,9 +332,17 @@ th, td {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img, svg {
|
||||||
max-height: 600px;
|
max-height: 600px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
header > img {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
border-radius: 75px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-icon {
|
.nav-icon {
|
||||||
@ -615,8 +358,72 @@ ul {
|
|||||||
padding-inline-start: 20px;
|
padding-inline-start: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre.src {
|
.org-src-container,
|
||||||
background: $dark;
|
pre {
|
||||||
color: $light;
|
border-radius: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.org-src-container {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 1em;
|
||||||
|
box-shadow: 3px 3px 10px rgba(0,0,0,.3);
|
||||||
|
min-height: 5.5em;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: -moz-fit-content;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
width: -moz-fit-content;
|
||||||
|
width: fit-content;
|
||||||
|
border: none;
|
||||||
|
box-shadow: none !important;
|
||||||
|
margin: .5em;
|
||||||
|
padding: 2.75em 1.5em !important;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre.src::before {
|
||||||
|
top: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.src-fish::before {
|
||||||
|
content: 'fish';
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.src-rust::before {
|
||||||
|
content: 'Rust';
|
||||||
|
}
|
||||||
|
|
||||||
|
.closeButton,
|
||||||
|
.minButton,
|
||||||
|
.maxButton,
|
||||||
|
.floatButton {
|
||||||
|
position: absolute;
|
||||||
|
position: absolute;
|
||||||
|
width: .8em;
|
||||||
|
height: .8em;
|
||||||
|
border-radius: .4em;
|
||||||
|
z-index: 2;
|
||||||
|
left: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.closeButton {
|
||||||
|
top: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minButton {
|
||||||
|
top: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maxButton {
|
||||||
|
top: 2.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatButton {
|
||||||
|
bottom: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.twitter-tweet {
|
||||||
|
margin: 10px auto;
|
||||||
|
}
|
||||||
|
230
web/style/themes.scss
Normal file
230
web/style/themes.scss
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
// Variables //////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
$tooltip-underline-size: 3px;
|
||||||
|
|
||||||
|
// Themes /////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
$nord0: #2e3440;
|
||||||
|
$nord1: #3b4252;
|
||||||
|
$nord2: #434c5e;
|
||||||
|
$nord3: #4c566a;
|
||||||
|
$nord4: #d8dee9;
|
||||||
|
$nord5: #e5e9f0;
|
||||||
|
$nord6: #eceff4;
|
||||||
|
$nord7: #8fbcbb;
|
||||||
|
$nord8: #88c0d0;
|
||||||
|
$nord9: #81a1c1;
|
||||||
|
$nord10: #5e81ac;
|
||||||
|
$nord11: #bf616a;
|
||||||
|
$nord12: #d08770;
|
||||||
|
$nord13: #ebcb8b;
|
||||||
|
$nord14: #a3be8c;
|
||||||
|
$nord15: #b48ead;
|
||||||
|
$dark: $nord1;
|
||||||
|
$light: $nord5;
|
||||||
|
$accent1: $nord7;
|
||||||
|
$accent2: $nord9;
|
||||||
|
$accent3: $nord8;
|
||||||
|
|
||||||
|
.light {
|
||||||
|
$border-color: $accent1;
|
||||||
|
|
||||||
|
color: $dark;
|
||||||
|
background: $light;
|
||||||
|
|
||||||
|
$bg-nav: linear-gradient(to right, $nord6, $nord4);
|
||||||
|
.navbar, header, .dropdown {
|
||||||
|
background: $bg-nav;
|
||||||
|
color: $dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar svg {
|
||||||
|
fill: $dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
transition: background 500ms ease-in-out, color 1s ease-in-out;
|
||||||
|
|
||||||
|
pre {
|
||||||
|
border-color: $light;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.src, pre.example {
|
||||||
|
&::before {
|
||||||
|
background-color: $nord6;
|
||||||
|
color: $dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.src, pre.example, .org-src-container {
|
||||||
|
background: $light;
|
||||||
|
color: $dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
background: $bg-nav;
|
||||||
|
color: $dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
border-bottom: $tooltip-underline-size dotted $accent3;
|
||||||
|
|
||||||
|
.tooltiptext {
|
||||||
|
background-color: $accent3;
|
||||||
|
color: $dark;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-color: $accent3 transparent transparent transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
a {
|
||||||
|
box-shadow: inset 0 -3px 0 $accent3;
|
||||||
|
transition: box-shadow 300ms ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: inset 0 -23px 0 $accent3;
|
||||||
|
transition: box-shadow 300ms ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid $dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: darken($light, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gentree {
|
||||||
|
filter: invert(0%);
|
||||||
|
transition: filter 1s ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.black, .dark {
|
||||||
|
$border-color: $nord1;
|
||||||
|
|
||||||
|
color: $nord6;
|
||||||
|
background: $nord0;
|
||||||
|
|
||||||
|
$bg-nav: linear-gradient(to right, $nord3, $nord1);
|
||||||
|
.navbar, header, .dropdown {
|
||||||
|
background: $bg-nav;
|
||||||
|
color: $light;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar svg {
|
||||||
|
fill: $light;
|
||||||
|
}
|
||||||
|
|
||||||
|
transition: background 500ms ease-in-out, color 1s ease-in-out;
|
||||||
|
|
||||||
|
pre {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.src, pre.example {
|
||||||
|
&::before {
|
||||||
|
background-color: $nord0;
|
||||||
|
color: $nord6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
background: $bg-nav;
|
||||||
|
color: $nord6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
border-bottom: $tooltip-underline-size dotted $nord7;
|
||||||
|
|
||||||
|
.tooltiptext {
|
||||||
|
background-color: $nord7;
|
||||||
|
color: $nord6;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-color: $nord7 transparent transparent transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
a {
|
||||||
|
box-shadow: inset 0 -3px 0 $nord7;
|
||||||
|
transition: box-shadow 300ms ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: inset 0 -23px 0 $nord7;
|
||||||
|
transition: box-shadow 300ms ease-in-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid $nord7;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background: darken($nord0, 2.5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gentree {
|
||||||
|
filter: invert(100%);
|
||||||
|
transition: filter 1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.src, pre.example, .org-src-container {
|
||||||
|
background: $nord1;
|
||||||
|
color: $nord5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.black {
|
||||||
|
background: black;
|
||||||
|
color: $nord4;
|
||||||
|
|
||||||
|
$bg-nav: linear-gradient(to right, $nord2, $nord0);
|
||||||
|
.navbar, header, .dropdown {
|
||||||
|
background: $bg-nav;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.src, pre.example, .org-src-container {
|
||||||
|
background: $nord0;
|
||||||
|
color: $nord4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#lightBtn {
|
||||||
|
background: $light;
|
||||||
|
}
|
||||||
|
|
||||||
|
#darkBtn {
|
||||||
|
background: $nord0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#blackBtn {
|
||||||
|
background: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.closeButton {
|
||||||
|
background-color: $nord11;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minButton {
|
||||||
|
background-color: $nord12;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maxButton {
|
||||||
|
background-color: $nord14;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floatButton {
|
||||||
|
background-color: $nord15;
|
||||||
|
}
|
Reference in New Issue
Block a user