mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-22 21:31:20 -08:00
refactor(core): CORE-16 type display modes and own fullscreen lifetimes
This commit is contained in:
1 parent
1b83081e8f
commit
88aef830df
81 files changed
+33897
-1503
No files matched your search
@@ -1,47 +0,0 @@
|
||||
import { def, setStyle } from '../utils'
|
||||
|
||||
export default function aspectRatioMix(art) {
|
||||
const {
|
||||
i18n,
|
||||
notice,
|
||||
template: { $video, $player },
|
||||
} = art
|
||||
|
||||
def(art, 'aspectRatio', {
|
||||
get() {
|
||||
return $player.dataset.aspectRatio || 'default'
|
||||
},
|
||||
set(ratio) {
|
||||
if (!ratio)
|
||||
ratio = 'default'
|
||||
if (ratio === 'default') {
|
||||
setStyle($video, 'width', null)
|
||||
setStyle($video, 'height', null)
|
||||
setStyle($video, 'margin', null)
|
||||
delete $player.dataset.aspectRatio
|
||||
}
|
||||
else {
|
||||
const ratioArray = ratio.split(':').map(Number)
|
||||
const { clientWidth, clientHeight } = $player
|
||||
const playerRatio = clientWidth / clientHeight
|
||||
const setupRatio = ratioArray[0] / ratioArray[1]
|
||||
|
||||
if (playerRatio > setupRatio) {
|
||||
setStyle($video, 'width', `${setupRatio * clientHeight}px`)
|
||||
setStyle($video, 'height', '100%')
|
||||
setStyle($video, 'margin', '0 auto')
|
||||
}
|
||||
else {
|
||||
setStyle($video, 'width', '100%')
|
||||
setStyle($video, 'height', `${clientWidth / setupRatio}px`)
|
||||
setStyle($video, 'margin', 'auto 0')
|
||||
}
|
||||
|
||||
$player.dataset.aspectRatio = ratio
|
||||
}
|
||||
|
||||
notice.show = `${i18n.get('Aspect Ratio')}: ${ratio === 'default' ? i18n.get('Default') : ratio}`
|
||||
art.emit('aspectRatio', ratio)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import type { AspectRatioHost } from '../display/sizing-types'
|
||||
import { containSize } from '../display/sizing'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function aspectRatioMix(art: AspectRatioHost): void {
|
||||
const { i18n, notice, template: { $video, $player } } = art
|
||||
def(art, 'aspectRatio', {
|
||||
get: () => $player.dataset.aspectRatio || 'default',
|
||||
set(ratio: string) {
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (!ratio)
|
||||
ratio = 'default'
|
||||
if (ratio === 'default') {
|
||||
$video.style.width = ''
|
||||
$video.style.height = ''
|
||||
$video.style.margin = ''
|
||||
delete $player.dataset.aspectRatio
|
||||
}
|
||||
else {
|
||||
// Keep the legacy split/Number coercion and dataset even for invalid ratios.
|
||||
const parts = ratio.split(':').map(Number)
|
||||
const size = containSize({ width: $player.clientWidth, height: $player.clientHeight }, parts[0]! / parts[1]!)
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (size?.axis === 'width') {
|
||||
$video.style.width = `${size.width}px`
|
||||
$video.style.height = '100%'
|
||||
$video.style.margin = '0 auto'
|
||||
}
|
||||
else if (size) {
|
||||
$video.style.width = '100%'
|
||||
$video.style.height = `${size.height}px`
|
||||
$video.style.margin = 'auto 0'
|
||||
}
|
||||
$player.dataset.aspectRatio = ratio
|
||||
}
|
||||
notice.show = `${i18n.get('Aspect Ratio')}: ${ratio === 'default' ? i18n.get('Default') : ratio}`
|
||||
if (!isClosing(art))
|
||||
art.emit('aspectRatio', ratio)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import { def, setStyle } from '../utils'
|
||||
|
||||
export default function autoHeightMix(art) {
|
||||
const {
|
||||
template: { $container, $video },
|
||||
} = art
|
||||
|
||||
def(art, 'autoHeight', {
|
||||
value() {
|
||||
const { clientWidth } = $container
|
||||
const { videoHeight, videoWidth } = $video
|
||||
const height = videoHeight * (clientWidth / videoWidth)
|
||||
setStyle($container, 'height', `${height}px`)
|
||||
art.emit('autoHeight', height)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import type { AutoHeightHost } from '../display/sizing-types'
|
||||
import { proportionalHeight } from '../display/sizing'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function autoHeightMix(art: AutoHeightHost): void {
|
||||
const { $container, $video } = art.template
|
||||
def(art, 'autoHeight', {
|
||||
value() {
|
||||
if (isClosing(art))
|
||||
return
|
||||
const height = proportionalHeight($container.clientWidth, { width: $video.videoWidth, height: $video.videoHeight })
|
||||
if (height === undefined || isClosing(art))
|
||||
return
|
||||
$container.style.height = `${height}px`
|
||||
art.emit('autoHeight', height)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { def, getRect, setStyle } from '../utils'
|
||||
|
||||
export default function autoSizeMix(art) {
|
||||
const { $container, $player, $video } = art.template
|
||||
|
||||
def(art, 'autoSize', {
|
||||
value() {
|
||||
const { videoWidth, videoHeight } = $video
|
||||
const { width, height } = getRect($container)
|
||||
const videoRatio = videoWidth / videoHeight
|
||||
const containerRatio = width / height
|
||||
if (containerRatio > videoRatio) {
|
||||
const percentage = ((height * videoRatio) / width) * 100
|
||||
setStyle($player, 'width', `${percentage}%`)
|
||||
setStyle($player, 'height', '100%')
|
||||
}
|
||||
else {
|
||||
const percentage = (width / videoRatio / height) * 100
|
||||
setStyle($player, 'width', '100%')
|
||||
setStyle($player, 'height', `${percentage}%`)
|
||||
}
|
||||
art.emit('autoSize', {
|
||||
width: art.width,
|
||||
height: art.height,
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import type { AutoSizeHost } from '../display/sizing-types'
|
||||
import { containSize, positiveSize } from '../display/sizing'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import { def, getRect } from '../utils'
|
||||
|
||||
export default function autoSizeMix(art: AutoSizeHost): void {
|
||||
const { $container, $player, $video } = art.template
|
||||
def(art, 'autoSize', {
|
||||
value() {
|
||||
if (isClosing(art))
|
||||
return
|
||||
const media = { width: $video.videoWidth, height: $video.videoHeight }
|
||||
if (!positiveSize(media))
|
||||
return
|
||||
const container = getRect($container)
|
||||
const size = containSize(container, media.width / media.height)
|
||||
if (!size || isClosing(art))
|
||||
return
|
||||
if (size.axis === 'width') {
|
||||
$player.style.width = `${(size.width / container.width) * 100}%`
|
||||
$player.style.height = '100%'
|
||||
}
|
||||
else {
|
||||
$player.style.width = '100%'
|
||||
$player.style.height = `${(size.height / container.height) * 100}%`
|
||||
}
|
||||
art.emit('autoSize', { width: art.width, height: art.height })
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import { capitalize, def } from '../utils'
|
||||
|
||||
export default function flipMix(art) {
|
||||
const {
|
||||
template: { $player },
|
||||
i18n,
|
||||
notice,
|
||||
} = art
|
||||
|
||||
def(art, 'flip', {
|
||||
get() {
|
||||
return $player.dataset.flip || 'normal'
|
||||
},
|
||||
set(flip) {
|
||||
if (!flip)
|
||||
flip = 'normal'
|
||||
if (flip === 'normal') {
|
||||
delete $player.dataset.flip
|
||||
}
|
||||
else {
|
||||
$player.dataset.flip = flip
|
||||
}
|
||||
|
||||
notice.show = `${i18n.get('Video Flip')}: ${i18n.get(capitalize(flip))}`
|
||||
art.emit('flip', flip)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { FlipHost } from '../display/sizing-types'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import { capitalize, def } from '../utils'
|
||||
|
||||
export default function flipMix(art: FlipHost): void {
|
||||
const { template: { $player }, i18n, notice } = art
|
||||
def(art, 'flip', {
|
||||
get: () => $player.dataset.flip || 'normal',
|
||||
set(flip: string) {
|
||||
if (isClosing(art))
|
||||
return
|
||||
if (!flip)
|
||||
flip = 'normal'
|
||||
if (flip === 'normal')
|
||||
delete $player.dataset.flip
|
||||
else
|
||||
$player.dataset.flip = flip
|
||||
notice.show = `${i18n.get('Video Flip')}: ${i18n.get(capitalize(flip))}`
|
||||
if (!isClosing(art))
|
||||
art.emit('flip', flip)
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
import screenfull from '../libs/screenfull'
|
||||
import { addClass, def, get, removeClass } from '../utils'
|
||||
|
||||
export default function fullscreenMix(art) {
|
||||
const {
|
||||
i18n,
|
||||
notice,
|
||||
template: { $video, $player },
|
||||
} = art
|
||||
|
||||
const nativeScreenfull = (art) => {
|
||||
screenfull.on('change', () => {
|
||||
art.emit('fullscreen', screenfull.isFullscreen)
|
||||
|
||||
if (screenfull.isFullscreen) {
|
||||
art.state = 'fullscreen'
|
||||
addClass($player, 'art-fullscreen')
|
||||
}
|
||||
else {
|
||||
removeClass($player, 'art-fullscreen')
|
||||
}
|
||||
|
||||
art.emit('resize')
|
||||
})
|
||||
|
||||
screenfull.on('error', (event) => {
|
||||
art.emit('fullscreenError', event)
|
||||
})
|
||||
|
||||
def(art, 'fullscreen', {
|
||||
get() {
|
||||
return screenfull.isFullscreen
|
||||
},
|
||||
async set(value) {
|
||||
if (value) {
|
||||
await screenfull.request($player)
|
||||
}
|
||||
else {
|
||||
await screenfull.exit()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
const webkitScreenfull = (art) => {
|
||||
art.on('document:webkitfullscreenchange', () => {
|
||||
art.emit('fullscreen', art.fullscreen)
|
||||
art.emit('resize')
|
||||
})
|
||||
|
||||
def(art, 'fullscreen', {
|
||||
get() {
|
||||
return document.fullscreenElement === $video
|
||||
},
|
||||
set(value) {
|
||||
if (value) {
|
||||
art.state = 'fullscreen'
|
||||
$video.webkitEnterFullscreen()
|
||||
}
|
||||
else {
|
||||
$video.webkitExitFullscreen()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
art.once('video:loadedmetadata', () => {
|
||||
if (screenfull.isEnabled) {
|
||||
nativeScreenfull(art)
|
||||
}
|
||||
else if ($video.webkitSupportsFullscreen) {
|
||||
webkitScreenfull(art)
|
||||
}
|
||||
else {
|
||||
def(art, 'fullscreen', {
|
||||
get() {
|
||||
return false
|
||||
},
|
||||
set() {
|
||||
notice.show = i18n.get('Fullscreen Not Supported')
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Asynchronous setting
|
||||
def(art, 'fullscreen', get(art, 'fullscreen'))
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import type { FullscreenHost } from '../display/types'
|
||||
import { fullscreenAdapter } from '../display/fullscreen-adapter'
|
||||
import { nativeFullscreen } from '../display/native-fullscreen'
|
||||
import { videoFullscreen } from '../display/video-fullscreen'
|
||||
import { getScope, isClosing } from '../lifecycle/instance'
|
||||
import { def, get } from '../utils'
|
||||
|
||||
export default function fullscreenMix(art: FullscreenHost): void {
|
||||
const { i18n, notice, template: { $video, $player } } = art
|
||||
const metadata = () => {
|
||||
if (isClosing(art))
|
||||
return
|
||||
const adapter = fullscreenAdapter($player)
|
||||
if (adapter) {
|
||||
def(art, 'fullscreen', nativeFullscreen(art, adapter))
|
||||
}
|
||||
else if ($video.webkitSupportsFullscreen && typeof $video.webkitEnterFullscreen === 'function' && typeof $video.webkitExitFullscreen === 'function') {
|
||||
def(art, 'fullscreen', videoFullscreen(art))
|
||||
}
|
||||
else {
|
||||
def(art, 'fullscreen', {
|
||||
get: () => false,
|
||||
set() {
|
||||
if (!isClosing(art))
|
||||
notice.show = i18n.get('Fullscreen Not Supported')
|
||||
},
|
||||
})
|
||||
}
|
||||
def(art, 'fullscreen', get(art, 'fullscreen')!)
|
||||
}
|
||||
art.once('video:loadedmetadata', metadata)
|
||||
getScope(art).add(() => {
|
||||
art.off('video:loadedmetadata', metadata)
|
||||
})
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
import { addClass, append, def, hasClass, removeClass, setStyle } from '../utils'
|
||||
|
||||
export default function fullscreenWebMix(art) {
|
||||
const {
|
||||
constructor,
|
||||
template: { $container, $player },
|
||||
} = art
|
||||
|
||||
let cssText = ''
|
||||
def(art, 'fullscreenWeb', {
|
||||
get() {
|
||||
return hasClass($player, 'art-fullscreen-web')
|
||||
},
|
||||
set(value) {
|
||||
if (value) {
|
||||
cssText = $player.style.cssText
|
||||
if (constructor.FULLSCREEN_WEB_IN_BODY) {
|
||||
append(document.body, $player)
|
||||
}
|
||||
art.state = 'fullscreenWeb'
|
||||
setStyle($player, 'width', '100%')
|
||||
setStyle($player, 'height', '100%')
|
||||
addClass($player, 'art-fullscreen-web')
|
||||
art.emit('fullscreenWeb', true)
|
||||
}
|
||||
else {
|
||||
if (constructor.FULLSCREEN_WEB_IN_BODY) {
|
||||
append($container, $player)
|
||||
}
|
||||
if (cssText) {
|
||||
$player.style.cssText = cssText
|
||||
cssText = ''
|
||||
}
|
||||
removeClass($player, 'art-fullscreen-web')
|
||||
art.emit('fullscreenWeb', false)
|
||||
}
|
||||
|
||||
art.emit('resize')
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { WebFullscreenHost, WebFullscreenProperty } from '../display/types'
|
||||
import { webFullscreen } from '../display/web-fullscreen'
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function fullscreenWebMix(art: WebFullscreenHost): asserts art is WebFullscreenHost & WebFullscreenProperty {
|
||||
const setFullscreen = webFullscreen(art)
|
||||
def(art, 'fullscreenWeb', {
|
||||
get(): boolean {
|
||||
return art.template.$player.classList.contains('art-fullscreen-web')
|
||||
},
|
||||
set: setFullscreen,
|
||||
})
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
import { addClass, append, createElement, def, getRect, hasClass, isInViewport, removeClass, setStyle, silencePromise } from '../utils'
|
||||
|
||||
export default function miniMix(art) {
|
||||
const {
|
||||
icons,
|
||||
proxy,
|
||||
storage,
|
||||
template: { $player, $video },
|
||||
} = art
|
||||
|
||||
let isDragging = false
|
||||
let lastPageX = 0
|
||||
let lastPageY = 0
|
||||
|
||||
function hideMini() {
|
||||
const { $mini } = art.template
|
||||
if ($mini) {
|
||||
removeClass($player, 'art-mini')
|
||||
setStyle($mini, 'display', 'none')
|
||||
$player.prepend($video)
|
||||
art.emit('mini', false)
|
||||
}
|
||||
}
|
||||
|
||||
function initState($play, $pause) {
|
||||
if (art.playing) {
|
||||
setStyle($play, 'display', `none`)
|
||||
setStyle($pause, 'display', `flex`)
|
||||
}
|
||||
else {
|
||||
setStyle($play, 'display', `flex`)
|
||||
setStyle($pause, 'display', `none`)
|
||||
}
|
||||
}
|
||||
|
||||
function createMini() {
|
||||
const { $mini } = art.template
|
||||
if ($mini) {
|
||||
append($mini, $video)
|
||||
return setStyle($mini, 'display', 'flex')
|
||||
}
|
||||
else {
|
||||
const $mini = createElement('div')
|
||||
addClass($mini, 'art-mini-popup')
|
||||
append(document.body, $mini)
|
||||
art.template.$mini = $mini
|
||||
append($mini, $video)
|
||||
|
||||
const $close = append($mini, `<div class="art-mini-close"></div>`)
|
||||
append($close, icons.close)
|
||||
proxy($close, 'click', hideMini)
|
||||
|
||||
const $state = append($mini, `<div class="art-mini-state"></div>`)
|
||||
const $play = append($state, icons.play)
|
||||
const $pause = append($state, icons.pause)
|
||||
proxy($play, 'click', () => silencePromise(art.play()))
|
||||
proxy($pause, 'click', () => art.pause())
|
||||
initState($play, $pause)
|
||||
art.on('video:playing', () => initState($play, $pause))
|
||||
art.on('video:pause', () => initState($play, $pause))
|
||||
art.on('video:timeupdate', () => initState($play, $pause))
|
||||
|
||||
proxy($mini, 'mousedown', (event) => {
|
||||
isDragging = event.button === 0
|
||||
lastPageX = event.pageX
|
||||
lastPageY = event.pageY
|
||||
})
|
||||
|
||||
art.on('document:mousemove', (event) => {
|
||||
if (isDragging) {
|
||||
addClass($mini, 'art-mini-dragging')
|
||||
const x = event.pageX - lastPageX
|
||||
const y = event.pageY - lastPageY
|
||||
setStyle($mini, 'transform', `translate(${x}px, ${y}px)`)
|
||||
}
|
||||
})
|
||||
|
||||
art.on('document:mouseup', () => {
|
||||
if (isDragging) {
|
||||
isDragging = false
|
||||
removeClass($mini, 'art-mini-dragging')
|
||||
const rect = getRect($mini)
|
||||
storage.set('left', rect.left)
|
||||
storage.set('top', rect.top)
|
||||
setStyle($mini, 'left', `${rect.left}px`)
|
||||
setStyle($mini, 'top', `${rect.top}px`)
|
||||
setStyle($mini, 'transform', null)
|
||||
}
|
||||
})
|
||||
|
||||
return $mini
|
||||
}
|
||||
}
|
||||
|
||||
function initMini() {
|
||||
const { $mini } = art.template
|
||||
const rect = getRect($mini)
|
||||
const top = window.innerHeight - rect.height - 50
|
||||
const left = window.innerWidth - rect.width - 50
|
||||
storage.set('top', top)
|
||||
storage.set('left', left)
|
||||
setStyle($mini, 'top', `${top}px`)
|
||||
setStyle($mini, 'left', `${left}px`)
|
||||
}
|
||||
|
||||
def(art, 'mini', {
|
||||
get() {
|
||||
return hasClass($player, 'art-mini')
|
||||
},
|
||||
set(value) {
|
||||
if (value) {
|
||||
art.state = 'mini'
|
||||
addClass($player, 'art-mini')
|
||||
const $mini = createMini()
|
||||
const top = storage.get('top')
|
||||
const left = storage.get('left')
|
||||
if (typeof top === 'number' && typeof left === 'number') {
|
||||
setStyle($mini, 'top', `${top}px`)
|
||||
setStyle($mini, 'left', `${left}px`)
|
||||
if (!isInViewport($mini)) {
|
||||
initMini()
|
||||
}
|
||||
}
|
||||
else {
|
||||
initMini()
|
||||
}
|
||||
art.emit('mini', true)
|
||||
}
|
||||
else {
|
||||
hideMini()
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { MiniHost, MiniProperty } from '../display/types'
|
||||
import { mini } from '../display/mini'
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function miniMix(art: MiniHost): asserts art is MiniHost & MiniProperty {
|
||||
def(art, 'mini', mini(art))
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
import { def } from '../utils'
|
||||
|
||||
function nativePip(art) {
|
||||
const {
|
||||
template: { $video },
|
||||
proxy,
|
||||
notice,
|
||||
} = art
|
||||
|
||||
$video.disablePictureInPicture = false
|
||||
|
||||
def(art, 'pip', {
|
||||
get() {
|
||||
return document.pictureInPictureElement
|
||||
},
|
||||
set(value) {
|
||||
if (value) {
|
||||
art.state = 'pip'
|
||||
$video.requestPictureInPicture().catch((err) => {
|
||||
notice.show = err
|
||||
throw err
|
||||
})
|
||||
}
|
||||
else {
|
||||
document.exitPictureInPicture().catch((err) => {
|
||||
notice.show = err
|
||||
throw err
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
proxy($video, 'enterpictureinpicture', () => {
|
||||
art.emit('pip', true)
|
||||
})
|
||||
|
||||
proxy($video, 'leavepictureinpicture', () => {
|
||||
art.emit('pip', false)
|
||||
})
|
||||
}
|
||||
|
||||
function webkitPip(art) {
|
||||
const { $video } = art.template
|
||||
|
||||
$video.webkitSetPresentationMode('inline')
|
||||
|
||||
def(art, 'pip', {
|
||||
get() {
|
||||
return $video.webkitPresentationMode === 'picture-in-picture'
|
||||
},
|
||||
set(value) {
|
||||
if (value) {
|
||||
art.state = 'pip'
|
||||
$video.webkitSetPresentationMode('picture-in-picture')
|
||||
art.emit('pip', true)
|
||||
}
|
||||
else {
|
||||
$video.webkitSetPresentationMode('inline')
|
||||
art.emit('pip', false)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export default function pipMix(art) {
|
||||
const {
|
||||
i18n,
|
||||
notice,
|
||||
template: { $video },
|
||||
} = art
|
||||
if (document.pictureInPictureEnabled) {
|
||||
nativePip(art)
|
||||
}
|
||||
else if ($video.webkitSupportsPresentationMode) {
|
||||
webkitPip(art)
|
||||
}
|
||||
else {
|
||||
def(art, 'pip', {
|
||||
get() {
|
||||
return false
|
||||
},
|
||||
set() {
|
||||
notice.show = i18n.get('PIP Not Supported')
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { PipHost, PipProperty } from '../display/types'
|
||||
import { nativePip } from '../display/native-pip'
|
||||
import { webkitPip } from '../display/webkit-pip'
|
||||
import { isClosing } from '../lifecycle/instance'
|
||||
import { def } from '../utils'
|
||||
|
||||
export default function pipMix(art: PipHost): asserts art is PipHost & PipProperty {
|
||||
const { i18n, notice, template: { $video } } = art
|
||||
const document = $video.ownerDocument
|
||||
if (document.pictureInPictureEnabled && typeof $video.requestPictureInPicture === 'function' && typeof document.exitPictureInPicture === 'function') {
|
||||
def(art, 'pip', nativePip(art))
|
||||
}
|
||||
else if (typeof $video.webkitSupportsPresentationMode === 'function' && typeof $video.webkitSetPresentationMode === 'function') {
|
||||
def(art, 'pip', webkitPip(art))
|
||||
}
|
||||
else {
|
||||
def(art, 'pip', {
|
||||
get: () => false,
|
||||
set() {
|
||||
if (!isClosing(art))
|
||||
notice.show = i18n.get('PIP Not Supported')
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user