{"version":3,"file":"video-d3r.js","names":[],"sources":["../resources/javascript/video-d3r.js"],"sourcesContent":["// Shared across every video-d3r instance so hls.js is fetched at most once,\n// only for browsers (e.g. Firefox) that can't play HLS natively.\nlet hlsModulePromise = null;\n\nfunction loadHls() {\n  hlsModulePromise ??= import(\"hls.js\").then(m => m.default);\n  return hlsModulePromise;\n}\n\nclass VideoD3R extends HTMLElement {\n  connectedCallback() {\n    const root = this.#attachShadowRoot();\n    this.#setUpHls();\n  }\n\n  // Declarative shadow DOM (<template shadowrootmode>) is only promoted\n  // automatically by the browser's streaming HTML parser. Markup inserted\n  // later via innerHTML/AJAX (e.g. a dialog or overlay) leaves the template\n  // inert in the light DOM, so fall back to attaching it manually.\n  #attachShadowRoot() {\n    if (this.shadowRoot) return this.shadowRoot;\n\n    const template = this.querySelector('template[shadowrootmode]');\n    if (!template) return null;\n\n    const root = this.attachShadow({ mode: template.getAttribute('shadowrootmode') });\n    root.appendChild(template.content);\n    template.remove();\n    return root;\n  }\n\n  #setUpHls() {\n    const video = this.video;\n    const source = video?.querySelector('source');\n    if (!video || !source || video.dataset.hlsChecked) return;\n    video.dataset.hlsChecked = '';\n\n    if (source.type.toLowerCase() !== 'application/x-mpegurl') {\n      return; // e.g. mp4 — leave it to the browser's native handling\n    }\n\n    const src = source.src;\n    // `force-hls` opts out of native playback even where it's supported (e.g.\n    // Safari) so hls.js's ABR can pick a better starting quality than the\n    // native heuristic, which tends to start conservative.\n    if (!this.hasAttribute('force-hls') && video.canPlayType('application/vnd.apple.mpegurl')) {\n      return; // Safari / Chrome 142+ already picked up the <source> natively\n    }\n\n    loadHls().then(Hls => {\n      if (!Hls.isSupported()) return;\n      const hls = new Hls();\n      hls.loadSource(src);\n      hls.attachMedia(video);\n    });\n  }\n\n  // The one deliberate escape hatch: JS can still get a real handle on the\n  // video (e.g. for a player SDK), even though CSS and querySelector from\n  // outside cannot.\n  get video() {\n    return this.shadowRoot.querySelector('video');\n  }\n}\n\ncustomElements.define('video-d3r', VideoD3R);\n"],"mappings":"AAEA,IAAI,EAAmB,KAEvB,SAAS,GAAU,CAEjB,MADA,KAAqB,OAAO,0BAAS,CAAC,KAAK,GAAK,EAAE,OAAO,EAClD,CACT,CAEA,IAAM,EAAN,cAAuB,WAAY,CACjC,mBAAoB,CACL,KAAK,GAAkB,EACpC,KAAK,GAAU,CACjB,CAMA,IAAoB,CAClB,GAAI,KAAK,WAAY,OAAO,KAAK,WAEjC,IAAM,EAAW,KAAK,cAAc,0BAA0B,EAC9D,GAAI,CAAC,EAAU,OAAO,KAEtB,IAAM,EAAO,KAAK,aAAa,CAAE,KAAM,EAAS,aAAa,gBAAgB,CAAE,CAAC,EAGhF,OAFA,EAAK,YAAY,EAAS,OAAO,EACjC,EAAS,OAAO,EACT,CACT,CAEA,IAAY,CACV,IAAM,EAAQ,KAAK,MACb,EAAS,GAAO,cAAc,QAAQ,EAI5C,GAHI,CAAC,GAAS,CAAC,GAAU,EAAM,QAAQ,aACvC,EAAM,QAAQ,WAAa,GAEvB,EAAO,KAAK,YAAY,IAAM,yBAChC,OAGF,IAAM,EAAM,EAAO,IAIf,CAAC,KAAK,aAAa,WAAW,GAAK,EAAM,YAAY,+BAA+B,GAIxF,EAAQ,CAAC,CAAC,KAAK,GAAO,CACpB,GAAI,CAAC,EAAI,YAAY,EAAG,OACxB,IAAM,EAAM,IAAI,EAChB,EAAI,WAAW,CAAG,EAClB,EAAI,YAAY,CAAK,CACvB,CAAC,CACH,CAKA,IAAI,OAAQ,CACV,OAAO,KAAK,WAAW,cAAc,OAAO,CAC9C,CACF,EAEA,eAAe,OAAO,YAAa,CAAQ"}