mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-28 18:41:20 -08:00
refactor(core): CORE-05 separate typed defaults and resolved options
This commit is contained in:
1 parent
4eec8112fa
commit
97d320bd74
27 files changed
+2278
-240
No files matched your search
@@ -13,6 +13,8 @@ import { beginLifecycle, destroyInstance, finishLifecycle, getScope } from './li
|
||||
import Loading from './loading'
|
||||
import Mask from './mask'
|
||||
import Notice from './notice'
|
||||
import createDefaults from './option/defaults'
|
||||
import resolveOption from './option/resolve'
|
||||
import Player from './player'
|
||||
import Plugins from './plugins'
|
||||
import scheme from './scheme'
|
||||
@@ -36,10 +38,7 @@ export default class Artplayer extends Emitter {
|
||||
|
||||
this.id = ++id
|
||||
|
||||
const mergeOption = utils.mergeDeep(Artplayer.option, option)
|
||||
mergeOption.container = option.container
|
||||
|
||||
this.option = validator(mergeOption, scheme)
|
||||
this.option = resolveOption(option, Artplayer.option)
|
||||
|
||||
this.isLock = false
|
||||
this.isReady = false
|
||||
@@ -135,76 +134,7 @@ export default class Artplayer extends Emitter {
|
||||
}
|
||||
|
||||
static get option() {
|
||||
return {
|
||||
id: '',
|
||||
container: '#artplayer',
|
||||
url: '',
|
||||
poster: '',
|
||||
type: '',
|
||||
theme: '#f00',
|
||||
volume: 0.7,
|
||||
isLive: false,
|
||||
muted: false,
|
||||
autoplay: false,
|
||||
autoSize: false,
|
||||
autoMini: false,
|
||||
loop: false,
|
||||
flip: false,
|
||||
playbackRate: false,
|
||||
aspectRatio: false,
|
||||
screenshot: false,
|
||||
setting: false,
|
||||
hotkey: true,
|
||||
pip: false,
|
||||
mutex: true,
|
||||
backdrop: true,
|
||||
fullscreen: false,
|
||||
fullscreenWeb: false,
|
||||
subtitleOffset: false,
|
||||
miniProgressBar: false,
|
||||
useSSR: false,
|
||||
playsInline: true,
|
||||
lock: false,
|
||||
gesture: true,
|
||||
fastForward: false,
|
||||
autoPlayback: false,
|
||||
autoOrientation: false,
|
||||
airplay: false,
|
||||
proxy: undefined,
|
||||
layers: [],
|
||||
contextmenu: [],
|
||||
controls: [],
|
||||
settings: [],
|
||||
quality: [],
|
||||
highlight: [],
|
||||
plugins: [],
|
||||
thumbnails: {
|
||||
url: '',
|
||||
number: 60,
|
||||
column: 10,
|
||||
width: 0,
|
||||
height: 0,
|
||||
scale: 1,
|
||||
},
|
||||
subtitle: {
|
||||
url: '',
|
||||
type: '',
|
||||
style: {},
|
||||
name: '',
|
||||
escape: true,
|
||||
encoding: 'utf-8',
|
||||
onVttLoad: vtt => vtt,
|
||||
},
|
||||
moreVideoAttr: {
|
||||
controls: false,
|
||||
preload: utils.isSafari ? 'auto' : 'metadata',
|
||||
},
|
||||
i18n: {},
|
||||
icons: {},
|
||||
cssVar: {},
|
||||
customType: {},
|
||||
lang: navigator?.language.toLowerCase(),
|
||||
}
|
||||
return createDefaults()
|
||||
}
|
||||
|
||||
get proxy() {
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import type { ResolvedOption } from './types'
|
||||
import { isSafari } from '../utils/compatibility'
|
||||
|
||||
export default function createDefaults(): ResolvedOption {
|
||||
return {
|
||||
id: '',
|
||||
container: '#artplayer',
|
||||
url: '',
|
||||
poster: '',
|
||||
type: '',
|
||||
theme: '#f00',
|
||||
volume: 0.7,
|
||||
isLive: false,
|
||||
muted: false,
|
||||
autoplay: false,
|
||||
autoSize: false,
|
||||
autoMini: false,
|
||||
loop: false,
|
||||
flip: false,
|
||||
playbackRate: false,
|
||||
aspectRatio: false,
|
||||
screenshot: false,
|
||||
setting: false,
|
||||
hotkey: true,
|
||||
pip: false,
|
||||
mutex: true,
|
||||
backdrop: true,
|
||||
fullscreen: false,
|
||||
fullscreenWeb: false,
|
||||
subtitleOffset: false,
|
||||
miniProgressBar: false,
|
||||
useSSR: false,
|
||||
playsInline: true,
|
||||
lock: false,
|
||||
gesture: true,
|
||||
fastForward: false,
|
||||
autoPlayback: false,
|
||||
autoOrientation: false,
|
||||
airplay: false,
|
||||
proxy: undefined,
|
||||
layers: [],
|
||||
contextmenu: [],
|
||||
controls: [],
|
||||
settings: [],
|
||||
quality: [],
|
||||
highlight: [],
|
||||
plugins: [],
|
||||
thumbnails: {
|
||||
url: '',
|
||||
number: 60,
|
||||
column: 10,
|
||||
width: 0,
|
||||
height: 0,
|
||||
scale: 1,
|
||||
},
|
||||
subtitle: {
|
||||
url: '',
|
||||
type: '',
|
||||
style: {},
|
||||
name: '',
|
||||
escape: true,
|
||||
encoding: 'utf-8',
|
||||
onVttLoad: vtt => vtt,
|
||||
},
|
||||
moreVideoAttr: {
|
||||
controls: false,
|
||||
preload: isSafari ? 'auto' : 'metadata',
|
||||
},
|
||||
i18n: {},
|
||||
icons: {},
|
||||
cssVar: {},
|
||||
customType: {},
|
||||
lang: navigator?.language.toLowerCase(),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { Option, ResolvedInput, ResolvedOption } from './types'
|
||||
import validator from 'option-validator'
|
||||
import scheme from '../scheme'
|
||||
import { mergeDeep } from '../utils/property'
|
||||
|
||||
export default function resolveOption<Input extends Option>(input: Input, defaults: ResolvedOption): ResolvedInput<Input> {
|
||||
const merged = mergeDeep(defaults, input)
|
||||
merged.container = input.container
|
||||
// Keep the existing runtime validator. It checks the known schema, not extension data.
|
||||
return validator(merged, scheme) as ResolvedInput<Input>
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { Option, Thumbnails } from '../../types/option'
|
||||
import type { Subtitle } from '../../types/subtitle'
|
||||
|
||||
export type { Option } from '../../types/option'
|
||||
|
||||
// A successfully merged typed input, not a general guard for arbitrary JS objects.
|
||||
export interface ResolvedOption extends Omit<Required<Option>, 'proxy' | 'subtitle' | 'thumbnails'> {
|
||||
proxy: Option['proxy']
|
||||
subtitle: Required<Subtitle>
|
||||
thumbnails: Required<Thumbnails>
|
||||
}
|
||||
|
||||
export type ResolvedInput<Input extends Option> = ResolvedOption & Omit<Input, keyof Option>
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { Scheme, ValidatorPath } from 'option-validator'
|
||||
import type { Option } from '../option/types'
|
||||
import { errorHandle } from '../utils'
|
||||
|
||||
const a = 'array'
|
||||
@@ -7,7 +9,7 @@ const n = 'number'
|
||||
const o = 'object'
|
||||
const f = 'function'
|
||||
|
||||
function validElement(value, type, paths) {
|
||||
function validElement(value: unknown, type: string, paths: ValidatorPath) {
|
||||
return errorHandle(
|
||||
type === s || type === n || value instanceof Element,
|
||||
`${paths.join('.')} require '${s}' or 'Element' type`,
|
||||
@@ -33,7 +35,7 @@ export const ComponentOption = {
|
||||
onChange: `?${f}`,
|
||||
}
|
||||
|
||||
export default {
|
||||
const scheme = {
|
||||
id: s,
|
||||
container: validElement,
|
||||
url: s,
|
||||
@@ -77,10 +79,10 @@ export default {
|
||||
controls: [
|
||||
{
|
||||
...ComponentOption,
|
||||
position: (value, _, paths) => {
|
||||
position: (value: unknown, _: string, paths: ValidatorPath) => {
|
||||
const position = ['top', 'left', 'right']
|
||||
return errorHandle(
|
||||
position.includes(value),
|
||||
typeof value === 'string' && position.includes(value),
|
||||
`${paths.join('.')} only accept ${position.toString()} as parameters`,
|
||||
)
|
||||
},
|
||||
@@ -121,4 +123,6 @@ export default {
|
||||
icons: o,
|
||||
cssVar: o,
|
||||
customType: o,
|
||||
}
|
||||
} satisfies Record<keyof Option, Scheme>
|
||||
|
||||
export default scheme
|
||||
Reference in new issue
Block a user