scripts.html 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. {{ if .Site.Params.custom_js }}
  2. {{ range .Site.Params.custom_js }}
  3. {{ $custom_template := resources.Get . }}
  4. {{ if $custom_template }}
  5. {{ $custom_js := $custom_template | resources.Minify | resources.Fingerprint }}
  6. <script defer src="{{ $custom_js.RelPermalink }}"></script>
  7. {{ end }}
  8. {{ end }}
  9. {{ end }}
  10. {{ if $.Param "enableSearch" }}
  11. {{ $fuse := resources.Get "js/fuse.min.js" | resources.Fingerprint }}
  12. <script defer src="{{ $fuse.RelPermalink }}"></script>
  13. {{ end }}
  14. {{ $enquire := resources.Get "js/enquire.min.js" | resources.Fingerprint }}
  15. <script src="{{ $enquire.RelPermalink }}"></script>
  16. {{ $lazysizes := resources.Get "js/lazysizes.min.js" | resources.Fingerprint }}
  17. <script defer src="{{ $lazysizes.RelPermalink }}"></script>
  18. {{ $getParents := resources.Get "js/helper/getParents.js" | resources.Minify | resources.Fingerprint }}
  19. <script defer src="{{ $getParents.RelPermalink }}"></script>
  20. {{ $fadeinout := resources.Get "js/helper/fadeinout.js" | resources.Minify | resources.Fingerprint }}
  21. <script defer src="{{ $fadeinout.RelPermalink }}"></script>
  22. <script>
  23. "use strict";
  24. window.onload = function() {
  25. {{ $languagedir := ($.Param "languagedir" | default "ltr") }}
  26. var languagedir = JSON.parse({{ $languagedir | jsonify }});
  27. {{ $baseurl := $.Site.BaseURL }}
  28. var baseurl = JSON.parse({{ $baseurl | jsonify }});
  29. {{ $permalink := .Permalink }}
  30. var permalink = JSON.parse({{ $permalink | jsonify }});
  31. // ==================== toc visibility ========================
  32. var toggleSidebarElem = document.getElementById("toggle-sidebar");
  33. var toggleMenuElem = document.getElementById("toggle-menu");
  34. var tocBodyElem = document.querySelector('.toc__body');
  35. var tocLabelElem = document.querySelector('.toc__label');
  36. var listMainElem = document.getElementById('list-main');
  37. var listSideElem = document.getElementById('list-side');
  38. var singleMenuElem = document.getElementById('single-menu');
  39. var sliderIcons = document.querySelectorAll('.slider__icon');
  40. toggleSidebarElem ?
  41. toggleSidebarElem.addEventListener('change', function (e) {
  42. if (e.target.checked) {
  43. if (tocBodyElem) {
  44. fadeIn(tocBodyElem, 200);
  45. }
  46. if (tocLabelElem) {
  47. fadeIn(tocLabelElem, 200);
  48. }
  49. if (listMainElem && listSideElem) {
  50. listMainElem.className = 'm';
  51. listSideElem.className = 'r';
  52. }
  53. sliderIcons && sliderIcons.forEach(function (elem) {
  54. if (elem.classList.contains('hide')) {
  55. elem.classList.remove('hide');
  56. } else {
  57. elem.classList.add('hide');
  58. }
  59. });
  60. } else {
  61. if (tocBodyElem) {
  62. fadeOut(tocBodyElem, 200);
  63. }
  64. if (tocLabelElem) {
  65. fadeOut(tocLabelElem, 200);
  66. }
  67. if (listMainElem && listSideElem) {
  68. listMainElem.className = 'mr';
  69. listSideElem.className = 'hide';
  70. }
  71. sliderIcons && sliderIcons.forEach(function (elem) {
  72. if (elem.classList.contains('hide')) {
  73. elem.classList.remove('hide');
  74. } else {
  75. elem.classList.add('hide');
  76. }
  77. });
  78. }
  79. }) : null;
  80. toggleMenuElem ?
  81. toggleMenuElem.addEventListener('change', function (e) {
  82. if (e.target.checked) {
  83. if (listMainElem && singleMenuElem) {
  84. listMainElem.className = 'm';
  85. singleMenuElem.className = 'l';
  86. }
  87. sliderIcons && sliderIcons.forEach(function (elem) {
  88. if (elem.classList.contains('hide')) {
  89. elem.classList.remove('hide');
  90. } else {
  91. elem.classList.add('hide');
  92. }
  93. });
  94. } else {
  95. if (listMainElem && singleMenuElem) {
  96. listMainElem.className = 'lm';
  97. singleMenuElem.className = 'hide';
  98. }
  99. sliderIcons && sliderIcons.forEach(function (elem) {
  100. if (elem.classList.contains('hide')) {
  101. elem.classList.remove('hide');
  102. } else {
  103. elem.classList.add('hide');
  104. }
  105. });
  106. }
  107. }) : null;
  108. // ============================================================
  109. // ===================== navbar collapse ======================
  110. var navCollapseBtn = document.getElementById('navCollapseBtn');
  111. navCollapseBtn ? navCollapseBtn.addEventListener('click', function(e) {
  112. var navCollapse = document.querySelector('.navbar__collapse');
  113. if (navCollapse) {
  114. var dataOpen = navCollapse.getAttribute('data-open');
  115. if (dataOpen === 'true') {
  116. navCollapse.setAttribute('data-open', 'false');
  117. navCollapse.style.maxHeight = 0;
  118. } else {
  119. navCollapse.setAttribute('data-open', 'true');
  120. navCollapse.style.maxHeight = navCollapse.scrollHeight + "px";
  121. }
  122. }
  123. }) : null;
  124. // ============================================================
  125. // ========================== expand ==========================
  126. var expandBtn = document.querySelectorAll('.expand__button');
  127. for (let i = 0; i < expandBtn.length; i++) {
  128. expandBtn[i].addEventListener("click", function () {
  129. var content = this.nextElementSibling;
  130. if (content.style.maxHeight) {
  131. content.style.maxHeight = null;
  132. this.querySelector('svg').classList.add('expand-icon__right');
  133. this.querySelector('svg').classList.remove('expand-icon__down');
  134. } else {
  135. content.style.maxHeight = content.scrollHeight + "px";
  136. this.querySelector('svg').classList.remove('expand-icon__right');
  137. this.querySelector('svg').classList.add('expand-icon__down');
  138. }
  139. });
  140. }
  141. // ============================================================
  142. // ============================ tab ============================
  143. document.querySelectorAll('.tab') ?
  144. document.querySelectorAll('.tab').forEach(function(elem, idx) {
  145. var containerId = elem.getAttribute('id');
  146. var containerElem = elem;
  147. var tabLinks = elem.querySelectorAll('.tab__link');
  148. var tabContents = elem.querySelectorAll('.tab__content');
  149. var ids = [];
  150. tabLinks && tabLinks.length > 0 ?
  151. tabLinks.forEach(function(link, index, self) {
  152. link.onclick = function(e) {
  153. for (var i = 0; i < self.length; i++) {
  154. if (index === parseInt(i, 10)) {
  155. if (!self[i].classList.contains('active')) {
  156. self[i].classList.add('active');
  157. tabContents[i].style.display = 'block';
  158. }
  159. } else {
  160. self[i].classList.remove('active');
  161. tabContents[i].style.display = 'none';
  162. }
  163. }
  164. }
  165. }) : null;
  166. }) : null;
  167. // =============================================================
  168. // ========================== codetab ==========================
  169. document.querySelectorAll('.codetab') ?
  170. document.querySelectorAll('.codetab').forEach(function(elem, idx) {
  171. var containerId = elem.getAttribute('id');
  172. var containerElem = elem;
  173. var codetabLinks = elem.querySelectorAll('.codetab__link');
  174. var codetabContents = elem.querySelectorAll('.codetab__content');
  175. var ids = [];
  176. codetabLinks && codetabLinks.length > 0 ?
  177. codetabLinks.forEach(function(link, index, self) {
  178. link.onclick = function(e) {
  179. for (var i = 0; i < self.length; i++) {
  180. if (index === parseInt(i, 10)) {
  181. if (!self[i].classList.contains('active')) {
  182. self[i].classList.add('active');
  183. codetabContents[i].style.display = 'block';
  184. }
  185. } else {
  186. self[i].classList.remove('active');
  187. codetabContents[i].style.display = 'none';
  188. }
  189. }
  190. }
  191. }) : null;
  192. }) : null;
  193. // =============================================================
  194. // ======================= toggle theme =======================
  195. {{ $enableDarkMode := ($.Param "enableDarkMode") }}
  196. var enableDarkMode = JSON.parse({{ $enableDarkMode | jsonify }});
  197. var root = document.getElementById('root');
  198. var toggleToLightBtn = document.getElementById('toggleToLight');
  199. var toggleToDarkBtn = document.getElementById('toggleToDark');
  200. if (!enableDarkMode) {
  201. root.className = 'theme__light';
  202. localStorage.setItem('theme', 'light');
  203. }
  204. if (toggleToDarkBtn) {
  205. toggleToDarkBtn.onclick = function (e) {
  206. root.className = 'theme__dark';
  207. localStorage.setItem('theme', 'dark');
  208. toggleToLightBtn.className = 'navbar__icons--icon';
  209. toggleToDarkBtn.className = 'hide';
  210. }
  211. }
  212. if (toggleToLightBtn) {
  213. toggleToLightBtn.onclick = function (e) {
  214. root.className = 'theme__light';
  215. localStorage.setItem('theme', 'light');
  216. toggleToLightBtn.className = 'hide';
  217. toggleToDarkBtn.className = 'navbar__icons--icon';
  218. }
  219. }
  220. // =================== section menu collapse ==================
  221. document.querySelectorAll('.menu__list').forEach(function(elem) {
  222. if (elem.classList.contains('active')) {
  223. elem.style.maxHeight = elem.scrollHeight + "px";
  224. }
  225. });
  226. document.querySelectorAll('.menu__title--collapse').forEach(function(elem) {
  227. elem.addEventListener('click', function (e) {
  228. var content = this.nextElementSibling;
  229. var menuTitleIcon = this.querySelector('.menu__title--icon');
  230. if (!content) {
  231. return null;
  232. }
  233. var parent = elem.parentNode;
  234. while (parent.classList.contains('menu__list') && parent.classList.contains('active')) {
  235. parent.style.maxHeight = 100 * parent.children.length + "px";
  236. parent = parent.parentNode;
  237. }
  238. if (content.style.maxHeight) {
  239. content.style.maxHeight = null;
  240. content.classList.remove('active');
  241. menuTitleIcon.classList.add('right');
  242. if (languagedir === 'rtl') {
  243. menuTitleIcon.classList.remove('downrtl');
  244. } else {
  245. menuTitleIcon.classList.remove('down');
  246. }
  247. } else {
  248. content.style.maxHeight = content.scrollHeight + "px";
  249. content.classList.add('active');
  250. menuTitleIcon.classList.remove('right');
  251. if (languagedir === 'rtl') {
  252. menuTitleIcon.classList.add('downrtl');
  253. } else {
  254. menuTitleIcon.classList.add('down');
  255. }
  256. }
  257. });
  258. });
  259. // ============================================================
  260. // ========================== drawer ==========================
  261. var mobileLogo = document.getElementById('mobileLogo');
  262. var modal = document.getElementById("myModal");
  263. var drawer = document.getElementById('myDrawer');
  264. var drawerCloseBtn = document.querySelector('.drawer__close');
  265. var openDrawer = function() {
  266. modal.style.opacity = 1;
  267. if (languagedir === 'rtl') {
  268. modal.style.right = 0;
  269. drawer.style.right = 0;
  270. } else {
  271. modal.style.left = 0;
  272. drawer.style.left = 0;
  273. }
  274. }
  275. var closeDrawer = function() {
  276. modal.style.opacity = 0;
  277. if (languagedir === 'rtl') {
  278. drawer.style.right = '-100%';
  279. } else {
  280. drawer.style.left = '-100%';
  281. }
  282. setTimeout(function () {
  283. if (languagedir === 'rtl') {
  284. modal.style.right = '-100%';
  285. } else {
  286. modal.style.left = '-100%';
  287. }
  288. }, 250);
  289. }
  290. mobileLogo.onclick = function () {
  291. openDrawer();
  292. localStorage.setItem('isDrawerOpen', 'true');
  293. }
  294. modal.onclick = function () {
  295. closeDrawer();
  296. localStorage.setItem('isDrawerOpen', 'false');
  297. }
  298. drawerCloseBtn.onclick = function () {
  299. closeDrawer();
  300. localStorage.setItem('isDrawerOpen', 'false');
  301. }
  302. // ==============================================================
  303. // =========================== scroll ===========================
  304. var lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
  305. var tocElem = document.querySelector('.toc');
  306. var tableOfContentsElem = tocElem ? tocElem.querySelector('#TableOfContents') : null;
  307. var singleContentsElem = document.querySelector('.single__contents');
  308. var dataBGImgs = document.querySelectorAll('div[data-bgimg]');
  309. {{ $tocLevels := ($.Param "tocLevels") }}
  310. var tocLevels = JSON.parse({{ $tocLevels | jsonify }});
  311. if (tocLevels) {
  312. tocLevels = tocLevels.toString();
  313. } else {
  314. tocLevels = "h1, h2, h3, h4, h5, h6";
  315. }
  316. {{ $isLandingBgImg := $.Params.landing.backgroundImage }}
  317. var isLandingBgImg = JSON.parse({{ $isLandingBgImg | jsonify }});
  318. {{ $isHome := .IsHome }}
  319. var isHome = JSON.parse({{ $isHome | jsonify }});
  320. function setNavbarBG(scrollTop) {
  321. if (isHome && isLandingBgImg && Object.keys(isLandingBgImg).length) {
  322. if (isLandingBgImg.height <= scrollTop) {
  323. dataBGImgs.forEach(function(elem) {
  324. elem.setAttribute('data-bgimg', 'false');
  325. });
  326. } else {
  327. dataBGImgs.forEach(function (elem) {
  328. elem.setAttribute('data-bgimg', 'true');
  329. });
  330. }
  331. }
  332. }
  333. setNavbarBG(lastScrollTop);
  334. window.onscroll = function () {
  335. var st = window.pageYOffset || document.documentElement.scrollTop;
  336. if (st > lastScrollTop) { // scroll down
  337. singleContentsElem ?
  338. singleContentsElem.querySelectorAll(tocLevels.toString()).forEach(function(elem) {
  339. if (document.documentElement.scrollTop >= elem.offsetTop) {
  340. if (tableOfContentsElem) {
  341. var id = elem.getAttribute('id');
  342. tocElem.querySelectorAll('a').forEach(function (elem) {
  343. elem.classList.remove('active');
  344. });
  345. tocElem.querySelector('a[href="#' + id + '"]') ?
  346. tocElem.querySelector('a[href="#' + id + '"]').classList.add('active') : null;
  347. }
  348. }
  349. }) : null;
  350. setNavbarBG(st);
  351. } else { // scroll up
  352. singleContentsElem ?
  353. singleContentsElem.querySelectorAll(tocLevels.toString()).forEach(function(elem) {
  354. if (document.documentElement.scrollTop >= elem.offsetTop) {
  355. if (tableOfContentsElem) {
  356. var id = elem.getAttribute('id');
  357. tocElem.querySelectorAll('a').forEach(function (elem) {
  358. elem.classList.remove('active');
  359. });
  360. tocElem.querySelector('a[href="#' + id + '"]') ?
  361. tocElem.querySelector('a[href="#' + id + '"]').classList.add('active') : null;
  362. }
  363. }
  364. }) : null;
  365. setNavbarBG(st);
  366. }
  367. lastScrollTop = st <= 0 ? 0 : st;
  368. };
  369. // ============================================================
  370. // ====================== mobile search =======================
  371. var mobileSearchInputElem = document.querySelector('#search-mobile');
  372. var mobileSearchClassElem = document.querySelector('.mobile-search');
  373. var mobileSearchBtnElem = document.querySelector('#mobileSearchBtn');
  374. var mobileSearchCloseBtnElem = document.querySelector('#search-mobile-close');
  375. var mobileSearchContainer = document.querySelector('#search-mobile-container');
  376. var mobileSearchResultsElem = document.querySelector('#search-mobile-results');
  377. var htmlElem = document.querySelector('html');
  378. if (mobileSearchClassElem) {
  379. mobileSearchClassElem.style.display = 'none';
  380. }
  381. mobileSearchBtnElem ?
  382. mobileSearchBtnElem.addEventListener('click', function () {
  383. if (mobileSearchContainer) {
  384. mobileSearchContainer.style.display = 'block';
  385. }
  386. if (mobileSearchInputElem) {
  387. mobileSearchInputElem.focus();
  388. }
  389. if (htmlElem) {
  390. htmlElem.style.overflowY = 'hidden';
  391. }
  392. }) : null;
  393. mobileSearchCloseBtnElem ?
  394. mobileSearchCloseBtnElem.addEventListener('click', function() {
  395. if (mobileSearchContainer) {
  396. mobileSearchContainer.style.display = 'none';
  397. }
  398. if (mobileSearchInputElem) {
  399. mobileSearchInputElem.value = '';
  400. }
  401. if (mobileSearchResultsElem) {
  402. while (mobileSearchResultsElem.firstChild) {
  403. mobileSearchResultsElem.removeChild(mobileSearchResultsElem.firstChild);
  404. }
  405. }
  406. if (htmlElem) {
  407. htmlElem.style.overflowY = 'visible';
  408. }
  409. }) : null;
  410. mobileSearchInputElem ?
  411. mobileSearchInputElem.addEventListener('keydown', function(e) {
  412. if (e.key === 'Escape') {
  413. if (mobileSearchContainer) {
  414. mobileSearchContainer.style.display = 'none';
  415. }
  416. if (mobileSearchInputElem) {
  417. mobileSearchInputElem.value = '';
  418. }
  419. if (mobileSearchResultsElem) {
  420. while (mobileSearchResultsElem.firstChild) {
  421. mobileSearchResultsElem.removeChild(mobileSearchResultsElem.firstChild);
  422. }
  423. }
  424. if (htmlElem) {
  425. htmlElem.style.overflowY = 'visible';
  426. }
  427. }
  428. }) : null;
  429. // ============================================================
  430. // ======================= theme change =======================
  431. var localTheme = localStorage.getItem('theme');
  432. var rootEleme = document.getElementById('root');
  433. var selectThemeElem = document.querySelectorAll('.select-theme');
  434. var selectThemeItemElem = document.querySelectorAll('.select-theme__item');
  435. if (localTheme) {
  436. selectThemeItemElem ?
  437. selectThemeItemElem.forEach(function (elem) {
  438. if (elem.text.trim() === localTheme) {
  439. elem.classList.add('is-active');
  440. } else {
  441. elem.classList.remove('is-active');
  442. }
  443. }) : null;
  444. }
  445. selectThemeItemElem ?
  446. selectThemeItemElem.forEach(function (v, i) {
  447. v.addEventListener('click', function (e) {
  448. var selectedThemeVariant = e.target.text.trim();
  449. localStorage.setItem('theme', selectedThemeVariant);
  450. rootEleme.removeAttribute('class');
  451. rootEleme.classList.add(`theme__${selectedThemeVariant}`);
  452. selectThemeElem.forEach(function(rootElem) {
  453. rootElem.querySelectorAll('a').forEach(function (elem) {
  454. if (elem.classList) {
  455. if (elem.text.trim() === selectedThemeVariant) {
  456. if (!elem.classList.contains('is-active')) {
  457. elem.classList.add('is-active');
  458. }
  459. } else {
  460. if (elem.classList.contains('is-active')) {
  461. elem.classList.remove('is-active');
  462. }
  463. }
  464. }
  465. });
  466. });
  467. if (window.mermaid) {
  468. if (selectedThemeVariant === "dark" || selectedThemeVariant === "hacker") {
  469. mermaid.initialize({ theme: 'dark' });
  470. location.reload();
  471. } else {
  472. mermaid.initialize({ theme: 'default' });
  473. location.reload();
  474. }
  475. }
  476. var utterances = document.querySelector('iframe');
  477. if (utterances) {
  478. utterances.contentWindow.postMessage({
  479. type: 'set-theme',
  480. theme: selectedThemeVariant === "dark" || selectedThemeVariant === "hacker" ? 'photon-dark' : selectedThemeVariant === 'kimbie' ? 'github-dark-orange' : 'github-light',
  481. }, 'https://utteranc.es');
  482. }
  483. });
  484. }) : null;
  485. // ============================================================
  486. // ========================== search ==========================
  487. {{ $langprefix := $.Site.LanguagePrefix }}
  488. var langprefix = JSON.parse({{ $langprefix | jsonify }});
  489. var searchResults = null;
  490. var searchMenu = null;
  491. var searchText = null;
  492. {{ $enableSearchHighlight := ($.Param "enableSearchHighlight") }}
  493. var enableSearchHighlight = JSON.parse({{ $enableSearchHighlight | jsonify }});
  494. {{ $enableSearch := ($.Param "enableSearch") }}
  495. var enableSearch = JSON.parse({{ $enableSearch | jsonify }});
  496. var fuse = null;
  497. if (enableSearch) {
  498. (function initFuse() {
  499. var xhr = new XMLHttpRequest();
  500. xhr.open('GET', baseurl + langprefix + "/index.json");
  501. xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
  502. xhr.onload = function () {
  503. if (xhr.status === 200) {
  504. fuse = new Fuse(JSON.parse(xhr.response.toString('utf-8')), {
  505. keys: ['title', 'description', 'content'],
  506. includeMatches: enableSearchHighlight,
  507. shouldSort: true,
  508. threshold: 0.4,
  509. location: 0,
  510. distance: 100,
  511. maxPatternLength: 32,
  512. minMatchCharLength: 1,
  513. });
  514. }
  515. else {
  516. console.error(`[${xhr.status}]Error:`, xhr.statusText);
  517. }
  518. };
  519. xhr.send();
  520. })();
  521. }
  522. function makeLi(ulElem, obj) {
  523. var li = document.createElement('li');
  524. li.className = 'search-result__item';
  525. var a = document.createElement('a');
  526. a.innerHTML = obj.title;
  527. a.setAttribute('class', 'search-result__item--title');
  528. a.setAttribute('href', obj.permalink);
  529. var descDiv = document.createElement('div');
  530. descDiv.setAttribute('class', 'search-result__item--desc');
  531. if (obj.description) {
  532. descDiv.innerHTML = obj.description;
  533. } else if (obj.content) {
  534. descDiv.innerHTML = obj.content.substring(0, 80);
  535. }
  536. li.appendChild(a);
  537. li.appendChild(descDiv);
  538. ulElem.appendChild(li);
  539. }
  540. function makeHighlightLi(ulElem, obj) {
  541. var li = document.createElement('li');
  542. li.className = 'search-result__item';
  543. var descDiv = null;
  544. var a = document.createElement('a');
  545. a.innerHTML = obj.item.title;
  546. a.setAttribute('class', 'search-result__item--title');
  547. a.setAttribute('href', obj.item.uri);
  548. if (obj.matches && obj.matches.length) {
  549. for (var i = 0; i < obj.matches.length; i++) {
  550. if ('title' === obj.matches[i].key) {
  551. a = document.createElement('a');
  552. a.innerHTML = generateHighlightedText(obj.matches[i].value, obj.matches[i].indices);
  553. a.setAttribute('class', 'search-result__item--title');
  554. a.setAttribute('href', obj.item.uri);
  555. }
  556. if ('description' === obj.matches[i].key) {
  557. descDiv = document.createElement('div');
  558. descDiv.setAttribute('class', 'search-result__item--desc');
  559. descDiv.innerHTML = generateHighlightedText(obj.item.description, obj.matches[i].indices);
  560. } else if ('content' === obj.matches[i].key) {
  561. if (!descDiv) {
  562. descDiv = document.createElement('div');
  563. descDiv.setAttribute('class', 'search-result__item--desc');
  564. descDiv.innerHTML = generateHighlightedText(obj.item.content.substring(0, 80), obj.matches[i].indices);
  565. }
  566. } else {
  567. if (obj.item.description) {
  568. descDiv = document.createElement('div');
  569. descDiv.setAttribute('class', 'search-result__item--desc');
  570. descDiv.innerHTML = obj.item.description;
  571. } else {
  572. descDiv = document.createElement('div');
  573. descDiv.setAttribute('class', 'search-result__item--desc');
  574. descDiv.innerHTML = obj.item.content.substring(0, 80);
  575. }
  576. }
  577. }
  578. li.appendChild(a);
  579. if (descDiv) {
  580. li.appendChild(descDiv);
  581. }
  582. if (li) {
  583. ulElem.appendChild(li);
  584. }
  585. }
  586. }
  587. function renderSearchResults(searchText, results) {
  588. searchResults = document.getElementById('search-results');
  589. searchMenu = document.getElementById('search-menu');
  590. searchResults.setAttribute('class', 'dd is-active');
  591. var ul = document.createElement('ul');
  592. ul.setAttribute('class', 'dd-content search-content');
  593. if (results.length) {
  594. results.forEach(function (result) {
  595. var li = document.createElement('li');
  596. var a = document.createElement('a');
  597. a.setAttribute('href', result.uri);
  598. a.setAttribute('class', 'dd-item');
  599. a.appendChild(li);
  600. var titleDiv = document.createElement('div');
  601. titleDiv.innerHTML = result.title;
  602. titleDiv.setAttribute('class', 'search-result__item--title');
  603. var descDiv = document.createElement('div');
  604. descDiv.setAttribute('class', 'search-result__item--desc');
  605. if (result.description) {
  606. descDiv.innerHTML = result.description;
  607. } else if (result.content) {
  608. descDiv.innerHTML = result.content.substring(0, 80);
  609. }
  610. li.appendChild(titleDiv);
  611. li.appendChild(descDiv);
  612. ul.appendChild(a);
  613. });
  614. } else {
  615. var li = document.createElement('li');
  616. li.setAttribute('class', 'dd-item');
  617. li.innerText = 'No results found';
  618. ul.appendChild(li);
  619. }
  620. while (searchMenu.hasChildNodes()) {
  621. searchMenu.removeChild(
  622. searchMenu.lastChild
  623. );
  624. }
  625. searchMenu.appendChild(ul);
  626. }
  627. function renderSearchHighlightResults(searchText, results) {
  628. searchResults = document.getElementById('search-results');
  629. searchMenu = document.getElementById('search-menu');
  630. searchResults.setAttribute('class', 'dd is-active');
  631. var ul = document.createElement('ul');
  632. ul.setAttribute('class', 'dd-content search-content');
  633. if (results.length) {
  634. results.forEach(function (result) {
  635. var li = document.createElement('li');
  636. var a = document.createElement('a');
  637. var descDiv = null;
  638. a.setAttribute('href', result.item.uri);
  639. a.setAttribute('class', 'dd-item');
  640. a.appendChild(li);
  641. var titleDiv = document.createElement('div');
  642. titleDiv.innerHTML = result.item.title;
  643. titleDiv.setAttribute('class', 'search-result__item--title');
  644. if (result.matches && result.matches.length) {
  645. for (var i = 0; i < result.matches.length; i++) {
  646. if ('title' === result.matches[i].key) {
  647. titleDiv.innerHTML = generateHighlightedText(result.matches[i].value, result.matches[i].indices);
  648. }
  649. if ('description' === result.matches[i].key) {
  650. descDiv = document.createElement('div');
  651. descDiv.setAttribute('class', 'search-result__item--desc');
  652. descDiv.innerHTML = generateHighlightedText(result.item.description, result.matches[i].indices);
  653. } else if ('content' === result.matches[i].key) {
  654. if (!descDiv) {
  655. descDiv = document.createElement('div');
  656. descDiv.setAttribute('class', 'search-result__item--desc');
  657. descDiv.innerHTML = generateHighlightedText(result.item.content.substring(0, 80), result.matches[i].indices);
  658. }
  659. } else {
  660. if (result.item.description) {
  661. descDiv = document.createElement('div');
  662. descDiv.setAttribute('class', 'search-result__item--desc');
  663. descDiv.innerHTML = result.item.description;
  664. } else {
  665. descDiv = document.createElement('div');
  666. descDiv.setAttribute('class', 'search-result__item--desc');
  667. descDiv.innerHTML = result.item.content.substring(0, 80);
  668. }
  669. }
  670. }
  671. li.appendChild(titleDiv);
  672. if (descDiv) {
  673. li.appendChild(descDiv);
  674. }
  675. ul.appendChild(a);
  676. }
  677. });
  678. } else {
  679. var li = document.createElement('li');
  680. li.setAttribute('class', 'dd-item');
  681. li.innerText = 'No results found';
  682. ul.appendChild(li);
  683. }
  684. while (searchMenu.hasChildNodes()) {
  685. searchMenu.removeChild(
  686. searchMenu.lastChild
  687. );
  688. }
  689. searchMenu.appendChild(ul);
  690. }
  691. function renderSearchResultsMobile(searchText, results) {
  692. searchResults = document.getElementById('search-mobile-results');
  693. var content = document.createElement('div');
  694. content.setAttribute('class', 'mobile-search__content');
  695. if (results.length > 0) {
  696. results.forEach(function (result) {
  697. var item = document.createElement('a');
  698. item.setAttribute('href', result.uri);
  699. item.innerHTML = '<div class="mobile-search__item"><div class="mobile-search__item--title">📄 ' + result.title + '</div><div class="mobile-search__item--desc">' + (result.description ? result.description : result.content) + '</div></div>';
  700. content.appendChild(item);
  701. });
  702. } else {
  703. var item = document.createElement('span');
  704. content.appendChild(item);
  705. }
  706. let wrap = document.getElementById('search-mobile-results');
  707. while (wrap.firstChild) {
  708. wrap.removeChild(wrap.firstChild)
  709. }
  710. searchResults.appendChild(content);
  711. }
  712. function renderSearchHighlightResultsMobile(searchText, results) {
  713. searchResults = document.getElementById('search-mobile-results');
  714. var ul = document.createElement('div');
  715. ul.setAttribute('class', 'mobile-search__content');
  716. if (results.length) {
  717. results.forEach(function (result) {
  718. var li = document.createElement('li');
  719. var a = document.createElement('a');
  720. var descDiv = null;
  721. a.setAttribute('href', result.item.uri);
  722. a.appendChild(li);
  723. li.setAttribute('class', 'mobile-search__item');
  724. var titleDiv = document.createElement('div');
  725. titleDiv.innerHTML = result.item.title;
  726. titleDiv.setAttribute('class', 'mobile-search__item--title');
  727. if (result.matches && result.matches.length) {
  728. for (var i = 0; i < result.matches.length; i++) {
  729. if ('title' === result.matches[i].key) {
  730. titleDiv.innerHTML = generateHighlightedText(result.matches[i].value, result.matches[i].indices);
  731. }
  732. if ('description' === result.matches[i].key) {
  733. descDiv = document.createElement('div');
  734. descDiv.setAttribute('class', 'mobile-search__item--desc');
  735. descDiv.innerHTML = generateHighlightedText(result.item.description, result.matches[i].indices);
  736. } else if ('content' === result.matches[i].key) {
  737. if (!descDiv) {
  738. descDiv = document.createElement('div');
  739. descDiv.setAttribute('class', 'mobile-search__item--desc');
  740. descDiv.innerHTML = generateHighlightedText(result.item.content.substring(0, 150), result.matches[i].indices);
  741. }
  742. } else {
  743. if (result.item.description) {
  744. descDiv = document.createElement('div');
  745. descDiv.setAttribute('class', 'mobile-search__item--desc');
  746. descDiv.innerHTML = result.item.description;
  747. } else {
  748. descDiv = document.createElement('div');
  749. descDiv.setAttribute('class', 'mobile-search__item--desc');
  750. descDiv.innerHTML = result.item.content.substring(0, 150);
  751. }
  752. }
  753. }
  754. li.appendChild(titleDiv);
  755. if (descDiv) {
  756. li.appendChild(descDiv);
  757. }
  758. ul.appendChild(a);
  759. }
  760. });
  761. } else {
  762. var item = document.createElement('span');
  763. ul.appendChild(item);
  764. }
  765. let wrap = document.getElementById('search-mobile-results');
  766. while (wrap.firstChild) {
  767. wrap.removeChild(wrap.firstChild)
  768. }
  769. searchResults.appendChild(ul);
  770. }
  771. function generateHighlightedText(text, regions) {
  772. if (!regions) {
  773. return text;
  774. }
  775. var content = '', nextUnhighlightedRegionStartingIndex = 0;
  776. regions.forEach(function(region) {
  777. if (region[0] === region[1]) {
  778. return null;
  779. }
  780. content += '' +
  781. text.substring(nextUnhighlightedRegionStartingIndex, region[0]) +
  782. '<span class="search__highlight">' +
  783. text.substring(region[0], region[1] + 1) +
  784. '</span>' +
  785. '';
  786. nextUnhighlightedRegionStartingIndex = region[1] + 1;
  787. });
  788. content += text.substring(nextUnhighlightedRegionStartingIndex);
  789. return content;
  790. };
  791. var searchElem = document.getElementById('search');
  792. var searchMobile = document.getElementById('search-mobile');
  793. var searchResultsContainer = document.getElementById('search-results');
  794. searchElem ?
  795. searchElem.addEventListener('input', function(e) {
  796. if (!e.target.value | window.innerWidth < 770) {
  797. searchResultsContainer ? searchResultsContainer.setAttribute('class', 'dd') : null;
  798. return null;
  799. }
  800. searchText = e.target.value;
  801. var results = fuse.search(e.target.value);
  802. if (enableSearchHighlight) {
  803. renderSearchHighlightResults(searchText, results);
  804. } else {
  805. renderSearchResults(searchText, results);
  806. }
  807. var dropdownItems = searchResultsContainer.querySelectorAll('.dd-item');
  808. dropdownItems ? dropdownItems.forEach(function (item) {
  809. item.addEventListener('mousedown', function (e) {
  810. e.target.click();
  811. });
  812. }) : null;
  813. }) : null;
  814. searchElem ?
  815. searchElem.addEventListener('blur', function() {
  816. if (window.innerWidth < 770) {
  817. return null;
  818. }
  819. searchResultsContainer ? searchResultsContainer.setAttribute('class', 'dd') : null;
  820. }) : null;
  821. searchElem ?
  822. searchElem.addEventListener('click', function(e) {
  823. if (window.innerWidth < 770) {
  824. return null;
  825. }
  826. if (!e.target.value) {
  827. searchResultsContainer ? searchResultsContainer.setAttribute('class', 'dd') : null;
  828. return null;
  829. }
  830. searchText = e.target.value;
  831. var results = fuse.search(e.target.value);
  832. if (enableSearchHighlight) {
  833. renderSearchHighlightResults(searchText, results);
  834. } else {
  835. renderSearchResults(searchText, results);
  836. }
  837. var dropdownItems = searchResultsContainer.querySelectorAll('.dd-item');
  838. dropdownItems ? dropdownItems.forEach(function (item) {
  839. item.addEventListener('mousedown', function (e) {
  840. e.target.click();
  841. });
  842. }) : null;
  843. }) : null;
  844. var searchMenuElem = document.getElementById("search-menu");
  845. var activeItem = document.querySelector('#search-menu .dd-item.is-active');
  846. var activeIndex = null;
  847. var items = null;
  848. var searchContainerMaxHeight = 350;
  849. searchElem ?
  850. searchElem.addEventListener('keydown', function(e) {
  851. if (window.innerWidth < 770) {
  852. return null;
  853. }
  854. var items = document.querySelectorAll('#search-menu .dd-item');
  855. if (e.key === 'ArrowDown') {
  856. if (activeIndex === null) {
  857. activeIndex = 0;
  858. items[activeIndex].classList.remove('is-active');
  859. } else {
  860. items[activeIndex].classList.remove('is-active');
  861. activeIndex = activeIndex === items.length - 1 ? 0 : activeIndex + 1;
  862. }
  863. items[activeIndex].classList.add('is-active');
  864. let overflowedPixel = items[activeIndex].offsetTop + items[activeIndex].clientHeight - searchContainerMaxHeight;
  865. if (overflowedPixel > 0) {
  866. document.querySelector(".search-content").scrollTop += items[activeIndex].getBoundingClientRect().height;
  867. } else if (activeIndex === 0) {
  868. document.querySelector(".search-content").scrollTop = 0;
  869. }
  870. } else if (e.key === 'ArrowUp') {
  871. if (activeIndex === null) {
  872. activeIndex = items.length - 1;
  873. items[activeIndex].classList.remove('is-active');
  874. } else {
  875. items[activeIndex].classList.remove('is-active');
  876. activeIndex = activeIndex === 0 ? items.length - 1 : activeIndex - 1;
  877. }
  878. items[activeIndex].classList.add('is-active');
  879. let overflowedPixel = items[activeIndex].offsetTop + items[activeIndex].clientHeight - searchContainerMaxHeight;
  880. if (overflowedPixel < 0) {
  881. document.querySelector(".search-content").scrollTop -= items[activeIndex].getBoundingClientRect().height;
  882. } else {
  883. document.querySelector(".search-content").scrollTop = overflowedPixel + items[activeIndex].getBoundingClientRect().height;
  884. }
  885. } else if (e.key === 'Enter') {
  886. var currentItemLink = items[activeIndex].getAttribute('href');
  887. if (currentItemLink) {
  888. location.href = currentItemLink;
  889. }
  890. } else if (e.key === 'Escape') {
  891. e.target.value = null;
  892. if (searchResults) {
  893. searchResults.classList.remove('is-active');
  894. }
  895. }
  896. }) : null;
  897. searchMobile ?
  898. searchMobile.addEventListener('input', function(e) {
  899. if (!e.target.value) {
  900. let wrap = document.getElementById('search-mobile-results');
  901. while (wrap.firstChild) {
  902. wrap.removeChild(wrap.firstChild);
  903. }
  904. return null;
  905. }
  906. searchText = e.target.value;
  907. var results = fuse.search(e.target.value);
  908. if (enableSearchHighlight) {
  909. renderSearchHighlightResultsMobile(searchText, results);
  910. } else {
  911. renderSearchResultsMobile(searchText, results);
  912. }
  913. var dropdownItems = searchResultsContainer.querySelectorAll('.dd-item');
  914. dropdownItems ? dropdownItems.forEach(function (item) {
  915. item.addEventListener('mousedown', function (e) {
  916. e.target.click();
  917. });
  918. }) : null;
  919. }) : null;
  920. // ============================================================
  921. }
  922. </script>