@hopeplayer/core 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/HopePlayerElement.d.ts +11 -2
- package/dist/HopePlayerElement.d.ts.map +1 -1
- package/dist/chunks/{accessibility-CehDBG3h.js → accessibility-DeUIoAda.js} +43 -40
- package/dist/chunks/accessibility-DeUIoAda.js.map +1 -0
- package/dist/chunks/{ads-BFmyld9u.js → ads-CdWbE9aD.js} +2 -2
- package/dist/chunks/{ads-BFmyld9u.js.map → ads-CdWbE9aD.js.map} +1 -1
- package/dist/chunks/{cast-DJXOJLEZ.js → cast-BQ-suTcF.js} +2 -2
- package/dist/chunks/{cast-DJXOJLEZ.js.map → cast-BQ-suTcF.js.map} +1 -1
- package/dist/chunks/{history-YQ9A8HBv.js → history-DAbqEhNB.js} +2 -2
- package/dist/chunks/{history-YQ9A8HBv.js.map → history-DAbqEhNB.js.map} +1 -1
- package/dist/chunks/{markers-BmcD53SJ.js → markers-B04NMI79.js} +2 -2
- package/dist/chunks/{markers-BmcD53SJ.js.map → markers-B04NMI79.js.map} +1 -1
- package/dist/chunks/{player-BVkwkn4b.js → player-D7WQxMzr.js} +546 -452
- package/dist/chunks/player-D7WQxMzr.js.map +1 -0
- package/dist/chunks/{playlist-jDbObKz3.js → playlist-C6Mh9BE8.js} +2 -2
- package/dist/chunks/{playlist-jDbObKz3.js.map → playlist-C6Mh9BE8.js.map} +1 -1
- package/dist/chunks/pluginHost-DjvLmMYZ.js +376 -0
- package/dist/chunks/pluginHost-DjvLmMYZ.js.map +1 -0
- package/dist/chunks/{redirectScreen-CFZKtEdv.js → redirectScreen-5HAVRtxe.js} +2 -2
- package/dist/chunks/{redirectScreen-CFZKtEdv.js.map → redirectScreen-5HAVRtxe.js.map} +1 -1
- package/dist/chunks/{rewardedUnlock-Cn4_68a3.js → rewardedUnlock-CGhQyWOk.js} +2 -2
- package/dist/chunks/{rewardedUnlock-Cn4_68a3.js.map → rewardedUnlock-CGhQyWOk.js.map} +1 -1
- package/dist/chunks/{segments-DXARAkpS.js → segments-gCPrWRig.js} +2 -2
- package/dist/chunks/{segments-DXARAkpS.js.map → segments-gCPrWRig.js.map} +1 -1
- package/dist/chunks/{skipSegments-U0aUwoDt.js → skipSegments-BbWzPpXz.js} +55 -42
- package/dist/chunks/{skipSegments-U0aUwoDt.js.map → skipSegments-BbWzPpXz.js.map} +1 -1
- package/dist/chunks/{spriteThumbnails-DLfTFsPU.js → spriteThumbnails-B7oDZFTo.js} +2 -2
- package/dist/chunks/{spriteThumbnails-DLfTFsPU.js.map → spriteThumbnails-B7oDZFTo.js.map} +1 -1
- package/dist/chunks/{story-Ce56rEaN.js → story-BLBij82f.js} +2 -2
- package/dist/chunks/{story-Ce56rEaN.js.map → story-BLBij82f.js.map} +1 -1
- package/dist/controls/ControlBar.d.ts +2 -0
- package/dist/controls/ControlBar.d.ts.map +1 -1
- package/dist/controls/SettingsMenu.d.ts +5 -0
- package/dist/controls/SettingsMenu.d.ts.map +1 -1
- package/dist/hope-player.js +6 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/plugin-api/PluginHost.d.ts +65 -0
- package/dist/plugin-api/PluginHost.d.ts.map +1 -0
- package/dist/plugin-api/registry.d.ts +10 -0
- package/dist/plugin-api/registry.d.ts.map +1 -0
- package/dist/plugin-api/types.d.ts +170 -0
- package/dist/plugin-api/types.d.ts.map +1 -0
- package/dist/plugins/accessibility/Accessibility.d.ts +5 -0
- package/dist/plugins/accessibility/Accessibility.d.ts.map +1 -1
- package/dist/plugins/skip-segments/index.d.ts +2 -0
- package/dist/plugins/skip-segments/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunks/accessibility-CehDBG3h.js.map +0 -1
- package/dist/chunks/player-BVkwkn4b.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var A = Object.defineProperty;
|
|
2
2
|
var g = (h, t, e) => t in h ? A(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
|
|
3
3
|
var n = (h, t, e) => g(h, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
-
import { i as b, c as P } from "./player-
|
|
4
|
+
import { i as b, c as P } from "./player-D7WQxMzr.js";
|
|
5
5
|
const I = {
|
|
6
6
|
startMode: "after_current",
|
|
7
7
|
startIndex: 0,
|
|
@@ -233,4 +233,4 @@ export {
|
|
|
233
233
|
w as PlaylistRunner,
|
|
234
234
|
N as installPlaylist
|
|
235
235
|
};
|
|
236
|
-
//# sourceMappingURL=playlist-
|
|
236
|
+
//# sourceMappingURL=playlist-C6Mh9BE8.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playlist-jDbObKz3.js","sources":["../../src/plugins/playlist/PlaylistRunner.ts","../../src/plugins/playlist/index.ts"],"sourcesContent":["import { createIcon } from '../../icons/Icon';\nimport type { PlayableItem, PlaylistOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { isAudioOutputError } from '../../utils/media-error';\n\nexport interface PlaylistPlayerContext {\n videoEl: HTMLVideoElement;\n hostEl: HTMLElement;\n /** Liste UI'ının monte edileceği, shadow root içindeki panel. */\n panelEl: HTMLElement;\n loadSource(src: string, type?: string): Promise<void>;\n setPoster(url: string): void;\n /** AdsController varsa retry/VMAP durumunu sıfırlayıp item'ın (varsa) kendi adTagPreroll'üyle yeniden reklam ister — yoksa no-op. */\n requestFreshAd(prerollTag?: string): void;\n i18n: HopeLocaleStrings;\n}\n\ntype SourceMode = 'hls' | 'mp4';\n\ninterface Attempt {\n id: number;\n index: number;\n mode: SourceMode;\n tried: Set<SourceMode>;\n mp4Index: number;\n}\n\nconst DEFAULTS: Required<Omit<PlaylistOptions, 'items' | 'adTagPreroll' | 'ui'>> = {\n startMode: 'after_current',\n startIndex: 0,\n loop: false,\n autoplayNext: true,\n preferHls: true,\n adsOnItemChange: true,\n};\n\n/** Tek player üzerinde sıralı oynatma listesi (startMode, loop, hata fallback zinciri). */\nexport class PlaylistRunner {\n private readonly options: Required<Omit<PlaylistOptions, 'items' | 'adTagPreroll' | 'ui'>>;\n private readonly items: PlayableItem[];\n\n private index: number;\n private destroyed = false;\n private switching = false;\n private playlistActive = false;\n private startPendingAfterCurrent = false;\n private attemptId = 0;\n private attempt: Attempt | null = null;\n private lastErrorAt = 0;\n private lastAdsIndex: number | null = null;\n private lastDispatchedIndex: number | null = null;\n private userHasStartedPlayback = false;\n\n private readonly ui: {\n root: HTMLElement;\n titleEl: HTMLElement;\n listEl: HTMLElement;\n prevBtn: HTMLButtonElement;\n nextBtn: HTMLButtonElement;\n itemEls: Array<{ li: HTMLElement; titleRow: HTMLElement; progressFill: HTMLElement | null; timeEl: HTMLElement | null }>;\n };\n\n constructor(\n private readonly ctx: PlaylistPlayerContext,\n private readonly rawOptions: PlaylistOptions\n ) {\n this.options = { ...DEFAULTS, ...rawOptions };\n this.items = Array.isArray(rawOptions.items) ? rawOptions.items : [];\n this.index = this.clampIndex(this.options.startIndex);\n\n this.ui = this.buildUi();\n this.bindPlayerEvents();\n this.init();\n }\n\n // ── lifecycle ──\n\n private init(): void {\n if (!this.items.length) return;\n\n if (this.options.startMode === 'after_current') {\n this.startPendingAfterCurrent = true;\n this.playlistActive = false;\n this.setActive(this.index);\n return;\n }\n\n this.playlistActive = true;\n void this.loadAndPlay(this.index, { userInitiated: false, isPlaylistStart: true });\n }\n\n refreshLabels(): void {\n this.ui.titleEl.textContent = this.playlistTitleText();\n this.ui.prevBtn.setAttribute('aria-label', this.ctx.i18n.playlistPrev);\n this.ui.nextBtn.setAttribute('aria-label', this.ctx.i18n.playlistNext);\n this.ui.itemEls.forEach((entry, idx) => {\n const item = this.items[idx];\n if (item && !item.title) entry.titleRow.textContent = this.ctx.i18n.videoFallbackTitle(idx);\n });\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.ctx.videoEl.removeEventListener('ended', this.onEnded);\n this.ctx.videoEl.removeEventListener('error', this.onError);\n this.ctx.videoEl.removeEventListener('play', this.onUserPlay);\n this.ui.root.remove();\n }\n\n // ── public api ──\n\n start(opts: { index?: number } = {}): void {\n if (this.destroyed || !this.items.length) return;\n this.startPendingAfterCurrent = false;\n this.playlistActive = true;\n this.index = this.clampIndex(opts.index ?? this.index);\n this.setActive(this.index);\n void this.loadAndPlay(this.index, { userInitiated: false, isPlaylistStart: true });\n }\n\n next(): void {\n if (this.destroyed || !this.items.length) return;\n if (!this.playlistActive) return this.start({ index: this.index });\n\n if (this.index < this.items.length - 1) this.index++;\n else if (this.options.loop) this.index = 0;\n else return;\n\n this.setActive(this.index);\n void this.loadAndPlay(this.index, { userInitiated: true });\n }\n\n prev(): void {\n if (this.destroyed || !this.items.length) return;\n if (!this.playlistActive) return this.start({ index: this.index });\n if (this.index === 0) return;\n this.index--;\n this.setActive(this.index);\n void this.loadAndPlay(this.index, { userInitiated: true });\n }\n\n setIndex(i: number): void {\n if (this.destroyed || !this.items.length) return;\n this.index = this.clampIndex(i);\n this.setActive(this.index);\n if (!this.playlistActive) return this.start({ index: this.index });\n void this.loadAndPlay(this.index, { userInitiated: true });\n }\n\n getIndex(): number {\n return this.index;\n }\n\n isActive(): boolean {\n return this.playlistActive;\n }\n\n // ── player events ──\n\n private bindPlayerEvents(): void {\n this.ctx.videoEl.addEventListener('ended', this.onEnded);\n this.ctx.videoEl.addEventListener('error', this.onError);\n this.ctx.videoEl.addEventListener('play', this.onUserPlay);\n this.ctx.videoEl.addEventListener('timeupdate', this.onTimeUpdate);\n }\n\n private readonly onUserPlay = (): void => {\n this.userHasStartedPlayback = true;\n };\n\n private readonly onEnded = (): void => {\n if (this.startPendingAfterCurrent && !this.playlistActive) {\n this.startPendingAfterCurrent = false;\n this.playlistActive = true;\n this.setActive(this.index);\n void this.loadAndPlay(this.index, { userInitiated: true, isPlaylistStart: true });\n return;\n }\n if (this.playlistActive) this.next();\n };\n\n private readonly onError = (): void => {\n if (this.destroyed || !this.playlistActive) return;\n // Ses aygıtı yok (Firefox): video sessiz oynamaya devam ediyor — sonraki öğeye atlama.\n if (isAudioOutputError(this.ctx.videoEl.error)) return;\n const now = Date.now();\n if (now - this.lastErrorAt < 200) return;\n this.lastErrorAt = now;\n void this.fallbackOrSkip();\n };\n\n private readonly onTimeUpdate = (): void => {\n this.updateProgress();\n };\n\n // ── core load ──\n\n private async loadAndPlay(\n i: number,\n opts: { userInitiated?: boolean; forceMode?: SourceMode | null; forceMp4Index?: number | null; isFallback?: boolean; isPlaylistStart?: boolean } = {}\n ): Promise<void> {\n if (this.destroyed || this.switching || !this.playlistActive) return;\n this.switching = true;\n\n const item = this.items[i];\n if (!item) {\n this.switching = false;\n return;\n }\n const attemptId = ++this.attemptId;\n const mode = opts.forceMode ?? this.resolveMode(item);\n\n let tried = new Set<SourceMode>([mode]);\n let mp4Index = opts.forceMp4Index ?? 0;\n if (opts.isFallback && this.attempt?.index === i && this.attempt?.tried) {\n tried = new Set(this.attempt.tried);\n tried.add(mode);\n if (opts.forceMp4Index == null) mp4Index = this.attempt.mp4Index ?? 0;\n }\n this.attempt = { id: attemptId, index: i, mode, tried, mp4Index };\n\n try {\n const payload = this.buildPayload(item, mode, mp4Index);\n if (!payload) throw new Error('No playable source');\n\n this.setActive(i);\n this.ctx.videoEl.pause();\n if (item.image) this.ctx.setPoster(item.image);\n await this.ctx.loadSource(payload.src, payload.type);\n\n if (this.options.adsOnItemChange) this.maybeRequestAds(i, item, !!opts.isFallback);\n\n if (this.shouldAutoPlay(!!opts.userInitiated)) {\n try {\n await this.ctx.videoEl.play();\n } catch {\n /* autoplay engellendi — sessizce geç */\n }\n }\n this.updateProgress();\n } finally {\n this.switching = false;\n }\n }\n\n private async fallbackOrSkip(): Promise<void> {\n if (this.destroyed || !this.attempt) return;\n const item = this.items[this.attempt.index];\n if (!item) return;\n\n if (this.attempt.mode === 'mp4') {\n const mp4List = (item.mp4 || []).filter((v) => v?.src);\n const nextMp4 = (this.attempt.mp4Index ?? 0) + 1;\n if (nextMp4 < mp4List.length) {\n await this.loadAndPlay(this.attempt.index, { forceMode: 'mp4', forceMp4Index: nextMp4, isFallback: true });\n return;\n }\n }\n\n const otherMode: SourceMode = this.attempt.mode === 'hls' ? 'mp4' : 'hls';\n if (this.hasMode(item, otherMode) && !this.attempt.tried.has(otherMode)) {\n await this.loadAndPlay(this.attempt.index, { forceMode: otherMode, isFallback: true });\n return;\n }\n\n this.next();\n }\n\n // ── ads ──\n\n private maybeRequestAds(index: number, item: PlayableItem, _isFallback: boolean): void {\n if (this.lastAdsIndex === index) return;\n this.lastAdsIndex = index;\n this.ctx.requestFreshAd(item.adTagPreroll || this.rawOptions.adTagPreroll);\n }\n\n // ── sources ──\n\n private resolveMode(item: PlayableItem): SourceMode {\n if (this.options.preferHls) return this.hasMode(item, 'hls') ? 'hls' : this.hasMode(item, 'mp4') ? 'mp4' : 'hls';\n return this.hasMode(item, 'mp4') ? 'mp4' : this.hasMode(item, 'hls') ? 'hls' : 'mp4';\n }\n\n private hasMode(item: PlayableItem, mode: SourceMode): boolean {\n return Array.isArray(item[mode]) && item[mode]!.some((v) => v?.src);\n }\n\n private buildPayload(item: PlayableItem, mode: SourceMode, mp4Index = 0): { src: string; type?: string } | null {\n const list = (item[mode] || []).filter((v) => v?.src);\n if (!list.length) return null;\n\n let src;\n if (mode === 'mp4') {\n src = mp4Index > 0 ? list[mp4Index] || list[0] : list.find((v) => v.selected) || list[0];\n } else {\n src = list[0];\n }\n return { src: src!.src, type: src!.type || (mode === 'hls' ? 'application/x-mpegURL' : 'video/mp4') };\n }\n\n private shouldAutoPlay(userInitiated: boolean): boolean {\n if (userInitiated) return true;\n return this.options.autoplayNext && this.userHasStartedPlayback;\n }\n\n private clampIndex(i: number): number {\n if (!Number.isFinite(i) || !this.items.length) return 0;\n return Math.max(0, Math.min(this.items.length - 1, Math.trunc(i)));\n }\n\n // ── ui ──\n\n private buildUi() {\n const ui = this.rawOptions.ui ?? {};\n const root = document.createElement('div');\n root.setAttribute('part', 'playlist-panel');\n root.className = 'hp:flex hp:flex-col hp:gap-2 hp:p-3 hp:bg-surface-elev hp:max-h-80 hp:overflow-y-auto';\n\n const header = document.createElement('div');\n header.className = 'hp:flex hp:items-center hp:justify-between hp:gap-2 hp:mb-1';\n\n const titleEl = document.createElement('div');\n titleEl.className = 'hp:text-sm hp:font-semibold hp:text-on-surface';\n titleEl.textContent = this.playlistTitleText();\n header.appendChild(titleEl);\n\n const navWrap = document.createElement('div');\n navWrap.className = 'hp:flex hp:gap-1';\n const prevBtn = this.navButton('chevron-left', this.ctx.i18n.playlistPrev, () => this.prev());\n const nextBtn = this.navButton('chevron-left', this.ctx.i18n.playlistNext, () => this.next());\n nextBtn.style.transform = 'rotate(180deg)';\n navWrap.append(prevBtn, nextBtn);\n header.appendChild(navWrap);\n\n root.appendChild(header);\n\n const listEl = document.createElement('ul');\n listEl.className = 'hp:flex hp:flex-col hp:gap-1 hp:list-none hp:m-0 hp:p-0';\n root.appendChild(listEl);\n\n const itemEls: Array<{ li: HTMLElement; titleRow: HTMLElement; progressFill: HTMLElement | null; timeEl: HTMLElement | null }> = [];\n this.items.forEach((item, idx) => {\n const li = document.createElement('li');\n li.className =\n 'hp:flex hp:items-center hp:gap-2 hp:p-2 hp:rounded hp:cursor-pointer hp:text-on-surface-muted hp:text-sm ' +\n 'hp:hover:bg-on-surface/5 hp:data-[active=true]:bg-accent/15 hp:data-[active=true]:text-on-surface';\n\n if (item.image) {\n const img = document.createElement('img');\n img.src = item.image;\n img.loading = 'lazy';\n img.className = 'hp:w-16 hp:aspect-video hp:object-cover hp:rounded hp:shrink-0';\n li.appendChild(img);\n }\n\n const body = document.createElement('div');\n body.className = 'hp:flex-1 hp:min-w-0';\n const titleRow = document.createElement('div');\n titleRow.className = 'hp:truncate hp:font-medium';\n titleRow.textContent = item.title || this.ctx.i18n.videoFallbackTitle(idx);\n body.appendChild(titleRow);\n\n let progressFill: HTMLElement | null = null;\n let timeEl: HTMLElement | null = null;\n if (ui.showMeta !== false) {\n const metaRow = document.createElement('div');\n metaRow.className = 'hp:flex hp:items-center hp:gap-2 hp:text-xs hp:opacity-70 hp:mt-0.5';\n timeEl = document.createElement('span');\n timeEl.textContent = '';\n metaRow.appendChild(timeEl);\n\n const bar = document.createElement('div');\n bar.className = 'hp:flex-1 hp:h-0.5 hp:bg-on-surface/20 hp:rounded-full hp:overflow-hidden';\n progressFill = document.createElement('div');\n progressFill.className = 'hp:h-full hp:bg-accent';\n progressFill.style.width = '0%';\n bar.appendChild(progressFill);\n metaRow.appendChild(bar);\n body.appendChild(metaRow);\n }\n\n li.appendChild(body);\n li.addEventListener('click', () => this.setIndex(idx));\n listEl.appendChild(li);\n itemEls.push({ li, titleRow, progressFill, timeEl });\n });\n\n this.ctx.panelEl.appendChild(root);\n return { root, titleEl, listEl, prevBtn, nextBtn, itemEls };\n }\n\n private playlistTitleText(): string {\n const ui = this.rawOptions.ui ?? {};\n const title = ui.title || this.ctx.i18n.playlistTitle;\n return ui.showCount === false ? title : `${title} (${this.items.length})`;\n }\n\n private navButton(iconName: string, label: string, onClick: () => void): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.setAttribute('aria-label', label);\n btn.className = 'hp:flex hp:items-center hp:justify-center hp:w-6 hp:h-6 hp:text-on-surface hp:bg-transparent hp:border-0 hp:cursor-pointer';\n btn.appendChild(createIcon(iconName, 'hp:text-sm'));\n btn.addEventListener('click', onClick);\n return btn;\n }\n\n private setActive(index: number): void {\n this.ui.itemEls.forEach((entry, idx) => {\n if (idx === index) entry.li.setAttribute('data-active', 'true');\n else entry.li.removeAttribute('data-active');\n });\n // loadAndPlay() hem anlık UI geri bildirimi için önceden (next/prev/setIndex\n // içinden) hem de kaynak gerçekten yüklendiğinde setActive() çağırıyor —\n // aynı index için event'i yalnızca BİR kez yaymak için guard.\n if (this.lastDispatchedIndex !== index) {\n this.lastDispatchedIndex = index;\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:itemchange', { detail: { index, source: 'playlist' } }));\n }\n }\n\n private updateProgress(): void {\n const active = this.ui.itemEls[this.index];\n if (!active) return;\n const duration = this.ctx.videoEl.duration;\n const current = this.ctx.videoEl.currentTime;\n if (active.timeEl) active.timeEl.textContent = this.formatTime(current);\n if (active.progressFill && Number.isFinite(duration) && duration > 0) {\n active.progressFill.style.width = `${Math.min(100, (current / duration) * 100)}%`;\n }\n }\n\n private formatTime(sec: number): string {\n const s = Math.max(0, Math.floor(sec || 0));\n const m = Math.floor(s / 60);\n const r = s % 60;\n return `${m}:${String(r).padStart(2, '0')}`;\n }\n}\n","import { PlaylistRunner, type PlaylistPlayerContext } from './PlaylistRunner';\nimport type { PlaylistOptions } from '../../types';\n\nexport function installPlaylist(ctx: PlaylistPlayerContext, options: PlaylistOptions): PlaylistRunner {\n return new PlaylistRunner(ctx, options);\n}\n\nexport { PlaylistRunner };\nexport type { PlaylistPlayerContext };\n"],"names":["DEFAULTS","PlaylistRunner","ctx","rawOptions","__publicField","isAudioOutputError","now","entry","idx","item","opts","i","attemptId","mode","tried","mp4Index","_a","_b","payload","mp4List","v","nextMp4","otherMode","index","_isFallback","list","src","userInitiated","ui","root","header","titleEl","navWrap","prevBtn","nextBtn","listEl","itemEls","li","img","body","titleRow","progressFill","timeEl","metaRow","bar","title","iconName","label","onClick","btn","createIcon","active","duration","current","sec","s","m","r","installPlaylist","options"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"playlist-C6Mh9BE8.js","sources":["../../src/plugins/playlist/PlaylistRunner.ts","../../src/plugins/playlist/index.ts"],"sourcesContent":["import { createIcon } from '../../icons/Icon';\nimport type { PlayableItem, PlaylistOptions } from '../../types';\nimport type { HopeLocaleStrings } from '../../i18n/types';\nimport { isAudioOutputError } from '../../utils/media-error';\n\nexport interface PlaylistPlayerContext {\n videoEl: HTMLVideoElement;\n hostEl: HTMLElement;\n /** Liste UI'ının monte edileceği, shadow root içindeki panel. */\n panelEl: HTMLElement;\n loadSource(src: string, type?: string): Promise<void>;\n setPoster(url: string): void;\n /** AdsController varsa retry/VMAP durumunu sıfırlayıp item'ın (varsa) kendi adTagPreroll'üyle yeniden reklam ister — yoksa no-op. */\n requestFreshAd(prerollTag?: string): void;\n i18n: HopeLocaleStrings;\n}\n\ntype SourceMode = 'hls' | 'mp4';\n\ninterface Attempt {\n id: number;\n index: number;\n mode: SourceMode;\n tried: Set<SourceMode>;\n mp4Index: number;\n}\n\nconst DEFAULTS: Required<Omit<PlaylistOptions, 'items' | 'adTagPreroll' | 'ui'>> = {\n startMode: 'after_current',\n startIndex: 0,\n loop: false,\n autoplayNext: true,\n preferHls: true,\n adsOnItemChange: true,\n};\n\n/** Tek player üzerinde sıralı oynatma listesi (startMode, loop, hata fallback zinciri). */\nexport class PlaylistRunner {\n private readonly options: Required<Omit<PlaylistOptions, 'items' | 'adTagPreroll' | 'ui'>>;\n private readonly items: PlayableItem[];\n\n private index: number;\n private destroyed = false;\n private switching = false;\n private playlistActive = false;\n private startPendingAfterCurrent = false;\n private attemptId = 0;\n private attempt: Attempt | null = null;\n private lastErrorAt = 0;\n private lastAdsIndex: number | null = null;\n private lastDispatchedIndex: number | null = null;\n private userHasStartedPlayback = false;\n\n private readonly ui: {\n root: HTMLElement;\n titleEl: HTMLElement;\n listEl: HTMLElement;\n prevBtn: HTMLButtonElement;\n nextBtn: HTMLButtonElement;\n itemEls: Array<{ li: HTMLElement; titleRow: HTMLElement; progressFill: HTMLElement | null; timeEl: HTMLElement | null }>;\n };\n\n constructor(\n private readonly ctx: PlaylistPlayerContext,\n private readonly rawOptions: PlaylistOptions\n ) {\n this.options = { ...DEFAULTS, ...rawOptions };\n this.items = Array.isArray(rawOptions.items) ? rawOptions.items : [];\n this.index = this.clampIndex(this.options.startIndex);\n\n this.ui = this.buildUi();\n this.bindPlayerEvents();\n this.init();\n }\n\n // ── lifecycle ──\n\n private init(): void {\n if (!this.items.length) return;\n\n if (this.options.startMode === 'after_current') {\n this.startPendingAfterCurrent = true;\n this.playlistActive = false;\n this.setActive(this.index);\n return;\n }\n\n this.playlistActive = true;\n void this.loadAndPlay(this.index, { userInitiated: false, isPlaylistStart: true });\n }\n\n refreshLabels(): void {\n this.ui.titleEl.textContent = this.playlistTitleText();\n this.ui.prevBtn.setAttribute('aria-label', this.ctx.i18n.playlistPrev);\n this.ui.nextBtn.setAttribute('aria-label', this.ctx.i18n.playlistNext);\n this.ui.itemEls.forEach((entry, idx) => {\n const item = this.items[idx];\n if (item && !item.title) entry.titleRow.textContent = this.ctx.i18n.videoFallbackTitle(idx);\n });\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.ctx.videoEl.removeEventListener('ended', this.onEnded);\n this.ctx.videoEl.removeEventListener('error', this.onError);\n this.ctx.videoEl.removeEventListener('play', this.onUserPlay);\n this.ui.root.remove();\n }\n\n // ── public api ──\n\n start(opts: { index?: number } = {}): void {\n if (this.destroyed || !this.items.length) return;\n this.startPendingAfterCurrent = false;\n this.playlistActive = true;\n this.index = this.clampIndex(opts.index ?? this.index);\n this.setActive(this.index);\n void this.loadAndPlay(this.index, { userInitiated: false, isPlaylistStart: true });\n }\n\n next(): void {\n if (this.destroyed || !this.items.length) return;\n if (!this.playlistActive) return this.start({ index: this.index });\n\n if (this.index < this.items.length - 1) this.index++;\n else if (this.options.loop) this.index = 0;\n else return;\n\n this.setActive(this.index);\n void this.loadAndPlay(this.index, { userInitiated: true });\n }\n\n prev(): void {\n if (this.destroyed || !this.items.length) return;\n if (!this.playlistActive) return this.start({ index: this.index });\n if (this.index === 0) return;\n this.index--;\n this.setActive(this.index);\n void this.loadAndPlay(this.index, { userInitiated: true });\n }\n\n setIndex(i: number): void {\n if (this.destroyed || !this.items.length) return;\n this.index = this.clampIndex(i);\n this.setActive(this.index);\n if (!this.playlistActive) return this.start({ index: this.index });\n void this.loadAndPlay(this.index, { userInitiated: true });\n }\n\n getIndex(): number {\n return this.index;\n }\n\n isActive(): boolean {\n return this.playlistActive;\n }\n\n // ── player events ──\n\n private bindPlayerEvents(): void {\n this.ctx.videoEl.addEventListener('ended', this.onEnded);\n this.ctx.videoEl.addEventListener('error', this.onError);\n this.ctx.videoEl.addEventListener('play', this.onUserPlay);\n this.ctx.videoEl.addEventListener('timeupdate', this.onTimeUpdate);\n }\n\n private readonly onUserPlay = (): void => {\n this.userHasStartedPlayback = true;\n };\n\n private readonly onEnded = (): void => {\n if (this.startPendingAfterCurrent && !this.playlistActive) {\n this.startPendingAfterCurrent = false;\n this.playlistActive = true;\n this.setActive(this.index);\n void this.loadAndPlay(this.index, { userInitiated: true, isPlaylistStart: true });\n return;\n }\n if (this.playlistActive) this.next();\n };\n\n private readonly onError = (): void => {\n if (this.destroyed || !this.playlistActive) return;\n // Ses aygıtı yok (Firefox): video sessiz oynamaya devam ediyor — sonraki öğeye atlama.\n if (isAudioOutputError(this.ctx.videoEl.error)) return;\n const now = Date.now();\n if (now - this.lastErrorAt < 200) return;\n this.lastErrorAt = now;\n void this.fallbackOrSkip();\n };\n\n private readonly onTimeUpdate = (): void => {\n this.updateProgress();\n };\n\n // ── core load ──\n\n private async loadAndPlay(\n i: number,\n opts: { userInitiated?: boolean; forceMode?: SourceMode | null; forceMp4Index?: number | null; isFallback?: boolean; isPlaylistStart?: boolean } = {}\n ): Promise<void> {\n if (this.destroyed || this.switching || !this.playlistActive) return;\n this.switching = true;\n\n const item = this.items[i];\n if (!item) {\n this.switching = false;\n return;\n }\n const attemptId = ++this.attemptId;\n const mode = opts.forceMode ?? this.resolveMode(item);\n\n let tried = new Set<SourceMode>([mode]);\n let mp4Index = opts.forceMp4Index ?? 0;\n if (opts.isFallback && this.attempt?.index === i && this.attempt?.tried) {\n tried = new Set(this.attempt.tried);\n tried.add(mode);\n if (opts.forceMp4Index == null) mp4Index = this.attempt.mp4Index ?? 0;\n }\n this.attempt = { id: attemptId, index: i, mode, tried, mp4Index };\n\n try {\n const payload = this.buildPayload(item, mode, mp4Index);\n if (!payload) throw new Error('No playable source');\n\n this.setActive(i);\n this.ctx.videoEl.pause();\n if (item.image) this.ctx.setPoster(item.image);\n await this.ctx.loadSource(payload.src, payload.type);\n\n if (this.options.adsOnItemChange) this.maybeRequestAds(i, item, !!opts.isFallback);\n\n if (this.shouldAutoPlay(!!opts.userInitiated)) {\n try {\n await this.ctx.videoEl.play();\n } catch {\n /* autoplay engellendi — sessizce geç */\n }\n }\n this.updateProgress();\n } finally {\n this.switching = false;\n }\n }\n\n private async fallbackOrSkip(): Promise<void> {\n if (this.destroyed || !this.attempt) return;\n const item = this.items[this.attempt.index];\n if (!item) return;\n\n if (this.attempt.mode === 'mp4') {\n const mp4List = (item.mp4 || []).filter((v) => v?.src);\n const nextMp4 = (this.attempt.mp4Index ?? 0) + 1;\n if (nextMp4 < mp4List.length) {\n await this.loadAndPlay(this.attempt.index, { forceMode: 'mp4', forceMp4Index: nextMp4, isFallback: true });\n return;\n }\n }\n\n const otherMode: SourceMode = this.attempt.mode === 'hls' ? 'mp4' : 'hls';\n if (this.hasMode(item, otherMode) && !this.attempt.tried.has(otherMode)) {\n await this.loadAndPlay(this.attempt.index, { forceMode: otherMode, isFallback: true });\n return;\n }\n\n this.next();\n }\n\n // ── ads ──\n\n private maybeRequestAds(index: number, item: PlayableItem, _isFallback: boolean): void {\n if (this.lastAdsIndex === index) return;\n this.lastAdsIndex = index;\n this.ctx.requestFreshAd(item.adTagPreroll || this.rawOptions.adTagPreroll);\n }\n\n // ── sources ──\n\n private resolveMode(item: PlayableItem): SourceMode {\n if (this.options.preferHls) return this.hasMode(item, 'hls') ? 'hls' : this.hasMode(item, 'mp4') ? 'mp4' : 'hls';\n return this.hasMode(item, 'mp4') ? 'mp4' : this.hasMode(item, 'hls') ? 'hls' : 'mp4';\n }\n\n private hasMode(item: PlayableItem, mode: SourceMode): boolean {\n return Array.isArray(item[mode]) && item[mode]!.some((v) => v?.src);\n }\n\n private buildPayload(item: PlayableItem, mode: SourceMode, mp4Index = 0): { src: string; type?: string } | null {\n const list = (item[mode] || []).filter((v) => v?.src);\n if (!list.length) return null;\n\n let src;\n if (mode === 'mp4') {\n src = mp4Index > 0 ? list[mp4Index] || list[0] : list.find((v) => v.selected) || list[0];\n } else {\n src = list[0];\n }\n return { src: src!.src, type: src!.type || (mode === 'hls' ? 'application/x-mpegURL' : 'video/mp4') };\n }\n\n private shouldAutoPlay(userInitiated: boolean): boolean {\n if (userInitiated) return true;\n return this.options.autoplayNext && this.userHasStartedPlayback;\n }\n\n private clampIndex(i: number): number {\n if (!Number.isFinite(i) || !this.items.length) return 0;\n return Math.max(0, Math.min(this.items.length - 1, Math.trunc(i)));\n }\n\n // ── ui ──\n\n private buildUi() {\n const ui = this.rawOptions.ui ?? {};\n const root = document.createElement('div');\n root.setAttribute('part', 'playlist-panel');\n root.className = 'hp:flex hp:flex-col hp:gap-2 hp:p-3 hp:bg-surface-elev hp:max-h-80 hp:overflow-y-auto';\n\n const header = document.createElement('div');\n header.className = 'hp:flex hp:items-center hp:justify-between hp:gap-2 hp:mb-1';\n\n const titleEl = document.createElement('div');\n titleEl.className = 'hp:text-sm hp:font-semibold hp:text-on-surface';\n titleEl.textContent = this.playlistTitleText();\n header.appendChild(titleEl);\n\n const navWrap = document.createElement('div');\n navWrap.className = 'hp:flex hp:gap-1';\n const prevBtn = this.navButton('chevron-left', this.ctx.i18n.playlistPrev, () => this.prev());\n const nextBtn = this.navButton('chevron-left', this.ctx.i18n.playlistNext, () => this.next());\n nextBtn.style.transform = 'rotate(180deg)';\n navWrap.append(prevBtn, nextBtn);\n header.appendChild(navWrap);\n\n root.appendChild(header);\n\n const listEl = document.createElement('ul');\n listEl.className = 'hp:flex hp:flex-col hp:gap-1 hp:list-none hp:m-0 hp:p-0';\n root.appendChild(listEl);\n\n const itemEls: Array<{ li: HTMLElement; titleRow: HTMLElement; progressFill: HTMLElement | null; timeEl: HTMLElement | null }> = [];\n this.items.forEach((item, idx) => {\n const li = document.createElement('li');\n li.className =\n 'hp:flex hp:items-center hp:gap-2 hp:p-2 hp:rounded hp:cursor-pointer hp:text-on-surface-muted hp:text-sm ' +\n 'hp:hover:bg-on-surface/5 hp:data-[active=true]:bg-accent/15 hp:data-[active=true]:text-on-surface';\n\n if (item.image) {\n const img = document.createElement('img');\n img.src = item.image;\n img.loading = 'lazy';\n img.className = 'hp:w-16 hp:aspect-video hp:object-cover hp:rounded hp:shrink-0';\n li.appendChild(img);\n }\n\n const body = document.createElement('div');\n body.className = 'hp:flex-1 hp:min-w-0';\n const titleRow = document.createElement('div');\n titleRow.className = 'hp:truncate hp:font-medium';\n titleRow.textContent = item.title || this.ctx.i18n.videoFallbackTitle(idx);\n body.appendChild(titleRow);\n\n let progressFill: HTMLElement | null = null;\n let timeEl: HTMLElement | null = null;\n if (ui.showMeta !== false) {\n const metaRow = document.createElement('div');\n metaRow.className = 'hp:flex hp:items-center hp:gap-2 hp:text-xs hp:opacity-70 hp:mt-0.5';\n timeEl = document.createElement('span');\n timeEl.textContent = '';\n metaRow.appendChild(timeEl);\n\n const bar = document.createElement('div');\n bar.className = 'hp:flex-1 hp:h-0.5 hp:bg-on-surface/20 hp:rounded-full hp:overflow-hidden';\n progressFill = document.createElement('div');\n progressFill.className = 'hp:h-full hp:bg-accent';\n progressFill.style.width = '0%';\n bar.appendChild(progressFill);\n metaRow.appendChild(bar);\n body.appendChild(metaRow);\n }\n\n li.appendChild(body);\n li.addEventListener('click', () => this.setIndex(idx));\n listEl.appendChild(li);\n itemEls.push({ li, titleRow, progressFill, timeEl });\n });\n\n this.ctx.panelEl.appendChild(root);\n return { root, titleEl, listEl, prevBtn, nextBtn, itemEls };\n }\n\n private playlistTitleText(): string {\n const ui = this.rawOptions.ui ?? {};\n const title = ui.title || this.ctx.i18n.playlistTitle;\n return ui.showCount === false ? title : `${title} (${this.items.length})`;\n }\n\n private navButton(iconName: string, label: string, onClick: () => void): HTMLButtonElement {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.setAttribute('aria-label', label);\n btn.className = 'hp:flex hp:items-center hp:justify-center hp:w-6 hp:h-6 hp:text-on-surface hp:bg-transparent hp:border-0 hp:cursor-pointer';\n btn.appendChild(createIcon(iconName, 'hp:text-sm'));\n btn.addEventListener('click', onClick);\n return btn;\n }\n\n private setActive(index: number): void {\n this.ui.itemEls.forEach((entry, idx) => {\n if (idx === index) entry.li.setAttribute('data-active', 'true');\n else entry.li.removeAttribute('data-active');\n });\n // loadAndPlay() hem anlık UI geri bildirimi için önceden (next/prev/setIndex\n // içinden) hem de kaynak gerçekten yüklendiğinde setActive() çağırıyor —\n // aynı index için event'i yalnızca BİR kez yaymak için guard.\n if (this.lastDispatchedIndex !== index) {\n this.lastDispatchedIndex = index;\n this.ctx.hostEl.dispatchEvent(new CustomEvent('hp:itemchange', { detail: { index, source: 'playlist' } }));\n }\n }\n\n private updateProgress(): void {\n const active = this.ui.itemEls[this.index];\n if (!active) return;\n const duration = this.ctx.videoEl.duration;\n const current = this.ctx.videoEl.currentTime;\n if (active.timeEl) active.timeEl.textContent = this.formatTime(current);\n if (active.progressFill && Number.isFinite(duration) && duration > 0) {\n active.progressFill.style.width = `${Math.min(100, (current / duration) * 100)}%`;\n }\n }\n\n private formatTime(sec: number): string {\n const s = Math.max(0, Math.floor(sec || 0));\n const m = Math.floor(s / 60);\n const r = s % 60;\n return `${m}:${String(r).padStart(2, '0')}`;\n }\n}\n","import { PlaylistRunner, type PlaylistPlayerContext } from './PlaylistRunner';\nimport type { PlaylistOptions } from '../../types';\n\nexport function installPlaylist(ctx: PlaylistPlayerContext, options: PlaylistOptions): PlaylistRunner {\n return new PlaylistRunner(ctx, options);\n}\n\nexport { PlaylistRunner };\nexport type { PlaylistPlayerContext };\n"],"names":["DEFAULTS","PlaylistRunner","ctx","rawOptions","__publicField","isAudioOutputError","now","entry","idx","item","opts","i","attemptId","mode","tried","mp4Index","_a","_b","payload","mp4List","v","nextMp4","otherMode","index","_isFallback","list","src","userInitiated","ui","root","header","titleEl","navWrap","prevBtn","nextBtn","listEl","itemEls","li","img","body","titleRow","progressFill","timeEl","metaRow","bar","title","iconName","label","onClick","btn","createIcon","active","duration","current","sec","s","m","r","installPlaylist","options"],"mappings":"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"}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
var A = Object.defineProperty;
|
|
2
|
+
var $ = (u, e, t) => e in u ? A(u, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[e] = t;
|
|
3
|
+
var f = (u, e, t) => $(u, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { P as b, c as T } from "./player-D7WQxMzr.js";
|
|
5
|
+
const m = (u) => typeof u == "function" ? u() : u;
|
|
6
|
+
function k(u) {
|
|
7
|
+
const e = u.split("+"), t = (e.pop() || "+").toLowerCase(), r = e.map((i) => i.toLowerCase()), n = /^[a-z]$/.test(t);
|
|
8
|
+
return { key: t, shift: r.includes("shift") ? !0 : n ? !1 : null, alt: r.includes("alt"), ctrl: r.includes("ctrl") || r.includes("control"), meta: r.includes("meta") || r.includes("cmd") };
|
|
9
|
+
}
|
|
10
|
+
function x(u, e) {
|
|
11
|
+
return e.key.toLowerCase() === u.key && e.altKey === u.alt && e.ctrlKey === u.ctrl && e.metaKey === u.meta && (u.shift === null || e.shiftKey === u.shift);
|
|
12
|
+
}
|
|
13
|
+
class K {
|
|
14
|
+
constructor(e) {
|
|
15
|
+
f(this, "instances", /* @__PURE__ */ new Map());
|
|
16
|
+
f(this, "shortcutList", []);
|
|
17
|
+
f(this, "syncSeq", 0);
|
|
18
|
+
f(this, "toastEl", null);
|
|
19
|
+
f(this, "toastTimer", null);
|
|
20
|
+
/** Ayar satırı anahtarları. */
|
|
21
|
+
f(this, "keySeq", 0);
|
|
22
|
+
f(this, "onKeyDown", (e) => {
|
|
23
|
+
if (e.defaultPrevented) return;
|
|
24
|
+
const t = e.composedPath()[0];
|
|
25
|
+
if (!(t instanceof HTMLElement && (t.isContentEditable || /^(input|textarea|select)$/i.test(t.tagName)))) {
|
|
26
|
+
for (const r of this.shortcutList)
|
|
27
|
+
if (x(r.spec, e)) {
|
|
28
|
+
e.preventDefault(), r.handler(e);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
this.ctx = e, e.element.addEventListener("keydown", this.onKeyDown);
|
|
34
|
+
}
|
|
35
|
+
/** Listeye eşitler: kurar, kaldırır, günceller (aynı adlıda sonraki kazanır). */
|
|
36
|
+
async sync(e, t) {
|
|
37
|
+
const r = ++this.syncSeq, n = await Promise.all([...e, ...t].map((l) => this.resolveEntry(l)));
|
|
38
|
+
if (r !== this.syncSeq) return;
|
|
39
|
+
const i = /* @__PURE__ */ new Map();
|
|
40
|
+
for (const l of n) l && i.set(l.plugin.name, l);
|
|
41
|
+
for (const [l, c] of this.instances) i.has(l) || this.dispose(l, c);
|
|
42
|
+
for (const [l, { plugin: c, options: p }] of i) {
|
|
43
|
+
const g = C(p), s = this.instances.get(l);
|
|
44
|
+
if (s && s.plugin === c) {
|
|
45
|
+
if (s.optionsKey === g) continue;
|
|
46
|
+
if (c.update) {
|
|
47
|
+
s.optionsKey = g, this.guard(l, () => c.update(p))();
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
s && this.dispose(l, s), await this.install(c, p, g);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Dil değişince. */
|
|
55
|
+
refreshLabels() {
|
|
56
|
+
for (const [e, t] of this.instances) {
|
|
57
|
+
for (const r of t.relabel) this.guard(e, r)();
|
|
58
|
+
for (const r of t.localeHandlers) this.guard(e, () => r(this.ctx.locale()))();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** `?` listesi için. */
|
|
62
|
+
shortcuts() {
|
|
63
|
+
return this.shortcutList.filter((e) => e.description !== void 0).map((e) => ({ keys: [e.label], description: m(e.description) }));
|
|
64
|
+
}
|
|
65
|
+
has(e) {
|
|
66
|
+
return this.instances.has(e);
|
|
67
|
+
}
|
|
68
|
+
destroy() {
|
|
69
|
+
var e;
|
|
70
|
+
++this.syncSeq;
|
|
71
|
+
for (const [t, r] of this.instances) this.dispose(t, r);
|
|
72
|
+
this.ctx.element.removeEventListener("keydown", this.onKeyDown), (e = this.toastEl) == null || e.remove(), this.toastTimer && clearTimeout(this.toastTimer);
|
|
73
|
+
}
|
|
74
|
+
// ── Kurulum ──
|
|
75
|
+
async resolveEntry(e) {
|
|
76
|
+
const [t, r] = Array.isArray(e) ? e : [e, void 0];
|
|
77
|
+
try {
|
|
78
|
+
if (typeof t == "function") {
|
|
79
|
+
const n = await t(), i = "setup" in n ? n : "default" in n ? n.default : n.plugin;
|
|
80
|
+
return i && typeof i.setup == "function" ? { plugin: i, options: r } : null;
|
|
81
|
+
}
|
|
82
|
+
return t && typeof t.setup == "function" && typeof t.name == "string" ? { plugin: t, options: r } : null;
|
|
83
|
+
} catch (n) {
|
|
84
|
+
return this.ctx.log(`Plugin could not be loaded: ${(n == null ? void 0 : n.message) ?? n}`, { plugin: typeof t == "function" ? "loader" : String(t == null ? void 0 : t.name) }), null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async install(e, t, r) {
|
|
88
|
+
const n = e.name;
|
|
89
|
+
e.apiVersion && e.apiVersion > b && this.ctx.log(`Plugin "${n}" was written for plugin API v${e.apiVersion}; this player has v${b}`, { plugin: n });
|
|
90
|
+
const i = { plugin: e, optionsKey: r, api: null, disposers: [], relabel: [], localeHandlers: [], cleanup: null, removed: !1 };
|
|
91
|
+
i.api = this.createApi(i), this.instances.set(n, i);
|
|
92
|
+
try {
|
|
93
|
+
const l = await e.setup(i.api, t);
|
|
94
|
+
if (i.removed) {
|
|
95
|
+
typeof l == "function" && this.guard(n, l)();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
typeof l == "function" && (i.cleanup = l);
|
|
99
|
+
} catch (l) {
|
|
100
|
+
this.report(n, l, "setup"), this.dispose(n, i);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
dispose(e, t) {
|
|
104
|
+
if (!t.removed) {
|
|
105
|
+
t.removed = !0, this.instances.get(e) === t && this.instances.delete(e), t.cleanup && this.guard(e, t.cleanup)();
|
|
106
|
+
for (const r of t.disposers.reverse())
|
|
107
|
+
try {
|
|
108
|
+
r();
|
|
109
|
+
} catch {
|
|
110
|
+
}
|
|
111
|
+
t.disposers = [];
|
|
112
|
+
for (let r = this.shortcutList.length - 1; r >= 0; r--) this.shortcutList[r].owner === e && this.shortcutList.splice(r, 1);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
report(e, t, r) {
|
|
116
|
+
const n = (t == null ? void 0 : t.message) ?? String(t);
|
|
117
|
+
this.ctx.log(`Plugin "${e}" failed in ${r}: ${n}`, { plugin: e }), console.error(`[hope-player] plugin "${e}" (${r}):`, t);
|
|
118
|
+
}
|
|
119
|
+
/** Eklenti kodu hep bundan çağrılır; hata player'a geçmez. */
|
|
120
|
+
guard(e, t, r = "handler") {
|
|
121
|
+
return (...n) => {
|
|
122
|
+
try {
|
|
123
|
+
const i = t(...n);
|
|
124
|
+
i instanceof Promise && i.catch((l) => this.report(e, l, r));
|
|
125
|
+
} catch (i) {
|
|
126
|
+
this.report(e, i, r);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// ── PlayerApi ──
|
|
131
|
+
createApi(e) {
|
|
132
|
+
const t = this.ctx, r = e.plugin.name, n = (s) => {
|
|
133
|
+
e.removed ? s() : e.disposers.push(s);
|
|
134
|
+
}, i = (s, o) => this.guard(r, s, o), l = {}, c = this, p = (s, o, a = !1) => {
|
|
135
|
+
const d = s.includes(":") ? t.element : t.video, h = i((w) => {
|
|
136
|
+
a && v(), o(w);
|
|
137
|
+
}, `on(${s})`);
|
|
138
|
+
d.addEventListener(s, h);
|
|
139
|
+
let y = !1;
|
|
140
|
+
const v = () => {
|
|
141
|
+
y || (y = !0, d.removeEventListener(s, h));
|
|
142
|
+
};
|
|
143
|
+
return n(v), v;
|
|
144
|
+
};
|
|
145
|
+
return {
|
|
146
|
+
plugin: r,
|
|
147
|
+
apiVersion: b,
|
|
148
|
+
element: t.element,
|
|
149
|
+
video: t.video,
|
|
150
|
+
get locale() {
|
|
151
|
+
return t.locale();
|
|
152
|
+
},
|
|
153
|
+
labels: t.labels,
|
|
154
|
+
get currentTime() {
|
|
155
|
+
return t.video.currentTime;
|
|
156
|
+
},
|
|
157
|
+
get duration() {
|
|
158
|
+
return t.video.duration;
|
|
159
|
+
},
|
|
160
|
+
get paused() {
|
|
161
|
+
return t.video.paused;
|
|
162
|
+
},
|
|
163
|
+
get isLive() {
|
|
164
|
+
return t.video.duration === 1 / 0;
|
|
165
|
+
},
|
|
166
|
+
get isAdPlaying() {
|
|
167
|
+
return t.isAdPlaying();
|
|
168
|
+
},
|
|
169
|
+
get isFullscreen() {
|
|
170
|
+
return t.isFullscreen();
|
|
171
|
+
},
|
|
172
|
+
get src() {
|
|
173
|
+
return t.currentSrc();
|
|
174
|
+
},
|
|
175
|
+
play: () => t.video.play(),
|
|
176
|
+
pause: () => t.video.pause(),
|
|
177
|
+
seek: (s) => {
|
|
178
|
+
Number.isFinite(s) && (t.video.currentTime = Math.max(0, s));
|
|
179
|
+
},
|
|
180
|
+
on: (s, o) => p(s, o),
|
|
181
|
+
once: (s, o) => p(s, o, !0),
|
|
182
|
+
emit: (s, o) => {
|
|
183
|
+
t.element.dispatchEvent(new CustomEvent(`${r}:${s}`, { detail: o, bubbles: !0, composed: !0 }));
|
|
184
|
+
},
|
|
185
|
+
onSourceChange: (s) => p("loadstart", () => s(t.currentSrc())),
|
|
186
|
+
onLocaleChange: (s) => {
|
|
187
|
+
e.localeHandlers.push(s);
|
|
188
|
+
const o = () => {
|
|
189
|
+
const a = e.localeHandlers.indexOf(s);
|
|
190
|
+
a >= 0 && e.localeHandlers.splice(a, 1);
|
|
191
|
+
};
|
|
192
|
+
return n(o), o;
|
|
193
|
+
},
|
|
194
|
+
onDestroy: (s) => n(i(s, "onDestroy")),
|
|
195
|
+
setTimeout: (s, o) => {
|
|
196
|
+
const a = window.setTimeout(i(s, "setTimeout"), o);
|
|
197
|
+
return n(() => clearTimeout(a)), a;
|
|
198
|
+
},
|
|
199
|
+
setInterval: (s, o) => {
|
|
200
|
+
const a = window.setInterval(i(s, "setInterval"), o);
|
|
201
|
+
return n(() => clearInterval(a)), a;
|
|
202
|
+
},
|
|
203
|
+
ui: {
|
|
204
|
+
addButton: (s) => c.addButton(e, s, n, i),
|
|
205
|
+
addLayer: (s) => c.addLayer(e, s ?? {}, n),
|
|
206
|
+
toast: (s, o) => c.toast(s, o == null ? void 0 : o.durationMs)
|
|
207
|
+
},
|
|
208
|
+
settings: {
|
|
209
|
+
addToggle: (s) => {
|
|
210
|
+
const o = `plugin:${r}:toggle:${++c.keySeq}`, a = () => t.settings.registerToggle({
|
|
211
|
+
key: o,
|
|
212
|
+
label: m(s.label),
|
|
213
|
+
getValueLabel: () => s.get() ? E(t.labels, !0) : E(t.labels, !1),
|
|
214
|
+
onToggle: i(() => s.set(!s.get()), "settings.toggle")
|
|
215
|
+
});
|
|
216
|
+
return a(), e.relabel.push(a), n(() => t.settings.unregisterToggle(o)), S(a, () => t.settings.unregisterToggle(o));
|
|
217
|
+
},
|
|
218
|
+
addSelect: (s) => {
|
|
219
|
+
const o = `plugin:${r}:select:${++c.keySeq}`, a = () => typeof s.options == "function" ? s.options() : s.options, d = () => t.settings.registerSubmenu({
|
|
220
|
+
key: o,
|
|
221
|
+
title: m(s.label),
|
|
222
|
+
getValueLabel: () => {
|
|
223
|
+
const h = a().find((y) => y.value === s.get());
|
|
224
|
+
return h ? m(h.label) : "";
|
|
225
|
+
},
|
|
226
|
+
getItems: () => a().map((h) => ({ label: m(h.label), active: h.value === s.get(), onSelect: i(() => s.set(h.value), "settings.select") }))
|
|
227
|
+
});
|
|
228
|
+
return d(), e.relabel.push(d), n(() => t.settings.unregisterSubmenu(o)), S(d, () => t.settings.unregisterSubmenu(o));
|
|
229
|
+
},
|
|
230
|
+
addSubmenu: (s) => {
|
|
231
|
+
const o = `plugin:${r}:submenu:${++c.keySeq}`, a = () => t.settings.registerSubmenu({
|
|
232
|
+
key: o,
|
|
233
|
+
title: m(s.label),
|
|
234
|
+
getValueLabel: () => s.value ? s.value() : "",
|
|
235
|
+
getItems: () => s.items().map((d) => ({ label: m(d.label), active: !!d.active, onSelect: i(() => d.onSelect(), "settings.submenu") }))
|
|
236
|
+
});
|
|
237
|
+
return a(), e.relabel.push(a), n(() => t.settings.unregisterSubmenu(o)), S(a, () => t.settings.unregisterSubmenu(o));
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
keys: {
|
|
241
|
+
add: (s, o, a) => {
|
|
242
|
+
const d = { owner: r, spec: k(s), label: s, description: a, handler: i(o, `keys(${s})`) };
|
|
243
|
+
c.shortcutList.push(d);
|
|
244
|
+
const h = () => {
|
|
245
|
+
const y = c.shortcutList.indexOf(d);
|
|
246
|
+
y >= 0 && c.shortcutList.splice(y, 1);
|
|
247
|
+
};
|
|
248
|
+
return n(h), h;
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
i18n: {
|
|
252
|
+
add: (s) => {
|
|
253
|
+
for (const [o, a] of Object.entries(s)) l[o] = { ...l[o], ...a };
|
|
254
|
+
},
|
|
255
|
+
t: (s, o) => {
|
|
256
|
+
var a, d;
|
|
257
|
+
return ((a = l[t.locale()]) == null ? void 0 : a[s]) ?? ((d = l.en) == null ? void 0 : d[s]) ?? o ?? s;
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
storage: {
|
|
261
|
+
get: (s, o) => {
|
|
262
|
+
try {
|
|
263
|
+
const a = localStorage.getItem(L(r, s));
|
|
264
|
+
return a === null ? o : JSON.parse(a);
|
|
265
|
+
} catch {
|
|
266
|
+
return o;
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
set: (s, o) => {
|
|
270
|
+
try {
|
|
271
|
+
localStorage.setItem(L(r, s), JSON.stringify(o));
|
|
272
|
+
} catch {
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
remove: (s) => {
|
|
276
|
+
try {
|
|
277
|
+
localStorage.removeItem(L(r, s));
|
|
278
|
+
} catch {
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
log: (s, o) => t.log(s, { plugin: r, ...o })
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
addButton(e, t, r, n) {
|
|
286
|
+
const i = document.createElement("button");
|
|
287
|
+
i.type = "button", i.className = "hp-chip hp-plugin-btn hp:flex hp:items-center hp:justify-center hp:w-[var(--hp-ctrl-btn-size)] hp:h-[var(--hp-ctrl-btn-size)] hp:cursor-pointer hp:shrink-0", i.setAttribute("part", `plugin-button plugin-${e.plugin.name}`), i.dataset.plugin = e.plugin.name;
|
|
288
|
+
let l = t.label, c = !!t.active;
|
|
289
|
+
const p = (a) => {
|
|
290
|
+
var d;
|
|
291
|
+
i.textContent = "", a.trim().startsWith("<") ? (i.insertAdjacentHTML("beforeend", a), (d = i.querySelector("svg")) == null || d.setAttribute("aria-hidden", "true")) : i.appendChild(T(a, "hp:text-[length:var(--hp-ctrl-icon-size)]"));
|
|
292
|
+
}, g = () => i.setAttribute("aria-label", m(l)), s = () => {
|
|
293
|
+
t.active !== void 0 && i.setAttribute("aria-pressed", String(c));
|
|
294
|
+
};
|
|
295
|
+
p(t.icon), g(), s(), e.relabel.push(g);
|
|
296
|
+
const o = {
|
|
297
|
+
el: i,
|
|
298
|
+
get active() {
|
|
299
|
+
return c;
|
|
300
|
+
},
|
|
301
|
+
setLabel: (a) => {
|
|
302
|
+
l = a, g();
|
|
303
|
+
},
|
|
304
|
+
setIcon: p,
|
|
305
|
+
setActive: (a) => {
|
|
306
|
+
c = a, i.setAttribute("aria-pressed", String(a));
|
|
307
|
+
},
|
|
308
|
+
show: () => {
|
|
309
|
+
i.style.display = "";
|
|
310
|
+
},
|
|
311
|
+
hide: () => {
|
|
312
|
+
i.style.display = "none";
|
|
313
|
+
},
|
|
314
|
+
remove: () => i.remove()
|
|
315
|
+
};
|
|
316
|
+
if (t.onClick) {
|
|
317
|
+
const a = n((d) => t.onClick(d, o), "button.onClick");
|
|
318
|
+
i.addEventListener("click", (d) => {
|
|
319
|
+
d.stopPropagation(), a(d);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
return this.ctx.addControlButton(i, t.position ?? "right"), r(() => i.remove()), o;
|
|
323
|
+
}
|
|
324
|
+
addLayer(e, t, r) {
|
|
325
|
+
const n = document.createElement("div");
|
|
326
|
+
if (n.className = "hp-plugin-layer", n.setAttribute("part", `plugin-layer plugin-${e.plugin.name}`), n.dataset.plugin = e.plugin.name, n.dataset.position = t.position ?? "fill", n.toggleAttribute("data-autohide", !!t.autoHide), n.toggleAttribute("data-interactive", !!t.interactive), n.toggleAttribute("data-above", !!t.above), t.css) {
|
|
327
|
+
const c = document.createElement("style");
|
|
328
|
+
c.textContent = t.css, n.appendChild(c);
|
|
329
|
+
}
|
|
330
|
+
let i = t.visible !== !1;
|
|
331
|
+
if (n.hidden = !i, t.above ? this.ctx.videoArea.appendChild(n) : this.ctx.videoArea.insertBefore(n, this.ctx.chromeEl), t.interactive)
|
|
332
|
+
for (const c of ["pointerdown", "mousedown", "mouseup", "touchstart", "touchend", "click", "dblclick"]) n.addEventListener(c, (p) => p.stopPropagation());
|
|
333
|
+
r(() => n.remove());
|
|
334
|
+
const l = (c) => {
|
|
335
|
+
i = c, n.hidden = !c;
|
|
336
|
+
};
|
|
337
|
+
return {
|
|
338
|
+
el: n,
|
|
339
|
+
get visible() {
|
|
340
|
+
return i;
|
|
341
|
+
},
|
|
342
|
+
show: () => l(!0),
|
|
343
|
+
hide: () => l(!1),
|
|
344
|
+
toggle: (c) => l(c ?? !i),
|
|
345
|
+
remove: () => n.remove()
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
toast(e, t = 2500) {
|
|
349
|
+
this.toastEl || (this.toastEl = document.createElement("div"), this.toastEl.className = "hp-plugin-toast", this.toastEl.setAttribute("part", "plugin-toast"), this.toastEl.setAttribute("role", "status"), this.toastEl.setAttribute("aria-live", "polite"), this.ctx.videoArea.appendChild(this.toastEl)), this.toastEl.textContent = e, this.toastEl.setAttribute("data-visible", ""), this.toastTimer && clearTimeout(this.toastTimer), this.toastTimer = setTimeout(() => {
|
|
350
|
+
var r;
|
|
351
|
+
return (r = this.toastEl) == null ? void 0 : r.removeAttribute("data-visible");
|
|
352
|
+
}, Math.max(500, t));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function S(u, e) {
|
|
356
|
+
return { refresh: u, remove: e };
|
|
357
|
+
}
|
|
358
|
+
function E(u, e) {
|
|
359
|
+
const t = e ? u.a11yOn : u.a11yOff;
|
|
360
|
+
return typeof t == "string" ? t : e ? "On" : "Off";
|
|
361
|
+
}
|
|
362
|
+
function L(u, e) {
|
|
363
|
+
return `hp-plugin:${u}:${e}`;
|
|
364
|
+
}
|
|
365
|
+
function C(u) {
|
|
366
|
+
try {
|
|
367
|
+
return JSON.stringify(u ?? null, (e, t) => typeof t == "function" ? `fn:${t.name ?? ""}` : t);
|
|
368
|
+
} catch {
|
|
369
|
+
return String(Math.random());
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
export {
|
|
373
|
+
b as PLUGIN_API_VERSION,
|
|
374
|
+
K as PluginHost
|
|
375
|
+
};
|
|
376
|
+
//# sourceMappingURL=pluginHost-DjvLmMYZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pluginHost-DjvLmMYZ.js","sources":["../../src/plugin-api/PluginHost.ts"],"sourcesContent":["// Eklentileri kurar / kaldırır; eklenenleri izler ve temizler, hataları yakalar.\nimport { createIcon } from '../icons/Icon';\nimport type { SettingsSubmenuDef, SettingsSubmenuItem } from '../controls/SettingsMenu';\nimport {\n PLUGIN_API_VERSION,\n type HopePlugin,\n type PlayerApi,\n type PluginButtonHandle,\n type PluginButtonOptions,\n type PluginCleanup,\n type PluginEntry,\n type PluginLabel,\n type PluginLayerHandle,\n type PluginLayerOptions,\n type PluginLoader,\n type PluginSettingsHandle,\n} from './types';\n\n/** Player → PluginHost bağlamı (eklentiler görmez). */\nexport interface PluginHostContext {\n element: HTMLElement;\n video: HTMLVideoElement;\n videoArea: HTMLElement;\n /** Alt katmanlar bunun önüne eklenir. */\n chromeEl: HTMLElement;\n labels: Readonly<Record<string, unknown>>;\n locale(): string;\n currentSrc(): string | null;\n isAdPlaying(): boolean;\n isFullscreen(): boolean;\n addControlButton(button: HTMLButtonElement, position: 'left' | 'right'): void;\n settings: {\n registerToggle(row: { key: string; label: string; getValueLabel(): string; onToggle(): void }): void;\n unregisterToggle(key: string): void;\n registerSubmenu(def: SettingsSubmenuDef): void;\n unregisterSubmenu(key: string): void;\n };\n log(message: string, details?: Record<string, string | number | boolean | undefined>): void;\n}\n\ninterface Instance {\n plugin: HopePlugin<any>;\n optionsKey: string;\n api: PlayerApi;\n disposers: Array<() => void>;\n /** Dil değişince yeniden çizilecekler. */\n relabel: Array<() => void>;\n localeHandlers: Array<(locale: string) => void>;\n cleanup: PluginCleanup | null;\n removed: boolean;\n}\n\n/** `Shift+W` gibi kısayol. */\ninterface KeySpec {\n key: string;\n shift: boolean | null;\n alt: boolean;\n ctrl: boolean;\n meta: boolean;\n}\n\nexport interface PluginShortcut {\n keys: string[];\n description: string;\n}\n\nconst resolve = (label: PluginLabel): string => (typeof label === 'function' ? label() : label);\n\nfunction parseKey(spec: string): KeySpec {\n const parts = spec.split('+');\n // \"Shift++\" gibi: son parça boşsa tuş \"+\".\n const key = (parts.pop() || '+').toLowerCase();\n const mods = parts.map((p) => p.toLowerCase());\n const letter = /^[a-z]$/.test(key);\n return { key, shift: mods.includes('shift') ? true : letter ? false : null, alt: mods.includes('alt'), ctrl: mods.includes('ctrl') || mods.includes('control'), meta: mods.includes('meta') || mods.includes('cmd') };\n}\n\nfunction matches(spec: KeySpec, e: KeyboardEvent): boolean {\n return (\n e.key.toLowerCase() === spec.key &&\n e.altKey === spec.alt &&\n e.ctrlKey === spec.ctrl &&\n e.metaKey === spec.meta &&\n (spec.shift === null || e.shiftKey === spec.shift)\n );\n}\n\nexport class PluginHost {\n private readonly instances = new Map<string, Instance>();\n private readonly shortcutList: Array<{ owner: string; spec: KeySpec; label: string; description: PluginLabel | undefined; handler: (e: KeyboardEvent) => void }> = [];\n private syncSeq = 0;\n private toastEl: HTMLDivElement | null = null;\n private toastTimer: ReturnType<typeof setTimeout> | null = null;\n /** Ayar satırı anahtarları. */\n private keySeq = 0;\n\n constructor(private readonly ctx: PluginHostContext) {\n ctx.element.addEventListener('keydown', this.onKeyDown);\n }\n\n /** Listeye eşitler: kurar, kaldırır, günceller (aynı adlıda sonraki kazanır). */\n async sync(builtin: PluginEntry[], user: PluginEntry[]): Promise<void> {\n const seq = ++this.syncSeq;\n const resolved = await Promise.all([...builtin, ...user].map((e) => this.resolveEntry(e)));\n if (seq !== this.syncSeq) return; // daha yenisi başladı\n const wanted = new Map<string, { plugin: HopePlugin<any>; options: unknown }>();\n for (const r of resolved) if (r) wanted.set(r.plugin.name, r);\n\n for (const [name, inst] of this.instances) if (!wanted.has(name)) this.dispose(name, inst);\n for (const [name, { plugin, options }] of wanted) {\n const key = optionsKey(options);\n const inst = this.instances.get(name);\n if (inst && inst.plugin === plugin) {\n if (inst.optionsKey === key) continue;\n if (plugin.update) {\n inst.optionsKey = key;\n this.guard(name, () => plugin.update!(options))();\n continue;\n }\n }\n if (inst) this.dispose(name, inst);\n await this.install(plugin, options, key);\n }\n }\n\n /** Dil değişince. */\n refreshLabels(): void {\n for (const [name, inst] of this.instances) {\n for (const fn of inst.relabel) this.guard(name, fn)();\n for (const fn of inst.localeHandlers) this.guard(name, () => fn(this.ctx.locale()))();\n }\n }\n\n /** `?` listesi için. */\n shortcuts(): PluginShortcut[] {\n return this.shortcutList.filter((s) => s.description !== undefined).map((s) => ({ keys: [s.label], description: resolve(s.description!) }));\n }\n\n has(name: string): boolean {\n return this.instances.has(name);\n }\n\n destroy(): void {\n ++this.syncSeq;\n for (const [name, inst] of this.instances) this.dispose(name, inst);\n this.ctx.element.removeEventListener('keydown', this.onKeyDown);\n this.toastEl?.remove();\n if (this.toastTimer) clearTimeout(this.toastTimer);\n }\n\n // ── Kurulum ──\n\n private async resolveEntry(entry: PluginEntry): Promise<{ plugin: HopePlugin<any>; options: unknown } | null> {\n const [target, options] = Array.isArray(entry) ? entry : [entry, undefined];\n try {\n if (typeof target === 'function') {\n const mod = await (target as PluginLoader)();\n const plugin = 'setup' in mod ? mod : 'default' in mod ? mod.default : mod.plugin;\n return plugin && typeof plugin.setup === 'function' ? { plugin, options } : null;\n }\n return target && typeof target.setup === 'function' && typeof target.name === 'string' ? { plugin: target, options } : null;\n } catch (err) {\n this.ctx.log(`Plugin could not be loaded: ${(err as Error)?.message ?? err}`, { plugin: typeof target === 'function' ? 'loader' : String((target as HopePlugin)?.name) });\n return null;\n }\n }\n\n private async install(plugin: HopePlugin<any>, options: unknown, key: string): Promise<void> {\n const name = plugin.name;\n if (plugin.apiVersion && plugin.apiVersion > PLUGIN_API_VERSION) {\n this.ctx.log(`Plugin \"${name}\" was written for plugin API v${plugin.apiVersion}; this player has v${PLUGIN_API_VERSION}`, { plugin: name });\n }\n const inst: Instance = { plugin, optionsKey: key, api: null as unknown as PlayerApi, disposers: [], relabel: [], localeHandlers: [], cleanup: null, removed: false };\n inst.api = this.createApi(inst);\n this.instances.set(name, inst);\n try {\n const result = await plugin.setup(inst.api, options);\n if (inst.removed) {\n if (typeof result === 'function') this.guard(name, result)();\n return;\n }\n if (typeof result === 'function') inst.cleanup = result;\n } catch (err) {\n this.report(name, err, 'setup');\n this.dispose(name, inst);\n }\n }\n\n private dispose(name: string, inst: Instance): void {\n if (inst.removed) return;\n inst.removed = true;\n if (this.instances.get(name) === inst) this.instances.delete(name);\n if (inst.cleanup) this.guard(name, inst.cleanup)();\n // Ters sırada kaldır.\n for (const d of inst.disposers.reverse()) {\n try {\n d();\n } catch {\n /* yok say */\n }\n }\n inst.disposers = [];\n for (let i = this.shortcutList.length - 1; i >= 0; i--) if (this.shortcutList[i]!.owner === name) this.shortcutList.splice(i, 1);\n }\n\n private report(name: string, err: unknown, where: string): void {\n const message = (err as Error)?.message ?? String(err);\n this.ctx.log(`Plugin \"${name}\" failed in ${where}: ${message}`, { plugin: name });\n console.error(`[hope-player] plugin \"${name}\" (${where}):`, err);\n }\n\n /** Eklenti kodu hep bundan çağrılır; hata player'a geçmez. */\n private guard<A extends unknown[]>(name: string, fn: (...args: A) => unknown, where = 'handler'): (...args: A) => void {\n return (...args: A) => {\n try {\n const r = fn(...args);\n if (r instanceof Promise) r.catch((err) => this.report(name, err, where));\n } catch (err) {\n this.report(name, err, where);\n }\n };\n }\n\n private readonly onKeyDown = (e: KeyboardEvent): void => {\n // Player'ın kendi tuşları önce; işlendiyse karışma.\n if (e.defaultPrevented) return;\n const target = e.composedPath()[0];\n if (target instanceof HTMLElement && (target.isContentEditable || /^(input|textarea|select)$/i.test(target.tagName))) return;\n for (const s of this.shortcutList) {\n if (matches(s.spec, e)) {\n e.preventDefault();\n s.handler(e);\n return;\n }\n }\n };\n\n // ── PlayerApi ──\n\n private createApi(inst: Instance): PlayerApi {\n const ctx = this.ctx;\n const name = inst.plugin.name;\n const track = (dispose: () => void): void => {\n if (inst.removed) dispose();\n else inst.disposers.push(dispose);\n };\n const guard = <A extends unknown[]>(fn: (...args: A) => unknown, where?: string) => this.guard(name, fn, where);\n const strings: Record<string, Record<string, string>> = {};\n const host = this;\n\n const on = (event: string, handler: (event: Event) => void, once = false): (() => void) => {\n // `x:y` olayları elementte, diğerleri videoda.\n const target: EventTarget = event.includes(':') ? ctx.element : ctx.video;\n const wrapped = guard((ev: Event) => {\n if (once) off();\n handler(ev);\n }, `on(${event})`);\n target.addEventListener(event, wrapped);\n let done = false;\n const off = (): void => {\n if (done) return;\n done = true;\n target.removeEventListener(event, wrapped);\n };\n track(off);\n return off;\n };\n\n const api: PlayerApi = {\n plugin: name,\n apiVersion: PLUGIN_API_VERSION,\n element: ctx.element,\n video: ctx.video,\n get locale() {\n return ctx.locale();\n },\n labels: ctx.labels,\n get currentTime() {\n return ctx.video.currentTime;\n },\n get duration() {\n return ctx.video.duration;\n },\n get paused() {\n return ctx.video.paused;\n },\n get isLive() {\n return ctx.video.duration === Infinity;\n },\n get isAdPlaying() {\n return ctx.isAdPlaying();\n },\n get isFullscreen() {\n return ctx.isFullscreen();\n },\n get src() {\n return ctx.currentSrc();\n },\n play: () => ctx.video.play(),\n pause: () => ctx.video.pause(),\n seek: (time: number) => {\n if (Number.isFinite(time)) ctx.video.currentTime = Math.max(0, time);\n },\n on: (event, handler) => on(event, handler),\n once: (event, handler) => on(event, handler, true),\n emit: (event, detail) => {\n ctx.element.dispatchEvent(new CustomEvent(`${name}:${event}`, { detail, bubbles: true, composed: true }));\n },\n onSourceChange: (handler) => on('loadstart', () => handler(ctx.currentSrc())),\n onLocaleChange: (handler) => {\n inst.localeHandlers.push(handler);\n const off = (): void => {\n const i = inst.localeHandlers.indexOf(handler);\n if (i >= 0) inst.localeHandlers.splice(i, 1);\n };\n track(off);\n return off;\n },\n onDestroy: (handler) => track(guard(handler, 'onDestroy')),\n setTimeout: (handler, ms) => {\n const id = window.setTimeout(guard(handler, 'setTimeout'), ms);\n track(() => clearTimeout(id));\n return id;\n },\n setInterval: (handler, ms) => {\n const id = window.setInterval(guard(handler, 'setInterval'), ms);\n track(() => clearInterval(id));\n return id;\n },\n ui: {\n addButton: (o) => host.addButton(inst, o, track, guard),\n addLayer: (o) => host.addLayer(inst, o ?? {}, track),\n toast: (message, o) => host.toast(message, o?.durationMs),\n },\n settings: {\n addToggle: (o) => {\n const key = `plugin:${name}:toggle:${++host.keySeq}`;\n const register = (): void =>\n ctx.settings.registerToggle({\n key,\n label: resolve(o.label),\n getValueLabel: () => (o.get() ? onOff(ctx.labels, true) : onOff(ctx.labels, false)),\n onToggle: guard(() => o.set(!o.get()), 'settings.toggle'),\n });\n register();\n inst.relabel.push(register);\n track(() => ctx.settings.unregisterToggle(key));\n return settingsHandle(register, () => ctx.settings.unregisterToggle(key));\n },\n addSelect: (o) => {\n const key = `plugin:${name}:select:${++host.keySeq}`;\n const list = () => (typeof o.options === 'function' ? o.options() : o.options);\n const register = (): void =>\n ctx.settings.registerSubmenu({\n key,\n title: resolve(o.label),\n getValueLabel: () => {\n const current = list().find((x) => x.value === o.get());\n return current ? resolve(current.label) : '';\n },\n getItems: () => list().map((x) => ({ label: resolve(x.label), active: x.value === o.get(), onSelect: guard(() => o.set(x.value), 'settings.select') })),\n });\n register();\n inst.relabel.push(register);\n track(() => ctx.settings.unregisterSubmenu(key));\n return settingsHandle(register, () => ctx.settings.unregisterSubmenu(key));\n },\n addSubmenu: (o) => {\n const key = `plugin:${name}:submenu:${++host.keySeq}`;\n const register = (): void =>\n ctx.settings.registerSubmenu({\n key,\n title: resolve(o.label),\n getValueLabel: () => (o.value ? o.value() : ''),\n getItems: (): SettingsSubmenuItem[] =>\n o.items().map((x) => ({ label: resolve(x.label), active: !!x.active, onSelect: guard(() => x.onSelect(), 'settings.submenu') })),\n });\n register();\n inst.relabel.push(register);\n track(() => ctx.settings.unregisterSubmenu(key));\n return settingsHandle(register, () => ctx.settings.unregisterSubmenu(key));\n },\n },\n keys: {\n add: (key, handler, description) => {\n const entry = { owner: name, spec: parseKey(key), label: key, description, handler: guard(handler, `keys(${key})`) };\n host.shortcutList.push(entry);\n const off = (): void => {\n const i = host.shortcutList.indexOf(entry);\n if (i >= 0) host.shortcutList.splice(i, 1);\n };\n track(off);\n return off;\n },\n },\n i18n: {\n add: (more) => {\n for (const [locale, values] of Object.entries(more)) strings[locale] = { ...strings[locale], ...values };\n },\n t: (key, fallback) => strings[ctx.locale()]?.[key] ?? strings.en?.[key] ?? fallback ?? key,\n },\n storage: {\n get: <T>(key: string, fallback?: T): T | undefined => {\n try {\n const raw = localStorage.getItem(storageKey(name, key));\n return raw === null ? fallback : (JSON.parse(raw) as T);\n } catch {\n return fallback;\n }\n },\n set: (key, value) => {\n try {\n localStorage.setItem(storageKey(name, key), JSON.stringify(value));\n } catch {\n /* yok say */\n }\n },\n remove: (key) => {\n try {\n localStorage.removeItem(storageKey(name, key));\n } catch {\n /* yok say */\n }\n },\n },\n log: (message, details) => ctx.log(message, { plugin: name, ...details }),\n };\n return api;\n }\n\n private addButton(\n inst: Instance,\n o: PluginButtonOptions,\n track: (d: () => void) => void,\n guard: <A extends unknown[]>(fn: (...args: A) => unknown, where?: string) => (...args: A) => void\n ): PluginButtonHandle {\n const btn = document.createElement('button');\n btn.type = 'button';\n btn.className =\n 'hp-chip hp-plugin-btn hp:flex hp:items-center hp:justify-center hp:w-[var(--hp-ctrl-btn-size)] hp:h-[var(--hp-ctrl-btn-size)] hp:cursor-pointer hp:shrink-0';\n btn.setAttribute('part', `plugin-button plugin-${inst.plugin.name}`);\n btn.dataset.plugin = inst.plugin.name;\n let label: PluginLabel = o.label;\n let active = !!o.active;\n const setIcon = (icon: string): void => {\n btn.textContent = '';\n if (icon.trim().startsWith('<')) {\n btn.insertAdjacentHTML('beforeend', icon);\n btn.querySelector('svg')?.setAttribute('aria-hidden', 'true');\n } else btn.appendChild(createIcon(icon, 'hp:text-[length:var(--hp-ctrl-icon-size)]'));\n };\n const applyLabel = (): void => btn.setAttribute('aria-label', resolve(label));\n const applyActive = (): void => {\n if (o.active !== undefined) btn.setAttribute('aria-pressed', String(active));\n };\n setIcon(o.icon);\n applyLabel();\n applyActive();\n inst.relabel.push(applyLabel);\n const handle: PluginButtonHandle = {\n el: btn,\n get active() {\n return active;\n },\n setLabel: (l) => {\n label = l;\n applyLabel();\n },\n setIcon,\n setActive: (a) => {\n active = a;\n btn.setAttribute('aria-pressed', String(a));\n },\n show: () => {\n btn.style.display = '';\n },\n hide: () => {\n btn.style.display = 'none';\n },\n remove: () => btn.remove(),\n };\n if (o.onClick) {\n const click = guard((e: MouseEvent) => o.onClick!(e, handle), 'button.onClick');\n btn.addEventListener('click', (e) => {\n e.stopPropagation();\n click(e);\n });\n }\n this.ctx.addControlButton(btn, o.position ?? 'right');\n track(() => btn.remove());\n return handle;\n }\n\n private addLayer(inst: Instance, o: PluginLayerOptions, track: (d: () => void) => void): PluginLayerHandle {\n const el = document.createElement('div');\n el.className = 'hp-plugin-layer';\n el.setAttribute('part', `plugin-layer plugin-${inst.plugin.name}`);\n el.dataset.plugin = inst.plugin.name;\n el.dataset.position = o.position ?? 'fill';\n el.toggleAttribute('data-autohide', !!o.autoHide);\n el.toggleAttribute('data-interactive', !!o.interactive);\n el.toggleAttribute('data-above', !!o.above);\n if (o.css) {\n const style = document.createElement('style');\n style.textContent = o.css;\n el.appendChild(style);\n }\n let visible = o.visible !== false;\n el.hidden = !visible;\n\n if (o.above) this.ctx.videoArea.appendChild(el);\n else this.ctx.videoArea.insertBefore(el, this.ctx.chromeEl);\n if (o.interactive) {\n // Tıklama videoya geçmesin.\n for (const ev of ['pointerdown', 'mousedown', 'mouseup', 'touchstart', 'touchend', 'click', 'dblclick'] as const) el.addEventListener(ev, (e) => e.stopPropagation());\n }\n track(() => el.remove());\n const set = (v: boolean): void => {\n visible = v;\n el.hidden = !v;\n };\n return {\n el,\n get visible() {\n return visible;\n },\n show: () => set(true),\n hide: () => set(false),\n toggle: (force) => set(force ?? !visible),\n remove: () => el.remove(),\n };\n }\n\n private toast(message: string, durationMs = 2500): void {\n if (!this.toastEl) {\n this.toastEl = document.createElement('div');\n this.toastEl.className = 'hp-plugin-toast';\n this.toastEl.setAttribute('part', 'plugin-toast');\n this.toastEl.setAttribute('role', 'status');\n this.toastEl.setAttribute('aria-live', 'polite');\n this.ctx.videoArea.appendChild(this.toastEl);\n }\n this.toastEl.textContent = message;\n this.toastEl.setAttribute('data-visible', '');\n if (this.toastTimer) clearTimeout(this.toastTimer);\n this.toastTimer = setTimeout(() => this.toastEl?.removeAttribute('data-visible'), Math.max(500, durationMs));\n }\n}\n\nfunction settingsHandle(register: () => void, remove: () => void): PluginSettingsHandle {\n return { refresh: register, remove };\n}\n\nfunction onOff(labels: Readonly<Record<string, unknown>>, on: boolean): string {\n const value = on ? labels.a11yOn : labels.a11yOff;\n return typeof value === 'string' ? value : on ? 'On' : 'Off';\n}\n\nfunction storageKey(plugin: string, key: string): string {\n return `hp-plugin:${plugin}:${key}`;\n}\n\n/** Seçenek karşılaştırma anahtarı. */\nfunction optionsKey(options: unknown): string {\n try {\n return JSON.stringify(options ?? null, (_k, v: unknown) => (typeof v === 'function' ? `fn:${(v as { name?: string }).name ?? ''}` : v));\n } catch {\n return String(Math.random());\n }\n}\n\nexport { PLUGIN_API_VERSION };\nexport type { PluginShortcut as Shortcut };\n"],"names":["resolve","label","parseKey","spec","parts","key","mods","p","letter","matches","PluginHost","ctx","__publicField","target","s","builtin","user","seq","resolved","e","wanted","r","name","inst","plugin","options","optionsKey","fn","_a","entry","mod","err","PLUGIN_API_VERSION","result","d","i","where","message","args","track","dispose","guard","strings","host","on","event","handler","once","wrapped","ev","off","done","time","detail","ms","id","o","register","onOff","settingsHandle","list","current","x","description","more","locale","values","fallback","_b","raw","storageKey","value","details","btn","active","setIcon","icon","createIcon","applyLabel","applyActive","handle","l","click","el","style","visible","set","v","force","durationMs","remove","labels","_k"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var w = Object.defineProperty;
|
|
2
2
|
var N = (o, e, t) => e in o ? w(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
|
|
3
3
|
var l = (o, e, t) => N(o, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
-
import { c as f } from "./player-
|
|
4
|
+
import { c as f } from "./player-D7WQxMzr.js";
|
|
5
5
|
const b = "http://www.w3.org/2000/svg", C = 18, g = 2 * Math.PI * C, A = 10;
|
|
6
6
|
function y(o) {
|
|
7
7
|
const e = document.createElementNS(b, "svg");
|
|
@@ -205,4 +205,4 @@ export {
|
|
|
205
205
|
L as RedirectScreen,
|
|
206
206
|
T as installRedirectScreen
|
|
207
207
|
};
|
|
208
|
-
//# sourceMappingURL=redirectScreen-
|
|
208
|
+
//# sourceMappingURL=redirectScreen-5HAVRtxe.js.map
|