mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-22 21:31:20 -08:00
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:
1 parent
532dd67cfd
commit
35ad9883af
447 files changed
+18248
-17946
No files matched your search
@@ -1,9 +1,9 @@
|
||||
export const userAgent = globalThis?.CUSTOM_USER_AGENT ?? (typeof navigator !== 'undefined' ? navigator.userAgent : '');
|
||||
export const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
|
||||
export const isWechat = /MicroMessenger/i.test(userAgent);
|
||||
export const isIE = /MSIE|Trident/i.test(userAgent);
|
||||
export const isAndroid = /android/i.test(userAgent);
|
||||
export const isIOS = /iPad|iPhone|iPod/i.test(userAgent) && !window.MSStream;
|
||||
export const isIOS13 = isIOS || (userAgent.includes('Macintosh') && navigator.maxTouchPoints >= 1);
|
||||
export const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent) || isIOS13;
|
||||
export const isBrowser = typeof window !== 'undefined';
|
||||
export const userAgent = globalThis?.CUSTOM_USER_AGENT ?? (typeof navigator !== 'undefined' ? navigator.userAgent : '')
|
||||
export const isSafari = /^(?:(?!chrome|android).)*safari/i.test(userAgent)
|
||||
export const isWechat = /MicroMessenger/i.test(userAgent)
|
||||
export const isIE = /MSIE|Trident/i.test(userAgent)
|
||||
export const isAndroid = /android/i.test(userAgent)
|
||||
export const isIOS = /iPad|iPhone|iPod/i.test(userAgent) && !window.MSStream
|
||||
export const isIOS13 = isIOS || (userAgent.includes('Macintosh') && navigator.maxTouchPoints >= 1)
|
||||
export const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent) || isIOS13
|
||||
export const isBrowser = typeof window !== 'undefined'
|
||||
@@ -1,118 +1,121 @@
|
||||
import { remove, append, tooltip, hasClass, addClass, setStyles, removeClass, createElement } from './dom';
|
||||
import { errorHandle } from './error';
|
||||
import validator from 'option-validator';
|
||||
import { ComponentOption } from '../scheme';
|
||||
import validator from 'option-validator'
|
||||
import { ComponentOption } from '../scheme'
|
||||
import { addClass, append, createElement, hasClass, remove, removeClass, setStyles, tooltip } from './dom'
|
||||
import { errorHandle } from './error'
|
||||
|
||||
export default class Component {
|
||||
constructor(art) {
|
||||
this.id = 0;
|
||||
this.art = art;
|
||||
this.cache = new Map();
|
||||
this.add = this.add.bind(this);
|
||||
this.remove = this.remove.bind(this);
|
||||
this.update = this.update.bind(this);
|
||||
constructor(art) {
|
||||
this.id = 0
|
||||
this.art = art
|
||||
this.cache = new Map()
|
||||
this.add = this.add.bind(this)
|
||||
this.remove = this.remove.bind(this)
|
||||
this.update = this.update.bind(this)
|
||||
}
|
||||
|
||||
get show() {
|
||||
return hasClass(this.art.template.$player, `art-${this.name}-show`)
|
||||
}
|
||||
|
||||
set show(value) {
|
||||
const { $player } = this.art.template
|
||||
const className = `art-${this.name}-show`
|
||||
if (value) {
|
||||
addClass($player, className)
|
||||
}
|
||||
else {
|
||||
removeClass($player, className)
|
||||
}
|
||||
this.art.emit(this.name, value)
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.show = !this.show
|
||||
}
|
||||
|
||||
add(getOption) {
|
||||
const option = typeof getOption === 'function' ? getOption(this.art) : getOption
|
||||
option.html = option.html || ''
|
||||
validator(option, ComponentOption)
|
||||
if (!this.$parent || !this.name || option.disable)
|
||||
return
|
||||
const name = option.name || `${this.name}${this.id}`
|
||||
const item = this.cache.get(name)
|
||||
errorHandle(!item, `Can't add an existing [${name}] to the [${this.name}]`)
|
||||
|
||||
this.id += 1
|
||||
const $ref = createElement('div')
|
||||
addClass($ref, `art-${this.name}`)
|
||||
addClass($ref, `art-${this.name}-${name}`)
|
||||
|
||||
const childs = Array.from(this.$parent.children)
|
||||
$ref.dataset.index = option.index || this.id
|
||||
const nextChild = childs.find(item => Number(item.dataset.index) >= Number($ref.dataset.index))
|
||||
if (nextChild) {
|
||||
nextChild.insertAdjacentElement('beforebegin', $ref)
|
||||
}
|
||||
else {
|
||||
append(this.$parent, $ref)
|
||||
}
|
||||
|
||||
get show() {
|
||||
return hasClass(this.art.template.$player, `art-${this.name}-show`);
|
||||
if (option.html) {
|
||||
append($ref, option.html)
|
||||
}
|
||||
|
||||
set show(value) {
|
||||
const { $player } = this.art.template;
|
||||
const className = `art-${this.name}-show`;
|
||||
if (value) {
|
||||
addClass($player, className);
|
||||
} else {
|
||||
removeClass($player, className);
|
||||
}
|
||||
this.art.emit(this.name, value);
|
||||
if (option.style) {
|
||||
setStyles($ref, option.style)
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.show = !this.show;
|
||||
if (option.tooltip) {
|
||||
tooltip($ref, option.tooltip)
|
||||
}
|
||||
|
||||
add(getOption) {
|
||||
const option = typeof getOption === 'function' ? getOption(this.art) : getOption;
|
||||
option.html = option.html || '';
|
||||
validator(option, ComponentOption);
|
||||
if (!this.$parent || !this.name || option.disable) return;
|
||||
const name = option.name || `${this.name}${this.id}`;
|
||||
const item = this.cache.get(name);
|
||||
errorHandle(!item, `Can't add an existing [${name}] to the [${this.name}]`);
|
||||
|
||||
this.id += 1;
|
||||
const $ref = createElement('div');
|
||||
addClass($ref, `art-${this.name}`);
|
||||
addClass($ref, `art-${this.name}-${name}`);
|
||||
|
||||
const childs = Array.from(this.$parent.children);
|
||||
$ref.dataset.index = option.index || this.id;
|
||||
const nextChild = childs.find((item) => Number(item.dataset.index) >= Number($ref.dataset.index));
|
||||
if (nextChild) {
|
||||
nextChild.insertAdjacentElement('beforebegin', $ref);
|
||||
} else {
|
||||
append(this.$parent, $ref);
|
||||
}
|
||||
|
||||
if (option.html) {
|
||||
append($ref, option.html);
|
||||
}
|
||||
|
||||
if (option.style) {
|
||||
setStyles($ref, option.style);
|
||||
}
|
||||
|
||||
if (option.tooltip) {
|
||||
tooltip($ref, option.tooltip);
|
||||
}
|
||||
|
||||
const events = [];
|
||||
if (option.click) {
|
||||
const destroyEvent = this.art.events.proxy($ref, 'click', (event) => {
|
||||
event.preventDefault();
|
||||
option.click.call(this.art, this, event);
|
||||
});
|
||||
events.push(destroyEvent);
|
||||
}
|
||||
|
||||
if (option.selector && ['left', 'right'].includes(option.position)) {
|
||||
this.selector(option, $ref, events);
|
||||
}
|
||||
|
||||
this[name] = $ref;
|
||||
this.cache.set(name, { $ref, events, option });
|
||||
|
||||
if (option.mounted) {
|
||||
option.mounted.call(this.art, $ref);
|
||||
}
|
||||
|
||||
return $ref;
|
||||
const events = []
|
||||
if (option.click) {
|
||||
const destroyEvent = this.art.events.proxy($ref, 'click', (event) => {
|
||||
event.preventDefault()
|
||||
option.click.call(this.art, this, event)
|
||||
})
|
||||
events.push(destroyEvent)
|
||||
}
|
||||
|
||||
remove(name) {
|
||||
const item = this.cache.get(name);
|
||||
errorHandle(item, `Can't find [${name}] from the [${this.name}]`);
|
||||
|
||||
if (item.option.beforeUnmount) {
|
||||
item.option.beforeUnmount.call(this.art, item.$ref);
|
||||
}
|
||||
|
||||
for (let index = 0; index < item.events.length; index++) {
|
||||
this.art.events.remove(item.events[index]);
|
||||
}
|
||||
|
||||
this.cache.delete(name);
|
||||
delete this[name];
|
||||
remove(item.$ref);
|
||||
if (option.selector && ['left', 'right'].includes(option.position)) {
|
||||
this.selector(option, $ref, events)
|
||||
}
|
||||
|
||||
update(option) {
|
||||
const item = this.cache.get(option.name);
|
||||
if (item) {
|
||||
option = Object.assign(item.option, option);
|
||||
this.remove(option.name);
|
||||
}
|
||||
return this.add(option);
|
||||
this[name] = $ref
|
||||
this.cache.set(name, { $ref, events, option })
|
||||
|
||||
if (option.mounted) {
|
||||
option.mounted.call(this.art, $ref)
|
||||
}
|
||||
|
||||
return $ref
|
||||
}
|
||||
|
||||
remove(name) {
|
||||
const item = this.cache.get(name)
|
||||
errorHandle(item, `Can't find [${name}] from the [${this.name}]`)
|
||||
|
||||
if (item.option.beforeUnmount) {
|
||||
item.option.beforeUnmount.call(this.art, item.$ref)
|
||||
}
|
||||
|
||||
for (let index = 0; index < item.events.length; index++) {
|
||||
this.art.events.remove(item.events[index])
|
||||
}
|
||||
|
||||
this.cache.delete(name)
|
||||
delete this[name]
|
||||
remove(item.$ref)
|
||||
}
|
||||
|
||||
update(option) {
|
||||
const item = this.cache.get(option.name)
|
||||
if (item) {
|
||||
option = Object.assign(item.option, option)
|
||||
this.remove(option.name)
|
||||
}
|
||||
return this.add(option)
|
||||
}
|
||||
}
|
||||
+105
-100
@@ -1,177 +1,182 @@
|
||||
import { isMobile } from './compatibility';
|
||||
import { isMobile } from './compatibility'
|
||||
|
||||
export function query(selector, parent = document) {
|
||||
return parent.querySelector(selector);
|
||||
return parent.querySelector(selector)
|
||||
}
|
||||
|
||||
export function queryAll(selector, parent = document) {
|
||||
return Array.from(parent.querySelectorAll(selector));
|
||||
return Array.from(parent.querySelectorAll(selector))
|
||||
}
|
||||
|
||||
export function addClass(target, className) {
|
||||
return target.classList.add(className);
|
||||
return target.classList.add(className)
|
||||
}
|
||||
|
||||
export function removeClass(target, className) {
|
||||
return target.classList.remove(className);
|
||||
return target.classList.remove(className)
|
||||
}
|
||||
|
||||
export function hasClass(target, className) {
|
||||
return target.classList.contains(className);
|
||||
return target.classList.contains(className)
|
||||
}
|
||||
|
||||
export function append(parent, child) {
|
||||
if (child instanceof Element) {
|
||||
parent.appendChild(child);
|
||||
} else {
|
||||
parent.insertAdjacentHTML('beforeend', String(child));
|
||||
}
|
||||
return parent.lastElementChild || parent.lastChild;
|
||||
if (child instanceof Element) {
|
||||
parent.appendChild(child)
|
||||
}
|
||||
else {
|
||||
parent.insertAdjacentHTML('beforeend', String(child))
|
||||
}
|
||||
return parent.lastElementChild || parent.lastChild
|
||||
}
|
||||
|
||||
export function remove(child) {
|
||||
return child.parentNode.removeChild(child);
|
||||
return child.parentNode.removeChild(child)
|
||||
}
|
||||
|
||||
export function setStyle(element, key, value) {
|
||||
element.style[key] = value;
|
||||
return element;
|
||||
element.style[key] = value
|
||||
return element
|
||||
}
|
||||
|
||||
export function setStyles(element, styles) {
|
||||
for (const key in styles) {
|
||||
setStyle(element, key, styles[key]);
|
||||
}
|
||||
return element;
|
||||
for (const key in styles) {
|
||||
setStyle(element, key, styles[key])
|
||||
}
|
||||
return element
|
||||
}
|
||||
|
||||
export function getStyle(element, key, numberType = true) {
|
||||
const value = window.getComputedStyle(element, null).getPropertyValue(key);
|
||||
return numberType ? parseFloat(value) : value;
|
||||
const value = window.getComputedStyle(element, null).getPropertyValue(key)
|
||||
return numberType ? Number.parseFloat(value) : value
|
||||
}
|
||||
|
||||
export function siblings(target) {
|
||||
return Array.from(target.parentElement.children).filter((item) => item !== target);
|
||||
return Array.from(target.parentElement.children).filter(item => item !== target)
|
||||
}
|
||||
|
||||
export function inverseClass(target, className) {
|
||||
siblings(target).forEach((item) => removeClass(item, className));
|
||||
addClass(target, className);
|
||||
siblings(target).forEach(item => removeClass(item, className))
|
||||
addClass(target, className)
|
||||
}
|
||||
|
||||
export function tooltip(target, msg, pos = 'top') {
|
||||
if (isMobile) return;
|
||||
target.setAttribute('aria-label', msg);
|
||||
addClass(target, 'hint--rounded');
|
||||
addClass(target, `hint--${pos}`);
|
||||
if (isMobile)
|
||||
return
|
||||
target.setAttribute('aria-label', msg)
|
||||
addClass(target, 'hint--rounded')
|
||||
addClass(target, `hint--${pos}`)
|
||||
}
|
||||
|
||||
export function isInViewport(el, offset = 0) {
|
||||
const rect = el.getBoundingClientRect();
|
||||
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
||||
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
||||
const vertInView = rect.top - offset <= windowHeight && rect.top + rect.height + offset >= 0;
|
||||
const horInView = rect.left - offset <= windowWidth + offset && rect.left + rect.width + offset >= 0;
|
||||
return vertInView && horInView;
|
||||
const rect = el.getBoundingClientRect()
|
||||
const windowHeight = window.innerHeight || document.documentElement.clientHeight
|
||||
const windowWidth = window.innerWidth || document.documentElement.clientWidth
|
||||
const vertInView = rect.top - offset <= windowHeight && rect.top + rect.height + offset >= 0
|
||||
const horInView = rect.left - offset <= windowWidth + offset && rect.left + rect.width + offset >= 0
|
||||
return vertInView && horInView
|
||||
}
|
||||
|
||||
export function includeFromEvent(event, target) {
|
||||
return getComposedPath(event).indexOf(target) > -1;
|
||||
return getComposedPath(event).includes(target)
|
||||
}
|
||||
|
||||
export function replaceElement(newChild, oldChild) {
|
||||
oldChild.parentNode.replaceChild(newChild, oldChild);
|
||||
return newChild;
|
||||
oldChild.parentNode.replaceChild(newChild, oldChild)
|
||||
return newChild
|
||||
}
|
||||
|
||||
export function createElement(tag) {
|
||||
return document.createElement(tag);
|
||||
return document.createElement(tag)
|
||||
}
|
||||
|
||||
export function getIcon(key = '', html = '') {
|
||||
const icon = createElement('i');
|
||||
addClass(icon, 'art-icon');
|
||||
addClass(icon, `art-icon-${key}`);
|
||||
append(icon, html);
|
||||
return icon;
|
||||
const icon = createElement('i')
|
||||
addClass(icon, 'art-icon')
|
||||
addClass(icon, `art-icon-${key}`)
|
||||
append(icon, html)
|
||||
return icon
|
||||
}
|
||||
|
||||
export function setStyleText(id, style) {
|
||||
let $style = document.getElementById(id);
|
||||
if (!$style) {
|
||||
$style = document.createElement('style');
|
||||
$style.id = id;
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.head.appendChild($style);
|
||||
});
|
||||
} else {
|
||||
(document.head || document.documentElement).appendChild($style);
|
||||
}
|
||||
let $style = document.getElementById(id)
|
||||
if (!$style) {
|
||||
$style = document.createElement('style')
|
||||
$style.id = id
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.head.appendChild($style)
|
||||
})
|
||||
}
|
||||
$style.textContent = style;
|
||||
else {
|
||||
(document.head || document.documentElement).appendChild($style)
|
||||
}
|
||||
}
|
||||
$style.textContent = style
|
||||
}
|
||||
|
||||
export function supportsFlex() {
|
||||
const div = document.createElement('div');
|
||||
div.style.display = 'flex';
|
||||
return div.style.display === 'flex';
|
||||
const div = document.createElement('div')
|
||||
div.style.display = 'flex'
|
||||
return div.style.display === 'flex'
|
||||
}
|
||||
|
||||
export function getRect(el) {
|
||||
return el.getBoundingClientRect();
|
||||
return el.getBoundingClientRect()
|
||||
}
|
||||
|
||||
export function loadImg(url, scale) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image()
|
||||
|
||||
img.onload = function () {
|
||||
if (!scale || scale === 1) {
|
||||
resolve(img);
|
||||
} else {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
canvas.width = img.width * scale;
|
||||
canvas.height = img.height * scale;
|
||||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
||||
img.onload = function () {
|
||||
if (!scale || scale === 1) {
|
||||
resolve(img)
|
||||
}
|
||||
else {
|
||||
const canvas = document.createElement('canvas')
|
||||
const ctx = canvas.getContext('2d')
|
||||
canvas.width = img.width * scale
|
||||
canvas.height = img.height * scale
|
||||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
|
||||
|
||||
canvas.toBlob((blob) => {
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
const scaledImg = new Image();
|
||||
canvas.toBlob((blob) => {
|
||||
const blobUrl = URL.createObjectURL(blob)
|
||||
const scaledImg = new Image()
|
||||
|
||||
scaledImg.onload = function () {
|
||||
resolve(scaledImg);
|
||||
};
|
||||
scaledImg.onload = function () {
|
||||
resolve(scaledImg)
|
||||
}
|
||||
|
||||
scaledImg.onerror = function () {
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
reject(new Error(`Image load failed: ${url}`));
|
||||
};
|
||||
scaledImg.onerror = function () {
|
||||
URL.revokeObjectURL(blobUrl)
|
||||
reject(new Error(`Image load failed: ${url}`))
|
||||
}
|
||||
|
||||
scaledImg.src = blobUrl;
|
||||
});
|
||||
}
|
||||
};
|
||||
scaledImg.src = blobUrl
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
img.onerror = function () {
|
||||
reject(new Error(`Image load failed: ${url}`));
|
||||
};
|
||||
img.onerror = function () {
|
||||
reject(new Error(`Image load failed: ${url}`))
|
||||
}
|
||||
|
||||
img.src = url;
|
||||
});
|
||||
img.src = url
|
||||
})
|
||||
}
|
||||
|
||||
export function getComposedPath(event) {
|
||||
if (event.composedPath) return event.composedPath();
|
||||
const path = [];
|
||||
let node = event.target;
|
||||
while (node) {
|
||||
path.push(node);
|
||||
node = node.parentNode;
|
||||
}
|
||||
if (path.indexOf(window) === -1 && window !== undefined) {
|
||||
path.push(window);
|
||||
}
|
||||
return path;
|
||||
if (event.composedPath)
|
||||
return event.composedPath()
|
||||
const path = []
|
||||
let node = event.target
|
||||
while (node) {
|
||||
path.push(node)
|
||||
node = node.parentNode
|
||||
}
|
||||
if (!path.includes(window) && window !== undefined) {
|
||||
path.push(window)
|
||||
}
|
||||
return path
|
||||
}
|
||||
@@ -1,42 +1,44 @@
|
||||
export default class Emitter {
|
||||
on(name, fn, ctx) {
|
||||
const e = this.e || (this.e = {});
|
||||
(e[name] || (e[name] = [])).push({ fn, ctx });
|
||||
return this;
|
||||
}
|
||||
on(name, fn, ctx) {
|
||||
const e = this.e || (this.e = {});
|
||||
(e[name] || (e[name] = [])).push({ fn, ctx })
|
||||
return this
|
||||
}
|
||||
|
||||
once(name, fn, ctx) {
|
||||
const self = this;
|
||||
function listener(...args) {
|
||||
self.off(name, listener);
|
||||
fn.apply(ctx, args);
|
||||
}
|
||||
listener._ = fn;
|
||||
return this.on(name, listener, ctx);
|
||||
once(name, fn, ctx) {
|
||||
const self = this
|
||||
function listener(...args) {
|
||||
self.off(name, listener)
|
||||
fn.apply(ctx, args)
|
||||
}
|
||||
listener._ = fn
|
||||
return this.on(name, listener, ctx)
|
||||
}
|
||||
|
||||
emit(name, ...data) {
|
||||
const evtArr = ((this.e || (this.e = {}))[name] || []).slice();
|
||||
for (let i = 0; i < evtArr.length; i += 1) {
|
||||
evtArr[i].fn.apply(evtArr[i].ctx, data);
|
||||
}
|
||||
return this;
|
||||
emit(name, ...data) {
|
||||
const evtArr = ((this.e || (this.e = {}))[name] || []).slice()
|
||||
for (let i = 0; i < evtArr.length; i += 1) {
|
||||
evtArr[i].fn.apply(evtArr[i].ctx, data)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
off(name, callback) {
|
||||
const e = this.e || (this.e = {});
|
||||
const evts = e[name];
|
||||
const liveEvents = [];
|
||||
if (evts && callback) {
|
||||
for (let i = 0, len = evts.length; i < len; i += 1) {
|
||||
if (evts[i].fn !== callback && evts[i].fn._ !== callback) liveEvents.push(evts[i]);
|
||||
}
|
||||
}
|
||||
if (liveEvents.length) {
|
||||
e[name] = liveEvents;
|
||||
} else {
|
||||
delete e[name];
|
||||
}
|
||||
return this;
|
||||
off(name, callback) {
|
||||
const e = this.e || (this.e = {})
|
||||
const evts = e[name]
|
||||
const liveEvents = []
|
||||
if (evts && callback) {
|
||||
for (let i = 0, len = evts.length; i < len; i += 1) {
|
||||
if (evts[i].fn !== callback && evts[i].fn._ !== callback)
|
||||
liveEvents.push(evts[i])
|
||||
}
|
||||
}
|
||||
if (liveEvents.length) {
|
||||
e[name] = liveEvents
|
||||
}
|
||||
else {
|
||||
delete e[name]
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
export class ArtPlayerError extends Error {
|
||||
constructor(message, context) {
|
||||
super(message);
|
||||
if (typeof Error.captureStackTrace === 'function') {
|
||||
Error.captureStackTrace(this, context || this.constructor);
|
||||
}
|
||||
this.name = 'ArtPlayerError';
|
||||
constructor(message, context) {
|
||||
super(message)
|
||||
if (typeof Error.captureStackTrace === 'function') {
|
||||
Error.captureStackTrace(this, context || this.constructor)
|
||||
}
|
||||
this.name = 'ArtPlayerError'
|
||||
}
|
||||
}
|
||||
|
||||
export function errorHandle(condition, msg) {
|
||||
if (!condition) {
|
||||
throw new ArtPlayerError(msg);
|
||||
}
|
||||
return condition;
|
||||
if (!condition) {
|
||||
throw new ArtPlayerError(msg)
|
||||
}
|
||||
return condition
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
export function getExt(url) {
|
||||
if (url.includes('?')) {
|
||||
return getExt(url.split('?')[0]);
|
||||
}
|
||||
if (url.includes('?')) {
|
||||
return getExt(url.split('?')[0])
|
||||
}
|
||||
|
||||
if (url.includes('#')) {
|
||||
return getExt(url.split('#')[0]);
|
||||
}
|
||||
if (url.includes('#')) {
|
||||
return getExt(url.split('#')[0])
|
||||
}
|
||||
|
||||
return url.trim().toLowerCase().split('.').pop();
|
||||
return url.trim().toLowerCase().split('.').pop()
|
||||
}
|
||||
|
||||
export function download(url, name) {
|
||||
const elink = document.createElement('a');
|
||||
elink.style.display = 'none';
|
||||
elink.href = url;
|
||||
elink.download = name;
|
||||
document.body.appendChild(elink);
|
||||
elink.click();
|
||||
document.body.removeChild(elink);
|
||||
const elink = document.createElement('a')
|
||||
elink.style.display = 'none'
|
||||
elink.href = url
|
||||
elink.download = name
|
||||
document.body.appendChild(elink)
|
||||
elink.click()
|
||||
document.body.removeChild(elink)
|
||||
}
|
||||
@@ -1,42 +1,43 @@
|
||||
export function clamp(num, a, b) {
|
||||
return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));
|
||||
return Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b))
|
||||
}
|
||||
|
||||
export function capitalize(str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
||||
export function secondToTime(second) {
|
||||
if (!second) return '00:00';
|
||||
const add0 = (num) => (num < 10 ? `0${num}` : String(num));
|
||||
const hour = Math.floor(second / 3600);
|
||||
const min = Math.floor((second - hour * 3600) / 60);
|
||||
const sec = Math.floor(second - hour * 3600 - min * 60);
|
||||
return (hour > 0 ? [hour, min, sec] : [min, sec]).map(add0).join(':');
|
||||
if (!second)
|
||||
return '00:00'
|
||||
const add0 = num => (num < 10 ? `0${num}` : String(num))
|
||||
const hour = Math.floor(second / 3600)
|
||||
const min = Math.floor((second - hour * 3600) / 60)
|
||||
const sec = Math.floor(second - hour * 3600 - min * 60)
|
||||
return (hour > 0 ? [hour, min, sec] : [min, sec]).map(add0).join(':')
|
||||
}
|
||||
|
||||
export function escape(str) {
|
||||
return str.replace(
|
||||
/[&<>'"]/g,
|
||||
(tag) =>
|
||||
({
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
"'": ''',
|
||||
'"': '"',
|
||||
})[tag] || tag,
|
||||
);
|
||||
return str.replace(
|
||||
/[&<>'"]/g,
|
||||
tag =>
|
||||
({
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'\'': ''',
|
||||
'"': '"',
|
||||
})[tag] || tag,
|
||||
)
|
||||
}
|
||||
|
||||
export function unescape(str) {
|
||||
const map = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
''': "'",
|
||||
'"': '"',
|
||||
};
|
||||
const reg = new RegExp(`(${Object.keys(map).join('|')})`, 'g');
|
||||
return str.replace(reg, (tag) => map[tag] || tag);
|
||||
const map = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
''': '\'',
|
||||
'"': '"',
|
||||
}
|
||||
const reg = new RegExp(`(${Object.keys(map).join('|')})`, 'g')
|
||||
return str.replace(reg, tag => map[tag] || tag)
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
export * from './dom';
|
||||
export * from './error';
|
||||
export * from './subtitle';
|
||||
export * from './file';
|
||||
export * from './property';
|
||||
export * from './time';
|
||||
export * from './format';
|
||||
export * from './compatibility';
|
||||
export * from './compatibility'
|
||||
export * from './dom'
|
||||
export * from './error'
|
||||
export * from './file'
|
||||
export * from './format'
|
||||
export * from './property'
|
||||
export * from './subtitle'
|
||||
export * from './time'
|
||||
@@ -1,28 +1,30 @@
|
||||
export const def = Object.defineProperty;
|
||||
export const def = Object.defineProperty
|
||||
|
||||
const { hasOwnProperty } = Object.prototype;
|
||||
const { hasOwnProperty } = Object.prototype
|
||||
export function has(obj, name) {
|
||||
return hasOwnProperty.call(obj, name);
|
||||
return hasOwnProperty.call(obj, name)
|
||||
}
|
||||
|
||||
export function get(obj, name) {
|
||||
return Object.getOwnPropertyDescriptor(obj, name);
|
||||
return Object.getOwnPropertyDescriptor(obj, name)
|
||||
}
|
||||
|
||||
export function mergeDeep(...objects) {
|
||||
const isObject = (item) => item && typeof item === 'object' && !Array.isArray(item);
|
||||
return objects.reduce((prev, obj) => {
|
||||
Object.keys(obj).forEach((key) => {
|
||||
const pVal = prev[key];
|
||||
const oVal = obj[key];
|
||||
if (Array.isArray(pVal) && Array.isArray(oVal)) {
|
||||
prev[key] = pVal.concat(...oVal);
|
||||
} else if (isObject(pVal) && isObject(oVal)) {
|
||||
prev[key] = mergeDeep(pVal, oVal);
|
||||
} else {
|
||||
prev[key] = oVal;
|
||||
}
|
||||
});
|
||||
return prev;
|
||||
}, {});
|
||||
const isObject = item => item && typeof item === 'object' && !Array.isArray(item)
|
||||
return objects.reduce((prev, obj) => {
|
||||
Object.keys(obj).forEach((key) => {
|
||||
const pVal = prev[key]
|
||||
const oVal = obj[key]
|
||||
if (Array.isArray(pVal) && Array.isArray(oVal)) {
|
||||
prev[key] = pVal.concat(...oVal)
|
||||
}
|
||||
else if (isObject(pVal) && isObject(oVal)) {
|
||||
prev[key] = mergeDeep(pVal, oVal)
|
||||
}
|
||||
else {
|
||||
prev[key] = oVal
|
||||
}
|
||||
})
|
||||
return prev
|
||||
}, {})
|
||||
}
|
||||
@@ -1,99 +1,101 @@
|
||||
function fixSrt(srt) {
|
||||
return srt.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g, (_, $1, $2) => {
|
||||
let ms = $2.slice(0, 3);
|
||||
if ($2.length === 1) {
|
||||
ms = $2 + '00';
|
||||
}
|
||||
if ($2.length === 2) {
|
||||
ms = $2 + '0';
|
||||
}
|
||||
return `${$1},${ms}`;
|
||||
});
|
||||
return srt.replace(/(\d\d:\d\d:\d\d)[,.](\d+)/g, (_, $1, $2) => {
|
||||
let ms = $2.slice(0, 3)
|
||||
if ($2.length === 1) {
|
||||
ms = `${$2}00`
|
||||
}
|
||||
if ($2.length === 2) {
|
||||
ms = `${$2}0`
|
||||
}
|
||||
return `${$1},${ms}`
|
||||
})
|
||||
}
|
||||
|
||||
export function srtToVtt(srtText) {
|
||||
return 'WEBVTT \r\n\r\n'.concat(
|
||||
fixSrt(srtText)
|
||||
.replace(/\{\\([ibu])\}/g, '</$1>')
|
||||
.replace(/\{\\([ibu])1\}/g, '<$1>')
|
||||
.replace(/\{([ibu])\}/g, '<$1>')
|
||||
.replace(/\{\/([ibu])\}/g, '</$1>')
|
||||
.replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g, '$1.$2')
|
||||
.replace(/{[\s\S]*?}/g, '')
|
||||
.concat('\r\n\r\n'),
|
||||
);
|
||||
return 'WEBVTT \r\n\r\n'.concat(
|
||||
fixSrt(srtText)
|
||||
.replace(/\{\\([ibu])\}/g, '</$1>')
|
||||
.replace(/\{\\([ibu])1\}/g, '<$1>')
|
||||
.replace(/\{([ibu])\}/g, '<$1>')
|
||||
.replace(/\{\/([ibu])\}/g, '</$1>')
|
||||
.replace(/(\d\d:\d\d:\d\d),(\d\d\d)/g, '$1.$2')
|
||||
.replace(/\{[\s\S]*?\}/g, '')
|
||||
.concat('\r\n\r\n'),
|
||||
)
|
||||
}
|
||||
|
||||
export function vttToBlob(vttText) {
|
||||
return URL.createObjectURL(
|
||||
new Blob([vttText], {
|
||||
type: 'text/vtt',
|
||||
}),
|
||||
);
|
||||
return URL.createObjectURL(
|
||||
new Blob([vttText], {
|
||||
type: 'text/vtt',
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
export function assToVtt(ass) {
|
||||
const reAss = new RegExp(
|
||||
'Dialogue:\\s\\d,' +
|
||||
'(\\d+:\\d\\d:\\d\\d.\\d\\d),' +
|
||||
'(\\d+:\\d\\d:\\d\\d.\\d\\d),' +
|
||||
'([^,]*),' +
|
||||
'([^,]*),' +
|
||||
'(?:[^,]*,){4}' +
|
||||
'([\\s\\S]*)$',
|
||||
'i',
|
||||
);
|
||||
const reAss = new RegExp(
|
||||
'Dialogue:\\s\\d,'
|
||||
+ '(\\d+:\\d\\d:\\d\\d.\\d\\d),'
|
||||
+ '(\\d+:\\d\\d:\\d\\d.\\d\\d),'
|
||||
+ '([^,]*),'
|
||||
+ '([^,]*),'
|
||||
+ '(?:[^,]*,){4}'
|
||||
+ '([\\s\\S]*)$',
|
||||
'i',
|
||||
)
|
||||
|
||||
function fixTime(time = '') {
|
||||
return time
|
||||
.split(/[:.]/)
|
||||
.map((item, index, arr) => {
|
||||
if (index === arr.length - 1) {
|
||||
if (item.length === 1) {
|
||||
return `.${item}00`;
|
||||
}
|
||||
function fixTime(time = '') {
|
||||
return time
|
||||
.split(/[:.]/)
|
||||
.map((item, index, arr) => {
|
||||
if (index === arr.length - 1) {
|
||||
if (item.length === 1) {
|
||||
return `.${item}00`
|
||||
}
|
||||
|
||||
if (item.length === 2) {
|
||||
return `.${item}0`;
|
||||
}
|
||||
} else if (item.length === 1) {
|
||||
return (index === 0 ? '0' : ':0') + item;
|
||||
}
|
||||
if (item.length === 2) {
|
||||
return `.${item}0`
|
||||
}
|
||||
}
|
||||
else if (item.length === 1) {
|
||||
return (index === 0 ? '0' : ':0') + item
|
||||
}
|
||||
|
||||
return index === 0 ? item : index === arr.length - 1 ? `.${item}` : `:${item}`;
|
||||
})
|
||||
.join('');
|
||||
}
|
||||
return index === 0 ? item : index === arr.length - 1 ? `.${item}` : `:${item}`
|
||||
})
|
||||
.join('')
|
||||
}
|
||||
|
||||
return (
|
||||
'WEBVTT' +
|
||||
'\n' +
|
||||
'\n' +
|
||||
ass
|
||||
.split(/\r?\n/)
|
||||
.map((line) => {
|
||||
const m = line.match(reAss);
|
||||
if (!m) return null;
|
||||
return {
|
||||
start: fixTime(m[1].trim()),
|
||||
end: fixTime(m[2].trim()),
|
||||
text: m[5]
|
||||
.replace(/{[\s\S]*?}/g, '')
|
||||
.replace(/(\\N)/g, '\n')
|
||||
.trim()
|
||||
.split(/\r?\n/)
|
||||
.map((item) => item.trim())
|
||||
.join('\n'),
|
||||
};
|
||||
})
|
||||
.filter((line) => line)
|
||||
.map((line, index) => {
|
||||
if (line) {
|
||||
return index + 1 + '\n' + `${line.start} --> ${line.end}` + '\n' + `${line.text}`;
|
||||
}
|
||||
return '';
|
||||
})
|
||||
.filter((line) => line.trim())
|
||||
.join('\n\n')
|
||||
);
|
||||
return (
|
||||
`WEBVTT`
|
||||
+ `\n`
|
||||
+ `\n${
|
||||
ass
|
||||
.split(/\r?\n/)
|
||||
.map((line) => {
|
||||
const m = line.match(reAss)
|
||||
if (!m)
|
||||
return null
|
||||
return {
|
||||
start: fixTime(m[1].trim()),
|
||||
end: fixTime(m[2].trim()),
|
||||
text: m[5]
|
||||
.replace(/\{[\s\S]*?\}/g, '')
|
||||
.replace(/(\\N)/g, '\n')
|
||||
.trim()
|
||||
.split(/\r?\n/)
|
||||
.map(item => item.trim())
|
||||
.join('\n'),
|
||||
}
|
||||
})
|
||||
.filter(line => line)
|
||||
.map((line, index) => {
|
||||
if (line) {
|
||||
return `${index + 1}\n` + `${line.start} --> ${line.end}` + `\n` + `${line.text}`
|
||||
}
|
||||
return ''
|
||||
})
|
||||
.filter(line => line.trim())
|
||||
.join('\n\n')}`
|
||||
)
|
||||
}
|
||||
@@ -1,32 +1,32 @@
|
||||
export function sleep(ms = 0) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
return new Promise(resolve => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
export function debounce(func, duration) {
|
||||
let timeout;
|
||||
let timeout
|
||||
|
||||
return function (...args) {
|
||||
const effect = () => {
|
||||
timeout = null;
|
||||
return func.apply(this, args);
|
||||
};
|
||||
return function (...args) {
|
||||
const effect = () => {
|
||||
timeout = null
|
||||
return func.apply(this, args)
|
||||
}
|
||||
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(effect, duration);
|
||||
};
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(effect, duration)
|
||||
}
|
||||
}
|
||||
|
||||
export function throttle(func, duration) {
|
||||
let shouldWait = false;
|
||||
let shouldWait = false
|
||||
|
||||
return function (...args) {
|
||||
if (!shouldWait) {
|
||||
func.apply(this, args);
|
||||
shouldWait = true;
|
||||
return function (...args) {
|
||||
if (!shouldWait) {
|
||||
func.apply(this, args)
|
||||
shouldWait = true
|
||||
|
||||
setTimeout(function () {
|
||||
shouldWait = false;
|
||||
}, duration);
|
||||
}
|
||||
};
|
||||
setTimeout(() => {
|
||||
shouldWait = false
|
||||
}, duration)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user