jekyll-theme-satellite 1.0.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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