scripts.html 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  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. var root = document.getElementById('root');
  196. var toggleToLightBtn = document.getElementById('toggleToLight');
  197. var toggleToDarkBtn = document.getElementById('toggleToDark');
  198. toggleToDark.onclick = function(e) {
  199. root.className = 'theme__dark';
  200. localStorage.setItem('theme', 'dark');
  201. toggleToLightBtn.className = 'navbar__icons--icon';
  202. toggleToDarkBtn.className = 'hide';
  203. }
  204. toggleToLight.onclick = function (e) {
  205. root.className = 'theme__light';
  206. localStorage.setItem('theme', 'light');
  207. toggleToLightBtn.className = 'hide';
  208. toggleToDarkBtn.className = 'navbar__icons--icon';
  209. }
  210. // =================== section menu collapse ==================
  211. document.querySelectorAll('.menu__list').forEach(function(elem) {
  212. if (elem.classList.contains('active')) {
  213. elem.style.maxHeight = elem.scrollHeight + "px";
  214. }
  215. });
  216. document.querySelectorAll('.menu__title--collapse').forEach(function(elem) {
  217. elem.addEventListener('click', function (e) {
  218. var content = this.nextElementSibling;
  219. var menuTitleIcon = this.querySelector('.menu__title--icon');
  220. if (!content) {
  221. return null;
  222. }
  223. var parent = elem.parentNode;
  224. while (parent.classList.contains('menu__list') && parent.classList.contains('active')) {
  225. parent.style.maxHeight = 100 * parent.children.length + "px";
  226. parent = parent.parentNode;
  227. }
  228. if (content.style.maxHeight) {
  229. content.style.maxHeight = null;
  230. content.classList.remove('active');
  231. menuTitleIcon.classList.add('right');
  232. if (languagedir === 'rtl') {
  233. menuTitleIcon.classList.remove('downrtl');
  234. } else {
  235. menuTitleIcon.classList.remove('down');
  236. }
  237. } else {
  238. content.style.maxHeight = content.scrollHeight + "px";
  239. content.classList.add('active');
  240. menuTitleIcon.classList.remove('right');
  241. if (languagedir === 'rtl') {
  242. menuTitleIcon.classList.add('downrtl');
  243. } else {
  244. menuTitleIcon.classList.add('down');
  245. }
  246. }
  247. });
  248. });
  249. // ============================================================
  250. // ========================== drawer ==========================
  251. var mobileLogo = document.getElementById('mobileLogo');
  252. var modal = document.getElementById("myModal");
  253. var drawer = document.getElementById('myDrawer');
  254. var drawerCloseBtn = document.querySelector('.drawer__close');
  255. var openDrawer = function() {
  256. modal.style.opacity = 1;
  257. if (languagedir === 'rtl') {
  258. modal.style.right = 0;
  259. drawer.style.right = 0;
  260. } else {
  261. modal.style.left = 0;
  262. drawer.style.left = 0;
  263. }
  264. }
  265. var closeDrawer = function() {
  266. modal.style.opacity = 0;
  267. if (languagedir === 'rtl') {
  268. drawer.style.right = '-100%';
  269. } else {
  270. drawer.style.left = '-100%';
  271. }
  272. setTimeout(function () {
  273. if (languagedir === 'rtl') {
  274. modal.style.right = '-100%';
  275. } else {
  276. modal.style.left = '-100%';
  277. }
  278. }, 250);
  279. }
  280. mobileLogo.onclick = function () {
  281. openDrawer();
  282. localStorage.setItem('isDrawerOpen', 'true');
  283. }
  284. modal.onclick = function () {
  285. closeDrawer();
  286. localStorage.setItem('isDrawerOpen', 'false');
  287. }
  288. drawerCloseBtn.onclick = function () {
  289. closeDrawer();
  290. localStorage.setItem('isDrawerOpen', 'false');
  291. }
  292. // ==============================================================
  293. // =========================== scroll ===========================
  294. var lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
  295. var tocElem = document.querySelector('.toc');
  296. var tableOfContentsElem = tocElem ? tocElem.querySelector('#TableOfContents') : null;
  297. var singleContentsElem = document.querySelector('.single__contents');
  298. var dataBGImgs = document.querySelectorAll('div[data-bgimg]');
  299. {{ $tocLevels := ($.Param "tocLevels") }}
  300. var tocLevels = JSON.parse({{ $tocLevels | jsonify }});
  301. if (tocLevels) {
  302. tocLevels = tocLevels.toString();
  303. } else {
  304. tocLevels = "h1, h2, h3, h4, h5, h6";
  305. }
  306. {{ $isLandingBgImg := $.Params.landing.backgroundImage }}
  307. var isLandingBgImg = JSON.parse({{ $isLandingBgImg | jsonify }});
  308. {{ $isHome := .IsHome }}
  309. var isHome = JSON.parse({{ $isHome | jsonify }});
  310. function setNavbarBG(scrollTop) {
  311. if (isHome && isLandingBgImg && Object.keys(isLandingBgImg).length) {
  312. if (isLandingBgImg.height <= scrollTop) {
  313. dataBGImgs.forEach(function(elem) {
  314. elem.setAttribute('data-bgimg', 'false');
  315. });
  316. } else {
  317. dataBGImgs.forEach(function (elem) {
  318. elem.setAttribute('data-bgimg', 'true');
  319. });
  320. }
  321. }
  322. }
  323. setNavbarBG(lastScrollTop);
  324. window.onscroll = function () {
  325. var st = window.pageYOffset || document.documentElement.scrollTop;
  326. if (st > lastScrollTop) { // scroll down
  327. singleContentsElem ?
  328. singleContentsElem.querySelectorAll(tocLevels.toString()).forEach(function(elem) {
  329. if (document.documentElement.scrollTop >= elem.offsetTop) {
  330. if (tableOfContentsElem) {
  331. var id = elem.getAttribute('id');
  332. tocElem.querySelectorAll('a').forEach(function (elem) {
  333. elem.classList.remove('active');
  334. });
  335. tocElem.querySelector('a[href="#' + id + '"]') ?
  336. tocElem.querySelector('a[href="#' + id + '"]').classList.add('active') : null;
  337. }
  338. }
  339. }) : null;
  340. setNavbarBG(st);
  341. } else { // scroll up
  342. singleContentsElem ?
  343. singleContentsElem.querySelectorAll(tocLevels.toString()).forEach(function(elem) {
  344. if (document.documentElement.scrollTop >= elem.offsetTop) {
  345. if (tableOfContentsElem) {
  346. var id = elem.getAttribute('id');
  347. tocElem.querySelectorAll('a').forEach(function (elem) {
  348. elem.classList.remove('active');
  349. });
  350. tocElem.querySelector('a[href="#' + id + '"]') ?
  351. tocElem.querySelector('a[href="#' + id + '"]').classList.add('active') : null;
  352. }
  353. }
  354. }) : null;
  355. setNavbarBG(st);
  356. }
  357. lastScrollTop = st <= 0 ? 0 : st;
  358. };
  359. // ============================================================
  360. // ====================== mobile search =======================
  361. var mobileSearchInputElem = document.querySelector('#search-mobile');
  362. var mobileSearchClassElem = document.querySelector('.mobile-search');
  363. var mobileSearchBtnElem = document.querySelector('#mobileSearchBtn');
  364. var mobileSearchCloseBtnElem = document.querySelector('#search-mobile-close');
  365. var mobileSearchContainer = document.querySelector('#search-mobile-container');
  366. var mobileSearchResultsElem = document.querySelector('#search-mobile-results');
  367. var htmlElem = document.querySelector('html');
  368. if (mobileSearchClassElem) {
  369. mobileSearchClassElem.style.display = 'none';
  370. }
  371. mobileSearchBtnElem ?
  372. mobileSearchBtnElem.addEventListener('click', function () {
  373. if (mobileSearchContainer) {
  374. mobileSearchContainer.style.display = 'block';
  375. }
  376. if (mobileSearchInputElem) {
  377. mobileSearchInputElem.focus();
  378. }
  379. if (htmlElem) {
  380. htmlElem.style.overflowY = 'hidden';
  381. }
  382. }) : null;
  383. mobileSearchCloseBtnElem ?
  384. mobileSearchCloseBtnElem.addEventListener('click', function() {
  385. if (mobileSearchContainer) {
  386. mobileSearchContainer.style.display = 'none';
  387. }
  388. if (mobileSearchInputElem) {
  389. mobileSearchInputElem.value = '';
  390. }
  391. if (mobileSearchResultsElem) {
  392. while (mobileSearchResultsElem.firstChild) {
  393. mobileSearchResultsElem.removeChild(mobileSearchResultsElem.firstChild);
  394. }
  395. }
  396. if (htmlElem) {
  397. htmlElem.style.overflowY = 'visible';
  398. }
  399. }) : null;
  400. mobileSearchInputElem ?
  401. mobileSearchInputElem.addEventListener('keydown', function(e) {
  402. if (e.key === 'Escape') {
  403. if (mobileSearchContainer) {
  404. mobileSearchContainer.style.display = 'none';
  405. }
  406. if (mobileSearchInputElem) {
  407. mobileSearchInputElem.value = '';
  408. }
  409. if (mobileSearchResultsElem) {
  410. while (mobileSearchResultsElem.firstChild) {
  411. mobileSearchResultsElem.removeChild(mobileSearchResultsElem.firstChild);
  412. }
  413. }
  414. if (htmlElem) {
  415. htmlElem.style.overflowY = 'visible';
  416. }
  417. }
  418. }) : null;
  419. // ============================================================
  420. // ======================= theme change =======================
  421. var localTheme = localStorage.getItem('theme');
  422. var rootEleme = document.getElementById('root');
  423. var selectThemeElem = document.querySelectorAll('.select-theme');
  424. var selectThemeItemElem = document.querySelectorAll('.select-theme__item');
  425. if (localTheme) {
  426. selectThemeItemElem ?
  427. selectThemeItemElem.forEach(function (elem) {
  428. if (elem.text.trim() === localTheme) {
  429. elem.classList.add('is-active');
  430. } else {
  431. elem.classList.remove('is-active');
  432. }
  433. }) : null;
  434. }
  435. selectThemeItemElem ?
  436. selectThemeItemElem.forEach(function (v, i) {
  437. v.addEventListener('click', function (e) {
  438. var selectedThemeVariant = e.target.text.trim();
  439. localStorage.setItem('theme', selectedThemeVariant);
  440. rootEleme.removeAttribute('class');
  441. rootEleme.classList.add(`theme__${selectedThemeVariant}`);
  442. selectThemeElem.forEach(function(rootElem) {
  443. rootElem.querySelectorAll('a').forEach(function (elem) {
  444. if (elem.classList) {
  445. if (elem.text.trim() === selectedThemeVariant) {
  446. if (!elem.classList.contains('is-active')) {
  447. elem.classList.add('is-active');
  448. }
  449. } else {
  450. if (elem.classList.contains('is-active')) {
  451. elem.classList.remove('is-active');
  452. }
  453. }
  454. }
  455. });
  456. });
  457. if (window.mermaid) {
  458. if (selectedThemeVariant === "dark" || selectedThemeVariant === "hacker") {
  459. mermaid.initialize({ theme: 'dark' });
  460. location.reload();
  461. } else {
  462. mermaid.initialize({ theme: 'default' });
  463. location.reload();
  464. }
  465. }
  466. var utterances = document.querySelector('iframe');
  467. if (utterances) {
  468. utterances.contentWindow.postMessage({
  469. type: 'set-theme',
  470. theme: selectedThemeVariant === "dark" || selectedThemeVariant === "hacker" ? 'photon-dark' : selectedThemeVariant === 'kimbie' ? 'github-dark-orange' : 'github-light',
  471. }, 'https://utteranc.es');
  472. }
  473. });
  474. }) : null;
  475. // ============================================================
  476. // ========================== search ==========================
  477. {{ $langprefix := $.Site.LanguagePrefix }}
  478. var langprefix = JSON.parse({{ $langprefix | jsonify }});
  479. var searchResults = null;
  480. var searchMenu = null;
  481. var searchText = null;
  482. {{ $enableSearchHighlight := ($.Param "enableSearchHighlight") }}
  483. var enableSearchHighlight = JSON.parse({{ $enableSearchHighlight | jsonify }});
  484. {{ $enableSearch := ($.Param "enableSearch") }}
  485. var enableSearch = JSON.parse({{ $enableSearch | jsonify }});
  486. var fuse = null;
  487. if (enableSearch) {
  488. (function initFuse() {
  489. var xhr = new XMLHttpRequest();
  490. xhr.open('GET', baseurl + langprefix + "/index.json");
  491. xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
  492. xhr.onload = function () {
  493. if (xhr.status === 200) {
  494. fuse = new Fuse(JSON.parse(xhr.response.toString('utf-8')), {
  495. keys: ['title', 'description', 'content'],
  496. includeMatches: enableSearchHighlight,
  497. shouldSort: true,
  498. threshold: 0.4,
  499. location: 0,
  500. distance: 100,
  501. maxPatternLength: 32,
  502. minMatchCharLength: 1,
  503. });
  504. }
  505. else {
  506. console.error(`[${xhr.status}]Error:`, xhr.statusText);
  507. }
  508. };
  509. xhr.send();
  510. })();
  511. }
  512. function makeLi(ulElem, obj) {
  513. var li = document.createElement('li');
  514. li.className = 'search-result__item';
  515. var a = document.createElement('a');
  516. a.innerHTML = obj.title;
  517. a.setAttribute('class', 'search-result__item--title');
  518. a.setAttribute('href', obj.permalink);
  519. var descDiv = document.createElement('div');
  520. descDiv.setAttribute('class', 'search-result__item--desc');
  521. if (obj.description) {
  522. descDiv.innerHTML = obj.description;
  523. } else if (obj.content) {
  524. descDiv.innerHTML = obj.content.substring(0, 80);
  525. }
  526. li.appendChild(a);
  527. li.appendChild(descDiv);
  528. ulElem.appendChild(li);
  529. }
  530. function makeHighlightLi(ulElem, obj) {
  531. var li = document.createElement('li');
  532. li.className = 'search-result__item';
  533. var descDiv = null;
  534. var a = document.createElement('a');
  535. a.innerHTML = obj.item.title;
  536. a.setAttribute('class', 'search-result__item--title');
  537. a.setAttribute('href', obj.item.uri);
  538. if (obj.matches && obj.matches.length) {
  539. for (var i = 0; i < obj.matches.length; i++) {
  540. if ('title' === obj.matches[i].key) {
  541. a = document.createElement('a');
  542. a.innerHTML = generateHighlightedText(obj.matches[i].value, obj.matches[i].indices);
  543. a.setAttribute('class', 'search-result__item--title');
  544. a.setAttribute('href', obj.item.uri);
  545. }
  546. if ('description' === obj.matches[i].key) {
  547. descDiv = document.createElement('div');
  548. descDiv.setAttribute('class', 'search-result__item--desc');
  549. descDiv.innerHTML = generateHighlightedText(obj.item.description, obj.matches[i].indices);
  550. } else if ('content' === obj.matches[i].key) {
  551. if (!descDiv) {
  552. descDiv = document.createElement('div');
  553. descDiv.setAttribute('class', 'search-result__item--desc');
  554. descDiv.innerHTML = generateHighlightedText(obj.item.content.substring(0, 80), obj.matches[i].indices);
  555. }
  556. } else {
  557. if (obj.item.description) {
  558. descDiv = document.createElement('div');
  559. descDiv.setAttribute('class', 'search-result__item--desc');
  560. descDiv.innerHTML = obj.item.description;
  561. } else {
  562. descDiv = document.createElement('div');
  563. descDiv.setAttribute('class', 'search-result__item--desc');
  564. descDiv.innerHTML = obj.item.content.substring(0, 80);
  565. }
  566. }
  567. }
  568. li.appendChild(a);
  569. if (descDiv) {
  570. li.appendChild(descDiv);
  571. }
  572. if (li) {
  573. ulElem.appendChild(li);
  574. }
  575. }
  576. }
  577. function renderSearchResults(searchText, results) {
  578. searchResults = document.getElementById('search-results');
  579. searchMenu = document.getElementById('search-menu');
  580. searchResults.setAttribute('class', 'dd is-active');
  581. var ul = document.createElement('ul');
  582. ul.setAttribute('class', 'dd-content search-content');
  583. if (results.length) {
  584. results.forEach(function (result) {
  585. var li = document.createElement('li');
  586. var a = document.createElement('a');
  587. a.setAttribute('href', result.uri);
  588. a.setAttribute('class', 'dd-item');
  589. a.appendChild(li);
  590. var titleDiv = document.createElement('div');
  591. titleDiv.innerHTML = result.title;
  592. titleDiv.setAttribute('class', 'search-result__item--title');
  593. var descDiv = document.createElement('div');
  594. descDiv.setAttribute('class', 'search-result__item--desc');
  595. if (result.description) {
  596. descDiv.innerHTML = result.description;
  597. } else if (result.content) {
  598. descDiv.innerHTML = result.content.substring(0, 80);
  599. }
  600. li.appendChild(titleDiv);
  601. li.appendChild(descDiv);
  602. ul.appendChild(a);
  603. });
  604. } else {
  605. var li = document.createElement('li');
  606. li.setAttribute('class', 'dd-item');
  607. li.innerText = 'No results found';
  608. ul.appendChild(li);
  609. }
  610. while (searchMenu.hasChildNodes()) {
  611. searchMenu.removeChild(
  612. searchMenu.lastChild
  613. );
  614. }
  615. searchMenu.appendChild(ul);
  616. }
  617. function renderSearchHighlightResults(searchText, results) {
  618. searchResults = document.getElementById('search-results');
  619. searchMenu = document.getElementById('search-menu');
  620. searchResults.setAttribute('class', 'dd is-active');
  621. var ul = document.createElement('ul');
  622. ul.setAttribute('class', 'dd-content search-content');
  623. if (results.length) {
  624. results.forEach(function (result) {
  625. var li = document.createElement('li');
  626. var a = document.createElement('a');
  627. var descDiv = null;
  628. a.setAttribute('href', result.item.uri);
  629. a.setAttribute('class', 'dd-item');
  630. a.appendChild(li);
  631. var titleDiv = document.createElement('div');
  632. titleDiv.innerHTML = result.item.title;
  633. titleDiv.setAttribute('class', 'search-result__item--title');
  634. if (result.matches && result.matches.length) {
  635. for (var i = 0; i < result.matches.length; i++) {
  636. if ('title' === result.matches[i].key) {
  637. titleDiv.innerHTML = generateHighlightedText(result.matches[i].value, result.matches[i].indices);
  638. }
  639. if ('description' === result.matches[i].key) {
  640. descDiv = document.createElement('div');
  641. descDiv.setAttribute('class', 'search-result__item--desc');
  642. descDiv.innerHTML = generateHighlightedText(result.item.description, result.matches[i].indices);
  643. } else if ('content' === result.matches[i].key) {
  644. if (!descDiv) {
  645. descDiv = document.createElement('div');
  646. descDiv.setAttribute('class', 'search-result__item--desc');
  647. descDiv.innerHTML = generateHighlightedText(result.item.content.substring(0, 80), result.matches[i].indices);
  648. }
  649. } else {
  650. if (result.item.description) {
  651. descDiv = document.createElement('div');
  652. descDiv.setAttribute('class', 'search-result__item--desc');
  653. descDiv.innerHTML = result.item.description;
  654. } else {
  655. descDiv = document.createElement('div');
  656. descDiv.setAttribute('class', 'search-result__item--desc');
  657. descDiv.innerHTML = result.item.content.substring(0, 80);
  658. }
  659. }
  660. }
  661. li.appendChild(titleDiv);
  662. if (descDiv) {
  663. li.appendChild(descDiv);
  664. }
  665. ul.appendChild(a);
  666. }
  667. });
  668. } else {
  669. var li = document.createElement('li');
  670. li.setAttribute('class', 'dd-item');
  671. li.innerText = 'No results found';
  672. ul.appendChild(li);
  673. }
  674. while (searchMenu.hasChildNodes()) {
  675. searchMenu.removeChild(
  676. searchMenu.lastChild
  677. );
  678. }
  679. searchMenu.appendChild(ul);
  680. }
  681. function renderSearchResultsMobile(searchText, results) {
  682. searchResults = document.getElementById('search-mobile-results');
  683. var content = document.createElement('div');
  684. content.setAttribute('class', 'mobile-search__content');
  685. if (results.length > 0) {
  686. results.forEach(function (result) {
  687. var item = document.createElement('a');
  688. item.setAttribute('href', result.uri);
  689. 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>';
  690. content.appendChild(item);
  691. });
  692. } else {
  693. var item = document.createElement('span');
  694. content.appendChild(item);
  695. }
  696. let wrap = document.getElementById('search-mobile-results');
  697. while (wrap.firstChild) {
  698. wrap.removeChild(wrap.firstChild)
  699. }
  700. searchResults.appendChild(content);
  701. }
  702. function renderSearchHighlightResultsMobile(searchText, results) {
  703. searchResults = document.getElementById('search-mobile-results');
  704. var ul = document.createElement('div');
  705. ul.setAttribute('class', 'mobile-search__content');
  706. if (results.length) {
  707. results.forEach(function (result) {
  708. var li = document.createElement('li');
  709. var a = document.createElement('a');
  710. var descDiv = null;
  711. a.setAttribute('href', result.item.uri);
  712. a.appendChild(li);
  713. li.setAttribute('class', 'mobile-search__item');
  714. var titleDiv = document.createElement('div');
  715. titleDiv.innerHTML = result.item.title;
  716. titleDiv.setAttribute('class', 'mobile-search__item--title');
  717. if (result.matches && result.matches.length) {
  718. for (var i = 0; i < result.matches.length; i++) {
  719. if ('title' === result.matches[i].key) {
  720. titleDiv.innerHTML = generateHighlightedText(result.matches[i].value, result.matches[i].indices);
  721. }
  722. if ('description' === result.matches[i].key) {
  723. descDiv = document.createElement('div');
  724. descDiv.setAttribute('class', 'mobile-search__item--desc');
  725. descDiv.innerHTML = generateHighlightedText(result.item.description, result.matches[i].indices);
  726. } else if ('content' === result.matches[i].key) {
  727. if (!descDiv) {
  728. descDiv = document.createElement('div');
  729. descDiv.setAttribute('class', 'mobile-search__item--desc');
  730. descDiv.innerHTML = generateHighlightedText(result.item.content.substring(0, 150), result.matches[i].indices);
  731. }
  732. } else {
  733. if (result.item.description) {
  734. descDiv = document.createElement('div');
  735. descDiv.setAttribute('class', 'mobile-search__item--desc');
  736. descDiv.innerHTML = result.item.description;
  737. } else {
  738. descDiv = document.createElement('div');
  739. descDiv.setAttribute('class', 'mobile-search__item--desc');
  740. descDiv.innerHTML = result.item.content.substring(0, 150);
  741. }
  742. }
  743. }
  744. li.appendChild(titleDiv);
  745. if (descDiv) {
  746. li.appendChild(descDiv);
  747. }
  748. ul.appendChild(a);
  749. }
  750. });
  751. } else {
  752. var item = document.createElement('span');
  753. ul.appendChild(item);
  754. }
  755. let wrap = document.getElementById('search-mobile-results');
  756. while (wrap.firstChild) {
  757. wrap.removeChild(wrap.firstChild)
  758. }
  759. searchResults.appendChild(ul);
  760. }
  761. function generateHighlightedText(text, regions) {
  762. if (!regions) {
  763. return text;
  764. }
  765. var content = '', nextUnhighlightedRegionStartingIndex = 0;
  766. regions.forEach(function(region) {
  767. if (region[0] === region[1]) {
  768. return null;
  769. }
  770. content += '' +
  771. text.substring(nextUnhighlightedRegionStartingIndex, region[0]) +
  772. '<span class="search__highlight">' +
  773. text.substring(region[0], region[1] + 1) +
  774. '</span>' +
  775. '';
  776. nextUnhighlightedRegionStartingIndex = region[1] + 1;
  777. });
  778. content += text.substring(nextUnhighlightedRegionStartingIndex);
  779. return content;
  780. };
  781. var searchElem = document.getElementById('search');
  782. var searchMobile = document.getElementById('search-mobile');
  783. var searchResultsContainer = document.getElementById('search-results');
  784. searchElem ?
  785. searchElem.addEventListener('input', function(e) {
  786. if (!e.target.value | window.innerWidth < 770) {
  787. searchResultsContainer ? searchResultsContainer.setAttribute('class', 'dd') : null;
  788. return null;
  789. }
  790. searchText = e.target.value;
  791. var results = fuse.search(e.target.value);
  792. if (enableSearchHighlight) {
  793. renderSearchHighlightResults(searchText, results);
  794. } else {
  795. renderSearchResults(searchText, results);
  796. }
  797. var dropdownItems = searchResultsContainer.querySelectorAll('.dd-item');
  798. dropdownItems ? dropdownItems.forEach(function (item) {
  799. item.addEventListener('mousedown', function (e) {
  800. e.target.click();
  801. });
  802. }) : null;
  803. }) : null;
  804. searchElem ?
  805. searchElem.addEventListener('blur', function() {
  806. if (window.innerWidth < 770) {
  807. return null;
  808. }
  809. searchResultsContainer ? searchResultsContainer.setAttribute('class', 'dd') : null;
  810. }) : null;
  811. searchElem ?
  812. searchElem.addEventListener('click', function(e) {
  813. if (window.innerWidth < 770) {
  814. return null;
  815. }
  816. if (!e.target.value) {
  817. searchResultsContainer ? searchResultsContainer.setAttribute('class', 'dd') : null;
  818. return null;
  819. }
  820. searchText = e.target.value;
  821. var results = fuse.search(e.target.value);
  822. if (enableSearchHighlight) {
  823. renderSearchHighlightResults(searchText, results);
  824. } else {
  825. renderSearchResults(searchText, results);
  826. }
  827. var dropdownItems = searchResultsContainer.querySelectorAll('.dd-item');
  828. dropdownItems ? dropdownItems.forEach(function (item) {
  829. item.addEventListener('mousedown', function (e) {
  830. e.target.click();
  831. });
  832. }) : null;
  833. }) : null;
  834. var searchMenuElem = document.getElementById("search-menu");
  835. var activeItem = document.querySelector('#search-menu .dd-item.is-active');
  836. var activeIndex = null;
  837. var items = null;
  838. var searchContainerMaxHeight = 350;
  839. searchElem ?
  840. searchElem.addEventListener('keydown', function(e) {
  841. if (window.innerWidth < 770) {
  842. return null;
  843. }
  844. var items = document.querySelectorAll('#search-menu .dd-item');
  845. if (e.key === 'ArrowDown') {
  846. if (activeIndex === null) {
  847. activeIndex = 0;
  848. items[activeIndex].classList.remove('is-active');
  849. } else {
  850. items[activeIndex].classList.remove('is-active');
  851. activeIndex = activeIndex === items.length - 1 ? 0 : activeIndex + 1;
  852. }
  853. items[activeIndex].classList.add('is-active');
  854. let overflowedPixel = items[activeIndex].offsetTop + items[activeIndex].clientHeight - searchContainerMaxHeight;
  855. if (overflowedPixel > 0) {
  856. document.querySelector(".search-content").scrollTop += items[activeIndex].getBoundingClientRect().height;
  857. } else if (activeIndex === 0) {
  858. document.querySelector(".search-content").scrollTop = 0;
  859. }
  860. } else if (e.key === 'ArrowUp') {
  861. if (activeIndex === null) {
  862. activeIndex = items.length - 1;
  863. items[activeIndex].classList.remove('is-active');
  864. } else {
  865. items[activeIndex].classList.remove('is-active');
  866. activeIndex = activeIndex === 0 ? items.length - 1 : activeIndex - 1;
  867. }
  868. items[activeIndex].classList.add('is-active');
  869. let overflowedPixel = items[activeIndex].offsetTop + items[activeIndex].clientHeight - searchContainerMaxHeight;
  870. if (overflowedPixel < 0) {
  871. document.querySelector(".search-content").scrollTop -= items[activeIndex].getBoundingClientRect().height;
  872. } else {
  873. document.querySelector(".search-content").scrollTop = overflowedPixel + items[activeIndex].getBoundingClientRect().height;
  874. }
  875. } else if (e.key === 'Enter') {
  876. var currentItemLink = items[activeIndex].getAttribute('href');
  877. if (currentItemLink) {
  878. location.href = currentItemLink;
  879. }
  880. } else if (e.key === 'Escape') {
  881. e.target.value = null;
  882. if (searchResults) {
  883. searchResults.classList.remove('is-active');
  884. }
  885. }
  886. }) : null;
  887. searchMobile ?
  888. searchMobile.addEventListener('input', function(e) {
  889. if (!e.target.value) {
  890. let wrap = document.getElementById('search-mobile-results');
  891. while (wrap.firstChild) {
  892. wrap.removeChild(wrap.firstChild);
  893. }
  894. return null;
  895. }
  896. searchText = e.target.value;
  897. var results = fuse.search(e.target.value);
  898. if (enableSearchHighlight) {
  899. renderSearchHighlightResultsMobile(searchText, results);
  900. } else {
  901. renderSearchResultsMobile(searchText, results);
  902. }
  903. var dropdownItems = searchResultsContainer.querySelectorAll('.dd-item');
  904. dropdownItems ? dropdownItems.forEach(function (item) {
  905. item.addEventListener('mousedown', function (e) {
  906. e.target.click();
  907. });
  908. }) : null;
  909. }) : null;
  910. // ============================================================
  911. }
  912. </script>