PageSourceSearch

https://center25.ru/wp-content/themes/sertrusttheme/assets/js/center25.js?ver=1790326822

js center25.ru collected 2026-09-30 10:32:15 UTC 4,751 bytes, 137 lines download raw bytes

1(function () {
2  'use strict';
3
4  var body = document.body;
5  var menuButton = document.querySelector('[data-menu-toggle]');
6  var menu = document.querySelector('[data-mobile-menu]');
7
8  function menuFocusables() {
9    if (!menu) return [];
10    return Array.prototype.filter.call(
11      menu.querySelectorAll('a[href], summary, button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])'),
12      function (element) { return !element.hidden && element.offsetParent !== null; }
13    );
14  }
15
16  function closeMenu(restoreFocus) {
17    if (!menuButton || !menu) return;
18    menuButton.setAttribute('aria-expanded', 'false');
19    menuButton.setAttribute('aria-label', 'Открыть меню');
20    menu.hidden = true;
21    body.classList.remove('menu-open');
22    if (restoreFocus) menuButton.focus();
23  }
24
25  function openMenu() {
26    if (!menuButton || !menu) return;
27    menuButton.setAttribute('aria-expanded', 'true');
28    menuButton.setAttribute('aria-label', 'Закрыть меню');
29    menu.hidden = false;
30    body.classList.add('menu-open');
31    var focusables = menuFocusables();
32    if (focusables.length) focusables[0].focus();
33  }
34
35  if (menuButton && menu) {
36    menuButton.addEventListener('click', function () {
37      var open = menuButton.getAttribute('aria-expanded') === 'true';
38      if (open) closeMenu(false);
39      else openMenu();
40    });
41    menu.querySelectorAll('a').forEach(function (link) {
42      link.addEventListener('click', function () { closeMenu(false); });
43    });
44    document.addEventListener('keydown', function (event) {
45      if (menu.hidden) return;
46      if (event.key === 'Escape') {
47        event.preventDefault();
48        closeMenu(true);
49        return;
50      }
51      if (event.key !== 'Tab') return;
52      var focusables = menuFocusables();
53      if (!focusables.length) return;
54      var first = focusables[0];
55      var last = focusables[focusables.length - 1];
56      if (event.shiftKey && document.activeElement === first) {
57        event.preventDefault();
58        last.focus();
59      } else if (!event.shiftKey && document.activeElement === last) {
60        event.preventDefault();
61        first.focus();
62      }
63    });
64    window.addEventListener('resize', function () {
65      if (window.innerWidth > 1040 && !menu.hidden) closeMenu(false);
66    });
67  }
68
69  document.querySelectorAll('.c25-nav__item--has-children').forEach(function (item) {
70    var trigger = item.querySelector(':scope > a');
71    item.addEventListener('keydown', function (event) {
72      if (event.key !== 'Escape') return;
73      event.preventDefault();
74      if (trigger) trigger.focus();
75      item.classList.add('is-escape-closed');
76    });
77    item.addEventListener('mouseleave', function () {
78      item.classList.remove('is-escape-closed');
79    });
80    item.addEventListener('focusout', function () {
81      window.setTimeout(function () {
82        if (!item.contains(document.activeElement)) item.classList.remove('is-escape-closed');
83      }, 0);
84    });
85  });
86
87  var dialog = document.querySelector('[data-consult-dialog]');
88  var lastFocused = null;
89
90  function openDialog() {
91    if (!dialog) return;
92    lastFocused = document.activeElement;
93    if (menu && !menu.hidden) {
94      closeMenu(false);
95      lastFocused = menuButton;
96    }
97    if (typeof dialog.showModal === 'function') dialog.showModal();
98    else dialog.setAttribute('open', '');
99    body.classList.add('dialog-open');
100    var focusable = dialog.querySelector('input, textarea, select, button, a[href]');
101    if (focusable) focusable.focus();
102  }
103
104  function closeDialog() {
105    if (!dialog) return;
106    if (typeof dialog.close === 'function') dialog.close();
107    else dialog.removeAttribute('open');
108    body.classList.remove('dialog-open');
109    if (lastFocused && typeof lastFocused.focus === 'function') lastFocused.focus();
110  }
111
112  document.querySelectorAll('[data-open-consult]').forEach(function (button) {
113    button.addEventListener('click', openDialog);
114  });
115  if (dialog) {
116    dialog.querySelectorAll('[data-close-consult]').forEach(function (button) {
117      button.addEventListener('click', closeDialog);
118    });
119    dialog.addEventListener('click', function (event) {
120      if (event.target === dialog) closeDialog();
121    });
122    dialog.addEventListener('cancel', function (event) {
123      event.preventDefault();
124      closeDialog();
125    });
126  }
127
128  document.querySelectorAll('a[href^="#"]').forEach(function (link) {
129    link.addEventListener('click', function () {
130      var id = link.getAttribute('href');
131      if (id && id.length > 1) {
132        var target = document.querySelector(id);
133        if (target) target.setAttribute('tabindex', '-1');
134      }
135    });
136  });
137})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.