jekyll-theme-satellite 1.0.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/assets/js/post.js ADDED
@@ -0,0 +1,191 @@
1
+ document.addEventListener('DOMContentLoaded', function(){
2
+ var content = document.querySelector('main');
3
+ let currentTheme = localStorage.getItem('theme');
4
+
5
+ // Lazy image loading
6
+ var images = content.querySelectorAll('img');
7
+
8
+ images.forEach((img) => {
9
+ img.setAttribute('loading', 'lazy');
10
+ });
11
+
12
+ // tocbot
13
+ var headings = content.querySelectorAll('h1, h2');
14
+ var headingMap = {};
15
+
16
+ Array.prototype.forEach.call(headings, function (heading) {
17
+ var id = heading.id ? heading.id : heading.textContent.trim().toLowerCase()
18
+ .split(' ').join('-').replace(/[\!\@\#\$\%\^\&\*\(\):]/ig, '');
19
+
20
+ headingMap[id] = !isNaN(headingMap[id]) ? ++headingMap[id] : 0;
21
+
22
+ if (headingMap[id]) {
23
+ heading.id = id + '-' + headingMap[id];
24
+ } else {
25
+ heading.id = id;
26
+ }
27
+ })
28
+
29
+ tocbot.init({
30
+ tocSelector: '.toc-board',
31
+ contentSelector: '.inner-content',
32
+ headingSelector:'h1, h2',
33
+ hasInnerContainers: false
34
+ });
35
+
36
+ // link (for hover effect)
37
+ var links = content.querySelectorAll('a:not(.related-item a)');
38
+
39
+ links.forEach((link) => {
40
+ link.setAttribute('data-content', link.innerText);
41
+ });
42
+
43
+ // code clipboard copy button
44
+ async function copyCode(block) {
45
+ let code = block.querySelector("code");
46
+ let text = code.innerText;
47
+
48
+ await navigator.clipboard.writeText(text);
49
+ }
50
+
51
+ let blocks = document.querySelectorAll("pre");
52
+
53
+ blocks.forEach((block) => {
54
+ // only add button if browser supports Clipboard API
55
+ if (navigator.clipboard) {
56
+ let clip_btn = document.createElement("button");
57
+ let clip_img = document.createElement("svg");
58
+
59
+ clip_btn.setAttribute('title', "Copy Code");
60
+ clip_img.ariaHidden = true;
61
+
62
+ block.appendChild(clip_btn);
63
+ clip_btn.appendChild(clip_img);
64
+
65
+ clip_btn.addEventListener("click", async () => {
66
+ await copyCode(block, clip_btn);
67
+ });
68
+ }
69
+ });
70
+
71
+ // Initialize/Change Giscus theme
72
+ var giscusTheme = "light";
73
+
74
+ const giscus_repo = $('meta[name="giscus_repo"]').attr("content");
75
+ const giscus_repoId = $('meta[name="giscus_repoId"]').attr("content");
76
+ const giscus_category = $('meta[name="giscus_category"]').attr("content");
77
+ const giscus_categoryId = $('meta[name="giscus_categoryId"]').attr("content");
78
+
79
+ if (giscus_repo !== undefined) {
80
+ if (currentTheme === 'dark'){
81
+ giscusTheme = "noborder_gray";
82
+ }
83
+
84
+ let giscusAttributes = {
85
+ "src": "https://giscus.app/client.js",
86
+ "data-repo": giscus_repo,
87
+ "data-repo-id": giscus_repoId,
88
+ "data-category": giscus_category,
89
+ "data-category-id": giscus_categoryId,
90
+ "data-mapping": "pathname",
91
+ "data-reactions-enabled": "1",
92
+ "data-emit-metadata": "1",
93
+ "data-theme": giscusTheme,
94
+ "data-lang": "en",
95
+ "crossorigin": "anonymous",
96
+ "async": "",
97
+ };
98
+
99
+ let giscusScript = document.createElement("script");
100
+ Object.entries(giscusAttributes).forEach(([key, value]) => giscusScript.setAttribute(key, value));
101
+ document.body.appendChild(giscusScript);
102
+ }
103
+
104
+ // Giscus IMetadataMessage event handler
105
+ function handleMessage(event) {
106
+ if (event.origin !== 'https://giscus.app') return;
107
+ if (!(typeof event.data === 'object' && event.data.giscus)) return;
108
+
109
+ const giscusData = event.data.giscus;
110
+
111
+ if (giscusData && giscusData.hasOwnProperty('discussion')) {
112
+ $('#num-comments').text(giscusData.discussion.totalCommentCount);
113
+ }
114
+ else {
115
+ $('#num-comments').text('0');
116
+ }
117
+ }
118
+
119
+ window.addEventListener('message', handleMessage);
120
+
121
+ // Tag EventListener
122
+ const searchPage = document.querySelector("#search");
123
+
124
+ document.querySelectorAll('.tag-box .tag').forEach(function(tagButton){
125
+ tagButton.addEventListener('click', function() {
126
+ const contentID = tagButton.getAttribute('contentID');
127
+ searchPage.classList.add('active');
128
+
129
+ $('#search-input').val(contentID);
130
+ $('#search-input').trigger('keyup');
131
+ });
132
+ });
133
+
134
+ // Page Hits
135
+ const pageHits = document.getElementById('page-hits');
136
+
137
+ if (pageHits) {
138
+ const goatcounterCode = pageHits.getAttribute('usercode');
139
+ const requestURL = 'https://'
140
+ + goatcounterCode
141
+ + '.goatcounter.com/counter/'
142
+ + encodeURIComponent(location.pathname)
143
+ + '.json';
144
+
145
+ var resp = new XMLHttpRequest();
146
+ resp.open('GET', requestURL);
147
+ resp.onerror = function() { pageHits.innerText = "0"; };
148
+ resp.onload = function() { pageHits.innerText = JSON.parse(this.responseText).count; };
149
+ resp.send();
150
+ }
151
+
152
+ // Sweat Scroll
153
+ const scroller = new SweetScroll({
154
+ /* some options */
155
+ });
156
+
157
+ // Move to Top
158
+ if (document.querySelector('.thumbnail')){
159
+ const arrowButton = document.querySelector('.top-arrow');
160
+
161
+ setInterval(function(){
162
+ var scrollPos = document.documentElement.scrollTop;
163
+
164
+ if (scrollPos < 512){
165
+ arrowButton.classList.remove('arrow-open');
166
+ }
167
+ else {
168
+ arrowButton.classList.add('arrow-open');
169
+ }
170
+ }, 1000);
171
+ }
172
+
173
+ // Code highlighter
174
+ if (currentTheme === 'dark'){
175
+ // Disable highlighter default color theme
176
+ document.getElementById("highlight-default").disabled=true;
177
+ }
178
+ else {
179
+ // Disable highlighter dark color theme
180
+ document.getElementById("highlight-dark").disabled=true;
181
+ }
182
+
183
+ hljs.highlightAll();
184
+
185
+ // Disable code highlights to the plaintext codeblocks
186
+ document.querySelectorAll('.language-text, .language-plaintext').forEach(function(codeblock){
187
+ codeblock.querySelectorAll('.hljs-keyword, .hljs-meta, .hljs-selector-tag').forEach(function($){
188
+ $.outerHTML = $.innerHTML;
189
+ });
190
+ });
191
+ });
@@ -0,0 +1,168 @@
1
+ function searchPost(pages){
2
+ $('#search-input').on('keyup', function () {
3
+ var keyword = this.value.toLowerCase();
4
+ var searchResult = [];
5
+
6
+ if (keyword.length > 0) {
7
+ $('#search-result').show();
8
+ $('#btn-clear').show();
9
+ } else {
10
+ $('#search-result').hide();
11
+ $('#btn-clear').hide();
12
+ }
13
+
14
+ $('.result-item').remove();
15
+
16
+ for (var i = 0; i < pages.length; i++) {
17
+ var post = pages[i];
18
+
19
+ if (post.title === 'Home' && post.type == 'category') continue;
20
+
21
+ if (post.title.toLowerCase().indexOf(keyword) >= 0
22
+ || post.path.toLowerCase().indexOf(keyword) >= 0
23
+ || post.tags.toLowerCase().indexOf(keyword) >= 0){
24
+ searchResult.push(post);
25
+ }
26
+ }
27
+
28
+ if (searchResult.length === 0) {
29
+ $('#search-result').append(
30
+ '<li class="result-item"><span class="description">There is no search result.</span></li>'
31
+ );
32
+
33
+ return;
34
+ }
35
+
36
+ searchResult.sort(function (a, b) {
37
+ if (a.type == 'category') return 1;
38
+
39
+ return -1;
40
+ });
41
+
42
+ for (var i = 0; i < searchResult.length; i++) {
43
+ var highlighted_path = highlightKeyword(searchResult[i].path, keyword);
44
+
45
+ if (highlighted_path === '')
46
+ highlighted_path = "Home";
47
+
48
+ if (searchResult[i].type === 'post'){
49
+ var highlighted_title = highlightKeyword(searchResult[i].title, keyword);
50
+ var highlighted_tags = highlightKeyword(searchResult[i].tags, keyword);
51
+
52
+ if (highlighted_tags === '')
53
+ highlighted_tags = "none";
54
+
55
+ $('#search-result').append(
56
+ '<li class="result-item"><a href="' +
57
+ searchResult[i].url +
58
+ '"><table><thead><tr><th><svg class="ico-book"></svg></th><th>' + highlighted_title +
59
+ '</th></tr></thead><tbody><tr><td><svg class="ico-folder"></svg></td><td>' + highlighted_path +
60
+ '</td></tr><tr><td><svg class="ico-tags"></svg></td><td>' + highlighted_tags +
61
+ '</td></tr><tr><td><svg class="ico-calendar"></svg></td><td>' + searchResult[i].date +
62
+ '</td></tr></tbody></table></a></li>'
63
+ );
64
+ }
65
+ else {
66
+ $('#search-result').append(
67
+ '<li class="result-item"><a href="' +
68
+ searchResult[i].url +
69
+ '"><table><thead><tr><th><svg class="ico-folder"></svg></th><th>' + highlighted_path +
70
+ '</th></tr></thead></table></a></li>'
71
+ );
72
+ }
73
+ }
74
+ });
75
+
76
+ function highlightKeyword(txt, keyword) {
77
+ var index = txt.toLowerCase().lastIndexOf(keyword);
78
+
79
+ if (index >= 0) {
80
+ out = txt.substring(0, index) +
81
+ "<span class='highlight'>" +
82
+ txt.substring(index, index+keyword.length) +
83
+ "</span>" +
84
+ txt.substring(index + keyword.length);
85
+ return out;
86
+ }
87
+
88
+ return txt;
89
+ }
90
+ }
91
+
92
+ function searchRelated(pages){
93
+ const refBox = document.getElementById('related-box');
94
+
95
+ if (!refBox) return;
96
+
97
+ var relatedPosts = [];
98
+ var currPost = pages.find(obj => {return obj.url === location.pathname});
99
+
100
+ let currTags = currPost.tags.split(', ');
101
+ let currCategory = currPost.path.split(' > ').pop();
102
+
103
+ for (var i = 0; i < pages.length; i++) {
104
+ let page = pages[i];
105
+
106
+ if (page.type === 'category') continue;
107
+
108
+ if (page.title === currPost.title) continue;
109
+
110
+ let tags = page.tags.split(', ');
111
+ let category = page.path.split(' > ').pop();
112
+ let correlationScore = 0;
113
+
114
+ for (var j = 0; j < currTags.length; j++){
115
+ if (tags.indexOf(currTags[j]) != -1) correlationScore += 1;
116
+ }
117
+
118
+ if (category === currCategory) correlationScore += 1;
119
+
120
+ if (correlationScore == 0) continue;
121
+
122
+ relatedPosts.push({
123
+ 'title': page.title,
124
+ 'date': page.date,
125
+ 'category': category,
126
+ 'url': page.url,
127
+ 'thumbnail': page.image,
128
+ 'score': correlationScore
129
+ });
130
+ }
131
+
132
+ relatedPosts.sort(function (a, b) {
133
+ if(a.hasOwnProperty('score')){
134
+ return b.score - a.score;
135
+ }
136
+ });
137
+
138
+ if (relatedPosts.length == 0){
139
+ $('#related-box').hide();
140
+ return;
141
+ }
142
+
143
+ for (var i = 0; i < Math.min(relatedPosts.length, 6); i++){
144
+ let post = relatedPosts[i];
145
+ let date = '-';
146
+ let category = 'No category';
147
+
148
+ if (post.date !== '1900-01-01'){
149
+ date = new Date(post.date);
150
+ date = date.toLocaleString('en-US', {day: 'numeric', month:'long', year:'numeric'});
151
+ }
152
+
153
+ if (post.category !== '') category = post.category;
154
+
155
+ if (post.thumbnail === ''){
156
+ post.thumbnail = "/assets/img/thumbnail/empty.jpg";
157
+ }
158
+
159
+ $('#related-posts').append(
160
+ '<li class="related-item"><a href="' + post.url +
161
+ '"><img src="' + post.thumbnail +
162
+ '"/><p class="category">' + category +
163
+ '</p><p class="title">' + post.title +
164
+ '</p><p class="date">' + date +
165
+ '</p></a></li>'
166
+ );
167
+ }
168
+ }
@@ -0,0 +1,132 @@
1
+ document.addEventListener('DOMContentLoaded', function(){
2
+ // Loading page
3
+ window.addEventListener("load", () => {
4
+ var load_div = document.querySelector('#loading');
5
+
6
+ if(load_div != null){
7
+ setTimeout(function(){
8
+ load_div.style.transition = '.75s';
9
+ load_div.style.opacity = '0';
10
+ load_div.style.visibility = 'hidden';
11
+ }, 800);
12
+ }
13
+ });
14
+
15
+ // pagination
16
+ const paginationNumbers = document.querySelector("#pagination-numbers");
17
+ const paginatedList = document.querySelector(".paginated-list");
18
+
19
+ if (paginatedList) {
20
+ const listItems = paginatedList.querySelectorAll("li");
21
+ const nextButton = document.querySelector("#next-button");
22
+ const prevButton = document.querySelector("#prev-button");
23
+ const pageKey = "pageKey=" + document.URL;
24
+
25
+ const paginationLimit = 5;
26
+ const pageCount = Math.ceil(listItems.length / paginationLimit);
27
+ let currentPage = 1;
28
+
29
+ const disableButton = (button) => {
30
+ button.classList.add("disabled");
31
+ button.setAttribute("disabled", true);
32
+ };
33
+
34
+ const enableButton = (button) => {
35
+ button.classList.remove("disabled");
36
+ button.removeAttribute("disabled");
37
+ };
38
+
39
+ const handlePageButtonsStatus = () => {
40
+ if (currentPage === 1) {
41
+ disableButton(prevButton);
42
+ } else {
43
+ enableButton(prevButton);
44
+ }
45
+
46
+ if (pageCount === currentPage) {
47
+ disableButton(nextButton);
48
+ } else {
49
+ enableButton(nextButton);
50
+ }
51
+ };
52
+
53
+ const handleActivePageNumber = () => {
54
+ document.querySelectorAll(".pagination-number").forEach((button) => {
55
+ button.classList.remove("active");
56
+
57
+ const pageIndex = Number(button.getAttribute("page-index"));
58
+
59
+ if (pageIndex == currentPage) {
60
+ button.classList.add("active");
61
+ }
62
+ });
63
+ };
64
+
65
+ const appendPageNumber = (index) => {
66
+ const pageNumber = document.createElement("button");
67
+
68
+ pageNumber.className = "pagination-number";
69
+ pageNumber.innerHTML = index;
70
+ pageNumber.setAttribute("page-index", index);
71
+ pageNumber.setAttribute("aria-label", "Page " + index);
72
+
73
+ paginationNumbers.appendChild(pageNumber);
74
+ };
75
+
76
+ const getPaginationNumbers = () => {
77
+ for (let i = 1; i <= pageCount; i++) {
78
+ appendPageNumber(i);
79
+ }
80
+ };
81
+
82
+ const setCurrentPage = (pageNum) => {
83
+ currentPage = pageNum;
84
+
85
+ handleActivePageNumber();
86
+ handlePageButtonsStatus();
87
+
88
+ const prevRange = (pageNum - 1) * paginationLimit;
89
+ const currRange = pageNum * paginationLimit;
90
+
91
+ listItems.forEach((item, index) => {
92
+ item.classList.add("hidden");
93
+
94
+ if (index >= prevRange && index < currRange) {
95
+ item.classList.remove("hidden");
96
+ }
97
+ });
98
+
99
+ $('html, body').scrollTop(0);
100
+ localStorage.setItem(pageKey, currentPage);
101
+ };
102
+
103
+ window.addEventListener("load", (event) => {
104
+ // Load last visited page number
105
+ if (event.persisted
106
+ || (window.performance && window.performance.navigation.type == 2)) {
107
+ currentPage = localStorage.getItem(pageKey);
108
+ }
109
+
110
+ getPaginationNumbers();
111
+ setCurrentPage(currentPage);
112
+
113
+ prevButton.addEventListener("click", () => {
114
+ setCurrentPage(currentPage - 1);
115
+ });
116
+
117
+ nextButton.addEventListener("click", () => {
118
+ setCurrentPage(currentPage + 1);
119
+ });
120
+
121
+ document.querySelectorAll(".pagination-number").forEach((button) => {
122
+ const pageIndex = Number(button.getAttribute("page-index"));
123
+
124
+ if (pageIndex) {
125
+ button.addEventListener("click", () => {
126
+ setCurrentPage(pageIndex);
127
+ });
128
+ }
129
+ });
130
+ });
131
+ }
132
+ });
metadata CHANGED
@@ -1,29 +1,105 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-theme-satellite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yankos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-29 00:00:00.000000000 Z
11
+ date: 2024-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.9'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '3.9'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: kramdown-parser-gfm
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.1.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 1.1.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: webrick
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 1.7.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 1.7.0
61
+ - !ruby/object:Gem::Dependency
62
+ name: jekyll-feed
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.12'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.12'
75
+ - !ruby/object:Gem::Dependency
76
+ name: jekyll-sitemap
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '1.3'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.3'
89
+ - !ruby/object:Gem::Dependency
90
+ name: jekyll-seo-tag
15
91
  requirement: !ruby/object:Gem::Requirement
16
92
  requirements:
17
93
  - - "~>"
18
94
  - !ruby/object:Gem::Version
19
- version: '4.3'
95
+ version: '2.6'
20
96
  type: :runtime
21
97
  prerelease: false
22
98
  version_requirements: !ruby/object:Gem::Requirement
23
99
  requirements:
24
100
  - - "~>"
25
101
  - !ruby/object:Gem::Version
26
- version: '4.3'
102
+ version: '2.6'
27
103
  description:
28
104
  email:
29
105
  - byanko55@gmail.com
@@ -32,14 +108,19 @@ extensions: []
32
108
  extra_rdoc_files: []
33
109
  files:
34
110
  - LICENSE
35
- - _config.yml
111
+ - README.md
112
+ - _includes/category.html
113
+ - _includes/footer.html
114
+ - _includes/head.html
36
115
  - _includes/loading.html
37
116
  - _includes/navigation.html
38
117
  - _includes/pagination.html
39
118
  - _includes/post.html
40
119
  - _includes/search.html
120
+ - _includes/search_event.html
41
121
  - _includes/sidebar.html
42
122
  - _layouts/default.html
123
+ - _layouts/page.html
43
124
  - _sass/darkmode.scss
44
125
  - _sass/layout.scss
45
126
  - _sass/navigation.scss
@@ -49,6 +130,8 @@ files:
49
130
  - _sass/sidebar.scss
50
131
  - _sass/toc.scss
51
132
  - _sass/vars.scss
133
+ - assets/css/404.scss
134
+ - assets/css/fonts.scss
52
135
  - assets/css/highlight-dark.min.css
53
136
  - assets/css/highlight-default.min.css
54
137
  - assets/css/style.scss
@@ -73,9 +156,13 @@ files:
73
156
  - assets/img/thumbnail/sample.png
74
157
  - assets/img/tile.png
75
158
  - assets/js/404.js
159
+ - assets/js/background.js
160
+ - assets/js/common.js
161
+ - assets/js/fontfaceobserver.js
76
162
  - assets/js/highlight.min.js
77
- - assets/js/main.js
78
- - assets/js/stars.js
163
+ - assets/js/post.js
164
+ - assets/js/search.js
165
+ - assets/js/subject.js
79
166
  - assets/js/sweet-scroll.min.js
80
167
  - assets/js/tocbot.min.js
81
168
  homepage: https://github.com/byanko55/jekyll-theme-satellite