jekyll-wikibonsai 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +57 -0
- data/_config.yml +269 -0
- data/_data/emoji.yml +46 -0
- data/_data/themes.yml +145 -0
- data/_includes/anchor-headings.html +156 -0
- data/_includes/branch.html +18 -0
- data/_includes/btn_state.html +14 -0
- data/_includes/connect.html +46 -0
- data/_includes/cookie-consent.html +79 -0
- data/_includes/dates.html +22 -0
- data/_includes/hp-tooltip.html +106 -0
- data/_includes/img/bullet-ancestor.svg +5 -0
- data/_includes/img/bullet-branch.svg +7 -0
- data/_includes/img/bullet-net-web.svg +9 -0
- data/_includes/img/bullet-tree.svg +9 -0
- data/_includes/img/pencil-filter.svg +17 -0
- data/_includes/share.html +47 -0
- data/_includes/site-nav.html +100 -0
- data/_includes/tags.html +49 -0
- data/_includes/themes.scss.liquid +80 -0
- data/_includes/toc.html +187 -0
- data/_layouts/404.html +10 -0
- data/_layouts/about.html +14 -0
- data/_layouts/archive.html +77 -0
- data/_layouts/base.html +68 -0
- data/_layouts/book.html +40 -0
- data/_layouts/entry.html +269 -0
- data/_layouts/home.html +96 -0
- data/_layouts/map.html +17 -0
- data/_layouts/post.html +37 -0
- data/_layouts/privacy.html +15 -0
- data/_layouts/recent.html +66 -0
- data/_layouts/state.html +70 -0
- data/_layouts/table-wrappers.html +7 -0
- data/_layouts/vendor/compress.html +10 -0
- data/_sass/base/_code.scss +133 -0
- data/_sass/base/_layout.scss +55 -0
- data/_sass/base/_link.scss +105 -0
- data/_sass/base/_main.scss +96 -0
- data/_sass/base/_markdown.scss +281 -0
- data/_sass/base/_typography.scss +89 -0
- data/_sass/base/code_themes/_gruvbox.scss +92 -0
- data/_sass/base/code_themes/_monokai.scss +217 -0
- data/_sass/base/code_themes/_solarized.scss +84 -0
- data/_sass/components/_btn.scss +95 -0
- data/_sass/components/_infobox.scss +48 -0
- data/_sass/components/_item.scss +28 -0
- data/_sass/components/_search.scss +61 -0
- data/_sass/components/_tag_pills.scss +24 -0
- data/_sass/components/_visited.scss +42 -0
- data/_sass/includes/_anchor_headings.scss +36 -0
- data/_sass/includes/_connect.scss +8 -0
- data/_sass/includes/_cookie_consent.scss +46 -0
- data/_sass/includes/_dates.scss +6 -0
- data/_sass/includes/_hp_tooltip.scss +41 -0
- data/_sass/includes/_share.scss +10 -0
- data/_sass/includes/_site_nav.scss +97 -0
- data/_sass/includes/_svg.scss +89 -0
- data/_sass/includes/_toc.scss +38 -0
- data/_sass/layouts/_404.scss +3 -0
- data/_sass/layouts/_about.scss +3 -0
- data/_sass/layouts/_archive.scss +26 -0
- data/_sass/layouts/_book.scss +17 -0
- data/_sass/layouts/_entry.scss +156 -0
- data/_sass/layouts/_home.scss +75 -0
- data/_sass/layouts/_map.scss +3 -0
- data/_sass/layouts/_post.scss +17 -0
- data/_sass/layouts/_privacy.scss +3 -0
- data/_sass/layouts/_recent.scss +77 -0
- data/_sass/layouts/_state.scss +98 -0
- data/_sass/main.scss +73 -0
- data/_sass/util/_functions.scss +9 -0
- data/_sass/util/_variables.scss +113 -0
- data/_sass/util/mixins/_buttons.scss +27 -0
- data/_sass/util/mixins/_layout.scss +81 -0
- data/_sass/util/mixins/_typography.scss +84 -0
- data/_sass/vendor/normalize.scss/README.md +7 -0
- data/_sass/vendor/normalize.scss/normalize.scss +349 -0
- data/assets/css/styles.scss +31 -0
- data/assets/font/Cutive_Mono/CutiveMono-Regular.ttf +0 -0
- data/assets/font/Cutive_Mono/OFL.txt +93 -0
- data/assets/font/Old_Standard_TT/OFL.txt +93 -0
- data/assets/font/Old_Standard_TT/OldStandardTT-Bold.ttf +0 -0
- data/assets/font/Old_Standard_TT/OldStandardTT-Italic.ttf +0 -0
- data/assets/font/Old_Standard_TT/OldStandardTT-Regular.ttf +0 -0
- data/assets/font/exo2/Exo2-Italic-VariableFont_wght.ttf +0 -0
- data/assets/font/exo2/Exo2-VariableFont_wght.ttf +0 -0
- data/assets/font/exo2/OFL.txt +93 -0
- data/assets/font/exo2/README.txt +81 -0
- data/assets/font/exo2/static/Exo2-Black.ttf +0 -0
- data/assets/font/exo2/static/Exo2-BlackItalic.ttf +0 -0
- data/assets/font/exo2/static/Exo2-Bold.ttf +0 -0
- data/assets/font/exo2/static/Exo2-BoldItalic.ttf +0 -0
- data/assets/font/exo2/static/Exo2-ExtraBold.ttf +0 -0
- data/assets/font/exo2/static/Exo2-ExtraBoldItalic.ttf +0 -0
- data/assets/font/exo2/static/Exo2-ExtraLight.ttf +0 -0
- data/assets/font/exo2/static/Exo2-ExtraLightItalic.ttf +0 -0
- data/assets/font/exo2/static/Exo2-Italic.ttf +0 -0
- data/assets/font/exo2/static/Exo2-Light.ttf +0 -0
- data/assets/font/exo2/static/Exo2-LightItalic.ttf +0 -0
- data/assets/font/exo2/static/Exo2-Medium.ttf +0 -0
- data/assets/font/exo2/static/Exo2-MediumItalic.ttf +0 -0
- data/assets/font/exo2/static/Exo2-Regular.ttf +0 -0
- data/assets/font/exo2/static/Exo2-SemiBold.ttf +0 -0
- data/assets/font/exo2/static/Exo2-SemiBoldItalic.ttf +0 -0
- data/assets/font/exo2/static/Exo2-Thin.ttf +0 -0
- data/assets/font/exo2/static/Exo2-ThinItalic.ttf +0 -0
- data/assets/img/bonsai-dark.png +0 -0
- data/assets/img/bonsai-dark.svg +106 -0
- data/assets/img/bonsai-light.png +0 -0
- data/assets/img/bonsai-light.svg +81 -0
- data/assets/img/bonsai-star.png +0 -0
- data/assets/img/bonsai-star.svg +1 -0
- data/assets/img/books/the-ancient-art-of-bonsai.png +0 -0
- data/assets/img/favicon-dark.png +0 -0
- data/assets/img/favicon-light.png +0 -0
- data/assets/img/nav-base-dark.svg +1 -0
- data/assets/img/nav-base-light.svg +1 -0
- data/assets/img/nav-base-star.svg +1 -0
- data/assets/img/nav-bonsai-dark.svg +1 -0
- data/assets/img/nav-bonsai-light.svg +1 -0
- data/assets/img/nav-bonsai-star.svg +1 -0
- data/assets/js/entry.js +130 -0
- data/assets/js/graph.js +64 -0
- data/assets/js/scripts.js +64 -0
- data/assets/js/search.js +165 -0
- data/assets/js/site-nav.js +132 -0
- data/assets/js/theme-colors.js +57 -0
- data/assets/js/vendor/lunr.js +3475 -0
- data/assets/js/vendor/lunr.min.js +6 -0
- data/assets/js/visited-nav.js +65 -0
- metadata +135 -2
data/assets/js/graph.js
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
---
|
2
|
+
---
|
3
|
+
import JekyllGraph from './jekyll-graph.js';
|
4
|
+
|
5
|
+
export default class GraphNav extends JekyllGraph {
|
6
|
+
|
7
|
+
constructor() {
|
8
|
+
super(); // 'this.graph' + 'this.graphDiv' set in JekyllGraph
|
9
|
+
this.graphTypeCheckBox = document.getElementById('graph-type-checkbox');
|
10
|
+
this.graphTypeEmojiSpan = document.getElementById('graph-type-emoji-span');
|
11
|
+
this.init(); // this.graphType set in initGraphType();
|
12
|
+
}
|
13
|
+
|
14
|
+
init() {
|
15
|
+
this.initGraphType();
|
16
|
+
this.bindEvents();
|
17
|
+
this.draw();
|
18
|
+
}
|
19
|
+
|
20
|
+
bindEvents() {
|
21
|
+
this.graphTypeCheckBox.addEventListener('click', () => {
|
22
|
+
this.updateGraphType();
|
23
|
+
this.draw();
|
24
|
+
});
|
25
|
+
}
|
26
|
+
|
27
|
+
// draw
|
28
|
+
|
29
|
+
draw() {
|
30
|
+
// redraw new chart
|
31
|
+
if (this.graphTypeCheckBox.checked) {
|
32
|
+
this.drawTree();
|
33
|
+
} else {
|
34
|
+
this.drawNetWeb();
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
redraw() {
|
39
|
+
this.updateGraphType();
|
40
|
+
this.draw();
|
41
|
+
}
|
42
|
+
|
43
|
+
// type
|
44
|
+
|
45
|
+
initGraphType() {
|
46
|
+
this.graphType = localStorage.getItem('graph-type');
|
47
|
+
if (this.graphType !== "tree" && this.graphType !== "net-web") {
|
48
|
+
this.graphType = '{{ site.bonsai.nav.graph.type }}';
|
49
|
+
}
|
50
|
+
this.graphTypeCheckBox.checked = (this.graphType === "tree");
|
51
|
+
this.updateGraphType();
|
52
|
+
}
|
53
|
+
|
54
|
+
updateGraphType() {
|
55
|
+
if (this.graphTypeCheckBox.checked) {
|
56
|
+
this.graphTypeEmojiSpan.innerText = "{{ site.data.emoji.net-web }}";
|
57
|
+
this.graphType = "tree";
|
58
|
+
} else {
|
59
|
+
this.graphTypeEmojiSpan.innerText = "{{ site.data.emoji.tree }}";
|
60
|
+
this.graphType = "net-web";
|
61
|
+
}
|
62
|
+
localStorage.setItem('graph-type', this.graphType);
|
63
|
+
}
|
64
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
---
|
2
|
+
---
|
3
|
+
import Entry from './entry.js';
|
4
|
+
import SiteNav from './site-nav.js';
|
5
|
+
|
6
|
+
// go
|
7
|
+
// from: https://stackoverflow.com/questions/9899372/pure-javascript-equivalent-of-jquerys-ready-how-to-call-a-function-when-t
|
8
|
+
(() => {
|
9
|
+
initLinks();
|
10
|
+
|
11
|
+
if (!isSafari() && !isMobile()) {
|
12
|
+
applyPencilFilter();
|
13
|
+
}
|
14
|
+
|
15
|
+
new SiteNav();
|
16
|
+
if (document.getElementById('entry')) {
|
17
|
+
new Entry();
|
18
|
+
}
|
19
|
+
})();
|
20
|
+
|
21
|
+
// helpers
|
22
|
+
|
23
|
+
function initLinks() {
|
24
|
+
// web
|
25
|
+
// open external links in new window; wiki-links in current window.
|
26
|
+
document.querySelectorAll('a.web-link').forEach(setupLinkOpen);
|
27
|
+
// wiki
|
28
|
+
// init hp-tooltip.html listeners.
|
29
|
+
document.querySelectorAll('{{ include.wrapperQuerySelector }} a.wiki-link').forEach(setupListeners);
|
30
|
+
// add microdata to wiki links
|
31
|
+
document.querySelectorAll('a.wiki-link').forEach((wikiLink) => wikiLink.classList.add('u-url'));
|
32
|
+
}
|
33
|
+
|
34
|
+
function setupLinkOpen (link) {
|
35
|
+
link.setAttribute("target", "_blank");
|
36
|
+
link.setAttribute("rel", "noopener"); // for security: https://css-tricks.com/use-target_blank/#correct-html
|
37
|
+
}
|
38
|
+
|
39
|
+
function applyPencilFilter() {
|
40
|
+
// apply pencil-filter to all svg images
|
41
|
+
let imgElements = document.getElementsByClassName('embed-image-wrapper');
|
42
|
+
Array.prototype.forEach.call(imgElements, (img) => {
|
43
|
+
if (img.firstElementChild.tagName === "svg") {
|
44
|
+
if ('{{ site.bonsai.svg.filter }}') {
|
45
|
+
// attach filter to svg element's parent because of safari/mobile bug
|
46
|
+
// bug from: https://github.com/Fyrd/caniuse/issues/3803
|
47
|
+
// workaround from: https://newbedev.com/why-is-filter-drop-shadow-causing-my-svg-to-disappear-in-safari
|
48
|
+
img.style.filter = "url(#PencilTexture)";
|
49
|
+
}
|
50
|
+
}
|
51
|
+
});
|
52
|
+
}
|
53
|
+
|
54
|
+
function isMobile() {
|
55
|
+
// from: https://stackoverflow.com/questions/58141018/mobile-device-detection
|
56
|
+
var check = false;
|
57
|
+
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
|
58
|
+
return check;
|
59
|
+
};
|
60
|
+
|
61
|
+
function isSafari() {
|
62
|
+
// Safari 3.0+ "[object HTMLElementConstructor]"
|
63
|
+
return /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && window['safari'].pushNotification));
|
64
|
+
};
|
data/assets/js/search.js
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
---
|
2
|
+
---
|
3
|
+
|
4
|
+
window.store = {
|
5
|
+
{% for doc in site.documents %}
|
6
|
+
{% unless site.bonsai.nav.search.exclude contains doc.type %}
|
7
|
+
"{{ doc.url | slugify }}": {
|
8
|
+
"title": "{{ doc.title | xml_escape }}",
|
9
|
+
"content": {{ doc.content | strip_html | strip_newlines | jsonify }},
|
10
|
+
"status": "{{ doc.status | xml_escape }}",
|
11
|
+
"tags": "{{ doc.tags | xml_escape }}",
|
12
|
+
"emoji": "{{ doc.emoji | xml_escape }}",
|
13
|
+
"url": "{{ doc.url | xml_escape }}",
|
14
|
+
}
|
15
|
+
{% unless forloop.last %},{% endunless %}
|
16
|
+
{% endunless %}
|
17
|
+
{% endfor %}
|
18
|
+
};
|
19
|
+
export default class Search {
|
20
|
+
|
21
|
+
constructor() {
|
22
|
+
this.searchBtn = document.getElementById('search-btn');
|
23
|
+
this.search = document.getElementById('search');
|
24
|
+
this.searchInput = document.getElementById('search-input');
|
25
|
+
this.searchResults = document.getElementById('search-results');
|
26
|
+
this.navContent = document.getElementById('site-nav-content');
|
27
|
+
this.init();
|
28
|
+
}
|
29
|
+
|
30
|
+
init() {
|
31
|
+
this.searchInput.classList.add('hide');
|
32
|
+
this.searchResults.classList.add('hide');
|
33
|
+
this.initIndex();
|
34
|
+
this.bindEvents();
|
35
|
+
}
|
36
|
+
|
37
|
+
bindEvents() {
|
38
|
+
// keys
|
39
|
+
/// cmd/ctrl + k
|
40
|
+
document.addEventListener('keydown', (event) => {
|
41
|
+
const macKeys = (event.metaKey && (event.key === 'k'));
|
42
|
+
const winKeys = (event.ctrlKey && (event.key === 'k'));
|
43
|
+
if (macKeys || winKeys) {
|
44
|
+
event.preventDefault();
|
45
|
+
this.toggleSearch();
|
46
|
+
}
|
47
|
+
});
|
48
|
+
// enter
|
49
|
+
document.addEventListener('keydown', (event) => {
|
50
|
+
if (event.key === 'Enter') {
|
51
|
+
this.doSearch();
|
52
|
+
}
|
53
|
+
});
|
54
|
+
/// esc
|
55
|
+
document.addEventListener('keydown', (event) => {
|
56
|
+
if (event.key === 'Escape') {
|
57
|
+
this.hideSearch();
|
58
|
+
}
|
59
|
+
});
|
60
|
+
// btn
|
61
|
+
this.searchBtn.addEventListener('click', () => {
|
62
|
+
this.toggleSearch();
|
63
|
+
});
|
64
|
+
// unfocus
|
65
|
+
this.searchInput.addEventListener('focusout', (event) => {
|
66
|
+
// click on a search result:
|
67
|
+
// if (event.relatedTarget.nodeName !== 'A')
|
68
|
+
if (!event.relatedTarget) {
|
69
|
+
this.hideSearch();
|
70
|
+
}
|
71
|
+
});
|
72
|
+
}
|
73
|
+
|
74
|
+
initIndex() {
|
75
|
+
// lunr: https://lunrjs.com/
|
76
|
+
// from: https://learn.cloudcannon.com/jekyll/jekyll-search-using-lunr-js/
|
77
|
+
// Initalize lunr with the fields it will be searching on. I've given title
|
78
|
+
// a boost of 10 to indicate matches on this field are more important.
|
79
|
+
this.idx = lunr(function () {
|
80
|
+
this.field('id');
|
81
|
+
this.field('title', { boost: 10 });
|
82
|
+
this.field('status');
|
83
|
+
// this.field('tags');
|
84
|
+
this.field('emoji');
|
85
|
+
this.field('content');
|
86
|
+
|
87
|
+
for (var key in window.store) { // Add the data to lunr
|
88
|
+
this.add({
|
89
|
+
'id': key,
|
90
|
+
'title': window.store[key].title,
|
91
|
+
'status': window.store[key].status,
|
92
|
+
// 'tags': window.store[key].tags,
|
93
|
+
'emoji': window.store[key].emoji,
|
94
|
+
'content': window.store[key].content
|
95
|
+
});
|
96
|
+
}
|
97
|
+
});
|
98
|
+
}
|
99
|
+
|
100
|
+
toggleSearch() {
|
101
|
+
if (this.searchInput.classList.contains('hide')) {
|
102
|
+
this.showSearch();
|
103
|
+
} else {
|
104
|
+
this.hideSearch();
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
showSearch() {
|
109
|
+
this.searchInput.classList.remove('hide');
|
110
|
+
this.searchInput.focus();
|
111
|
+
this.navContent.style.filter = "blur(4px)";
|
112
|
+
}
|
113
|
+
|
114
|
+
hideSearch() {
|
115
|
+
this.searchInput.classList.add('hide');
|
116
|
+
this.searchResults.classList.add('hide');
|
117
|
+
this.navContent.style.filter = "";
|
118
|
+
}
|
119
|
+
|
120
|
+
doSearch() {
|
121
|
+
// from: https://learn.cloudcannon.com/jekyll/jekyll-search-using-lunr-js/
|
122
|
+
var results = this.idx.search(this.searchInput.value);
|
123
|
+
this.displayResults(results, window.store);
|
124
|
+
}
|
125
|
+
|
126
|
+
displayResults(results, store) {
|
127
|
+
if (results.length) {
|
128
|
+
var appendString = '<ul>';
|
129
|
+
|
130
|
+
for (var i = 0; i < results.length; i++) {
|
131
|
+
var item = store[results[i].ref];
|
132
|
+
appendString += '<li>'
|
133
|
+
appendString += '<a href="' + '{{ site.baseurl }}' + item.url + '">';
|
134
|
+
if (item.status) {
|
135
|
+
appendString += '<h6> ' + item.status + ' ' + item.title + '</h6>';
|
136
|
+
} else if (item.emoji) {
|
137
|
+
appendString += '<h6> ' + item.emoji + ' ' + item.title + '</h6>';
|
138
|
+
} else {
|
139
|
+
appendString += '<h6> ' + item.title + '</h6>';
|
140
|
+
}
|
141
|
+
appendString += '<p>' + item.content.substring(0, 150) + '...</p>';
|
142
|
+
appendString += '</a>';
|
143
|
+
appendString += '</li>';
|
144
|
+
}
|
145
|
+
} else {
|
146
|
+
var appendString = '<ul><li>No results found</li></ul>';
|
147
|
+
}
|
148
|
+
this.searchResults.innerHTML = appendString + '</ul>';
|
149
|
+
this.searchResults.classList.remove('hide');
|
150
|
+
}
|
151
|
+
|
152
|
+
// getQueryVariable(variable) {
|
153
|
+
// // from: https://learn.cloudcannon.com/jekyll/jekyll-search-using-lunr-js/
|
154
|
+
// var query = window.location.search.substring(1);
|
155
|
+
// var vars = query.split('&');
|
156
|
+
|
157
|
+
// for (var i = 0; i < vars.length; i++) {
|
158
|
+
// var pair = vars[i].split('=');
|
159
|
+
|
160
|
+
// if (pair[0] === variable) {
|
161
|
+
// return decodeURIComponent(pair[1].replace(/\+/g, '%20'));
|
162
|
+
// }
|
163
|
+
// }
|
164
|
+
// }
|
165
|
+
}
|
@@ -0,0 +1,132 @@
|
|
1
|
+
---
|
2
|
+
---
|
3
|
+
|
4
|
+
import GraphNav from './graph.js';
|
5
|
+
import Search from './search.js';
|
6
|
+
import ThemeColors from './theme-colors.js';
|
7
|
+
import VisitedNav from './visited-nav.js';
|
8
|
+
|
9
|
+
export default class SiteNav {
|
10
|
+
|
11
|
+
constructor() {
|
12
|
+
// bonsai-burger --> [[.]]
|
13
|
+
this.bonsaiBurger = document.getElementById('bonsai-burger-nav-checkbox');
|
14
|
+
this.sideBar = document.getElementById('side-bar');
|
15
|
+
this.mainView = document.getElementById('main');
|
16
|
+
this.bonsai = document.getElementById('nav-bonsai');
|
17
|
+
|
18
|
+
this.bonsaiBurger.addEventListener('click', () => {
|
19
|
+
this.toggleSiteNav();
|
20
|
+
this.graph.redraw();
|
21
|
+
});
|
22
|
+
|
23
|
+
// themes
|
24
|
+
new ThemeColors();
|
25
|
+
|
26
|
+
// search
|
27
|
+
{% if site.bonsai.nav.search.enabled %}
|
28
|
+
this.search = new Search();
|
29
|
+
{% endif %}
|
30
|
+
|
31
|
+
// graph
|
32
|
+
this.graph = new GraphNav();
|
33
|
+
|
34
|
+
// visited nav
|
35
|
+
{% if site.bonsai.nav.visited.enabled %}
|
36
|
+
// attach elements
|
37
|
+
// this.navType set in initNavType();
|
38
|
+
this.navTypeCheckBox = document.getElementById('nav-type-checkbox');
|
39
|
+
this.navTypeEmojiSpan = document.getElementById('nav-type-emoji-span');
|
40
|
+
this.visited = new VisitedNav();
|
41
|
+
this.initNavType();
|
42
|
+
this.navTypeCheckBox.addEventListener('click', () => {
|
43
|
+
this.updateNavType();
|
44
|
+
});
|
45
|
+
{% endif %}
|
46
|
+
|
47
|
+
// visited data
|
48
|
+
// visitedURLs set in initVisitedData();
|
49
|
+
this.deleteVisitedBtn = document.getElementById('delete-btn');
|
50
|
+
this.initVisitedData();
|
51
|
+
this.deleteVisitedBtn.addEventListener('click', () => {
|
52
|
+
this.deleteVisitedData();
|
53
|
+
});
|
54
|
+
}
|
55
|
+
|
56
|
+
// bonsai-burger
|
57
|
+
|
58
|
+
toggleSiteNav() {
|
59
|
+
if (document.getElementById('bonsai-burger-nav-checkbox').checked) {
|
60
|
+
this.sideBar.classList.add('nav-open');
|
61
|
+
this.mainView.classList.add('hide');
|
62
|
+
this.bonsai.hidden = false;
|
63
|
+
} else {
|
64
|
+
this.sideBar.classList.remove('nav-open');
|
65
|
+
this.mainView.classList.remove('hide');
|
66
|
+
this.bonsai.hidden = true;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
// graph <-> visited toggles
|
71
|
+
|
72
|
+
initNavType() {
|
73
|
+
this.navType = localStorage.getItem('nav-type');
|
74
|
+
if (this.navType !== "graph" && this.navType !== "visited") {
|
75
|
+
this.navType = '{{ site.bonsai.nav.type }}';
|
76
|
+
}
|
77
|
+
this.navTypeCheckBox.checked = (this.navType === "graph");
|
78
|
+
this.updateNavType();
|
79
|
+
}
|
80
|
+
|
81
|
+
updateNavType() {
|
82
|
+
if (this.navTypeCheckBox.checked) {
|
83
|
+
this.navTypeEmojiSpan.innerText = "{{ site.data.emoji.visited }}";
|
84
|
+
this.navType = "graph";
|
85
|
+
this.visited.hide();
|
86
|
+
this.graph.graphDiv.classList.remove("hide");
|
87
|
+
} else {
|
88
|
+
this.navTypeEmojiSpan.innerText = "{{ site.data.emoji.graph }}";
|
89
|
+
this.navType = "visited";
|
90
|
+
this.graph.graphDiv.classList.add("hide");
|
91
|
+
this.visited.show();
|
92
|
+
}
|
93
|
+
localStorage.setItem('nav-type', this.navType);
|
94
|
+
}
|
95
|
+
|
96
|
+
// visited-data
|
97
|
+
|
98
|
+
initVisitedData() {
|
99
|
+
// init
|
100
|
+
this.visitedURLs = JSON.parse(localStorage.getItem('visited'));
|
101
|
+
if (!this.visitedURLs) this.visitedURLs = [];
|
102
|
+
// populate
|
103
|
+
if (this.visitedURLs) {
|
104
|
+
// remove duplicates to current (since json and !SortedSet)
|
105
|
+
// step backward so splicing doesn't change indeces as tabs are removed
|
106
|
+
for (var i = this.visitedURLs.length - 1; i > -1; i--) {
|
107
|
+
let aTab = this.visitedURLs[i];
|
108
|
+
if ((aTab['title'] == window.document.title)
|
109
|
+
&& (aTab['url'] == window.location.pathname)) {
|
110
|
+
this.visitedURLs.splice(i, 1);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
this.visitedURLs.push({ title: window.document.title, url: window.location.pathname });
|
114
|
+
localStorage.setItem('visited', JSON.stringify(this.visitedURLs));
|
115
|
+
}
|
116
|
+
// draw
|
117
|
+
{% if site.bonsai.nav.visited.enabled %}
|
118
|
+
this.visited.build(this.visitedURLs);
|
119
|
+
{% endif %}
|
120
|
+
}
|
121
|
+
|
122
|
+
deleteVisitedData() {
|
123
|
+
// reset
|
124
|
+
this.visitedURLs = [];
|
125
|
+
// store
|
126
|
+
localStorage.setItem('visited', JSON.stringify([]));
|
127
|
+
// redraw
|
128
|
+
{% if site.bonsai.nav.visited.enabled %}
|
129
|
+
this.visited.rebuild(this.visitedURLs);
|
130
|
+
{% endif %}
|
131
|
+
}
|
132
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
---
|
2
|
+
---
|
3
|
+
|
4
|
+
export default class ThemeColors {
|
5
|
+
constructor() {
|
6
|
+
// this.theme set in initThemeColors();
|
7
|
+
this.favicon = document.querySelector('[rel="icon"]');
|
8
|
+
this.navBonsai = document.getElementById('nav-bonsai');
|
9
|
+
this.navBase = document.getElementById('nav-base');
|
10
|
+
this.themeColorBtns = document.querySelectorAll('a[data-theme-id]');
|
11
|
+
// logo
|
12
|
+
this.homeLogo = document.getElementById('home-logo');
|
13
|
+
this.rootLogo = document.getElementById('root-logo');
|
14
|
+
this.init();
|
15
|
+
}
|
16
|
+
|
17
|
+
init() {
|
18
|
+
this.initThemeColors();
|
19
|
+
this.bindEvents();
|
20
|
+
}
|
21
|
+
|
22
|
+
bindEvents() {
|
23
|
+
Array.prototype.forEach.call(this.themeColorBtns, (btn) => {
|
24
|
+
btn.addEventListener('click', (event) => {
|
25
|
+
this.updateThemeColors(event);
|
26
|
+
});
|
27
|
+
});
|
28
|
+
}
|
29
|
+
|
30
|
+
initThemeColors() {
|
31
|
+
this.theme = localStorage.getItem("theme-colors");
|
32
|
+
if (!this.theme) {
|
33
|
+
this.theme = '{{ site.bonsai.default_theme }}' !== "" ? '{{ site.bonsai.default_theme }}' : '{{ site.data.themes[0].id }}';
|
34
|
+
}
|
35
|
+
this.updateThemeColors();
|
36
|
+
}
|
37
|
+
|
38
|
+
updateThemeColors (event) {
|
39
|
+
if (event) {
|
40
|
+
this.theme = event.target.dataset.themeId;
|
41
|
+
}
|
42
|
+
// update theme color data
|
43
|
+
document.documentElement.setAttribute('data-theme', this.theme);
|
44
|
+
// update icons and images
|
45
|
+
this.favicon.setAttribute('href', `{{site.baseurl}}${getComputedStyle(document.documentElement).getPropertyValue('--favicon-src')}`.replaceAll(/\s/g,''));
|
46
|
+
this.navBase.setAttribute('src', `{{site.baseurl}}${getComputedStyle(document.documentElement).getPropertyValue('--nav-burger-base')}`.replaceAll(/\s/g,''));
|
47
|
+
this.navBonsai.setAttribute('src', `{{site.baseurl}}${getComputedStyle(document.documentElement).getPropertyValue('--nav-burger-bonsai')}`.replaceAll(/\s/g,''));
|
48
|
+
if (this.homeLogo) {
|
49
|
+
this.homeLogo.setAttribute('src', `{{site.baseurl}}${getComputedStyle(document.documentElement).getPropertyValue('--logo-src')}`.replaceAll(/\s/g,''));
|
50
|
+
}
|
51
|
+
if (this.rootLogo) {
|
52
|
+
this.rootLogo.setAttribute('src', `{{site.baseurl}}${getComputedStyle(document.documentElement).getPropertyValue('--logo-src')}`.replaceAll(/\s/g,''));
|
53
|
+
}
|
54
|
+
// save to local storage
|
55
|
+
window.localStorage.setItem('theme-colors', this.theme);
|
56
|
+
}
|
57
|
+
}
|