{"version":3,"file":"main.umd.cjs","names":[],"sources":["../src/main.ts"],"sourcesContent":["import type { VistaData, VistaExtension, VistaImageParams, VistaImgConfig, VistaView } from 'vistaview';\nimport { VistaBox } from 'vistaview';\n\nexport type VistaVideoConfig = VistaImgConfig & {\n  type?: 'video' | string;\n  poster?: string;\n  videoType?: string;\n};\n\nconst VIDEO_EXTENSIONS = /\\.(mp4|webm|ogg|mov|m4v)(\\?.*)?(#.*)?$/i;\n\n// 1x1 transparent PNG, used when no poster/thumbnail is available\nconst BLANK_POSTER =\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=';\n\n/**\n * Detect whether a gallery item is a direct video file.\n * Matches either an explicit `type: 'video'` marker, or a src\n * ending in a known video file extension / blob URL.\n * @param item - Gallery item config\n * @returns true if the item should be handled as a native video\n */\nexport function isNativeVideo(item: VistaVideoConfig): boolean {\n  if (!item) return false;\n  if (item.type === 'video') return true;\n  if (!item.src) return false;\n  if (item.src.startsWith('blob:')) return true;\n  return VIDEO_EXTENSIONS.test(item.src);\n}\n\nexport class VistaNativeVideo extends VistaBox {\n  element: HTMLDivElement;\n  video: HTMLVideoElement;\n\n  constructor(par: VistaImageParams) {\n    super(par);\n\n    const config = par.elm.config as VistaVideoConfig;\n\n    const div = document.createElement('div');\n    div.style.position = 'relative';\n\n    const poster = document.createElement('img');\n    div.appendChild(poster);\n    poster.src = this.origin?.image.src || config.poster || BLANK_POSTER;\n    poster.style.width = '100%';\n    poster.style.height = '100%';\n    poster.style.objectFit = 'cover';\n    poster.classList.add('vvw--pulsing');\n\n    this.element = div;\n    this.element.classList.add('vvw-img-hi');\n\n    // set sizes\n    const { width: fullWidth, height: fullHeight } = this.getFullSizeDim();\n    this.fullH = fullHeight;\n    this.fullW = fullWidth;\n    this.minW = this.fullW * 0.5;\n    this.maxW = this.fullW; // no scaling, matches other video extensions\n    this.element.style.width = `${fullWidth}px`;\n    this.element.style.height = `${fullHeight}px`;\n\n    // trigger setSizes to setup thumb and video initial style\n    this.setSizes({ stableSize: false, initDimension: true });\n\n    const video = document.createElement('video');\n    video.controls = true;\n    video.preload = 'metadata';\n    video.playsInline = true;\n    if (config.poster) video.poster = config.poster;\n    video.style.position = 'absolute';\n    video.style.top = '0';\n    video.style.left = '0';\n    video.style.width = '100%';\n    video.style.height = '100%';\n    video.style.opacity = '0';\n    video.style.transition = 'opacity 333ms ease';\n    video.style.objectFit = 'contain';\n\n    if (config.videoType || config.type === 'video') {\n      const source = document.createElement('source');\n      source.src = config.src;\n      if (config.videoType) source.type = config.videoType;\n      video.appendChild(source);\n    } else {\n      video.src = config.src;\n    }\n\n    div.appendChild(video);\n    this.video = video;\n\n    video.onloadedmetadata = () => {\n      video.style.opacity = '1';\n      poster.classList.remove('vvw--pulsing');\n      this.isLoadedResolved!(true);\n    };\n\n    video.onerror = (e) => {\n      this.isLoadedRejected!(e);\n    };\n  }\n\n  // the default full size is the scaled thumbnail size\n  // so we change it to 16:9 full window width size (or max 800px)\n  protected getFullSizeDim(): { width: number; height: number } {\n    const maxWidth = Math.min(window.innerWidth, 800);\n    return {\n      width: maxWidth,\n      height: (maxWidth * 9) / 16,\n    };\n  }\n\n  destroy() {\n    // pause and release the decoder; never revoke config.src here since\n    // any blob: URL in it was created (and is owned) by the caller\n    this.video.pause();\n    this.video.removeAttribute('src');\n    this.video.querySelectorAll('source').forEach((s) => s.remove());\n    this.video.load();\n\n    super.destroy();\n  }\n\n  // override to avoid propagating content change event\n  // (because no change will happen on the video element)\n  setFinalTransform() {\n    return super.setFinalTransform({ propagateEvent: false });\n  }\n}\n\nexport function nativeVideo(): VistaExtension {\n  return {\n    name: 'nativeVideo',\n    onInitializeImage: (params: VistaImageParams) => {\n      const config = params.elm.config as VistaVideoConfig;\n      if (!isNativeVideo(config)) return;\n\n      return new VistaNativeVideo(params);\n    },\n    onImageView: async (data: VistaData, v: VistaView) => {\n      const mainData = data.images.to![Math.floor(data.images.to!.length / 2)];\n      if (mainData instanceof VistaNativeVideo) {\n        v.deactivateUi(['zoomIn', 'zoomOut'], mainData);\n      }\n    },\n  };\n}\n"],"mappings":"gRASA,IAAM,EAAmB,0CAGnB,EACJ,qHASF,SAAgB,EAAc,EAAiC,CAK7D,OAJK,EACD,EAAK,OAAS,QAAgB,GAC7B,EAAK,IACN,EAAK,IAAI,WAAW,QAAQ,CAAS,GAClC,EAAiB,KAAK,EAAK,IAAI,CAFhB,GAFJ,GAOpB,IAAa,EAAb,cAAsC,EAAA,QAAS,CAC7C,QACA,MAEA,YAAY,EAAuB,CACjC,MAAM,EAAI,CAEV,IAAM,EAAS,EAAI,IAAI,OAEjB,EAAM,SAAS,cAAc,MAAM,CACzC,EAAI,MAAM,SAAW,WAErB,IAAM,EAAS,SAAS,cAAc,MAAM,CAC5C,EAAI,YAAY,EAAO,CACvB,EAAO,IAAM,KAAK,QAAQ,MAAM,KAAO,EAAO,QAAU,EACxD,EAAO,MAAM,MAAQ,OACrB,EAAO,MAAM,OAAS,OACtB,EAAO,MAAM,UAAY,QACzB,EAAO,UAAU,IAAI,eAAe,CAEpC,KAAK,QAAU,EACf,KAAK,QAAQ,UAAU,IAAI,aAAa,CAGxC,GAAM,CAAE,MAAO,EAAW,OAAQ,GAAe,KAAK,gBAAgB,CACtE,KAAK,MAAQ,EACb,KAAK,MAAQ,EACb,KAAK,KAAO,KAAK,MAAQ,GACzB,KAAK,KAAO,KAAK,MACjB,KAAK,QAAQ,MAAM,MAAQ,GAAG,EAAU,IACxC,KAAK,QAAQ,MAAM,OAAS,GAAG,EAAW,IAG1C,KAAK,SAAS,CAAE,WAAY,GAAO,cAAe,GAAM,CAAC,CAEzD,IAAM,EAAQ,SAAS,cAAc,QAAQ,CAc7C,GAbA,EAAM,SAAW,GACjB,EAAM,QAAU,WAChB,EAAM,YAAc,GAChB,EAAO,SAAQ,EAAM,OAAS,EAAO,QACzC,EAAM,MAAM,SAAW,WACvB,EAAM,MAAM,IAAM,IAClB,EAAM,MAAM,KAAO,IACnB,EAAM,MAAM,MAAQ,OACpB,EAAM,MAAM,OAAS,OACrB,EAAM,MAAM,QAAU,IACtB,EAAM,MAAM,WAAa,qBACzB,EAAM,MAAM,UAAY,UAEpB,EAAO,WAAa,EAAO,OAAS,QAAS,CAC/C,IAAM,EAAS,SAAS,cAAc,SAAS,CAC/C,EAAO,IAAM,EAAO,IAChB,EAAO,YAAW,EAAO,KAAO,EAAO,WAC3C,EAAM,YAAY,EAAO,MAEzB,EAAM,IAAM,EAAO,IAGrB,EAAI,YAAY,EAAM,CACtB,KAAK,MAAQ,EAEb,EAAM,qBAAyB,CAC7B,EAAM,MAAM,QAAU,IACtB,EAAO,UAAU,OAAO,eAAe,CACvC,KAAK,iBAAkB,GAAK,EAG9B,EAAM,QAAW,GAAM,CACrB,KAAK,iBAAkB,EAAE,EAM7B,gBAA8D,CAC5D,IAAM,EAAW,KAAK,IAAI,OAAO,WAAY,IAAI,CACjD,MAAO,CACL,MAAO,EACP,OAAS,EAAW,EAAK,GAC1B,CAGH,SAAU,CAGR,KAAK,MAAM,OAAO,CAClB,KAAK,MAAM,gBAAgB,MAAM,CACjC,KAAK,MAAM,iBAAiB,SAAS,CAAC,QAAS,GAAM,EAAE,QAAQ,CAAC,CAChE,KAAK,MAAM,MAAM,CAEjB,MAAM,SAAS,CAKjB,mBAAoB,CAClB,OAAO,MAAM,kBAAkB,CAAE,eAAgB,GAAO,CAAC,GAI7D,SAAgB,GAA8B,CAC5C,MAAO,CACL,KAAM,cACN,kBAAoB,GAA6B,CAC/C,IAAM,EAAS,EAAO,IAAI,OACrB,KAAc,EAAO,CAE1B,OAAO,IAAI,EAAiB,EAAO,EAErC,YAAa,MAAO,EAAiB,IAAiB,CACpD,IAAM,EAAW,EAAK,OAAO,GAAI,KAAK,MAAM,EAAK,OAAO,GAAI,OAAS,EAAE,EACnE,aAAoB,GACtB,EAAE,aAAa,CAAC,SAAU,UAAU,CAAE,EAAS,EAGpD"}