scripts.html 32 KB

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