diff --git a/src/components/BarraEstado/BarraEstadoStandalone.js b/src/components/BarraEstado/BarraEstadoStandalone.js index f1afd4d..d403e55 100644 --- a/src/components/BarraEstado/BarraEstadoStandalone.js +++ b/src/components/BarraEstado/BarraEstadoStandalone.js @@ -1,463 +1,636 @@ -(function () { - 'use strict' +// barra-estado.js +// Web Component da barra de estado do Governo do RS + +const COMPONENT_TAG = 'barra-estado'; + +const DEFAULT_BLOCKED_HOSTS = [ + "sitedpers.des.intra.rs.gov.br", + "sitedpers.hml.rs.gov.br", + "www.defensoria.rs.def.br", + "www.defensoria.rs.gov.br", + "www.dpe.rs.gov.br", + "matriz2-hotsite.des.procergs.localhost", + "servicos.detran.rs.gov.br", + "siteexp.des.procergs.localhost", + "siteexp.des.intra.rs.gov.br", + "siteexp.hml.rs.gov.br", + "expointer.rs.gov.br", + "www.expointer.rs.gov.br", + "sitedigx.des.intra.rs.gov.br", + "sitedigx01.hml.rs.gov.br", + "sitedigx03.rs.gov.br", + "conversasdigitais.rs.gov.br", + "www.conversasdigitais.rs.gov.br"]; + +function normalizeEscapedHtml(input = '') { + if (typeof input !== 'string') return input; + + const entityMap = { + '<': '<', + '>': '>', + '&': '&', + '"': '"', + ''': "'", + ''': "'", + '/': '/', + '/': '/', + ' ': ' ', + }; + + const entityRegex = /&(lt|gt|amp|quot|#39|apos|#x2F|#47|nbsp);/g; + + let output = input; + let previous; + + // Reaplica até estabilizar, para corrigir casos duplamente escapados. + do { + previous = output; + output = output.replace(entityRegex, (match) => entityMap[match] ?? match); + } while (output !== previous && entityRegex.test(output)); + + return output; +} + +function escapeHtml(value = '') { + return String(value) + .replaceAll('&', '&') + .replaceAll('<', '<') + .replaceAll('>', '>') + .replaceAll('"', '"') + .replaceAll("'", '''); +} + +function sanitizeUrl(url = '') { + const value = normalizeEscapedHtml(String(url).trim()); + + try { + const parsed = new URL(value, window.location.href); + const allowedProtocols = ['http:', 'https:', 'mailto:', 'tel:']; + return allowedProtocols.includes(parsed.protocol) ? parsed.href : '#'; + } catch { + return '#'; + } +} + +const LOGO_SVG = normalizeEscapedHtml(` + +`); + +const GURIA_SVG = normalizeEscapedHtml(` + +`); - var STYLE_ID = 'barra-estado-standalone-style' - var MOUNT_ATTR = 'data-barra-estado-mounted' - var HOST_ATTR = 'data-barra-estado-host' - var toggleSequence = 0 +const DEFAULT_LINKS = [ + { href: 'https://estado.rs.gov.br/agencia-de-noticias', label: 'Notícias', srPrefix: 'Estado ' }, + { href: 'https://www.rs.gov.br/', label: 'Serviços', srPrefix: 'Estado ' }, + { href: 'https://www.centraldocidadao.rs.gov.br/', label: 'Central do Cidadão', srPrefix: 'Estado ' }, + { href: 'http://www.transparencia.rs.gov.br/', label: 'Transparência', srPrefix: 'Estado ' }, + { href: 'https://estado.rs.gov.br/institucional', label: 'Secretarias e Órgãos', srPrefix: 'Estado ' }, + { href: 'https://www.diariooficial.rs.gov.br/', label: 'Diário Oficial', srPrefix: 'Estado ' }, + { href: 'https://www.rs.gov.br/guria', label: 'GurIA', srPrefix: 'Estado ', svgHtml: GURIA_SVG }, +]; + +const CSS_TEXT = normalizeEscapedHtml(` +@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); - var STYLE_TEXT = ` :host { - display: block; - width: 100%; - - // --barra-estado-background: transparent; - --barra-estado-background: #4f4f4f; - --barra-estado-menu-background: #f8f8f8; - --barra-estado-hover-color: #000000; - --barra-estado-active-color: #e4e4e4; - --barra-estado-font-size: 12px; - --barra-estado-font-size-desktop: var(--barra-estado-font-size, 12px); --barra-estado-height: 32px; - --barra-estado-link-padding: 13px 40px; - --barra-estado-link-padding-desktop: 9px 13px; - --barra-estado-guria-link-padding: 7px 13px; - --barra-estado-highlight-color: var(--green-matriz-link-activated, #135428); - --barra-estado-toggle-color: #bcbcbb; - --barra-estado-toggle-hover-color: #fff; + --barra-estado-bg: #4f4f4f; + --barra-estado-menu-bg: #737474; + --barra-estado-text: #e4e4e4; + --barra-estado-text-hover: #ffffff; + --barra-estado-alt-text: #bcbcbb; + --barra-estado-logo-fill: #f4f4f1; + --barra-estado-container-max-768: 750px; + --barra-estado-container-max-992: 970px; + --barra-estado-container-max-1200: 1170px; + display: block; + font-family: Roboto, Arial, sans-serif; + -webkit-animation: bugfix infinite 1s; + animation: bugfix infinite 1s; } -#rs-gov { - color: var(--green-matriz-link, #1a7235); - vertical-align: initial; +*, *::before, *::after { + box-sizing: border-box; } -input.barra-estado__checkbox, -.barra-estado__toggle { - display: none; +@keyframes bugfix { + from, to { padding: 0; } +} + +.sr-only { + position: absolute; + inline-size: 1px; + block-size: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; } .barra-estado { - background: var(--barra-estado-background); - min-height: var(--barra-estado-height); + block-size: var(--barra-estado-height); + background-color: var(--barra-estado-bg); } .barra-estado__container { - min-height: var(--barra-estado-height); + position: relative; + inline-size: 100%; + block-size: 100%; + margin-inline: auto; + padding-inline: 15px; } -.barra-estado__menu { - background: var(--barra-estado-menu-background); +.barra-estado__container a { + text-decoration: none; } -.barra-estado__menu > li { - float: left; - list-style: none; +.barra-estado__logo { + position: absolute; + inset-inline-start: 15px; + inset-block-start: 8px; + inline-size: 77px; + block-size: 16px; + display: inline-flex; + align-items: center; } -.barra-estado__nav { + +.barra-estado__logo svg { display: block; - float: right; + inline-size: 77px; + block-size: 16px; +} + +.barra-estado__logo svg path { + fill: var(--barra-estado-logo-fill); } -.barra-estado__menu, -.barra-estado__menu > li, -.barra-estado__menu > li > a, .barra-estado__nav { - height: 100%; + display: block; + float: right; + block-size: 100%; } .barra-estado__nav__form { - display: inline-block; + margin: 0; padding: 0; + display: inline-flex; + align-items: stretch; + block-size: 100%; +} + +#barra-estado__toggle, +.barra-estado__toggle { + display: none; +} + +.barra-estado__menu { margin: 0; - min-height: var(--barra-estado-height); + padding: 0; + block-size: 100%; + display: flex; + align-items: stretch; + background: var(--barra-estado-menu-bg); + border-block-start: 1px solid #fff; + text-transform: uppercase; + list-style: none; +} + +.barra-estado__menu > li { + display: flex; + align-items: stretch; } .barra-estado__menu > li > a { - display: block; - box-sizing: border-box; - padding: var(--barra-estado-link-padding); - color: var(--green-matriz-link, #1a7235); - font-size: var(--barra-estado-font-size); + display: flex; + align-items: center; + padding: 0 13px; + color: var(--barra-estado-text); + font-size: 12px; font-weight: 700; line-height: 1; - transition: box-shadow 0.25s linear, color 0.25s linear; + white-space: nowrap; + transition: box-shadow .25s linear, color .25s linear; } -.barra-estado__menu > li > a:hover > svg > path, -.barra-estado__menu > li > a:focus > svg > path { - fill: var(--barra-estado-hover-color); + +.barra-estado__menu > li > a:visited, +.barra-estado__menu > li > a:active { + color: var(--barra-estado-text) !important; } -.barra-estado__menu > li > a:focus, -.barra-estado__menu > li > a:hover { - box-shadow: inset 5px 0 var(--barra-estado-highlight-color); - color: var(--barra-estado-hover-color); +.barra-estado__menu > li > a:hover, +.barra-estado__menu > li > a:focus-visible { + box-shadow: inset 5px 0 #fff; + color: var(--barra-estado-text-hover); + outline: none; } -.barra-estado__menu > li > a:active { - color: var(--barra-estado-active-color) !important; +.barra-estado__menu > li > a svg { + display: inline-block; + vertical-align: middle; + block-size: auto; + max-block-size: 14px; } -.barra-estado__menu, -.barra-estado__menu > li, -.barra-estado__menu > li > a { - height: auto; +.barra-estado__menu > li > a svg#GurIA { + transform: translateY(-2px); } .barra-estado__toggle { z-index: 2; } -.barra-estado__toggle:after { - color: var(--barra-estado-toggle-color); +.barra-estado__toggle::after { content: attr(data-open); - transition: all 0.5s linear; -} - -.barra-estado__toggle:hover:after { - color: var(--barra-estado-toggle-hover-color); + position: absolute; + inset-inline-end: 0; + inset-block-start: 0; + display: flex; + align-items: center; + justify-content: flex-end; + inline-size: 45px; + block-size: 32px; + padding-inline-end: 4px; + color: var(--barra-estado-alt-text); + font-size: 18px; + line-height: 1; + transition: color .5s linear; } -.barra-estado__toggle:focus-visible { - outline: 2px solid var(--govrs-color-focus, #ffcd07); - outline-offset: 2px; +.barra-estado__toggle:hover::after, +.barra-estado__toggle:focus-visible::after { + color: #fff; } -input.barra-estado__checkbox:checked + label.barra-estado__toggle:after { +#barra-estado__toggle:checked + .barra-estado__toggle::after { content: attr(data-close); } -@media only screen and (min-width: 992px) { +@media only screen and (max-width: 991.98px) { .barra-estado__menu { - padding: 0; - border-top: none; - margin-top: 0; - background: var(--barra-estado-menu-background); + position: absolute; + inset-inline-end: 0; + inset-block-start: 32px; + z-index: 999; + display: none; + flex-direction: column; + align-items: stretch; + inline-size: 280px; + block-size: auto; + padding-block: 4px; + opacity: 0; + background: var(--barra-estado-menu-bg); + border-block-start: 1px solid #fff; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); + } + + .barra-estado__menu > li { + display: block; + inline-size: 100%; + block-size: auto; + margin: 0; } .barra-estado__menu > li > a { - padding: var(--barra-estado-link-padding-desktop); - font-size: var(--barra-estado-font-size-desktop); + inline-size: 100%; + block-size: auto; + padding: 14px 20px; } - .barra-estado__menu > li > a:focus, - .barra-estado__menu > li > a:hover { - box-shadow: inset 0 2px var(--barra-estado-highlight-color); - color: var(--barra-estado-hover-color); + .barra-estado__toggle { + position: relative; + display: block; + inline-size: 45px; + block-size: 32px; + cursor: pointer; + user-select: none; + -webkit-touch-callout: none; } -} -.barra-estado__menu > li > a.barra-estado__guria-link { - padding: var(--barra-estado-guria-link-padding); + #barra-estado__toggle:checked ~ .barra-estado__menu { + display: flex; + opacity: 1; + } } -.visually-hidden { - position: absolute !important; - overflow: hidden !important; - width: 1px !important; - height: 1px !important; - padding: 0 !important; - border: 0 !important; - margin: -1px !important; - clip: rect(0, 0, 0, 0) !important; - white-space: nowrap !important; +@media (min-width: 768px) { + .barra-estado__container { + max-inline-size: var(--barra-estado-container-max-768); + } } -:host-context(.high-contrast) .barra-estado { - border-bottom: 1px solid var(--govrs-color-contrast-foreground, #ffffff) !important; - background-color: var(--govrs-color-contrast-background, #000000) !important; -} +@media (min-width: 992px) { + .barra-estado__container { + max-inline-size: var(--barra-estado-container-max-992); + } -:host-context(.high-contrast) .barra-estado__menu { - background-color: var(--govrs-color-contrast-background, #000000) !important; -} + .barra-estado__menu { + background: transparent; + border-block-start: none; + } -:host-context(.high-contrast) .barra-estado__menu > li > a > #GurIA path { - fill: var(--govrs-color-contrast-foreground, #ffffff) !important; -} + .barra-estado__menu > li > a { + font-size: 11px; + } -:host-context(.high-contrast) .barra-estado__menu > li > a:focus { - box-shadow: inset 0 5px var(--govrs-color-contrast-foreground, #ffffff) !important; - color: var(--govrs-color-contrast-foreground, #ffffff) !important; + .barra-estado__menu > li > a:hover, + .barra-estado__menu > li > a:focus-visible { + box-shadow: inset 0 2px #fff; + color: var(--barra-estado-text-hover); + } } -:host-context(.high-contrast) .barra-estado__menu > li > a:hover { - box-shadow: inset 0 5px var(--govrs-color-contrast-foreground, #ffffff) !important; - color: var(--govrs-color-contrast-foreground, #ffffff) !important; +@media (min-width: 1200px) { + .barra-estado__container { + max-inline-size: var(--barra-estado-container-max-1200); + } } +`); + +function createMenuHtml(links) { + const items = links.map((item) => { + const target = item.target === '_blank' ? '_blank' : '_self'; + const rel = target === '_blank' ? ' rel="noopener noreferrer"' : ''; + + const href = sanitizeUrl(item.href); + const label = escapeHtml(normalizeEscapedHtml(item.label || '')); + const srPrefix = escapeHtml(normalizeEscapedHtml(item.srPrefix || '')); + + + if (typeof item.svgHtml === 'string' && item.svgHtml.trim()) { + const svg = normalizeEscapedHtml(item.svgHtml); + return ` +
  • + + ${srPrefix}${label}${svg} + +
  • `; + } -:host-context(.high-contrast) #rs-gov > path { - fill: var(--govrs-color-contrast-foreground, #ffffff) !important; + return ` +
  • + + ${srPrefix}${label} + +
  • `; + }).join(''); + + return normalizeEscapedHtml(` +
    +
    + + +
    +
    + + + +
      + ${items} +
    +
    +
    +
    +
    + `); } -` - - var RS_GOV_SVG = ` - - RS.GOV - Governo do Estado do Rio Grande do Sul - - - - - - - - - - -` - - var GURIA_SVG = ` - - GurIA - A tua nova assistente digital - - - - - - - -` - - function renderMenuItem(item) { - var className = item.className ? ' class="' + item.className + '"' : '' - var content = item.html || 'Estado ' + item.label - return '
  • ' + content + '
  • ' +class BarraEstado extends HTMLElement { + static get observedAttributes() { + return ['links']; } - var MENU_ITEMS = [ - { href: 'https://estado.rs.gov.br/agencia-de-noticias', label: 'Notícias' }, - { href: 'https://www.rs.gov.br/', label: 'Serviços' }, - { href: 'https://www.centraldocidadao.rs.gov.br/', label: 'Central do Cidadão' }, - { href: 'http://www.transparencia.rs.gov.br/', label: 'Transparência' }, - { href: 'https://estado.rs.gov.br/institucional', label: 'Locais e Órgãos', className: 'barra-letters' }, - { href: 'https://www.diariooficial.rs.gov.br/', label: 'Diário Oficial' }, - { - href: 'https://www.rs.gov.br/guria', - className: 'barra-estado__guria-link', - html: 'Estado ' + GURIA_SVG, - }, - ] - - var MENU_ITEMS_HTML = MENU_ITEMS.map(renderMenuItem).join('') - - function ensureWindowOrigin() { - if (typeof window === 'undefined') return - - if (!('origin' in window.location)) { - try { - var locationObject = window.location - locationObject.origin = locationObject.protocol + '//' + locationObject.host - } catch (error) { - } - } - } + constructor() { + super(); - function ensureStyles(styleHost) { - if (typeof document === 'undefined' || !styleHost) return null + this._shadow = this.attachShadow({ mode: 'closed' }); - if (typeof styleHost.querySelector === 'function') { - var existingStyle = styleHost.querySelector('#' + STYLE_ID) - if (existingStyle) return existingStyle - } + this._links = null; + this._onToggleChange = null; + this._onToggleKeydown = null; +} - var styleElement = document.createElement('style') - styleElement.id = STYLE_ID - styleElement.type = 'text/css' - styleElement.textContent = STYLE_TEXT + + get links() { + return this._links ?? DEFAULT_LINKS; + } - if (typeof styleHost.appendChild === 'function') { - styleHost.appendChild(styleElement) - return styleElement + set links(value) { + if (Array.isArray(value) && value.length > 0) { + this._links = value; + this.render(); } - - return null } - function createToggleId() { - toggleSequence += 1 - return 'barra-estado__toggle-' + toggleSequence + attributeChangedCallback(name, oldValue, newValue) { + if (name === 'links' && oldValue !== newValue && typeof newValue === 'string') { + try { + const parsed = JSON.parse(newValue); + if (Array.isArray(parsed)) { + this._links = parsed; + this.render(); + } + } catch { + + } + } } - function renderMarkup(toggleId) { - return [ - '
    ', - '
    ', - '
    ', - '', - '
    ', - '
    ', - '', - '', - '
      ', - MENU_ITEMS_HTML, - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - '
    ', - ].join('') + connectedCallback() { + this.render(); } - function createRenderRoot(hostElement) { - if (!hostElement) return null + disconnectedCallback() { + this.removeA11yListeners(); + } - if (hostElement.shadowRoot) return hostElement.shadowRoot + render() { + if (!this._shadow) return; - if (typeof hostElement.attachShadow !== 'function') { - console.error('BarraEstadoStandalone: Shadow DOM não é suportado neste ambiente.') - return null - } + this.removeA11yListeners(); - try { - return hostElement.attachShadow({ mode: 'open' }) - } catch (error) { - console.error('BarraEstadoStandalone: falha ao criar Shadow DOM.', error) - return null - } - } + const safeCss = normalizeEscapedHtml(CSS_TEXT); + const safeHtml = createMenuHtml(this.links); - function clearRenderRoot(renderRoot) { - if (!renderRoot) return + this._shadow.innerHTML = ` + + ${safeHtml} + `; - while (renderRoot.firstChild) { - renderRoot.removeChild(renderRoot.firstChild) - } - } + this.setupA11y(); +} - function bindToggleBehavior(renderRoot, toggleId) { - if (!renderRoot || typeof renderRoot.querySelector !== 'function') return - var checkbox = renderRoot.querySelector('#' + toggleId) - var toggle = renderRoot.querySelector('#' + toggleId + '-toggle') + setupA11y() { + const toggleInput = this.shadowRoot?.querySelector('#barra-estado__toggle'); + const toggleLabel = this.shadowRoot?.querySelector('.barra-estado__toggle'); - if (!checkbox || !toggle) return + if (!toggleInput || !toggleLabel) return; - var syncAriaState = function () { - var isOpen = Boolean(checkbox.checked) - toggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false') - } + this._onToggleChange = () => { + toggleLabel.setAttribute('aria-expanded', String(toggleInput.checked)); + }; - toggle.addEventListener('keydown', function (event) { + this._onToggleKeydown = (event) => { if (event.key === 'Enter' || event.key === ' ') { - event.preventDefault() - checkbox.click() + event.preventDefault(); + toggleInput.checked = !toggleInput.checked; + toggleInput.dispatchEvent(new Event('change', { bubbles: true })); } + }; - if (event.key === 'Escape' && checkbox.checked) { - event.preventDefault() - checkbox.checked = false - checkbox.dispatchEvent(new Event('change', { bubbles: true })) - } - }) - - checkbox.addEventListener('change', syncAriaState) - syncAriaState() + this._onToggleChange(); + toggleInput.addEventListener('change', this._onToggleChange, { passive: true }); + toggleLabel.addEventListener('keydown', this._onToggleKeydown); } - function mountBarraEstado(hostElement) { - if (typeof document === 'undefined' || !hostElement) return null - - ensureWindowOrigin() - - var renderRoot = createRenderRoot(hostElement) - if (!renderRoot) return null - - var toggleId = createToggleId() - - clearRenderRoot(renderRoot) - ensureStyles(renderRoot) - - var fragmentHost = document.createElement('div') - fragmentHost.innerHTML = renderMarkup(toggleId) + removeA11yListeners() { + const toggleInput = this.shadowRoot?.querySelector('#barra-estado__toggle'); + const toggleLabel = this.shadowRoot?.querySelector('.barra-estado__toggle'); - while (fragmentHost.firstChild) { - renderRoot.appendChild(fragmentHost.firstChild) + if (toggleInput && this._onToggleChange) { + toggleInput.removeEventListener('change', this._onToggleChange); } - bindToggleBehavior(renderRoot, toggleId) - hostElement.setAttribute(MOUNT_ATTR, 'true') + if (toggleLabel && this._onToggleKeydown) { + toggleLabel.removeEventListener('keydown', this._onToggleKeydown); + } - return hostElement + this._onToggleChange = null; + this._onToggleKeydown = null; } +} - function getExistingHost() { - if (typeof document === 'undefined') return null - return document.querySelector('[' + HOST_ATTR + '="true"]') +function defineBarraEstado(tagName = COMPONENT_TAG) { + if (typeof window === 'undefined' || !('customElements' in window)) return; + if (!window.customElements.get(tagName)) { + window.customElements.define(tagName, BarraEstado); } +} - function createMountHost() { - if (typeof document === 'undefined' || !document.body) return null +function isHostBlocked() { + if (typeof window === 'undefined' || !window.location) return false; - var existingHost = getExistingHost() - if (existingHost) return existingHost + const config = window.barraEstadoConfig || {}; + const extra = Array.isArray(config.blockedHosts) ? config.blockedHosts : []; + const patterns = DEFAULT_BLOCKED_HOSTS.concat(extra); + const host = String(window.location.hostname || '').toLowerCase(); - var host = document.createElement('div') - host.setAttribute(HOST_ATTR, 'true') - host.setAttribute(MOUNT_ATTR, 'false') + return patterns.some((pattern) => { + if (pattern instanceof RegExp) return pattern.test(host); + if (typeof pattern !== 'string' || pattern === '') return false; - if (document.body.firstChild) { - document.body.insertBefore(host, document.body.firstChild) - } else { - document.body.appendChild(host) + const p = pattern.toLowerCase(); + + if (p.startsWith('.')) { + return host === p.slice(1) || host.endsWith(p); } + return host === p; + }); +} - return host - } +function injectBodyReset() { + if (typeof document === 'undefined' || !document.head) return; + if (document.getElementById('barra-estado-body-reset')) return; + + const style = document.createElement('style'); + style.id = 'barra-estado-body-reset'; + style.textContent = + 'html.barra-estado-mounted,' + + 'body.barra-estado-mounted{' + + 'margin-top:0 !important;' + + 'padding-top:0 !important;' + + '}'; + document.head.appendChild(style); +} - function bootstrapIntoBody() { - if (typeof document === 'undefined') return null +function autoMountBarraEstado() { + if (typeof document === 'undefined') return; + if (isHostBlocked()) return; - var run = function () { - var host = createMountHost() + const mount = () => { + + document.querySelectorAll( + '.barra-estado, .container-menu, .barra-estado-host, ' + COMPONENT_TAG + ).forEach((node) => node.remove()); - if (!host) { - console.error('BarraEstadoStandalone: não foi possível criar o host no .') - return null - } + if (!document.body) return; - return mountBarraEstado(host) - } + + injectBodyReset(); + document.documentElement.classList.add('barra-estado-mounted'); + document.body.classList.add('barra-estado-mounted'); - if (document.body) { - return run() - } + const wrapper = document.createElement('div'); + wrapper.className = 'barra-estado-host container-menu'; + wrapper.style.cssText = + 'margin:0;padding:0;display:block;width:100%;line-height:0;'; - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', run, { once: true }) - return null - } + const barra = document.createElement(COMPONENT_TAG); + barra.className = 'barra-estado'; + barra.style.cssText = 'display:block;margin:0;padding:0;line-height:normal;'; + wrapper.appendChild(barra); - window.addEventListener('load', run, { once: true }) - return null + document.body.prepend(wrapper); + }; + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', mount, { once: true }); + } else { + mount(); } +} + +if (typeof window !== 'undefined') { + window.BarraEstado = BarraEstado; + window.defineBarraEstado = defineBarraEstado; + window.mountBarraEstado = autoMountBarraEstado; + window.isBarraEstadoHostBlocked = isHostBlocked; + window.BARRA_ESTADO_DEFAULT_BLOCKED_HOSTS = DEFAULT_BLOCKED_HOSTS.slice(); +} + +defineBarraEstado(); +autoMountBarraEstado(); - bootstrapIntoBody() -})() \ No newline at end of file