1
0
mirror of https://github.com/cotes2020/jekyll-theme-chirpy.git synced 2025-12-25 00:53:31 +00:00

Exclude JS source code from the output

This commit is contained in:
Cotes Chung
2021-04-19 14:51:45 +08:00
parent 52f4012463
commit 72e8ffafa6
17 changed files with 24 additions and 23 deletions

View File

@@ -0,0 +1,30 @@
/*
* Tab 'Categories' expand/close effect.
*/
$(function() {
const childPrefix = "l_";
const parentPrefix = "h_";
const collapse = $(".collapse");
/* close up top-category */
collapse.on("hide.bs.collapse", function () { /* Bootstrap collapse events. */
const parentId = parentPrefix + $(this).attr("id").substring(childPrefix.length);
if (parentId) {
$(`#${parentId} .far.fa-folder-open`).attr("class", "far fa-folder fa-fw");
$(`#${parentId} i.fas`).addClass("rotate");
$(`#${parentId}`).removeClass("hide-border-bottom");
}
});
/* expand the top category */
collapse.on("show.bs.collapse", function() {
const parentId = parentPrefix + $(this).attr("id").substring(childPrefix.length);
if (parentId) {
$(`#${parentId} .far.fa-folder`).attr("class", "far fa-folder-open fa-fw");
$(`#${parentId} i.fas`).removeClass("rotate");
$(`#${parentId}`).addClass("hide-border-bottom");
}
});
});

View File

@@ -0,0 +1,20 @@
/**
* Add language indicator to code snippets
*/
$(function() {
const prefix = "language-";
const regex = new RegExp(`^${prefix}([a-z])+$`);
$(`div[class^=${prefix}`).each(function() {
let classes = $(this).attr("class").split(" ");
classes.forEach((_class) => {
if (regex.test(_class)) {
let lang = _class.substring(prefix.length);
$(this).attr("lang", `${lang}`);
}
});
});
});

View File

@@ -0,0 +1,250 @@
/*
* Count page views form GA or local cache file.
*
* Dependencies:
* - jQuery
* - countUp.js <https://github.com/inorganik/countUp.js>
*/
const getInitStatus = (function () {
let hasInit = false;
return () => {
let ret = hasInit;
if (!hasInit) {
hasInit = true;
}
return ret;
};
}());
const PvOpts = (function () {
function getContent(selector) {
return $(selector).attr("content");
}
function hasContent(selector) {
let content = getContent(selector);
return (typeof content !== "undefined" && content !== false);
}
return {
getProxyMeta() {
return getContent("meta[name=pv-proxy-endpoint]");
},
getLocalMeta() {
return getContent("meta[name=pv-cache-path]");
},
hasProxyMeta() {
return hasContent("meta[name=pv-proxy-endpoint]");
},
hasLocalMeta() {
return hasContent("meta[name=pv-cache-path]");
}
};
}());
const PvStorage = (function () {
const Keys = {
KEY_PV: "pv",
KEY_PV_SRC: "pv_src",
KEY_CREATION: "pv_created_date"
};
const Source = {
LOCAL: "same-origin",
PROXY: "cors"
};
function get(key) {
return localStorage.getItem(key);
}
function set(key, val) {
localStorage.setItem(key, val);
}
function saveCache(pv, src) {
set(Keys.KEY_PV, pv);
set(Keys.KEY_PV_SRC, src);
set(Keys.KEY_CREATION, new Date().toJSON());
}
return {
keysCount() {
return Object.keys(Keys).length;
},
hasCache() {
return (localStorage.getItem(Keys.KEY_PV) !== null);
},
getCache() {
return JSON.parse(localStorage.getItem(Keys.KEY_PV));
},
saveLocalCache(pv) {
saveCache(pv, Source.LOCAL);
},
saveProxyCache(pv) {
saveCache(pv, Source.PROXY);
},
isExpired() {
let date = new Date(get(Keys.KEY_CREATION));
date.setHours(date.getHours() + 1); // per hour
return Date.now() >= date.getTime();
},
isFromLocal() {
return get(Keys.KEY_PV_SRC) === Source.LOCAL;
},
isFromProxy() {
return get(Keys.KEY_PV_SRC) === Source.PROXY;
},
newerThan(pv) {
return PvStorage.getCache().totalsForAllResults["ga:pageviews"] > pv.totalsForAllResults["ga:pageviews"];
},
inspectKeys() {
if (localStorage.length !== PvStorage.keysCount()) {
localStorage.clear();
return;
}
for(let i = 0; i < localStorage.length; i++){
const key = localStorage.key(i);
switch (key) {
case Keys.KEY_PV:
case Keys.KEY_PV_SRC:
case Keys.KEY_CREATION:
break;
default:
localStorage.clear();
return;
}
}
}
};
}()); /* PvStorage */
function countUp(min, max, destId) {
if (min < max) {
let numAnim = new CountUp(destId, min, max);
if (!numAnim.error) {
numAnim.start();
} else {
console.error(numAnim.error);
}
}
}
function countPV(path, rows) {
let count = 0;
if (typeof rows !== "undefined" ) {
for (let i = 0; i < rows.length; ++i) {
const gaPath = rows[parseInt(i, 10)][0];
if (gaPath === path) { /* path format see: site.permalink */
count += parseInt(rows[parseInt(i, 10)][1], 10);
break;
}
}
}
return count;
}
function tacklePV(rows, path, elem, hasInit) {
let count = countPV(path, rows);
count = (count === 0 ? 1 : count);
if (!hasInit) {
elem.text(new Intl.NumberFormat().format(count));
} else {
const initCount = parseInt(elem.text().replace(/,/g, ""), 10);
if (count > initCount) {
countUp(initCount, count, elem.attr("id"));
}
}
}
function displayPageviews(data) {
if (typeof data === "undefined") {
return;
}
let hasInit = getInitStatus();
const rows = data.rows; /* could be undefined */
if ($("#post-list").length > 0) { /* the Home page */
$(".post-preview").each(function() {
const path = $(this).find("a").attr("href");
tacklePV(rows, path, $(this).find(".pageviews"), hasInit);
});
} else if ($(".post").length > 0) { /* the post */
const path = window.location.pathname;
tacklePV(rows, path, $("#pv"), hasInit);
}
}
function fetchProxyPageviews() {
if (PvOpts.hasProxyMeta()) {
$.ajax({
type: "GET",
url: PvOpts.getProxyMeta(),
dataType: "jsonp",
jsonpCallback: "displayPageviews",
success: (data) => {
PvStorage.saveProxyCache(JSON.stringify(data));
},
error: (jqXHR, textStatus, errorThrown) => {
console.log("Failed to load pageviews from proxy server: " + errorThrown);
}
});
}
}
function fetchLocalPageviews(hasCache = false) {
return fetch(PvOpts.getLocalMeta())
.then(response => response.json())
.then(data => {
if (hasCache) {
// The cache from the proxy will sometimes be more recent than the local one
if (PvStorage.isFromProxy() && PvStorage.newerThan(data)) {
return;
}
}
displayPageviews(data);
PvStorage.saveLocalCache(JSON.stringify(data));
});
}
$(function() {
if ($(".pageviews").length <= 0) {
return;
}
PvStorage.inspectKeys();
if (PvStorage.hasCache()) {
displayPageviews(PvStorage.getCache());
if (PvStorage.isExpired()) {
if (PvOpts.hasLocalMeta()) {
fetchLocalPageviews(true).then(fetchProxyPageviews);
} else {
fetchProxyPageviews();
}
} else {
if (PvStorage.isFromLocal()) {
fetchProxyPageviews();
}
}
} else { // no cached
if (PvOpts.hasLocalMeta()) {
fetchLocalPageviews().then(fetchProxyPageviews);
} else {
fetchProxyPageviews();
}
}
});

View File

@@ -0,0 +1,81 @@
/*
Safari doesn't support CSS `scroll-behavior: smooth`,
so here is a compatible solution for all browser to smooth scrolling
See: <https://css-tricks.com/snippets/jquery/smooth-scrolling/>
Warning: It must be called after all `<a>` tags (e.g., the dynamic TOC) are ready.
*/
$(function() {
$("a[href*='#']")
.not("[href='#']")
.not("[href='#0']")
.click(function(event) {
if (this.pathname.replace(/^\//, "") === location.pathname.replace(/^\//, "")) {
if (location.hostname === this.hostname) {
const REM = 16; /* 16px */
const hash = decodeURI(this.hash);
let isFnRef = RegExp(/^#fnref:/).test(hash);
let isFn = RegExp(/^#fn:/).test(hash);
let selector = hash.includes(":") ? hash.replace(/\:/, "\\:") : hash;
let target = $(selector);
if (target.length) {
event.preventDefault();
if (history.pushState) { /* add hash to URL */
history.pushState(null, null, hash);
}
let curOffset = $(this).offset().top;
let destOffset = target.offset().top;
const scrollUp = (destOffset < curOffset);
const topbarHeight = $("#topbar-wrapper").outerHeight();
if (scrollUp && isFnRef) {
/* Avoid the top-bar covering `fnref` when scrolling up
because `fnref` has no `%anchor`(see: module.scss) style. */
destOffset -= (topbarHeight + REM / 2);
}
$("html,body").animate({
scrollTop: destOffset
}, 800, () => {
const $target = $(target);
$target.focus();
const SCROLL_MARK = "scroll-focus";
/* clean up old scroll mark */
if ($(`[${SCROLL_MARK}=true]`).length) {
$(`[${SCROLL_MARK}=true]`).attr(SCROLL_MARK, false);
}
/* Clean :target links */
if ($(":target").length) { /* element that visited by the URL with hash */
$(":target").attr(SCROLL_MARK, false);
}
/* set scroll mark to footnotes */
if (isFn || isFnRef) {
$target.attr(SCROLL_MARK, true);
}
if ($target.is(":focus")) { /* Checking if the target was focused */
return false;
} else {
$target.attr("tabindex", "-1"); /* Adding tabindex for elements not focusable */
$target.focus(); /* Set focus again */
}
});
}
}
}
}); /* click() */
});

View File

@@ -0,0 +1,80 @@
/*
* Calculate the Timeago
*/
$(function() {
const timeagoElem = $(".timeago");
let toRefresh = timeagoElem.length;
let intervalId = void 0;
function timeago(iso, preposition) {
let now = new Date();
let past = new Date(iso);
let prep = (typeof preposition !== "undefined" ? `${preposition} ` : "");
if (past.getFullYear() !== now.getFullYear()) {
toRefresh -= 1;
return prep + past.toLocaleString("en-US", {
year: "numeric",
month: "short",
day: "numeric"
});
}
if (past.getMonth() !== now.getMonth()) {
toRefresh -= 1;
return prep + past.toLocaleString("en-US", {
month: "short",
day: "numeric"
});
}
let seconds = Math.floor((now - past) / 1000);
let day = Math.floor(seconds / 86400);
if (day >= 1) {
toRefresh -= 1;
return day + " day" + (day > 1 ? "s" : "") + " ago";
}
let hour = Math.floor(seconds / 3600);
if (hour >= 1) {
return hour + " hour" + (hour > 1 ? "s" : "") + " ago";
}
let minute = Math.floor(seconds / 60);
if (minute >= 1) {
return minute + " minute" + (minute > 1 ? "s" : "") + " ago";
}
return "just now";
}
function updateTimeago() {
$(".timeago").each(function() {
if ($(this).children("i").length > 0) {
let node = $(this).children("i");
let date = node.text(); /* ISO Date: "YYYY-MM-DDTHH:MM:SSZ" */
$(this).text(timeago(date, $(this).attr("prep")));
$(this).append(node);
}
});
if (toRefresh === 0 && typeof intervalId !== "undefined") {
clearInterval(intervalId); /* stop interval */
}
return toRefresh;
}
if (toRefresh === 0) {
return;
}
if (updateTimeago() > 0) { /* run immediately */
intervalId = setInterval(updateTimeago, 60000); /* run every minute */
}
});