summaryrefslogtreecommitdiff
path: root/themes/CodeIT/src
diff options
context:
space:
mode:
Diffstat (limited to 'themes/CodeIT/src')
-rw-r--r--themes/CodeIT/src/js/theme.js979
-rw-r--r--themes/CodeIT/src/lib/lunr.segmentit.js12
2 files changed, 991 insertions, 0 deletions
diff --git a/themes/CodeIT/src/js/theme.js b/themes/CodeIT/src/js/theme.js
new file mode 100644
index 0000000..6421e18
--- /dev/null
+++ b/themes/CodeIT/src/js/theme.js
@@ -0,0 +1,979 @@
+class Util {
+ forEach(elements, handler) {
+ elements = elements || [];
+ for (let i = 0; i < elements.length; i++) handler(elements[i]);
+ }
+
+ getScrollTop() {
+ return (
+ (document.documentElement && document.documentElement.scrollTop) ||
+ document.body.scrollTop
+ );
+ }
+
+ isMobile() {
+ return window.matchMedia("only screen and (max-width: 680px)").matches;
+ }
+
+ isTocStatic() {
+ return window.matchMedia("only screen and (max-width: 960px)").matches;
+ }
+
+ animateCSS(element, animation, reserved, callback) {
+ if (!Array.isArray(animation)) animation = [animation];
+ element.classList.add("animated", ...animation);
+ const handler = () => {
+ element.classList.remove("animated", ...animation);
+ element.removeEventListener("animationend", handler);
+ if (typeof callback === "function") callback();
+ };
+ if (!reserved) element.addEventListener("animationend", handler, false);
+ }
+}
+
+class Theme {
+ constructor() {
+ this.config = window.config;
+ this.data = this.config.data;
+ this.isDark = document.body.getAttribute("theme") === "dark";
+ this.util = new Util();
+ this.newScrollTop = this.util.getScrollTop();
+ this.oldScrollTop = this.newScrollTop;
+ this.scrollEventSet = new Set();
+ this.resizeEventSet = new Set();
+ this.switchThemeEventSet = new Set();
+ this.clickMaskEventSet = new Set();
+ if (window.objectFitImages) objectFitImages();
+ }
+
+ initSVGIcon() {
+ this.util.forEach(document.querySelectorAll("[data-svg-src]"), ($icon) => {
+ fetch($icon.getAttribute("data-svg-src"))
+ .then((response) => response.text())
+ .then((svg) => {
+ const $temp = document.createElement("div");
+ $temp.insertAdjacentHTML("afterbegin", svg);
+ const $svg = $temp.firstChild;
+ $svg.setAttribute("data-svg-src", $icon.getAttribute("data-svg-src"));
+ $svg.classList.add("icon");
+ const $titleElements = $svg.getElementsByTagName("title");
+ if ($titleElements.length) $svg.removeChild($titleElements[0]);
+ $icon.parentElement.replaceChild($svg, $icon);
+ })
+ .catch((err) => {
+ console.error(err);
+ });
+ });
+ }
+
+ initTwemoji() {
+ if (this.config.twemoji) twemoji.parse(document.body);
+ }
+
+ initMenuMobile() {
+ const $menuToggleMobile = document.getElementById("menu-toggle-mobile");
+ const $menuMobile = document.getElementById("menu-mobile");
+ $menuToggleMobile.addEventListener(
+ "click",
+ () => {
+ document.body.classList.toggle("blur");
+ $menuToggleMobile.classList.toggle("active");
+ $menuMobile.classList.toggle("active");
+ },
+ false
+ );
+ this._menuMobileOnClickMask =
+ this._menuMobileOnClickMask ||
+ (() => {
+ $menuToggleMobile.classList.remove("active");
+ $menuMobile.classList.remove("active");
+ });
+ this.clickMaskEventSet.add(this._menuMobileOnClickMask);
+ }
+
+ initSwitchTheme() {
+ this.util.forEach(
+ document.getElementsByClassName("theme-switch"),
+ ($themeSwitch) => {
+ $themeSwitch.addEventListener(
+ "click",
+ () => {
+ if (document.body.getAttribute("theme") === "dark")
+ document.body.setAttribute("theme", "light");
+ else document.body.setAttribute("theme", "dark");
+ this.isDark = !this.isDark;
+ window.localStorage &&
+ localStorage.setItem("theme", this.isDark ? "dark" : "light");
+ for (let event of this.switchThemeEventSet) event();
+ },
+ false
+ );
+ }
+ );
+ }
+
+ initSearch() {
+ const searchConfig = this.config.search;
+ const isMobile = this.util.isMobile();
+ if (
+ !searchConfig ||
+ (isMobile && this._searchMobileOnce) ||
+ (!isMobile && this._searchDesktopOnce)
+ )
+ return;
+
+ const maxResultLength = searchConfig.maxResultLength
+ ? searchConfig.maxResultLength
+ : 10;
+ const snippetLength = searchConfig.snippetLength
+ ? searchConfig.snippetLength
+ : 50;
+ const highlightTag = searchConfig.highlightTag
+ ? searchConfig.highlightTag
+ : "em";
+
+ const suffix = isMobile ? "mobile" : "desktop";
+ const $header = document.getElementById(`header-${suffix}`);
+ const $searchInput = document.getElementById(`search-input-${suffix}`);
+ const $searchToggle = document.getElementById(`search-toggle-${suffix}`);
+ const $searchLoading = document.getElementById(`search-loading-${suffix}`);
+ const $searchClear = document.getElementById(`search-clear-${suffix}`);
+ if (isMobile) {
+ this._searchMobileOnce = true;
+ $searchInput.addEventListener(
+ "focus",
+ () => {
+ document.body.classList.add("blur");
+ $header.classList.add("open");
+ },
+ false
+ );
+ document.getElementById("search-cancel-mobile").addEventListener(
+ "click",
+ () => {
+ $header.classList.remove("open");
+ document.body.classList.remove("blur");
+ document
+ .getElementById("menu-toggle-mobile")
+ .classList.remove("active");
+ document.getElementById("menu-mobile").classList.remove("active");
+ $searchLoading.style.display = "none";
+ $searchClear.style.display = "none";
+ this._searchMobile && this._searchMobile.autocomplete.setVal("");
+ },
+ false
+ );
+ $searchClear.addEventListener(
+ "click",
+ () => {
+ $searchClear.style.display = "none";
+ this._searchMobile && this._searchMobile.autocomplete.setVal("");
+ },
+ false
+ );
+ this._searchMobileOnClickMask =
+ this._searchMobileOnClickMask ||
+ (() => {
+ $header.classList.remove("open");
+ $searchLoading.style.display = "none";
+ $searchClear.style.display = "none";
+ this._searchMobile && this._searchMobile.autocomplete.setVal("");
+ });
+ this.clickMaskEventSet.add(this._searchMobileOnClickMask);
+ } else {
+ this._searchDesktopOnce = true;
+ $searchToggle.addEventListener(
+ "click",
+ () => {
+ document.body.classList.add("blur");
+ $header.classList.add("open");
+ $searchInput.focus();
+ },
+ false
+ );
+ $searchClear.addEventListener(
+ "click",
+ () => {
+ $searchClear.style.display = "none";
+ this._searchDesktop && this._searchDesktop.autocomplete.setVal("");
+ },
+ false
+ );
+ this._searchDesktopOnClickMask =
+ this._searchDesktopOnClickMask ||
+ (() => {
+ $header.classList.remove("open");
+ $searchLoading.style.display = "none";
+ $searchClear.style.display = "none";
+ this._searchDesktop && this._searchDesktop.autocomplete.setVal("");
+ });
+ this.clickMaskEventSet.add(this._searchDesktopOnClickMask);
+ }
+ $searchInput.addEventListener(
+ "input",
+ () => {
+ if ($searchInput.value === "") $searchClear.style.display = "none";
+ else $searchClear.style.display = "inline";
+ },
+ false
+ );
+
+ const initAutosearch = () => {
+ const autosearch = autocomplete(
+ `#search-input-${suffix}`,
+ {
+ hint: false,
+ autoselect: true,
+ dropdownMenuContainer: `#search-dropdown-${suffix}`,
+ clearOnSelected: true,
+ cssClasses: { noPrefix: true },
+ debug: true,
+ },
+ {
+ name: "search",
+ source: (query, callback) => {
+ $searchLoading.style.display = "inline";
+ $searchClear.style.display = "none";
+ const finish = (results) => {
+ $searchLoading.style.display = "none";
+ $searchClear.style.display = "inline";
+ callback(results);
+ };
+ if (searchConfig.type === "lunr") {
+ const search = () => {
+ if (lunr.queryHandler) query = lunr.queryHandler(query);
+ const results = {};
+ this._index
+ .search(query)
+ .forEach(({ ref, matchData: { metadata } }) => {
+ const matchData = this._indexData[ref];
+ let { uri, title, content: context } = matchData;
+ if (results[uri]) return;
+ let position = 0;
+ Object.values(metadata).forEach(({ content }) => {
+ if (content) {
+ const matchPosition = content.position[0][0];
+ if (matchPosition < position || position === 0)
+ position = matchPosition;
+ }
+ });
+ position -= snippetLength / 5;
+ if (position > 0) {
+ position +=
+ context.substr(position, 20).lastIndexOf(" ") + 1;
+ context = "..." + context.substr(position, snippetLength);
+ } else {
+ context = context.substr(0, snippetLength);
+ }
+ Object.keys(metadata).forEach((key) => {
+ title = title.replace(
+ new RegExp(`(${key})`, "gi"),
+ `<${highlightTag}>$1</${highlightTag}>`
+ );
+ context = context.replace(
+ new RegExp(`(${key})`, "gi"),
+ `<${highlightTag}>$1</${highlightTag}>`
+ );
+ });
+ results[uri] = {
+ uri: uri,
+ title: title,
+ date: matchData.date,
+ context: context,
+ };
+ });
+ return Object.values(results).slice(0, maxResultLength);
+ };
+ if (!this._index) {
+ fetch(searchConfig.lunrIndexURL)
+ .then((response) => response.json())
+ .then((data) => {
+ const indexData = {};
+ this._index = lunr(function () {
+ if (searchConfig.lunrLanguageCode)
+ this.use(lunr[searchConfig.lunrLanguageCode]);
+ this.ref("objectID");
+ this.field("title", { boost: 50 });
+ this.field("tags", { boost: 20 });
+ this.field("categories", { boost: 20 });
+ this.field("content", { boost: 10 });
+ this.metadataWhitelist = ["position"];
+ data.forEach((record) => {
+ indexData[record.objectID] = record;
+ this.add(record);
+ });
+ });
+ this._indexData = indexData;
+ finish(search());
+ })
+ .catch((err) => {
+ console.error(err);
+ finish([]);
+ });
+ } else finish(search());
+ } else if (searchConfig.type === "algolia") {
+ this._algoliaIndex =
+ this._algoliaIndex ||
+ algoliasearch(
+ searchConfig.algoliaAppID,
+ searchConfig.algoliaSearchKey
+ ).initIndex(searchConfig.algoliaIndex);
+ this._algoliaIndex
+ .search(query, {
+ offset: 0,
+ length: maxResultLength * 8,
+ attributesToHighlight: ["title"],
+ attributesToSnippet: [`content:${snippetLength}`],
+ highlightPreTag: `<${highlightTag}>`,
+ highlightPostTag: `</${highlightTag}>`,
+ })
+ .then(({ hits }) => {
+ const results = {};
+ hits.forEach(
+ ({
+ uri,
+ date,
+ _highlightResult: { title },
+ _snippetResult: { content },
+ }) => {
+ if (
+ results[uri] &&
+ results[uri].context.length > content.value
+ )
+ return;
+ results[uri] = {
+ uri: uri,
+ title: title.value,
+ date: date,
+ context: content.value,
+ };
+ }
+ );
+ finish(Object.values(results).slice(0, maxResultLength));
+ })
+ .catch((err) => {
+ console.error(err);
+ finish([]);
+ });
+ }
+ },
+ templates: {
+ suggestion: ({ title, date, context }) =>
+ `<div><span class="suggestion-title">${title}</span><span class="suggestion-date">${date}</span></div><div class="suggestion-context">${context}</div>`,
+ empty: ({ query }) =>
+ `<div class="search-empty">${searchConfig.noResultsFound}: <span class="search-query">"${query}"</span></div>`,
+ footer: ({}) => {
+ const { searchType, icon, href } =
+ searchConfig.type === "algolia"
+ ? {
+ searchType: "algolia",
+ icon: '<i class="fab fa-algolia fa-fw"></i>',
+ href: "https://www.algolia.com/",
+ }
+ : {
+ searchType: "Lunr.js",
+ icon: "",
+ href: "https://lunrjs.com/",
+ };
+ return `<div class="search-footer">Search by <a href="${href}" rel="noopener noreferrer" target="_blank">${icon} ${searchType}</a></div>`;
+ },
+ },
+ }
+ );
+ autosearch.on(
+ "autocomplete:selected",
+ (_event, suggestion, _dataset, _context) => {
+ window.location.assign(suggestion.uri);
+ }
+ );
+ if (isMobile) this._searchMobile = autosearch;
+ else this._searchDesktop = autosearch;
+ };
+ if (
+ searchConfig.lunrSegmentitURL &&
+ !document.getElementById("lunr-segmentit")
+ ) {
+ const script = document.createElement("script");
+ script.id = "lunr-segmentit";
+ script.type = "text/javascript";
+ script.src = searchConfig.lunrSegmentitURL;
+ script.async = true;
+ if (script.readyState) {
+ script.onreadystatechange = () => {
+ if (
+ script.readyState == "loaded" ||
+ script.readyState == "complete"
+ ) {
+ script.onreadystatechange = null;
+ initAutosearch();
+ }
+ };
+ } else {
+ script.onload = () => {
+ initAutosearch();
+ };
+ }
+ document.body.appendChild(script);
+ } else initAutosearch();
+ }
+
+ initDetails() {
+ this.util.forEach(
+ document.getElementsByClassName("details"),
+ ($details) => {
+ const $summary = $details.getElementsByClassName("details-summary")[0];
+ $summary.addEventListener(
+ "click",
+ () => {
+ $details.classList.toggle("open");
+ },
+ false
+ );
+ }
+ );
+ }
+
+ initLightGallery() {
+ if (this.config.lightGallery)
+ lightGallery(
+ document.getElementById("content"),
+ this.config.lightGallery
+ );
+ }
+
+ initHighlight() {
+ this.util.forEach(
+ document.querySelectorAll(".highlight > pre.chroma"),
+ ($preChroma) => {
+ const $chroma = document.createElement("div");
+ $chroma.className = $preChroma.className;
+ const $table = document.createElement("table");
+ $chroma.appendChild($table);
+ const $tbody = document.createElement("tbody");
+ $table.appendChild($tbody);
+ const $tr = document.createElement("tr");
+ $tbody.appendChild($tr);
+ const $td = document.createElement("td");
+ $tr.appendChild($td);
+ $preChroma.parentElement.replaceChild($chroma, $preChroma);
+ $td.appendChild($preChroma);
+ }
+ );
+ this.util.forEach(
+ document.querySelectorAll(".highlight > .chroma"),
+ ($chroma) => {
+ const $codeElements = $chroma.querySelectorAll("pre.chroma > code");
+ if ($codeElements.length) {
+ const $code = $codeElements[$codeElements.length - 1];
+ const $header = document.createElement("div");
+ $header.className = "code-header " + $code.className.toLowerCase();
+ const $title = document.createElement("span");
+ $title.classList.add("code-title");
+ $title.insertAdjacentHTML(
+ "afterbegin",
+ '<i class="arrow fas fa-chevron-right fa-fw"></i>'
+ );
+ $title.addEventListener(
+ "click",
+ () => {
+ $chroma.classList.toggle("open");
+ },
+ false
+ );
+ $header.appendChild($title);
+ const $ellipses = document.createElement("span");
+ $ellipses.insertAdjacentHTML(
+ "afterbegin",
+ '<i class="fas fa-ellipsis-h fa-fw"></i>'
+ );
+ $ellipses.classList.add("ellipses");
+ $ellipses.addEventListener(
+ "click",
+ () => {
+ $chroma.classList.add("open");
+ },
+ false
+ );
+ $header.appendChild($ellipses);
+ const $copy = document.createElement("span");
+ $copy.insertAdjacentHTML(
+ "afterbegin",
+ '<i class="far fa-copy fa-fw"></i>'
+ );
+ $copy.classList.add("copy");
+ const code = $code.innerText;
+ if (
+ this.config.code.maxShownLines < 0 ||
+ code.split("\n").length < this.config.code.maxShownLines + 2
+ )
+ $chroma.classList.add("open");
+ if (this.config.code.copyTitle) {
+ $copy.setAttribute("data-clipboard-text", code);
+ $copy.title = this.config.code.copyTitle;
+ const clipboard = new ClipboardJS($copy);
+ clipboard.on("success", (_e) => {
+ this.util.animateCSS($code, "flash");
+ });
+ $header.appendChild($copy);
+ }
+ $chroma.insertBefore($header, $chroma.firstChild);
+ }
+ }
+ );
+ }
+
+ initTable() {
+ this.util.forEach(document.querySelectorAll(".content table"), ($table) => {
+ const $wrapper = document.createElement("div");
+ $wrapper.className = "table-wrapper";
+ $table.parentElement.replaceChild($wrapper, $table);
+ $wrapper.appendChild($table);
+ });
+ }
+
+ initHeaderLink() {
+ for (let num = 1; num <= 6; num++) {
+ this.util.forEach(
+ document.querySelectorAll(".single .content > h" + num),
+ ($header) => {
+ $header.classList.add("headerLink");
+ $header.insertAdjacentHTML(
+ "afterbegin",
+ `<a href="#${$header.id}" class="header-mark"></a>`
+ );
+ }
+ );
+ }
+ }
+
+ initToc() {
+ const $tocCore = document.getElementById("TableOfContents");
+ if ($tocCore === null) return;
+ if (
+ document.getElementById("toc-static").getAttribute("kept") ||
+ this.util.isTocStatic()
+ ) {
+ const $tocContentStatic = document.getElementById("toc-content-static");
+ if ($tocCore.parentElement !== $tocContentStatic) {
+ $tocCore.parentElement.removeChild($tocCore);
+ $tocContentStatic.appendChild($tocCore);
+ }
+ if (this._tocOnScroll) this.scrollEventSet.delete(this._tocOnScroll);
+ } else {
+ const $tocContentAuto = document.getElementById("toc-content-auto");
+ if ($tocCore.parentElement !== $tocContentAuto) {
+ $tocCore.parentElement.removeChild($tocCore);
+ $tocContentAuto.appendChild($tocCore);
+ }
+ const $toc = document.getElementById("toc-auto");
+ const $page = document.getElementsByClassName("page")[0];
+ const rect = $page.getBoundingClientRect();
+ $toc.style.left = `${rect.left + rect.width + 20}px`;
+ $toc.style.maxWidth = `${$page.getBoundingClientRect().left - 20}px`;
+ $toc.style.visibility = "visible";
+ const $tocLinkElements = $tocCore.querySelectorAll("a:first-child");
+ const $tocLiElements = $tocCore.getElementsByTagName("li");
+ const $headerLinkElements = document.getElementsByClassName("headerLink");
+ const headerIsFixed =
+ document.body.getAttribute("header-desktop") !== "normal";
+ const headerHeight = document.getElementById("header-desktop")
+ .offsetHeight;
+ const TOP_SPACING = 20 + (headerIsFixed ? headerHeight : 0);
+ const minTocTop = $toc.offsetTop;
+ const minScrollTop =
+ minTocTop - TOP_SPACING + (headerIsFixed ? 0 : headerHeight);
+ this._tocOnScroll =
+ this._tocOnScroll ||
+ (() => {
+ const footerTop = document.getElementById("post-footer").offsetTop;
+ const maxTocTop = footerTop - $toc.getBoundingClientRect().height;
+ const maxScrollTop =
+ maxTocTop - TOP_SPACING + (headerIsFixed ? 0 : headerHeight);
+ if (this.newScrollTop < minScrollTop) {
+ $toc.style.position = "absolute";
+ $toc.style.top = `${minTocTop}px`;
+ } else if (this.newScrollTop > maxScrollTop) {
+ $toc.style.position = "absolute";
+ $toc.style.top = `${maxTocTop}px`;
+ } else {
+ $toc.style.position = "fixed";
+ $toc.style.top = `${TOP_SPACING}px`;
+ }
+
+ this.util.forEach($tocLinkElements, ($tocLink) => {
+ $tocLink.classList.remove("active");
+ });
+ this.util.forEach($tocLiElements, ($tocLi) => {
+ $tocLi.classList.remove("has-active");
+ });
+ const INDEX_SPACING = 20 + (headerIsFixed ? headerHeight : 0);
+ let activeTocIndex = $headerLinkElements.length - 1;
+ for (let i = 0; i < $headerLinkElements.length - 1; i++) {
+ const thisTop = $headerLinkElements[i].getBoundingClientRect().top;
+ const nextTop = $headerLinkElements[i + 1].getBoundingClientRect()
+ .top;
+ if (
+ (i == 0 && thisTop > INDEX_SPACING) ||
+ (thisTop <= INDEX_SPACING && nextTop > INDEX_SPACING)
+ ) {
+ activeTocIndex = i;
+ break;
+ }
+ }
+ if (activeTocIndex !== -1) {
+ $tocLinkElements[activeTocIndex].classList.add("active");
+ let $parent = $tocLinkElements[activeTocIndex].parentElement;
+ while ($parent !== $tocCore) {
+ $parent.classList.add("has-active");
+ $parent = $parent.parentElement.parentElement;
+ }
+ }
+ });
+ this._tocOnScroll();
+ this.scrollEventSet.add(this._tocOnScroll);
+ }
+ }
+
+ initMath() {
+ if (this.config.math) renderMathInElement(document.body, this.config.math);
+ }
+
+ initMermaid() {
+ const $mermaidElements = document.getElementsByClassName("mermaid");
+ if ($mermaidElements.length) {
+ mermaid.initialize({ startOnLoad: false, theme: "null" });
+ this.util.forEach($mermaidElements, ($mermaid) => {
+ mermaid.mermaidAPI.render(
+ "svg-" + $mermaid.id,
+ this.data[$mermaid.id],
+ (svgCode) => {
+ $mermaid.insertAdjacentHTML("afterbegin", svgCode);
+ },
+ $mermaid
+ );
+ });
+ }
+ }
+
+ initEcharts() {
+ this._echartsOnSwitchTheme =
+ this._echartsOnSwitchTheme ||
+ (() => {
+ this._echartsArr = this._echartsArr || [];
+ for (let i = 0; i < this._echartsArr.length; i++) {
+ this._echartsArr[i].dispose();
+ }
+ this._echartsArr = [];
+ this.util.forEach(
+ document.getElementsByClassName("echarts"),
+ ($echarts) => {
+ const chart = echarts.init(
+ $echarts,
+ this.isDark ? "dark" : "macarons",
+ { renderer: "svg" }
+ );
+ chart.setOption(JSON.parse(this.data[$echarts.id]));
+ this._echartsArr.push(chart);
+ }
+ );
+ });
+ this.switchThemeEventSet.add(this._echartsOnSwitchTheme);
+ this._echartsOnSwitchTheme();
+ this._echartsOnResize =
+ this._echartsOnResize ||
+ (() => {
+ for (let i = 0; i < this._echartsArr.length; i++) {
+ this._echartsArr[i].resize();
+ }
+ });
+ this.resizeEventSet.add(this._echartsOnResize);
+ }
+
+ initMapbox() {
+ if (this.config.mapbox) {
+ mapboxgl.accessToken = this.config.mapbox.accessToken;
+ mapboxgl.setRTLTextPlugin(this.config.mapbox.RTLTextPlugin);
+ this._mapboxArr = this._mapboxArr || [];
+ this.util.forEach(
+ document.getElementsByClassName("mapbox"),
+ ($mapbox) => {
+ const {
+ lng,
+ lat,
+ zoom,
+ lightStyle,
+ darkStyle,
+ marked,
+ navigation,
+ geolocate,
+ scale,
+ fullscreen,
+ } = this.data[$mapbox.id];
+ const mapbox = new mapboxgl.Map({
+ container: $mapbox,
+ center: [lng, lat],
+ zoom: zoom,
+ minZoom: 0.2,
+ style: this.isDark ? darkStyle : lightStyle,
+ attributionControl: false,
+ });
+ if (marked) {
+ new mapboxgl.Marker().setLngLat([lng, lat]).addTo(mapbox);
+ }
+ if (navigation) {
+ mapbox.addControl(new mapboxgl.NavigationControl(), "bottom-right");
+ }
+ if (geolocate) {
+ mapbox.addControl(
+ new mapboxgl.GeolocateControl({
+ positionOptions: {
+ enableHighAccuracy: true,
+ },
+ showUserLocation: true,
+ trackUserLocation: true,
+ }),
+ "bottom-right"
+ );
+ }
+ if (scale) {
+ mapbox.addControl(new mapboxgl.ScaleControl());
+ }
+ if (fullscreen) {
+ mapbox.addControl(new mapboxgl.FullscreenControl());
+ }
+ mapbox.addControl(new MapboxLanguage());
+ this._mapboxArr.push(mapbox);
+ }
+ );
+ this._mapboxOnSwitchTheme =
+ this._mapboxOnSwitchTheme ||
+ (() => {
+ this.util.forEach(this._mapboxArr, (mapbox) => {
+ const $mapbox = mapbox.getContainer();
+ const { lightStyle, darkStyle } = this.data[$mapbox.id];
+ mapbox.setStyle(this.isDark ? darkStyle : lightStyle);
+ mapbox.addControl(new MapboxLanguage());
+ });
+ });
+ this.switchThemeEventSet.add(this._mapboxOnSwitchTheme);
+ }
+ }
+
+ initTypeit() {
+ if (this.config.typeit) {
+ const typeitConfig = this.config.typeit;
+ const speed = typeitConfig.speed ? typeitConfig.speed : 100;
+ const cursorSpeed = typeitConfig.cursorSpeed
+ ? typeitConfig.cursorSpeed
+ : 1000;
+ const cursorChar = typeitConfig.cursorChar
+ ? typeitConfig.cursorChar
+ : "|";
+ Object.values(typeitConfig.data).forEach((group) => {
+ const typeone = (i) => {
+ const id = group[i];
+ const instance = new TypeIt(`#${id}`, {
+ strings: this.data[id],
+ speed: speed,
+ lifeLike: true,
+ cursorSpeed: cursorSpeed,
+ cursorChar: cursorChar,
+ waitUntilVisible: true,
+ afterComplete: () => {
+ if (i === group.length - 1) {
+ if (typeitConfig.duration >= 0)
+ window.setTimeout(() => {
+ instance.destroy();
+ }, typeitConfig.duration);
+ return;
+ }
+ instance.destroy();
+ typeone(i + 1);
+ },
+ }).go();
+ };
+ typeone(0);
+ });
+ }
+ }
+
+ initComment() {
+ if (this.config.comment) {
+ if (this.config.comment.gitalk) {
+ this.config.comment.gitalk.body = decodeURI(window.location.href);
+ const gitalk = new Gitalk(this.config.comment.gitalk);
+ gitalk.render("gitalk");
+ }
+ if (this.config.comment.valine) new Valine(this.config.comment.valine);
+ if (this.config.comment.utterances) {
+ const utterancesConfig = this.config.comment.utterances;
+ const script = document.createElement("script");
+ script.src = "https://utteranc.es/client.js";
+ script.type = "text/javascript";
+ script.setAttribute("repo", utterancesConfig.repo);
+ script.setAttribute("issue-term", utterancesConfig.issueTerm);
+ if (utterancesConfig.label)
+ script.setAttribute("label", utterancesConfig.label);
+ script.setAttribute(
+ "theme",
+ this.isDark ? utterancesConfig.darkTheme : utterancesConfig.lightTheme
+ );
+ script.crossOrigin = "anonymous";
+ script.async = true;
+ document.getElementById("utterances").appendChild(script);
+ this._utterancesOnSwitchTheme =
+ this._utterancesOnSwitchTheme ||
+ (() => {
+ const message = {
+ type: "set-theme",
+ theme: this.isDark
+ ? utterancesConfig.darkTheme
+ : utterancesConfig.lightTheme,
+ };
+ const iframe = document.querySelector(".utterances-frame");
+ iframe.contentWindow.postMessage(message, "https://utteranc.es");
+ });
+ this.switchThemeEventSet.add(this._utterancesOnSwitchTheme);
+ }
+ }
+ }
+
+ initSmoothScroll() {
+ if (SmoothScroll)
+ new SmoothScroll('[href^="#"]', {
+ speed: 300,
+ speedAsDuration: true,
+ header: "#header-desktop",
+ });
+ }
+
+ initCookieconsent() {
+ if (this.config.cookieconsent)
+ cookieconsent.initialise(this.config.cookieconsent);
+ }
+
+ onScroll() {
+ const $headers = [];
+ if (document.body.getAttribute("header-desktop") === "auto")
+ $headers.push(document.getElementById("header-desktop"));
+ if (document.body.getAttribute("header-mobile") === "auto")
+ $headers.push(document.getElementById("header-mobile"));
+ if (document.getElementById("comments")) {
+ const $viewComments = document.getElementById("view-comments");
+ $viewComments.href = `#comments`;
+ $viewComments.style.display = "block";
+ }
+ const $fixedButtons = document.getElementById("fixed-buttons");
+ const ACCURACY = 20,
+ MINIMUM = 100;
+ window.addEventListener(
+ "scroll",
+ () => {
+ this.newScrollTop = this.util.getScrollTop();
+ const scroll = this.newScrollTop - this.oldScrollTop;
+ const isMobile = this.util.isMobile();
+ this.util.forEach($headers, ($header) => {
+ if (scroll > ACCURACY) {
+ $header.classList.remove("fadeInDown");
+ this.util.animateCSS($header, ["fadeOutUp", "faster"], true);
+ } else if (scroll < -ACCURACY) {
+ $header.classList.remove("fadeOutUp");
+ this.util.animateCSS($header, ["fadeInDown", "faster"], true);
+ }
+ });
+ if (this.newScrollTop > MINIMUM) {
+ if (isMobile && scroll > ACCURACY) {
+ $fixedButtons.classList.remove("fadeIn");
+ this.util.animateCSS($fixedButtons, ["fadeOut", "faster"], true);
+ } else if (!isMobile || scroll < -ACCURACY) {
+ $fixedButtons.style.display = "block";
+ $fixedButtons.classList.remove("fadeOut");
+ this.util.animateCSS($fixedButtons, ["fadeIn", "faster"], true);
+ }
+ } else {
+ if (!isMobile) {
+ $fixedButtons.classList.remove("fadeIn");
+ this.util.animateCSS($fixedButtons, ["fadeOut", "faster"], true);
+ }
+ $fixedButtons.style.display = "none";
+ }
+ for (let event of this.scrollEventSet) event();
+ this.oldScrollTop = this.newScrollTop;
+ },
+ false
+ );
+ }
+
+ onResize() {
+ window.addEventListener(
+ "resize",
+ () => {
+ if (!this._resizeTimeout) {
+ this._resizeTimeout = window.setTimeout(() => {
+ this._resizeTimeout = null;
+ for (let event of this.resizeEventSet) event();
+ this.initToc();
+ this.initMermaid();
+ this.initSearch();
+ }, 100);
+ }
+ },
+ false
+ );
+ }
+
+ onClickMask() {
+ document.getElementById("mask").addEventListener(
+ "click",
+ () => {
+ for (let event of this.clickMaskEventSet) event();
+ document.body.classList.remove("blur");
+ },
+ false
+ );
+ }
+
+ init() {
+ try {
+ this.initSVGIcon();
+ this.initTwemoji();
+ this.initMenuMobile();
+ this.initSwitchTheme();
+ this.initSearch();
+ this.initDetails();
+ this.initLightGallery();
+ this.initHighlight();
+ this.initTable();
+ this.initHeaderLink();
+ this.initSmoothScroll();
+ this.initMath();
+ this.initMermaid();
+ this.initEcharts();
+ this.initTypeit();
+ this.initMapbox();
+ this.initCookieconsent();
+ } catch (err) {
+ console.error(err);
+ }
+
+ window.setTimeout(() => {
+ this.initToc();
+ this.initComment();
+
+ this.onScroll();
+ this.onResize();
+ this.onClickMask();
+ }, 100);
+ }
+}
+
+const themeInit = () => {
+ const theme = new Theme();
+ theme.init();
+};
+
+if (document.readyState !== "loading") {
+ themeInit();
+} else {
+ document.addEventListener("DOMContentLoaded", themeInit, false);
+}
diff --git a/themes/CodeIT/src/lib/lunr.segmentit.js b/themes/CodeIT/src/lib/lunr.segmentit.js
new file mode 100644
index 0000000..b9fdb37
--- /dev/null
+++ b/themes/CodeIT/src/lib/lunr.segmentit.js
@@ -0,0 +1,12 @@
+import { Segment, useDefault } from "segmentit";
+
+const segmentit = useDefault(new Segment());
+lunr.segmentit = segmentit;
+lunr.queryHandler = (query) => {
+ if (/^[\u4e00-\u9fa5]+$/.test(query))
+ query = lunr.segmentit
+ .doSegment(query)
+ .map((seg) => "+" + seg.w)
+ .join(" ");
+ return query;
+};