simple-jekyll-theme 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,48 @@
1
+ // Mobile Critical
2
+
3
+ @include tablet {
4
+ .container {
5
+ width: 75%;
6
+ }
7
+ #main-header {
8
+ a {
9
+ font-size: $huge;
10
+ }
11
+ }
12
+ figure > img {
13
+ width: 75%;
14
+ }
15
+ }
16
+
17
+ @include phone {
18
+ .container {
19
+ width: 90%;
20
+ }
21
+ #main-header {
22
+ a {
23
+ font-size: 10vw;
24
+ }
25
+ }
26
+ .header {
27
+ font-size: $LARGE;
28
+ }
29
+ figure > img {
30
+ width: 95%;
31
+ }
32
+ table {
33
+ width: 95%;
34
+ }
35
+ // https://stackoverflow.com/questions/5303263/fix-font-size-issue-on-mobile-safari-iphone-where-text-is-rendered-inconsisten
36
+ td {
37
+ -webkit-text-size-adjust:100%;
38
+ }
39
+ #blog-list a .card{
40
+ @include float-card;
41
+ padding-top: 10px;
42
+ padding-bottom: 10px;
43
+ .post-title {
44
+ font-size: $large;
45
+ font-weight: 600;
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,107 @@
1
+ // Print Styles
2
+
3
+ @media print {
4
+
5
+ @page {
6
+ size: A4;
7
+ }
8
+
9
+ *,
10
+ *::before,
11
+ *::after {
12
+ background: #fff !important;
13
+ color: #000 !important;
14
+ /* Black prints faster */
15
+ box-shadow: none !important;
16
+ text-shadow: none !important;
17
+ }
18
+
19
+ .container {
20
+ width: 90%;
21
+ }
22
+
23
+ body {
24
+ font-size: 12pt;
25
+ }
26
+
27
+ #main-header a {
28
+ font-size: 24pt;
29
+ }
30
+
31
+ #main-footer {
32
+ font-size: 11pt;
33
+ }
34
+
35
+ .header {
36
+ font-size: 18pt;
37
+ }
38
+
39
+ h1 {
40
+ font-size: 14pt;
41
+ }
42
+
43
+ h2 {
44
+ font-size: 13pt;
45
+ }
46
+
47
+ h3, h4 {
48
+ font-size: 12pt;
49
+ }
50
+
51
+ #navbar, #share-btn, #utterances, .reversefootnote {
52
+ display: none;
53
+ }
54
+
55
+ a[href]::after {
56
+ content: " (" attr(href) ")";
57
+ font-size: 80%;
58
+ }
59
+
60
+ abbr[title]::after {
61
+ content: " (" attr(title) ")";
62
+ }
63
+
64
+ /*
65
+ * Don't show links that are fragment identifiers,
66
+ * or use the `javascript:` pseudo protocol
67
+ */
68
+ a[href^="/index.html"]::after,
69
+ .tag a::after,
70
+ a[href^="#"]::after,
71
+ a[href^="javascript:"]::after {
72
+ content: "";
73
+ }
74
+
75
+ img {
76
+ max-width: 500px;
77
+ }
78
+
79
+ pre {
80
+ white-space: pre-wrap !important;
81
+ }
82
+
83
+ pre, blockquote, figure {
84
+ break-inside: avoid;
85
+ }
86
+
87
+ /*
88
+ * Printing Tables:
89
+ * https://web.archive.org/web/20180815150934/http://css-discuss.incutio.com/wiki/Printing_Tables
90
+ */
91
+ thead {
92
+ display: table-header-group;
93
+ }
94
+
95
+ tr,img {
96
+ break-inside: avoid;
97
+ }
98
+
99
+ p,h2,h3 {
100
+ orphans: 3;
101
+ widows: 3;
102
+ }
103
+
104
+ h1, h2, h3, h4, h5 {
105
+ break-after: avoid;
106
+ }
107
+ }
@@ -0,0 +1,15 @@
1
+ ---
2
+ ---
3
+ /*!
4
+ * © 2020 W Zhang
5
+ * For weixuanz.github.io
6
+ */
7
+
8
+ @import "definitions";
9
+
10
+ @import "main";
11
+
12
+ @import "blog";
13
+ @include blog-critical;
14
+
15
+ @import "mobile";
@@ -0,0 +1,14 @@
1
+ ---
2
+ ---
3
+ /*!
4
+ * © 2020 W Zhang
5
+ * For weixuanz.github.io, non-critical styles
6
+ */
7
+
8
+ @import "definitions";
9
+
10
+ @import "blog";
11
+ @include blog-noncritical;
12
+
13
+ @import "code";
14
+ @import "print";
@@ -0,0 +1,234 @@
1
+ /**
2
+ * @preserve W Zhang
3
+ * For weixuanz.github.io
4
+ */
5
+
6
+ /* Dark Toggle
7
+ * Modified, from https://gist.github.com/kslstn/20f654fd27eb29619040c74fa6526919
8
+ */
9
+
10
+ ;(function initializeTheme() {
11
+ syncBetweenTabs()
12
+ listenToOS()
13
+ listenToCheckbox()
14
+ hideCheckbox()
15
+
16
+ updatePref(storedPref() || OSPref(), false)
17
+ })()
18
+
19
+ // Helper Functions
20
+
21
+ function currentPref() {
22
+ return document.querySelector('#dark-toggle-box').checked ? 'dark' : 'light'
23
+ }
24
+
25
+ function OSPref() {
26
+ return window.matchMedia('(prefers-color-scheme: dark)').matches
27
+ ? 'dark'
28
+ : 'light'
29
+ }
30
+
31
+ function storedPref() {
32
+ const pref = localStorage.getItem('preference-theme')
33
+ if (pref === 'light') return 'light'
34
+ else if (pref === 'dark') return 'dark'
35
+ else return undefined
36
+ }
37
+
38
+ function updateCheckbox(pref) {
39
+ document.querySelector('#dark-toggle-box').checked = pref === 'dark'
40
+ }
41
+
42
+ function savePref(key, value) {
43
+ localStorage.setItem(key, value)
44
+ }
45
+
46
+ function updatePref(
47
+ newPref,
48
+ withTransition = true,
49
+ save = true,
50
+ override = false
51
+ ) {
52
+ const root = document.documentElement
53
+ const els = elsRequireTransit([
54
+ 'body',
55
+ '#navbar',
56
+ '#main-header',
57
+ 'code',
58
+ '#blog-list-mini',
59
+ '.card',
60
+ '#toc'
61
+ ])
62
+ if ((currentPref() === 'dark' || override) && newPref === 'light') {
63
+ if (withTransition) toggleTransition(els)
64
+ root.classList.remove('theme-dark')
65
+ navbar.style.background = '#fff'
66
+ updateCheckbox('light')
67
+ if (withTransition)
68
+ setTimeout(() => {
69
+ toggleTransition(els, false)
70
+ }, 1000)
71
+ } else if ((currentPref() === 'light' || override) && newPref === 'dark') {
72
+ if (withTransition) toggleTransition(els)
73
+ root.classList.add('theme-dark')
74
+ navbar.style.background = '#121212'
75
+ updateCheckbox('dark')
76
+ if (withTransition)
77
+ setTimeout(() => {
78
+ toggleTransition(els, false)
79
+ }, 1000)
80
+ }
81
+ if (save) savePref('preference-theme', newPref)
82
+ }
83
+
84
+ function toggleTransition(els, addTransit = true) {
85
+ els.map((el) => {
86
+ addTransit
87
+ ? el.forEach((e) => e.classList.add('theme-transit'))
88
+ : el.forEach((e) => e.classList.remove('theme-transit'))
89
+ })
90
+ }
91
+
92
+ function elsRequireTransit(els) {
93
+ return els.map((el) => document.querySelectorAll(el))
94
+ }
95
+
96
+ // Event Listeners
97
+
98
+ function hideCheckbox() {
99
+ const toggleLabel = document.querySelector('#dark-toggle-label')
100
+ window.addEventListener('scroll', function () {
101
+ if (this.scrollY >= nav_init) {
102
+ toggleLabel.classList.add('transparent')
103
+ if (currentPref() === 'dark') {
104
+ navbar.style.background = '#22222280'
105
+ }
106
+ } else {
107
+ toggleLabel.classList.remove('transparent')
108
+ if (currentPref() === 'dark') {
109
+ navbar.style.background = '#121212'
110
+ }
111
+ }
112
+ })
113
+ }
114
+
115
+ function syncBetweenTabs() {
116
+ window.addEventListener('storage', (e) => {
117
+ if (e.key === 'preference-theme') {
118
+ if (e.newValue === 'light') {
119
+ updatePref('light', true, false)
120
+ } else if (e.newValue === 'dark') {
121
+ updatePref('dark', true, false)
122
+ }
123
+ }
124
+ })
125
+ }
126
+
127
+ function listenToOS() {
128
+ const mediaQueryList = window.matchMedia('(prefers-color-scheme: dark)')
129
+ mediaQueryList.addListener((m) => {
130
+ if (m.matches !== true) {
131
+ updatePref('light')
132
+ } else {
133
+ updatePref('dark')
134
+ }
135
+ })
136
+ }
137
+
138
+ function listenToCheckbox() {
139
+ const checkbox = document.querySelector('#dark-toggle-box')
140
+ checkbox.addEventListener('change', function () {
141
+ if (this.checked) {
142
+ updatePref('dark', true, true, true)
143
+ } else {
144
+ updatePref('light', true, true, true)
145
+ }
146
+ })
147
+ }
148
+
149
+ /* Code Copy
150
+ * Modified, from https://stackoverflow.com/a/48078807/10365842
151
+ */
152
+ const allCodeBlocksElements = document.querySelectorAll('div.highlighter-rouge')
153
+ allCodeBlocksElements.forEach(function (el, i) {
154
+ const currentId = `codeblock${i + 1}`
155
+ el.querySelector('code').setAttribute('id', currentId)
156
+ const clipButton = document.createElement('button')
157
+ clipButton.innerHTML = '<svg class="icon"><use xlink:href="#icon-clone-solid"></use></svg>'
158
+ clipButton.className = 'code-copy-btn'
159
+ clipButton.setAttribute('data-clipboard-target', `#${currentId}`)
160
+ clipButton.setAttribute('aria-label', `Copy ${currentId}`)
161
+ el.querySelector('code').after(clipButton)
162
+ })
163
+ if (allCodeBlocksElements.length > 0) {
164
+ new ClipboardJS('.code-copy-btn')
165
+ }
166
+
167
+ /* Share Button */
168
+ function share() {
169
+ if (navigator.share !== undefined) {
170
+ navigator
171
+ .share({
172
+ title: document.querySelector('.header').textContent,
173
+ text: 'Check this out!',
174
+ url: window.location.href
175
+ })
176
+ .then(() => console.log('Shared!'))
177
+ .catch((e) => console.error(e))
178
+ } else {
179
+ const shareButton = document.querySelector('#share-btn')
180
+ shareButton.setAttribute('data-clipboard-text', location.href)
181
+ new ClipboardJS('#share-btn')
182
+ shareButton.classList.add('shared')
183
+ setTimeout(() => {
184
+ shareButton.classList.remove('shared')
185
+ }, 5000)
186
+ }
187
+ }
188
+
189
+ const shareButton = document.querySelector('#share-btn')
190
+ if (shareButton) shareButton.addEventListener('click', share)
191
+
192
+ /* Dynamic TOC */
193
+ const toc = document.querySelector('#toc')
194
+ if (toc) {
195
+ const tocItems = Array.from(toc.querySelectorAll('li'))
196
+ const tocMapping = tocItems.map(function (item) {
197
+ const anchor = item.querySelector('a')
198
+ const targetID = anchor.getAttribute('href').slice(1)
199
+ const target = document.getElementById(targetID)
200
+
201
+ return {
202
+ listItem: item,
203
+ anchor: anchor,
204
+ targetID: targetID,
205
+ target: target,
206
+ targetOffset: target.offsetTop
207
+ }
208
+ })
209
+
210
+ function getCurrentSection(tocMapping) {
211
+ return tocMapping.reduce((acc, val) =>
212
+ window.pageYOffset + 70 > val.targetOffset ? val : acc
213
+ )
214
+ }
215
+
216
+ function sectionUpdaterInit(initialSection = {}) {
217
+ let currentSection = initialSection
218
+ function wrapped(newSection) {
219
+ if (newSection.targetID !== currentSection.targetID) {
220
+ if (currentSection.targetID) {
221
+ currentSection.anchor.classList.remove('active')
222
+ }
223
+ newSection.anchor.classList.add('active')
224
+ currentSection = newSection
225
+ }
226
+ }
227
+ return wrapped
228
+ }
229
+
230
+ const sectionUpdater = sectionUpdaterInit()
231
+ window.addEventListener('scroll', () =>
232
+ sectionUpdater(getCurrentSection(tocMapping))
233
+ )
234
+ }
@@ -0,0 +1,13 @@
1
+ /*
2
+ W Zhang
3
+ For weixuanz.github.io
4
+ */
5
+ 'use strict';window.addEventListener("storage",a=>{"preference-theme"===a.key&&("light"===a.newValue?f("light",!0,!1):"dark"===a.newValue&&f("dark",!0,!1))});window.matchMedia("(prefers-color-scheme: dark)").addListener(a=>{!0!==a.matches?f("light"):f("dark")});document.querySelector("#dark-toggle-box").addEventListener("change",function(){this.checked?f("dark",!0,!0,!0):f("light",!0,!0,!0)});h();var k;{const a=localStorage.getItem("preference-theme");k="light"===a?"light":"dark"===a?"dark":void 0}
6
+ f(k||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"),!1);function l(){return document.querySelector("#dark-toggle-box").checked?"dark":"light"}function m(a){document.querySelector("#dark-toggle-box").checked="dark"===a}
7
+ function f(a,d=!0,b=!0,c=!1){const e=document.documentElement,g=n();"dark"!==l()&&!c||"light"!==a?"light"!==l()&&!c||"dark"!==a||(d&&p(g),e.classList.add("theme-dark"),navbar.style.background="#121212",m("dark"),d&&setTimeout(()=>{p(g,!1)},1E3)):(d&&p(g),e.classList.remove("theme-dark"),navbar.style.background="#fff",m("light"),d&&setTimeout(()=>{p(g,!1)},1E3));b&&localStorage.setItem("preference-theme",a)}
8
+ function p(a,d=!0){a.map(b=>{d?b.forEach(c=>c.classList.add("theme-transit")):b.forEach(c=>c.classList.remove("theme-transit"))})}function n(){return"body #navbar #main-header code #blog-list-mini .card #toc".split(" ").map(a=>document.querySelectorAll(a))}
9
+ function h(){const a=document.querySelector("#dark-toggle-label");window.addEventListener("scroll",function(){this.scrollY>=nav_init?(a.classList.add("transparent"),"dark"===l()&&(navbar.style.background="#22222280")):(a.classList.remove("transparent"),"dark"===l()&&(navbar.style.background="#121212"))})}const q=document.querySelectorAll("div.highlighter-rouge");
10
+ q.forEach(function(a,d){d=`codeblock${d+1}`;a.querySelector("code").setAttribute("id",d);const b=document.createElement("button");b.innerHTML='<svg class="icon"><use xlink:href="#icon-clone-solid"></use></svg>';b.className="code-copy-btn";b.setAttribute("data-clipboard-target",`#${d}`);b.setAttribute("aria-label",`Copy ${d}`);a.querySelector("code").after(b)});0<q.length&&new ClipboardJS(".code-copy-btn");
11
+ function r(){if(void 0!==navigator.share)navigator.share({title:document.querySelector(".header").textContent,text:"Check this out!",url:window.location.href}).then(()=>console.log("Shared!")).catch(a=>console.error(a));else{const a=document.querySelector("#share-btn");a.setAttribute("data-clipboard-text",location.href);new ClipboardJS("#share-btn");a.classList.add("shared");setTimeout(()=>{a.classList.remove("shared")},5E3)}}const t=document.querySelector("#share-btn");
12
+ t&&t.addEventListener("click",r);const u=document.querySelector("#toc");
13
+ if(u){var v=function(b){return b.reduce((c,e)=>window.pageYOffset+70>e.b?e:c)};const a=Array.from(u.querySelectorAll("li")).map(function(b){const c=b.querySelector("a"),e=c.getAttribute("href").slice(1),g=document.getElementById(e);return{c:b,anchor:c,a:e,target:g,b:g.offsetTop}}),d=function(b={}){let c=b;return function(e){e.a!==c.a&&(c.a&&c.anchor.classList.remove("active"),e.anchor.classList.add("active"),c=e)}}();window.addEventListener("scroll",()=>d(v(a)))};
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @preserve W Zhang
3
+ * For weixuanz.github.io
4
+ */
5
+
6
+ const loadBtn = document.querySelector('#loadmore-btn')
7
+ loadBtn.addEventListener('click', loadNextPage)
8
+
9
+ function loadNextPage() {
10
+ const postList = document.querySelector('#blog-list')
11
+ const currentPage = +postList.getAttribute('data-page')
12
+ const totalPages = +postList.getAttribute('data-totalPages')
13
+
14
+ const setBusy = () => {
15
+ loadBtn.textContent = 'Loading...'
16
+ loadBtn.disabled = true
17
+ }
18
+ const setInitial = () => {
19
+ loadBtn.textContent = 'Load more...'
20
+ loadBtn.disabled = false
21
+ }
22
+
23
+ if (currentPage === totalPages) {
24
+ return
25
+ }
26
+
27
+ setBusy()
28
+
29
+ const opts = {
30
+ method: 'GET',
31
+ headers: {}
32
+ }
33
+
34
+ fetch(`/page${currentPage + 1}`, opts)
35
+ .then((response) => response.text())
36
+ .then((html) => {
37
+ const parser = new DOMParser()
38
+ const doc = parser.parseFromString(html, 'text/html')
39
+ doc
40
+ .querySelectorAll('#blog-list a')
41
+ .forEach((el) => postList.appendChild(el))
42
+
43
+ setInitial()
44
+ postList.setAttribute('data-page', currentPage + 1)
45
+
46
+ if (currentPage + 1 === totalPages) {
47
+ loadBtn.onclick = null
48
+ loadBtn.remove()
49
+ }
50
+ })
51
+ }