scripts.html 38 KB

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