/* During build, DOC_VERSIONS is prefixed to convey all the versions available, informed by `_data/versions.json` * Example: * const DOC_VERSIONS = ["2.1","1.1"]; * const DOC_VERSIONS_ARCHIVED = ["2.0","1.0"]; * * DOC_VERSION_LATEST will pick `latest`, or in its absence the `current` version. * const DOC_VERSION_LATEST = "2.1"; */ const PREFIX = "OpenSearch "; const tpl = `
`; class VersionSelector extends HTMLElement { static get observedAttributes() { return ['selected']; } constructor() { super(); this.attachShadow({mode: 'open', delegatesFocus: true}); this._onBlur = (e => { this._expand(false); this.removeEventListener('blur', this._onBlur); }).bind(this); } async connectedCallback() { const {shadowRoot} = this; const frag = this._makeFragment(tpl); frag.querySelector('#selected').textContent = `${PREFIX}${this.getAttribute('selected')}.x`; const pathName = location.pathname.replace(/\/docs(\/((latest|\d+\.\d+)\/?)?)?/, ''); const versionsDOMNodes = DOC_VERSIONS.map((v, idx) => `${PREFIX}${v}.x`); if (Array.isArray(DOC_VERSIONS_ARCHIVED) && DOC_VERSIONS_ARCHIVED.length) { versionsDOMNodes.push( `Show archived`, `Archived`, ...DOC_VERSIONS_ARCHIVED.map((v, idx) => `${PREFIX}${v}.x`) ); } const versionsDOMText = versionsDOMNodes.join(''); frag.querySelector('#dropdown').appendChild(this._makeFragment(versionsDOMText)); frag.querySelector('#spacer').appendChild(this._makeFragment(versionsDOMText)); shadowRoot.appendChild(frag); this._instrument(shadowRoot); } _instrument(shadowRoot) { shadowRoot.querySelector('#root').addEventListener('click', e => { this._expand(this.getAttribute('aria-expanded') !== 'true'); }); const showNode = shadowRoot.querySelector('#dropdown .show-archived'); showNode?.addEventListener('click', e => { showNode.setAttribute('aria-expanded', 'true'); }); /* On some devices, `blur` is fired on the component before navigation occurs when choosing a version from the * dropdown; this ends up hiding the dropdown and preventing the navigation. The `pointerup` on the anchor * element is always fired before the `blur` is dispatched on the component and that is used here to trigger * the navigation before the dropdown is hidden. */ shadowRoot.querySelector('#dropdown').addEventListener('pointerup', e => { const {target} = e; e.preventDefault(); if (target.matches('a[href]') && target.href) document.location.href = target.href; }); } _expand(flag) { this.setAttribute('aria-expanded', flag); if (flag) this.addEventListener('blur', this._onBlur); } _makeFragment(html) { return document.createRange().createContextualFragment(html); } } customElements.define('version-selector', VersionSelector);