book.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. "use strict";
  2. // Fix back button cache problem
  3. window.onunload = function () { };
  4. // Global variable, shared between modules
  5. function playground_text(playground) {
  6. let code_block = playground.querySelector("code");
  7. if (window.ace && code_block.classList.contains("editable")) {
  8. let editor = window.ace.edit(code_block);
  9. return editor.getValue();
  10. } else {
  11. return code_block.textContent;
  12. }
  13. }
  14. (function codeSnippets() {
  15. function fetch_with_timeout(url, options, timeout = 6000) {
  16. return Promise.race([
  17. fetch(url, options),
  18. new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
  19. ]);
  20. }
  21. var playgrounds = Array.from(document.querySelectorAll(".playground"));
  22. if (playgrounds.length > 0) {
  23. fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
  24. headers: {
  25. 'Content-Type': "application/json",
  26. },
  27. method: 'POST',
  28. mode: 'cors',
  29. })
  30. .then(response => response.json())
  31. .then(response => {
  32. // get list of crates available in the rust playground
  33. let playground_crates = response.crates.map(item => item["id"]);
  34. playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
  35. });
  36. }
  37. function handle_crate_list_update(playground_block, playground_crates) {
  38. // update the play buttons after receiving the response
  39. update_play_button(playground_block, playground_crates);
  40. // and install on change listener to dynamically update ACE editors
  41. if (window.ace) {
  42. let code_block = playground_block.querySelector("code");
  43. if (code_block.classList.contains("editable")) {
  44. let editor = window.ace.edit(code_block);
  45. editor.addEventListener("change", function (e) {
  46. update_play_button(playground_block, playground_crates);
  47. });
  48. // add Ctrl-Enter command to execute rust code
  49. editor.commands.addCommand({
  50. name: "run",
  51. bindKey: {
  52. win: "Ctrl-Enter",
  53. mac: "Ctrl-Enter"
  54. },
  55. exec: _editor => run_rust_code(playground_block)
  56. });
  57. }
  58. }
  59. }
  60. // updates the visibility of play button based on `no_run` class and
  61. // used crates vs ones available on http://play.rust-lang.org
  62. function update_play_button(pre_block, playground_crates) {
  63. var play_button = pre_block.querySelector(".play-button");
  64. // skip if code is `no_run`
  65. if (pre_block.querySelector('code').classList.contains("no_run")) {
  66. play_button.classList.add("hidden");
  67. return;
  68. }
  69. // get list of `extern crate`'s from snippet
  70. var txt = playground_text(pre_block);
  71. var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
  72. var snippet_crates = [];
  73. var item;
  74. while (item = re.exec(txt)) {
  75. snippet_crates.push(item[1]);
  76. }
  77. // check if all used crates are available on play.rust-lang.org
  78. var all_available = snippet_crates.every(function (elem) {
  79. return playground_crates.indexOf(elem) > -1;
  80. });
  81. if (all_available) {
  82. play_button.classList.remove("hidden");
  83. } else {
  84. play_button.classList.add("hidden");
  85. }
  86. }
  87. function run_rust_code(code_block) {
  88. var result_block = code_block.querySelector(".result");
  89. if (!result_block) {
  90. result_block = document.createElement('code');
  91. result_block.className = 'result hljs language-bash';
  92. code_block.append(result_block);
  93. }
  94. let text = playground_text(code_block);
  95. let classes = code_block.querySelector('code').classList;
  96. let has_2018 = classes.contains("edition2018");
  97. let edition = has_2018 ? "2018" : "2015";
  98. var params = {
  99. version: "stable",
  100. optimize: "0",
  101. code: text,
  102. edition: edition
  103. };
  104. if (text.indexOf("#![feature") !== -1) {
  105. params.version = "nightly";
  106. }
  107. result_block.innerText = "Running...";
  108. fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
  109. headers: {
  110. 'Content-Type': "application/json",
  111. },
  112. method: 'POST',
  113. mode: 'cors',
  114. body: JSON.stringify(params)
  115. })
  116. .then(response => response.json())
  117. .then(response => result_block.innerText = response.result)
  118. .catch(error => result_block.innerText = "Playground Communication: " + error.message);
  119. }
  120. // Syntax highlighting Configuration
  121. hljs.configure({
  122. tabReplace: ' ', // 4 spaces
  123. languages: [], // Languages used for auto-detection
  124. });
  125. let code_nodes = Array
  126. .from(document.querySelectorAll('code'))
  127. // Don't highlight `inline code` blocks in headers.
  128. .filter(function (node) {return !node.parentElement.classList.contains("header"); });
  129. if (window.ace) {
  130. // language-rust class needs to be removed for editable
  131. // blocks or highlightjs will capture events
  132. Array
  133. .from(document.querySelectorAll('code.editable'))
  134. .forEach(function (block) { block.classList.remove('language-rust'); });
  135. Array
  136. .from(document.querySelectorAll('code:not(.editable)'))
  137. .forEach(function (block) { hljs.highlightBlock(block); });
  138. } else {
  139. code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
  140. }
  141. // Adding the hljs class gives code blocks the color css
  142. // even if highlighting doesn't apply
  143. code_nodes.forEach(function (block) { block.classList.add('hljs'); });
  144. Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) {
  145. var lines = Array.from(block.querySelectorAll('.boring'));
  146. // If no lines were hidden, return
  147. if (!lines.length) { return; }
  148. block.classList.add("hide-boring");
  149. var buttons = document.createElement('div');
  150. buttons.className = 'buttons';
  151. buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
  152. // add expand button
  153. var pre_block = block.parentNode;
  154. pre_block.insertBefore(buttons, pre_block.firstChild);
  155. pre_block.querySelector('.buttons').addEventListener('click', function (e) {
  156. if (e.target.classList.contains('fa-eye')) {
  157. e.target.classList.remove('fa-eye');
  158. e.target.classList.add('fa-eye-slash');
  159. e.target.title = 'Hide lines';
  160. e.target.setAttribute('aria-label', e.target.title);
  161. block.classList.remove('hide-boring');
  162. } else if (e.target.classList.contains('fa-eye-slash')) {
  163. e.target.classList.remove('fa-eye-slash');
  164. e.target.classList.add('fa-eye');
  165. e.target.title = 'Show hidden lines';
  166. e.target.setAttribute('aria-label', e.target.title);
  167. block.classList.add('hide-boring');
  168. }
  169. });
  170. });
  171. if (window.playground_copyable) {
  172. Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
  173. var pre_block = block.parentNode;
  174. if (!pre_block.classList.contains('playground')) {
  175. var buttons = pre_block.querySelector(".buttons");
  176. if (!buttons) {
  177. buttons = document.createElement('div');
  178. buttons.className = 'buttons';
  179. pre_block.insertBefore(buttons, pre_block.firstChild);
  180. }
  181. var clipButton = document.createElement('button');
  182. clipButton.className = 'fa fa-copy clip-button';
  183. clipButton.title = 'Copy to clipboard';
  184. clipButton.setAttribute('aria-label', clipButton.title);
  185. clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
  186. buttons.insertBefore(clipButton, buttons.firstChild);
  187. }
  188. });
  189. }
  190. // Process playground code blocks
  191. Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
  192. // Add play button
  193. var buttons = pre_block.querySelector(".buttons");
  194. if (!buttons) {
  195. buttons = document.createElement('div');
  196. buttons.className = 'buttons';
  197. pre_block.insertBefore(buttons, pre_block.firstChild);
  198. }
  199. var runCodeButton = document.createElement('button');
  200. runCodeButton.className = 'fa fa-play play-button';
  201. runCodeButton.hidden = true;
  202. runCodeButton.title = 'Run this code';
  203. runCodeButton.setAttribute('aria-label', runCodeButton.title);
  204. buttons.insertBefore(runCodeButton, buttons.firstChild);
  205. runCodeButton.addEventListener('click', function (e) {
  206. run_rust_code(pre_block);
  207. });
  208. if (window.playground_copyable) {
  209. var copyCodeClipboardButton = document.createElement('button');
  210. copyCodeClipboardButton.className = 'fa fa-copy clip-button';
  211. copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
  212. copyCodeClipboardButton.title = 'Copy to clipboard';
  213. copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
  214. buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
  215. }
  216. let code_block = pre_block.querySelector("code");
  217. if (window.ace && code_block.classList.contains("editable")) {
  218. var undoChangesButton = document.createElement('button');
  219. undoChangesButton.className = 'fa fa-history reset-button';
  220. undoChangesButton.title = 'Undo changes';
  221. undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
  222. buttons.insertBefore(undoChangesButton, buttons.firstChild);
  223. undoChangesButton.addEventListener('click', function () {
  224. let editor = window.ace.edit(code_block);
  225. editor.setValue(editor.originalCode);
  226. editor.clearSelection();
  227. });
  228. }
  229. });
  230. })();
  231. (function themes() {
  232. var html = document.querySelector('html');
  233. var themeToggleButton = document.getElementById('theme-toggle');
  234. var themePopup = document.getElementById('theme-list');
  235. var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
  236. var stylesheets = {
  237. ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
  238. tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
  239. highlight: document.querySelector("[href$='highlight.css']"),
  240. };
  241. function showThemes() {
  242. themePopup.style.display = 'block';
  243. themeToggleButton.setAttribute('aria-expanded', true);
  244. themePopup.querySelector("button#" + get_theme()).focus();
  245. }
  246. function hideThemes() {
  247. themePopup.style.display = 'none';
  248. themeToggleButton.setAttribute('aria-expanded', false);
  249. themeToggleButton.focus();
  250. }
  251. function get_theme() {
  252. var theme;
  253. try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
  254. if (theme === null || theme === undefined) {
  255. return default_theme;
  256. } else {
  257. return theme;
  258. }
  259. }
  260. function set_theme(theme, store = true) {
  261. let ace_theme;
  262. if (theme == 'coal' || theme == 'navy') {
  263. stylesheets.ayuHighlight.disabled = true;
  264. stylesheets.tomorrowNight.disabled = false;
  265. stylesheets.highlight.disabled = true;
  266. ace_theme = "ace/theme/tomorrow_night";
  267. } else if (theme == 'ayu') {
  268. stylesheets.ayuHighlight.disabled = false;
  269. stylesheets.tomorrowNight.disabled = true;
  270. stylesheets.highlight.disabled = true;
  271. ace_theme = "ace/theme/tomorrow_night";
  272. } else {
  273. stylesheets.ayuHighlight.disabled = true;
  274. stylesheets.tomorrowNight.disabled = true;
  275. stylesheets.highlight.disabled = false;
  276. ace_theme = "ace/theme/dawn";
  277. }
  278. setTimeout(function () {
  279. themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor;
  280. }, 1);
  281. if (window.ace && window.editors) {
  282. window.editors.forEach(function (editor) {
  283. editor.setTheme(ace_theme);
  284. });
  285. }
  286. var previousTheme = get_theme();
  287. if (store) {
  288. try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
  289. }
  290. html.classList.remove(previousTheme);
  291. html.classList.add(theme);
  292. }
  293. // Set theme
  294. var theme = get_theme();
  295. set_theme(theme, false);
  296. themeToggleButton.addEventListener('click', function () {
  297. if (themePopup.style.display === 'block') {
  298. hideThemes();
  299. } else {
  300. showThemes();
  301. }
  302. });
  303. themePopup.addEventListener('click', function (e) {
  304. var theme = e.target.id || e.target.parentElement.id;
  305. set_theme(theme);
  306. });
  307. themePopup.addEventListener('focusout', function(e) {
  308. // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
  309. if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
  310. hideThemes();
  311. }
  312. });
  313. // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
  314. document.addEventListener('click', function(e) {
  315. if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
  316. hideThemes();
  317. }
  318. });
  319. document.addEventListener('keydown', function (e) {
  320. if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
  321. if (!themePopup.contains(e.target)) { return; }
  322. switch (e.key) {
  323. case 'Escape':
  324. e.preventDefault();
  325. hideThemes();
  326. break;
  327. case 'ArrowUp':
  328. e.preventDefault();
  329. var li = document.activeElement.parentElement;
  330. if (li && li.previousElementSibling) {
  331. li.previousElementSibling.querySelector('button').focus();
  332. }
  333. break;
  334. case 'ArrowDown':
  335. e.preventDefault();
  336. var li = document.activeElement.parentElement;
  337. if (li && li.nextElementSibling) {
  338. li.nextElementSibling.querySelector('button').focus();
  339. }
  340. break;
  341. case 'Home':
  342. e.preventDefault();
  343. themePopup.querySelector('li:first-child button').focus();
  344. break;
  345. case 'End':
  346. e.preventDefault();
  347. themePopup.querySelector('li:last-child button').focus();
  348. break;
  349. }
  350. });
  351. })();
  352. (function sidebar() {
  353. var html = document.querySelector("html");
  354. var sidebar = document.getElementById("sidebar");
  355. var sidebarLinks = document.querySelectorAll('#sidebar a');
  356. var sidebarToggleButton = document.getElementById("sidebar-toggle");
  357. var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
  358. var firstContact = null;
  359. function showSidebar() {
  360. html.classList.remove('sidebar-hidden')
  361. html.classList.add('sidebar-visible');
  362. Array.from(sidebarLinks).forEach(function (link) {
  363. link.setAttribute('tabIndex', 0);
  364. });
  365. sidebarToggleButton.setAttribute('aria-expanded', true);
  366. sidebar.setAttribute('aria-hidden', false);
  367. try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
  368. }
  369. var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle');
  370. function toggleSection(ev) {
  371. ev.currentTarget.parentElement.classList.toggle('expanded');
  372. }
  373. Array.from(sidebarAnchorToggles).forEach(function (el) {
  374. el.addEventListener('click', toggleSection);
  375. });
  376. function hideSidebar() {
  377. html.classList.remove('sidebar-visible')
  378. html.classList.add('sidebar-hidden');
  379. Array.from(sidebarLinks).forEach(function (link) {
  380. link.setAttribute('tabIndex', -1);
  381. });
  382. sidebarToggleButton.setAttribute('aria-expanded', false);
  383. sidebar.setAttribute('aria-hidden', true);
  384. try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
  385. }
  386. // Toggle sidebar
  387. sidebarToggleButton.addEventListener('click', function sidebarToggle() {
  388. if (html.classList.contains("sidebar-hidden")) {
  389. var current_width = parseInt(
  390. document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
  391. if (current_width < 150) {
  392. document.documentElement.style.setProperty('--sidebar-width', '150px');
  393. }
  394. showSidebar();
  395. } else if (html.classList.contains("sidebar-visible")) {
  396. hideSidebar();
  397. } else {
  398. if (getComputedStyle(sidebar)['transform'] === 'none') {
  399. hideSidebar();
  400. } else {
  401. showSidebar();
  402. }
  403. }
  404. });
  405. sidebarResizeHandle.addEventListener('mousedown', initResize, false);
  406. function initResize(e) {
  407. window.addEventListener('mousemove', resize, false);
  408. window.addEventListener('mouseup', stopResize, false);
  409. html.classList.add('sidebar-resizing');
  410. }
  411. function resize(e) {
  412. var pos = (e.clientX - sidebar.offsetLeft);
  413. if (pos < 20) {
  414. hideSidebar();
  415. } else {
  416. if (html.classList.contains("sidebar-hidden")) {
  417. showSidebar();
  418. }
  419. pos = Math.min(pos, window.innerWidth - 100);
  420. document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
  421. }
  422. }
  423. //on mouseup remove windows functions mousemove & mouseup
  424. function stopResize(e) {
  425. html.classList.remove('sidebar-resizing');
  426. window.removeEventListener('mousemove', resize, false);
  427. window.removeEventListener('mouseup', stopResize, false);
  428. }
  429. document.addEventListener('touchstart', function (e) {
  430. firstContact = {
  431. x: e.touches[0].clientX,
  432. time: Date.now()
  433. };
  434. }, { passive: true });
  435. document.addEventListener('touchmove', function (e) {
  436. if (!firstContact)
  437. return;
  438. var curX = e.touches[0].clientX;
  439. var xDiff = curX - firstContact.x,
  440. tDiff = Date.now() - firstContact.time;
  441. if (tDiff < 250 && Math.abs(xDiff) >= 150) {
  442. if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
  443. showSidebar();
  444. else if (xDiff < 0 && curX < 300)
  445. hideSidebar();
  446. firstContact = null;
  447. }
  448. }, { passive: true });
  449. // Scroll sidebar to current active section
  450. var activeSection = document.getElementById("sidebar").querySelector(".active");
  451. if (activeSection) {
  452. // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
  453. activeSection.scrollIntoView({ block: 'center' });
  454. }
  455. })();
  456. (function chapterNavigation() {
  457. document.addEventListener('keydown', function (e) {
  458. if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
  459. if (window.search && window.search.hasFocus()) { return; }
  460. switch (e.key) {
  461. case 'ArrowRight':
  462. e.preventDefault();
  463. var nextButton = document.querySelector('.nav-chapters.next');
  464. if (nextButton) {
  465. window.location.href = nextButton.href;
  466. }
  467. break;
  468. case 'ArrowLeft':
  469. e.preventDefault();
  470. var previousButton = document.querySelector('.nav-chapters.previous');
  471. if (previousButton) {
  472. window.location.href = previousButton.href;
  473. }
  474. break;
  475. }
  476. });
  477. })();
  478. (function clipboard() {
  479. var clipButtons = document.querySelectorAll('.clip-button');
  480. function hideTooltip(elem) {
  481. elem.firstChild.innerText = "";
  482. elem.className = 'fa fa-copy clip-button';
  483. }
  484. function showTooltip(elem, msg) {
  485. elem.firstChild.innerText = msg;
  486. elem.className = 'fa fa-copy tooltipped';
  487. }
  488. var clipboardSnippets = new ClipboardJS('.clip-button', {
  489. text: function (trigger) {
  490. hideTooltip(trigger);
  491. let playground = trigger.closest("pre");
  492. return playground_text(playground);
  493. }
  494. });
  495. Array.from(clipButtons).forEach(function (clipButton) {
  496. clipButton.addEventListener('mouseout', function (e) {
  497. hideTooltip(e.currentTarget);
  498. });
  499. });
  500. clipboardSnippets.on('success', function (e) {
  501. e.clearSelection();
  502. showTooltip(e.trigger, "Copied!");
  503. });
  504. clipboardSnippets.on('error', function (e) {
  505. showTooltip(e.trigger, "Clipboard error!");
  506. });
  507. })();
  508. (function scrollToTop () {
  509. var menuTitle = document.querySelector('.menu-title');
  510. menuTitle.addEventListener('click', function () {
  511. document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
  512. });
  513. })();
  514. (function controllMenu() {
  515. var menu = document.getElementById('menu-bar');
  516. (function controllPosition() {
  517. var scrollTop = document.scrollingElement.scrollTop;
  518. var prevScrollTop = scrollTop;
  519. var minMenuY = -menu.clientHeight - 50;
  520. // When the script loads, the page can be at any scroll (e.g. if you reforesh it).
  521. menu.style.top = scrollTop + 'px';
  522. // Same as parseInt(menu.style.top.slice(0, -2), but faster
  523. var topCache = menu.style.top.slice(0, -2);
  524. menu.classList.remove('sticky');
  525. var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
  526. document.addEventListener('scroll', function () {
  527. scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
  528. // `null` means that it doesn't need to be updated
  529. var nextSticky = null;
  530. var nextTop = null;
  531. var scrollDown = scrollTop > prevScrollTop;
  532. var menuPosAbsoluteY = topCache - scrollTop;
  533. if (scrollDown) {
  534. nextSticky = false;
  535. if (menuPosAbsoluteY > 0) {
  536. nextTop = prevScrollTop;
  537. }
  538. } else {
  539. if (menuPosAbsoluteY > 0) {
  540. nextSticky = true;
  541. } else if (menuPosAbsoluteY < minMenuY) {
  542. nextTop = prevScrollTop + minMenuY;
  543. }
  544. }
  545. if (nextSticky === true && stickyCache === false) {
  546. menu.classList.add('sticky');
  547. stickyCache = true;
  548. } else if (nextSticky === false && stickyCache === true) {
  549. menu.classList.remove('sticky');
  550. stickyCache = false;
  551. }
  552. if (nextTop !== null) {
  553. menu.style.top = nextTop + 'px';
  554. topCache = nextTop;
  555. }
  556. prevScrollTop = scrollTop;
  557. }, { passive: true });
  558. })();
  559. (function controllBorder() {
  560. menu.classList.remove('bordered');
  561. document.addEventListener('scroll', function () {
  562. if (menu.offsetTop === 0) {
  563. menu.classList.remove('bordered');
  564. } else {
  565. menu.classList.add('bordered');
  566. }
  567. }, { passive: true });
  568. })();
  569. })();