build all

Refactor utility functions for improved readability and consistency

- Updated compatibility.js to use consistent line endings and formatting.
- Refactored component.js for better readability and structure, including consistent use of arrow functions and binding.
- Simplified dom.js functions with consistent formatting and improved readability.
- Enhanced emitter.js with consistent formatting and arrow function usage.
- Streamlined error.js for improved readability and consistency.
- Refactored file.js to use consistent formatting and improved readability.
- Improved format.js functions for better readability and consistency.
- Updated index.js to maintain consistent export formatting.
- Refactored property.js for improved readability and consistency.
- Enhanced subtitle.js with consistent formatting and improved readability.
- Refactored time.js for better readability and consistent formatting.

fix: update lint script to target only source files for consistency

Revert "fix: restore export statements for various plugins and update type definitions for better clarity"

This reverts commit b5e969d81ec765cd8a34b06e6ef4f232ef25087f.

fix: restore export statements for various plugins and update type definitions for better clarity

Refactor type definitions to use interfaces instead of type aliases for better extensibility and clarity across i18n, icons, option, player, quality, setting, subtitle, template, and utils modules.
This commit is contained in:
Harvey Zack committed 2025-08-03 13:17:33 +08:00
1 parent 532dd67cfd
commit 35ad9883af
447 files changed
+18248 -17946

No files matched your search

@@ -1,66 +1,69 @@
import { setStyle, addClass, removeClass, hasClass } from '../utils';
import { addClass, hasClass, removeClass, setStyle } from '../utils'
export default function autoOrientation(art) {
const {
constructor,
template: { $player, $video },
} = art;
const {
constructor,
template: { $player, $video },
} = art
art.on('fullscreenWeb', (state) => {
if (state) {
const { videoWidth, videoHeight } = $video;
const { clientWidth: viewWidth, clientHeight: viewHeight } = document.documentElement;
if (
(videoWidth > videoHeight && viewWidth < viewHeight) ||
(videoWidth < videoHeight && viewWidth > viewHeight)
) {
// There is a conflict with the fullscreen event, and it is changed to asynchronous execution
setTimeout(() => {
setStyle($player, 'width', `${viewHeight}px`);
setStyle($player, 'height', `${viewWidth}px`);
setStyle($player, 'transform-origin', '0 0');
setStyle($player, 'transform', `rotate(90deg) translate(0, -${viewWidth}px)`);
addClass($player, 'art-auto-orientation');
art.isRotate = true;
art.emit('resize');
}, constructor.AUTO_ORIENTATION_TIME);
}
} else {
if (hasClass($player, 'art-auto-orientation')) {
removeClass($player, 'art-auto-orientation');
art.isRotate = false;
art.emit('resize');
}
}
});
art.on('fullscreenWeb', (state) => {
if (state) {
const { videoWidth, videoHeight } = $video
const { clientWidth: viewWidth, clientHeight: viewHeight } = document.documentElement
if (
(videoWidth > videoHeight && viewWidth < viewHeight)
|| (videoWidth < videoHeight && viewWidth > viewHeight)
) {
// There is a conflict with the fullscreen event, and it is changed to asynchronous execution
setTimeout(() => {
setStyle($player, 'width', `${viewHeight}px`)
setStyle($player, 'height', `${viewWidth}px`)
setStyle($player, 'transform-origin', '0 0')
setStyle($player, 'transform', `rotate(90deg) translate(0, -${viewWidth}px)`)
addClass($player, 'art-auto-orientation')
art.isRotate = true
art.emit('resize')
}, constructor.AUTO_ORIENTATION_TIME)
}
}
else {
if (hasClass($player, 'art-auto-orientation')) {
removeClass($player, 'art-auto-orientation')
art.isRotate = false
art.emit('resize')
}
}
})
art.on('fullscreen', async (state) => {
if (!screen?.orientation?.lock) return;
art.on('fullscreen', async (state) => {
if (!screen?.orientation?.lock)
return
const lastOrientation = screen.orientation.type;
if (state) {
const { videoWidth, videoHeight } = $video;
const { clientWidth: viewWidth, clientHeight: viewHeight } = document.documentElement;
if (
(videoWidth > videoHeight && viewWidth < viewHeight) ||
(videoWidth < videoHeight && viewWidth > viewHeight)
) {
const oppositeOrientation = lastOrientation.startsWith('portrait') ? 'landscape' : 'portrait';
await screen.orientation.lock(oppositeOrientation);
addClass($player, 'art-auto-orientation-fullscreen');
}
} else {
if (hasClass($player, 'art-auto-orientation-fullscreen')) {
await screen.orientation.lock(lastOrientation);
removeClass($player, 'art-auto-orientation-fullscreen');
}
}
});
const lastOrientation = screen.orientation.type
if (state) {
const { videoWidth, videoHeight } = $video
const { clientWidth: viewWidth, clientHeight: viewHeight } = document.documentElement
if (
(videoWidth > videoHeight && viewWidth < viewHeight)
|| (videoWidth < videoHeight && viewWidth > viewHeight)
) {
const oppositeOrientation = lastOrientation.startsWith('portrait') ? 'landscape' : 'portrait'
await screen.orientation.lock(oppositeOrientation)
addClass($player, 'art-auto-orientation-fullscreen')
}
}
else {
if (hasClass($player, 'art-auto-orientation-fullscreen')) {
await screen.orientation.lock(lastOrientation)
removeClass($player, 'art-auto-orientation-fullscreen')
}
}
})
return {
name: 'autoOrientation',
get state() {
return hasClass($player, 'art-auto-orientation');
},
};
return {
name: 'autoOrientation',
get state() {
return hasClass($player, 'art-auto-orientation')
},
}
}
+77 -77
View File
@@ -1,91 +1,91 @@
import { secondToTime, setStyle, query, append } from '../utils';
import { append, query, secondToTime, setStyle } from '../utils'
export default function autoPlayback(art) {
const {
i18n,
icons,
storage,
constructor,
proxy,
template: { $poster },
} = art;
const {
i18n,
icons,
storage,
constructor,
proxy,
template: { $poster },
} = art
const $autoPlayback = art.layers.add({
name: 'auto-playback',
html: `
const $autoPlayback = art.layers.add({
name: 'auto-playback',
html: `
<div class="art-auto-playback-close"></div>
<div class="art-auto-playback-last"></div>
<div class="art-auto-playback-jump"></div>
`,
});
})
const $last = query('.art-auto-playback-last', $autoPlayback);
const $jump = query('.art-auto-playback-jump', $autoPlayback);
const $close = query('.art-auto-playback-close', $autoPlayback);
append($close, icons.close);
const $last = query('.art-auto-playback-last', $autoPlayback)
const $jump = query('.art-auto-playback-jump', $autoPlayback)
const $close = query('.art-auto-playback-close', $autoPlayback)
append($close, icons.close)
let timer = null;
let timer = null
art.on('video:timeupdate', () => {
if (art.playing) {
const times = storage.get('times') || {};
const keys = Object.keys(times);
if (keys.length > constructor.AUTO_PLAYBACK_MAX) {
delete times[keys[0]];
}
times[art.option.id || art.option.url] = art.currentTime;
storage.set('times', times);
}
});
function init() {
const times = storage.get('times') || {};
const currentTime = times[art.option.id || art.option.url];
clearTimeout(timer);
setStyle($autoPlayback, 'display', 'none');
if (currentTime && currentTime >= constructor.AUTO_PLAYBACK_MIN) {
setStyle($autoPlayback, 'display', 'flex');
$last.innerText = `${i18n.get('Last Seen')} ${secondToTime(currentTime)}`;
$jump.innerText = i18n.get('Jump Play');
proxy($close, 'click', () => {
setStyle($autoPlayback, 'display', 'none');
});
proxy($jump, 'click', () => {
art.seek = currentTime;
art.play();
setStyle($poster, 'display', 'none');
setStyle($autoPlayback, 'display', 'none');
});
art.once('video:timeupdate', () => {
timer = setTimeout(() => {
setStyle($autoPlayback, 'display', 'none');
}, constructor.AUTO_PLAYBACK_TIMEOUT);
});
}
art.on('video:timeupdate', () => {
if (art.playing) {
const times = storage.get('times') || {}
const keys = Object.keys(times)
if (keys.length > constructor.AUTO_PLAYBACK_MAX) {
delete times[keys[0]]
}
times[art.option.id || art.option.url] = art.currentTime
storage.set('times', times)
}
})
art.on('ready', init);
art.on('restart', init);
function init() {
const times = storage.get('times') || {}
const currentTime = times[art.option.id || art.option.url]
return {
name: 'auto-playback',
get times() {
return storage.get('times') || {};
},
clear() {
return storage.del('times');
},
delete(id) {
const times = storage.get('times') || {};
delete times[id];
storage.set('times', times);
return times;
},
};
clearTimeout(timer)
setStyle($autoPlayback, 'display', 'none')
if (currentTime && currentTime >= constructor.AUTO_PLAYBACK_MIN) {
setStyle($autoPlayback, 'display', 'flex')
$last.textContent = `${i18n.get('Last Seen')} ${secondToTime(currentTime)}`
$jump.textContent = i18n.get('Jump Play')
proxy($close, 'click', () => {
setStyle($autoPlayback, 'display', 'none')
})
proxy($jump, 'click', () => {
art.seek = currentTime
art.play()
setStyle($poster, 'display', 'none')
setStyle($autoPlayback, 'display', 'none')
})
art.once('video:timeupdate', () => {
timer = setTimeout(() => {
setStyle($autoPlayback, 'display', 'none')
}, constructor.AUTO_PLAYBACK_TIMEOUT)
})
}
}
art.on('ready', init)
art.on('restart', init)
return {
name: 'auto-playback',
get times() {
return storage.get('times') || {}
},
clear() {
return storage.del('times')
},
delete(id) {
const times = storage.get('times') || {}
delete times[id]
storage.set('times', times)
return times
},
}
}
+36 -36
View File
@@ -1,44 +1,44 @@
import { hasClass, addClass, removeClass } from '../utils';
import { addClass, hasClass, removeClass } from '../utils'
export default function fastForward(art) {
const {
constructor,
proxy,
template: { $player, $video },
} = art;
const {
constructor,
proxy,
template: { $player, $video },
} = art
let timer = null;
let isPress = false;
let lastPlaybackRate = 1;
let timer = null
let isPress = false
let lastPlaybackRate = 1
const onStart = (event) => {
if (event.touches.length === 1 && art.playing && !art.isLock) {
timer = setTimeout(() => {
isPress = true;
lastPlaybackRate = art.playbackRate;
art.playbackRate = constructor.FAST_FORWARD_VALUE;
addClass($player, 'art-fast-forward');
}, constructor.FAST_FORWARD_TIME);
}
};
const onStart = (event) => {
if (event.touches.length === 1 && art.playing && !art.isLock) {
timer = setTimeout(() => {
isPress = true
lastPlaybackRate = art.playbackRate
art.playbackRate = constructor.FAST_FORWARD_VALUE
addClass($player, 'art-fast-forward')
}, constructor.FAST_FORWARD_TIME)
}
}
const onStop = () => {
clearTimeout(timer);
if (isPress) {
isPress = false;
art.playbackRate = lastPlaybackRate;
removeClass($player, 'art-fast-forward');
}
};
const onStop = () => {
clearTimeout(timer)
if (isPress) {
isPress = false
art.playbackRate = lastPlaybackRate
removeClass($player, 'art-fast-forward')
}
}
proxy($video, 'touchstart', onStart);
proxy(document, 'touchmove', onStop);
proxy(document, 'touchend', onStop);
proxy($video, 'touchstart', onStart)
proxy(document, 'touchmove', onStop)
proxy(document, 'touchend', onStop)
return {
name: 'fastForward',
get state() {
return hasClass($player, 'art-fast-forward');
},
};
return {
name: 'fastForward',
get state() {
return hasClass($player, 'art-fast-forward')
},
}
}
+49 -48
View File
@@ -1,58 +1,59 @@
import { errorHandle, isMobile, has, def } from '../utils';
import miniProgressBar from './miniProgressBar';
import autoOrientation from './autoOrientation';
import autoPlayback from './autoPlayback';
import fastForward from './fastForward';
import lock from './lock';
import { def, errorHandle, has, isMobile } from '../utils'
import autoOrientation from './autoOrientation'
import autoPlayback from './autoPlayback'
import fastForward from './fastForward'
import lock from './lock'
import miniProgressBar from './miniProgressBar'
export default class Plugins {
constructor(art) {
this.art = art;
this.id = 0;
constructor(art) {
this.art = art
this.id = 0
const { option } = art;
const { option } = art
if (option.miniProgressBar && !option.isLive) {
this.add(miniProgressBar);
}
if (option.lock && isMobile) {
this.add(lock);
}
if (option.autoPlayback && !option.isLive) {
this.add(autoPlayback);
}
if (option.autoOrientation && isMobile) {
this.add(autoOrientation);
}
if (option.fastForward && isMobile && !option.isLive) {
this.add(fastForward);
}
for (let index = 0; index < option.plugins.length; index++) {
this.add(option.plugins[index]);
}
if (option.miniProgressBar && !option.isLive) {
this.add(miniProgressBar)
}
add(plugin) {
this.id += 1;
const result = plugin.call(this.art, this.art);
if (result instanceof Promise) {
return result.then((res) => this.next(plugin, res));
} else {
return this.next(plugin, result);
}
if (option.lock && isMobile) {
this.add(lock)
}
next(plugin, result) {
const pluginName = (result && result.name) || plugin.name || `plugin${this.id}`;
errorHandle(!has(this, pluginName), `Cannot add a plugin that already has the same name: ${pluginName}`);
def(this, pluginName, {
value: result,
});
return this;
if (option.autoPlayback && !option.isLive) {
this.add(autoPlayback)
}
if (option.autoOrientation && isMobile) {
this.add(autoOrientation)
}
if (option.fastForward && isMobile && !option.isLive) {
this.add(fastForward)
}
for (let index = 0; index < option.plugins.length; index++) {
this.add(option.plugins[index])
}
}
add(plugin) {
this.id += 1
const result = plugin.call(this.art, this.art)
if (result instanceof Promise) {
return result.then(res => this.next(plugin, res))
}
else {
return this.next(plugin, result)
}
}
next(plugin, result) {
const pluginName = (result && result.name) || plugin.name || `plugin${this.id}`
errorHandle(!has(this, pluginName), `Cannot add a plugin that already has the same name: ${pluginName}`)
def(this, pluginName, {
value: result,
})
return this
}
}
+59 -56
View File
@@ -1,65 +1,68 @@
import { append, setStyle, hasClass, addClass, removeClass } from '../utils';
import { addClass, append, hasClass, removeClass, setStyle } from '../utils'
export default function lock(art) {
const {
layers,
icons,
template: { $player },
} = art;
const {
layers,
icons,
template: { $player },
} = art
function getState() {
return hasClass($player, 'art-lock');
}
function getState() {
return hasClass($player, 'art-lock')
}
function setLock() {
addClass($player, 'art-lock');
art.isLock = true;
art.emit('lock', true);
}
function setLock() {
addClass($player, 'art-lock')
art.isLock = true
art.emit('lock', true)
}
function setUnlock() {
removeClass($player, 'art-lock');
art.isLock = false;
art.emit('lock', false);
}
function setUnlock() {
removeClass($player, 'art-lock')
art.isLock = false
art.emit('lock', false)
}
layers.add({
name: 'lock',
mounted($el) {
const $lock = append($el, icons.lock);
const $unlock = append($el, icons.unlock);
setStyle($lock, 'display', 'none');
layers.add({
name: 'lock',
mounted($el) {
const $lock = append($el, icons.lock)
const $unlock = append($el, icons.unlock)
setStyle($lock, 'display', 'none')
art.on('lock', (state) => {
if (state) {
setStyle($lock, 'display', 'inline-flex');
setStyle($unlock, 'display', 'none');
} else {
setStyle($lock, 'display', 'none');
setStyle($unlock, 'display', 'inline-flex');
}
});
},
click() {
if (getState()) {
setUnlock();
} else {
setLock();
}
},
});
art.on('lock', (state) => {
if (state) {
setStyle($lock, 'display', 'inline-flex')
setStyle($unlock, 'display', 'none')
}
else {
setStyle($lock, 'display', 'none')
setStyle($unlock, 'display', 'inline-flex')
}
})
},
click() {
if (getState()) {
setUnlock()
}
else {
setLock()
}
},
})
return {
name: 'lock',
get state() {
return getState();
},
set state(value) {
if (value) {
setLock();
} else {
setUnlock();
}
},
};
return {
name: 'lock',
get state() {
return getState()
},
set state(value) {
if (value) {
setLock()
}
else {
setUnlock()
}
},
}
}
@@ -1,13 +1,14 @@
import { addClass, removeClass } from '../utils';
import { addClass, removeClass } from '../utils'
export default function miniProgressBar(art) {
art.on('control', (state) => {
if (state) {
removeClass(art.template.$player, 'art-mini-progress-bar');
} else {
addClass(art.template.$player, 'art-mini-progress-bar');
}
});
art.on('control', (state) => {
if (state) {
removeClass(art.template.$player, 'art-mini-progress-bar')
}
else {
addClass(art.template.$player, 'art-mini-progress-bar')
}
})
return { name: 'mini-progress-bar' };
return { name: 'mini-progress-bar' }
}