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.