PageSourceSearch

https://site.de/_static/57b54aa969c5e910/scripts/features/common/mobile-help-bar.js

js site.de collected 2026-10-04 15:21:20 UTC 2,890 bytes, 63 lines download raw bytes

1import { bindLocaleRerender, tText } from '../../client-utils.js';
2
3// Keep the real launchers in their owning components. Moving or cloning them
4// would break deferred chat replacement, modal focus restoration, and badges.
5const createMobileHelpContent = (button, { icon = '', text = '' } = {}) => {
6  const iconElement = document.createElement('span');
7  iconElement.dataset.mobileHelpIcon = '';
8  iconElement.className = icon;
9  iconElement.setAttribute('aria-hidden', 'true');
10  const label = document.createElement('span');
11  label.dataset.mobileHelpLabel = '';
12  label.setAttribute('aria-hidden', 'true');
13  label.textContent = text;
14  button.append(iconElement, label);
15  return label;
16};
17
18const initMobileHelpBar = () => {
19  const html = document.documentElement;
20  if (html.hasAttribute('data-mobile-help-layout')) return;
21
22  const searchActions = document.querySelector('[data-search-floating-actions]');
23  html.dataset.mobileHelpLayout = searchActions ? 'search' : 'standard';
24  const background = document.createElement('div');
25  background.dataset.mobileHelpBar = '';
26  background.setAttribute('aria-hidden', 'true');
27  document.body.append(background);
28
29  if (searchActions) {
30    searchActions.parentElement.setAttribute('data-mobile-help-search-container', '');
31    const controls = [
32      ['[data-search-domain-list-trigger]', 'icon-search', 'common.search', 'Search'],
33      ['[data-cart-trigger]', 'icon-cart', 'common.cart.button', 'Cart'],
34      ['[data-contact-trigger]', 'icon-question-circle', 'common.contact.trigger', 'Contact us'],
35    ].map(([selector, icon, key, fallback]) => {
36      const button = searchActions.querySelector(selector);
37      return { key, fallback, label: button ? createMobileHelpContent(button, { icon }) : null };
38    });
39    const renderCopy = () =>
40      controls.forEach(({ key, fallback, label }) => {
41        if (label) label.textContent = tText(key, { fallback }) || fallback;
42      });
43    renderCopy();
44    bindLocaleRerender({ hasServerMarkup: () => false, render: renderCopy });
45  }
46
47  // Hide the toolbar as soon as editing starts, before the software keyboard
48  // resizes the viewport. Keep it hidden until focus leaves the form control.
49  const syncEditing = () => {
50    const active = document.activeElement;
51    const editing =
52      active instanceof HTMLElement &&
53      active.matches(
54        'textarea, select, [contenteditable]:not([contenteditable="false"]), input:not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"])',
55      );
56    html.toggleAttribute('data-mobile-help-editing', editing);
57  };
58  document.addEventListener('focusin', syncEditing);
59  document.addEventListener('focusout', () => queueMicrotask(syncEditing));
60  syncEditing();
61};
62
63export { createMobileHelpContent, initMobileHelpBar };

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.