{"version":3,"file":"index-B4wz-AmO.mjs","sources":["../../src/renderers/Epub/index.tsx"],"sourcesContent":["import { useEffect, useRef, useState, useCallback, useImperativeHandle, forwardRef } from 'react';\nimport ePub from '@likecoin/epub-ts';\nimport { X, ChevronLeft, ChevronRight, Maximize2, Minimize2, List } from 'lucide-react';\nimport { useTranslator } from '../../i18n/LocaleContext';\nimport { useFetcher } from '../../RequestContext';\nimport { RendererError } from '../RendererError';\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\n// 全局注入 epubjs 容器样式（只注入一次）\nif (typeof document !== 'undefined' && !document.getElementById('rfp-epub-styles')) {\n  const styleEl = document.createElement('style');\n  styleEl.id = 'rfp-epub-styles';\n  styleEl.textContent = `\n    .epub-container { overflow-y: auto !important; scrollbar-width: thin; }\n    .epub-container::-webkit-scrollbar { width: 8px; }\n    .epub-container::-webkit-scrollbar-track { background: transparent; }\n    .epub-container::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.15); border-radius: 4px; }\n    .epub-container::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,0.3); }\n    .epub-view > iframe { background: white; }\n  `;\n  document.head.appendChild(styleEl);\n}\n\nexport interface TocItem {\n  label: string;\n  href: string;\n  subitems?: TocItem[];\n}\n\nexport interface EpubRendererHandle extends RendererHandle {\n  prevPage: () => void;\n  nextPage: () => void;\n  toggleFullWidth: () => void;\n  toggleToc: () => void;\n}\n\ninterface EpubRendererProps {\n  url: string;\n}\n\ninterface RenditionLike {\n  display: (target?: string) => Promise<unknown>;\n  next: () => Promise<unknown>;\n  prev: () => Promise<unknown>;\n  on: (event: string, cb: (...args: unknown[]) => void) => void;\n  resize: (width: number, height: number) => void;\n  currentLocation: () => unknown;\n  destroy?: () => void;\n  themes: {\n    register: (name: string, styles: Record<string, unknown>) => void;\n    select: (name: string) => void;\n  };\n}\n\ninterface BookLike {\n  ready: Promise<unknown>;\n  loaded: { navigation: Promise<unknown> };\n  locations: {\n    generate: (chars: number) => Promise<string[]>;\n    length: () => number;\n    locationFromCfi: (cfi: string) => number;\n  };\n  renderTo: (el: HTMLElement, opts: Record<string, unknown>) => RenditionLike;\n  destroy: () => void;\n}\n\nconst A4_WIDTH = 794;\n\nexport const EpubRenderer = forwardRef<EpubRendererHandle, EpubRendererProps>(\n  ({ url }, ref) => {\n    const t = useTranslator();\n    const fetcher = useFetcher();\n    const viewerRef = useRef<HTMLDivElement>(null);\n    const bookRef = useRef<BookLike | null>(null);\n    const renditionRef = useRef<RenditionLike | null>(null);\n\n    const totalLocationsRef = useRef(0);\n    const lastCfiRef = useRef<string | null>(null);\n    const isFullWidthRef = useRef(false);\n\n    // 内部状态管理\n    const [loading, setLoading] = useState(true);\n    const [error, setError] = useState<string | null>(null);\n    const [isFullWidth, setIsFullWidth] = useState(false);\n    const [toc, setToc] = useState<TocItem[]>([]);\n    const [showToc, setShowToc] = useState(false);\n    const [activeTocHref, setActiveTocHref] = useState<string>('');\n    const [currentChapter, setCurrentChapter] = useState(0);\n    const [totalChapters, setTotalChapters] = useState(0);\n    const tocRef = useRef<TocItem[]>([]);\n    tocRef.current = toc;\n\n    isFullWidthRef.current = isFullWidth;\n\n    // 事件发射器：用于通知主组件工具栏状态变化\n    const listenersRef = useRef<Set<() => void>>(new Set());\n    const notifyToolbarChange = useCallback(() => {\n      listenersRef.current.forEach(listener => listener());\n    }, []);\n\n    // 监听影响工具栏的状态变化\n    useEffect(() => {\n      notifyToolbarChange();\n    }, [currentChapter, notifyToolbarChange]);\n\n    useEffect(() => {\n      notifyToolbarChange();\n    }, [totalChapters, notifyToolbarChange]);\n\n    useEffect(() => {\n      notifyToolbarChange();\n    }, [isFullWidth, notifyToolbarChange]);\n\n    useEffect(() => {\n      notifyToolbarChange();\n    }, [toc.length, notifyToolbarChange]);\n\n    const handlePrev = useCallback(() => {\n      renditionRef.current?.prev();\n    }, []);\n\n    const handleNext = useCallback(() => {\n      renditionRef.current?.next();\n    }, []);\n\n    // 滚动监听：接近底部时强制触发 check 加载后续 section\n    const scrollContainerRef = useRef<Element | null>(null);\n    const scrollRafRef = useRef(0);\n\n    const onScrollRef = useRef((_e?: Event) => {\n      const container = scrollContainerRef.current;\n      if (!container) return;\n      const el = container as HTMLElement;\n      const nearBottom = el.scrollTop + el.clientHeight >= el.scrollHeight - 200;\n      if (nearBottom) {\n        try {\n          const mgr = (renditionRef.current as unknown as { manager?: { check?: (t?: number, e?: number) => Promise<unknown> } })?.manager;\n          mgr?.check?.(500, 500);\n        } catch { /* ignore */ }\n      }\n    });\n\n    const reattachScrollListener = useCallback(() => {\n      // 清理旧监听\n      if (scrollContainerRef.current) {\n        scrollContainerRef.current.removeEventListener('scroll', onScrollRef.current);\n        scrollContainerRef.current = null;\n      }\n      cancelAnimationFrame(scrollRafRef.current);\n\n      const tryAttach = () => {\n        const container = viewerRef.current?.querySelector('.epub-container') ?? null;\n        if (!container) {\n          scrollRafRef.current = requestAnimationFrame(tryAttach);\n          return;\n        }\n        scrollContainerRef.current = container;\n        container.addEventListener('scroll', onScrollRef.current, { passive: true });\n      };\n      scrollRafRef.current = requestAnimationFrame(tryAttach);\n    }, []);\n\n    const toggleFullWidth = useCallback(() => {\n      const newVal = !isFullWidthRef.current;\n      setIsFullWidth(newVal);\n      // 等 CSS transition 完成后再 resize 并恢复位置\n      setTimeout(() => {\n        const viewer = viewerRef.current;\n        const rendition = renditionRef.current;\n        if (!viewer || !rendition) return;\n        rendition.resize(viewer.offsetWidth, viewer.offsetHeight);\n        // 重排后恢复阅读位置\n        if (lastCfiRef.current) {\n          rendition.display(lastCfiRef.current);\n        }\n        // resize/display 可能重建 .epub-container，需要重新绑定滚动监听\n        reattachScrollListener();\n      }, 350);\n    }, [reattachScrollListener]);\n\n    const toggleToc = useCallback(() => {\n      setShowToc(prev => !prev);\n    }, []);\n\n    const handleTocClick = useCallback((href: string) => {\n      setActiveTocHref(href);\n      renditionRef.current?.display(href);\n      setShowToc(false);\n    }, []);\n\n    // 工具栏配置\n    const getToolbarGroups = useCallback((): ToolbarGroup[] => [\n      {\n        items: [\n          { type: 'button', icon: <List className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.toc'), action: toggleToc, disabled: toc.length === 0, active: showToc },\n        ],\n      },\n      {\n        items: [\n          { type: 'button', icon: <ChevronLeft className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.prev_page'), action: handlePrev, disabled: currentChapter <= 1 },\n          { type: 'text', content: `${currentChapter} / ${totalChapters}`, minWidth: '4rem' },\n          { type: 'button', icon: <ChevronRight className=\"rfp-w-4 rfp-h-4\" />, tooltip: t('toolbar.next_page'), action: handleNext, disabled: currentChapter >= totalChapters },\n        ],\n      },\n      {\n        items: [\n          { type: 'button', icon: isFullWidth ? <Minimize2 className=\"rfp-w-4 rfp-h-4\" /> : <Maximize2 className=\"rfp-w-4 rfp-h-4\" />, tooltip: isFullWidth ? t('toolbar.normal_width') : t('toolbar.full_width'), action: toggleFullWidth, active: isFullWidth },\n        ],\n      },\n    ], [currentChapter, totalChapters, isFullWidth, showToc, toc.length, t, handlePrev, handleNext, toggleToc, toggleFullWidth]);\n\n    useImperativeHandle(ref, () => ({\n      getToolbarGroups,\n      onToolbarChange: (listener: () => void) => {\n        listenersRef.current.add(listener);\n        return () => listenersRef.current.delete(listener);\n      },\n      prevPage: handlePrev,\n      nextPage: handleNext,\n      toggleFullWidth,\n      toggleToc,\n    }), [getToolbarGroups, handlePrev, handleNext, toggleFullWidth, toggleToc]);\n\n    useEffect(() => {\n      const viewer = viewerRef.current;\n      // 只有 URL 有效时才加载（避免空字符串或已 revoke 的 blob URL）\n      if (!viewer || !url) return;\n\n      setLoading(true);\n      setError(null);\n      setToc([]);\n      setShowToc(false);\n      viewer.innerHTML = '';\n      lastCfiRef.current = null;\n      totalLocationsRef.current = 0;\n\n      let cancelled = false;\n      // StrictMode 下 effect 会立即 mount→unmount→mount\n      // 用 microtask 延迟初始化，让第一次的 cleanup 先执行，避免 epubjs 内部状态被污染\n      const loadTimer = window.setTimeout(() => {\n        if (cancelled) return;\n        load();\n      }, 0);\n\n      const load = async () => {\n        try {\n          let bookInput: string | ArrayBuffer = url;\n          if (url.startsWith('blob:')) {\n            const resp = await fetcher(url);\n            bookInput = await resp.arrayBuffer();\n          }\n\n          const book = ePub(bookInput) as unknown as BookLike;\n          bookRef.current = book;\n\n          const rendition = book.renderTo(viewer, {\n            manager: 'continuous',\n            flow: 'scrolled',\n            width: '100%',\n            height: '100%',\n          });\n          renditionRef.current = rendition;\n\n          rendition.themes.register('default', {\n            body: {\n              background: '#ffffff !important',\n              color: '#1a1a1a !important',\n              'font-family': '\"Noto Serif SC\", \"Source Han Serif SC\", Georgia, \"Times New Roman\", serif !important',\n              'font-size': '16px !important',\n              'line-height': '2 !important',\n              padding: '40px 60px !important',\n              'max-width': '100% !important',\n              'box-sizing': 'border-box !important',\n              'word-break': 'break-word !important',\n              'overflow-wrap': 'break-word !important',\n            },\n            p: { 'text-indent': '2em !important', margin: '0.8em 0 !important' },\n            h1: { 'text-align': 'center !important', margin: '1.5em 0 1em !important' },\n            h2: { margin: '1.2em 0 0.8em !important' },\n            h3: { margin: '1em 0 0.6em !important' },\n            img: { 'max-width': '100% !important', height: 'auto !important' },\n            a: { color: '#2563eb !important', 'text-decoration': 'none !important' },\n          });\n          rendition.themes.select('default');\n\n          await book.ready;\n\n          // 异步生成 locations 索引（用于实时页数）\n          book.locations.generate(1024).then(() => {\n            if (cancelled) return;\n            totalLocationsRef.current = book.locations.length();\n            // 更新内部状态\n            const loc = renditionRef.current?.currentLocation() as { start?: { location?: number; cfi?: string } } | undefined;\n            const cur = loc?.start?.location ?? 0;\n            setCurrentChapter(cur + 1);\n            setTotalChapters(totalLocationsRef.current);\n          }).catch(() => { /* ignore */ });\n\n          // 获取目录\n          const nav = await book.loaded.navigation as { toc?: TocItem[] };\n          if (!cancelled && Array.isArray(nav?.toc)) {\n            setToc(nav.toc);\n          }\n\n          await rendition.display();\n\n          if (cancelled) return;\n          setCurrentChapter(1);\n          setTotalChapters(totalLocationsRef.current || 1);\n\n          setLoading(false);\n\n          rendition.on('relocated', (location: unknown) => {\n            const loc = location as { start?: { cfi?: string; location?: number; href?: string } };\n            if (loc?.start?.cfi) {\n              lastCfiRef.current = loc.start.cfi;\n            }\n            if (loc?.start?.href) {\n              // 根据 spine href 查找匹配的 TOC 项\n              const spineHref = loc.start.href;\n              const matches: string[] = [];\n              const collect = (items: TocItem[]) => {\n                for (const item of items) {\n                  const base = item.href.split('#')[0];\n                  if (base && (spineHref === base || spineHref.endsWith('/' + base) || spineHref.endsWith(base))) {\n                    matches.push(item.href);\n                  }\n                  if (item.subitems) collect(item.subitems);\n                }\n              };\n              collect(tocRef.current);\n              if (matches.length === 1) {\n                // 唯一匹配，直接设置\n                setActiveTocHref(matches[0]);\n              }\n              // 多个匹配（同一文件不同 anchor）时保持当前选中（由点击设置）\n            }\n            const cur = loc?.start?.location;\n            const total = totalLocationsRef.current;\n            if (typeof cur === 'number' && total > 0) {\n              setCurrentChapter(cur + 1);\n              setTotalChapters(total);\n            }\n          });\n\n        } catch (err) {\n          console.error('EPUB 加载错误:', err);\n          if (!cancelled) {\n            setError(t('epub.load_failed'));\n            setLoading(false);\n          }\n        }\n      };\n\n      return () => {\n        cancelled = true;\n        window.clearTimeout(loadTimer);\n        try { renditionRef.current?.destroy?.(); } catch { /* ignore */ }\n        try { bookRef.current?.destroy(); } catch { /* ignore */ }\n        renditionRef.current = null;\n        bookRef.current = null;\n      };\n    }, [url]);\n\n    // 监听容器尺寸变化：等待 transition 完成后才 resize，避免 transition 期间频繁触发导致频闪\n    useEffect(() => {\n      const viewer = viewerRef.current;\n      if (!viewer) return;\n\n      let isInitialRender = true;\n      let lastDimensions = { width: 0, height: 0 };\n      let resizeTimeout: number | null = null;\n\n      const doResize = () => {\n        const v = viewerRef.current;\n        const rendition = renditionRef.current;\n        if (!v || !rendition) return;\n        rendition.resize(v.offsetWidth, v.offsetHeight);\n        // resize 后恢复阅读位置\n        if (lastCfiRef.current) {\n          try { rendition.display(lastCfiRef.current); } catch { /* ignore */ }\n        }\n        // resize/display 可能重建 .epub-container，需要重新绑定滚动监听\n        reattachScrollListener();\n      };\n\n      const observer = new ResizeObserver(() => {\n        const v = viewerRef.current;\n        if (!v) return;\n\n        if (isInitialRender) {\n          isInitialRender = false;\n          lastDimensions = { width: v.offsetWidth, height: v.offsetHeight };\n          return;\n        }\n\n        const newDimensions = { width: v.offsetWidth, height: v.offsetHeight };\n        const widthDiff = Math.abs(lastDimensions.width - newDimensions.width);\n        const heightDiff = Math.abs(lastDimensions.height - newDimensions.height);\n\n        // 微小变化不触发，避免抖动\n        if (widthDiff < 10 && heightDiff < 10) return;\n\n        lastDimensions = newDimensions;\n\n        // 防抖：等待 transition 完成（350ms）后才重新渲染\n        if (resizeTimeout !== null) clearTimeout(resizeTimeout);\n        resizeTimeout = window.setTimeout(() => {\n          doResize();\n        }, 350);\n      });\n\n      observer.observe(viewer);\n\n      return () => {\n        observer.disconnect();\n        if (resizeTimeout !== null) clearTimeout(resizeTimeout);\n      };\n    }, [reattachScrollListener]);\n\n    useEffect(() => {\n      reattachScrollListener();\n      return () => {\n        cancelAnimationFrame(scrollRafRef.current);\n        scrollContainerRef.current?.removeEventListener('scroll', onScrollRef.current);\n      };\n    }, [url, reattachScrollListener]);\n\n    const isActive = useCallback((href: string) => {\n      return href === activeTocHref;\n    }, [activeTocHref]);\n\n    const renderTocItems = (items: TocItem[], depth = 0) => (\n      <ul style={{ marginLeft: depth > 0 ? 16 : 0 }}>\n        {items.map((item, i) => {\n          const active = isActive(item.href);\n          return (\n            <li key={`${item.href}-${i}`}>\n              <button\n                onClick={() => handleTocClick(item.href)}\n                className={`rfp-w-full rfp-text-left rfp-py-2 rfp-px-3 rfp-text-sm rfp-rounded rfp-transition-all rfp-truncate ${active\n                    ? 'rfp-text-fg-primary rfp-bg-surface-3 rfp-font-medium'\n                    : 'rfp-text-fg-secondary hover:rfp-text-fg-primary hover:rfp-bg-surface-2'\n                  }`}\n                title={item.label}\n              >\n                {item.label.trim()}\n              </button>\n              {item.subitems && item.subitems.length > 0 && renderTocItems(item.subitems, depth + 1)}\n            </li>\n          );\n        })}\n      </ul>\n    );\n\n    return (\n      <div className=\"rfp-relative rfp-w-full rfp-h-full rfp-flex rfp-justify-center rfp-bg-surface-1 rfp-overflow-hidden\">\n        {error && <RendererError message={error} />}\n\n        {loading && !error && (\n          <div className=\"rfp-absolute rfp-inset-0 rfp-flex rfp-items-center rfp-justify-center rfp-z-10\">\n            <div className=\"rfp-w-12 rfp-h-12 rfp-border-4 rfp-border-line-strong rfp-border-t-spinner-head rfp-rounded-full rfp-animate-spin\" />\n          </div>\n        )}\n\n        {/* 目录侧栏 - 滑入动画 */}\n        {toc.length > 0 && (\n          <div\n            className=\"rfp-absolute rfp-inset-0 rfp-z-20 rfp-flex rfp-transition-opacity rfp-duration-300\"\n            style={{\n              opacity: showToc ? 1 : 0,\n              pointerEvents: showToc ? 'auto' : 'none',\n            }}\n          >\n            <div\n              className=\"rfp-w-72 rfp-max-w-[80%] rfp-h-full rfp-bg-surface-overlay rfp-backdrop-blur-xl rfp-border-r rfp-border-line-weak rfp-flex rfp-flex-col rfp-shadow-2xl rfp-transition-transform rfp-duration-300\"\n              style={{ transform: showToc ? 'translateX(0)' : 'translateX(-100%)' }}\n            >\n              <div className=\"rfp-flex rfp-items-center rfp-justify-between rfp-px-4 rfp-py-3 rfp-border-b rfp-border-line-weak rfp-flex-shrink-0\">\n                <span className=\"rfp-text-fg-primary rfp-font-medium rfp-text-sm\">{t('toolbar.toc')}</span>\n                <button\n                  onClick={() => setShowToc(false)}\n                  className=\"rfp-text-fg-tertiary hover:rfp-text-fg-primary rfp-transition-colors\"\n                >\n                  <X className=\"rfp-w-4 rfp-h-4\" />\n                </button>\n              </div>\n              <div className=\"rfp-flex-1 rfp-overflow-y-auto rfp-py-4 rfp-px-1\">\n                {renderTocItems(toc)}\n              </div>\n            </div>\n            <div\n              className=\"rfp-flex-1 rfp-transition-opacity rfp-duration-300\"\n              style={{ background: showToc ? 'rgba(0,0,0,0.3)' : 'transparent' }}\n              onClick={() => setShowToc(false)}\n            />\n          </div>\n        )}\n\n        {!error && (\n          <div\n            ref={viewerRef}\n            className=\"rfp-h-full rfp-bg-surface-toolbar rfp-shadow-lg\"\n            style={{\n              width: isFullWidth ? '100%' : `${A4_WIDTH}px`,\n              maxWidth: '100%',\n              transition: 'width 0.3s ease',\n              overflow: 'hidden',\n            }}\n          />\n        )}\n      </div>\n    );\n  }\n);\n"],"names":["styleEl","A4_WIDTH","EpubRenderer","forwardRef","url","ref","t","useTranslator","fetcher","useFetcher","viewerRef","useRef","bookRef","renditionRef","totalLocationsRef","lastCfiRef","isFullWidthRef","loading","setLoading","useState","error","setError","isFullWidth","setIsFullWidth","toc","setToc","showToc","setShowToc","activeTocHref","setActiveTocHref","currentChapter","setCurrentChapter","totalChapters","setTotalChapters","tocRef","listenersRef","notifyToolbarChange","useCallback","listener","useEffect","handlePrev","_a","handleNext","scrollContainerRef","scrollRafRef","onScrollRef","_e","container","el","mgr","_b","reattachScrollListener","tryAttach","toggleFullWidth","newVal","viewer","rendition","toggleToc","prev","handleTocClick","href","getToolbarGroups","List","jsx","ChevronLeft","ChevronRight","Minimize2","Maximize2","useImperativeHandle","cancelled","loadTimer","load","bookInput","book","ePub","loc","cur","nav","location","spineHref","matches","collect","items","item","base","_c","total","err","isInitialRender","lastDimensions","resizeTimeout","doResize","v","observer","newDimensions","widthDiff","heightDiff","isActive","renderTocItems","depth","i","active","jsxs","RendererError","X"],"mappings":"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"}