scripts.html 32 KB

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