压缩字符

This commit is contained in:
Harvey committed 2019-11-27 15:46:55 +08:00
1 parent 2df60a78ff
commit 5f40463713
40 files changed
+385 -481

No files matched your search

+12 -10
View File
@@ -153,16 +153,18 @@ export default class Control extends Component {
break;
}
const control = super.add(option, callback);
super.add(option, $ref => {
if (
!option.disable &&
option.position !== 'top' &&
!($ref.firstElementChild && $ref.firstElementChild.tagName === 'I')
) {
addClass($ref, 'art-control-onlyText');
}
if (
!option.disable &&
option.position !== 'top' &&
!(control.$ref.firstElementChild && control.$ref.firstElementChild.tagName === 'I')
) {
addClass(control.$ref, 'art-control-onlyText');
}
return control;
if (callback) {
callback($ref, this, this.art);
}
});
}
}
+5 -6
View File
@@ -11,7 +11,7 @@ export default class Events {
this.loadImg = this.loadImg.bind(this);
if (art.whitelist.state) {
art.once('video:canplay', () => {
art.on('ready', () => {
clickInit(art, this);
hoverInit(art, this);
mousemoveInit(art, this);
@@ -22,14 +22,13 @@ export default class Events {
proxy(target, name, callback, option = {}) {
if (Array.isArray(name)) {
name.forEach(item => this.proxy(target, item, callback, option));
return;
return name.map(item => this.proxy(target, item, callback, option));
}
target.addEventListener(name, callback, option);
this.destroyEvents.push(() => {
target.removeEventListener(name, callback, option);
});
const destroy = () => target.removeEventListener(name, callback, option);
this.destroyEvents.push(destroy);
return destroy;
}
hover(target, mouseenter, mouseleave) {
+1 -1
View File
@@ -1,6 +1,6 @@
import './style';
import validator from 'option-validator';
import Emitter from './emitter';
import Emitter from './utils/emitter';
import * as utils from './utils';
import scheme from './scheme';
import config from './config';
+1 -1
View File
@@ -24,7 +24,7 @@ export default class Info extends Component {
function loop() {
types.forEach(item => {
const value = $video[item.dataset.video];
item.innerHTML = typeof value === 'number' ? value.toFixed(2) : value;
item.innerText = typeof value === 'number' ? value.toFixed(2) : value;
});
timer = setTimeout(() => {
loop();
+7 -16
View File
@@ -3,26 +3,17 @@ import { addClass, removeClass } from './utils';
export default class Notice {
constructor(art) {
this.art = art;
this.time = 1000;
this.timer = null;
}
show(msg, autoHide = true, time = 1000) {
set show(msg) {
const { $player, $noticeInner } = this.art.template;
$noticeInner.innerHTML = msg instanceof Error ? msg.message.trim() : msg;
clearTimeout(this.timer);
if (autoHide) {
this.timer = setTimeout(() => {
this.hide();
}, time);
}
$noticeInner.innerText = msg instanceof Error ? msg.message.trim() : msg;
addClass($player, 'art-notice-show');
this.art.emit('notice:toggle', true);
}
hide() {
const { $player, $noticeInner } = this.art.template;
$noticeInner.innerHTML = '';
removeClass($player, 'art-notice-show');
this.art.emit('notice:toggle', true);
clearTimeout(this.timer);
this.timer = setTimeout(() => {
removeClass($player, 'art-notice-show');
}, this.time);
}
}
@@ -41,7 +41,7 @@ export default function aspectRatioMix(art, player) {
}
$player.dataset.aspectRatio = ratio;
notice.show(`${i18n.get('Aspect ratio')}: ${ratio === 'default' ? i18n.get('Default') : ratio}`);
notice.show = `${i18n.get('Aspect ratio')}: ${ratio === 'default' ? i18n.get('Default') : ratio}`;
art.emit('aspectRatioChange', ratio);
} else if (player.aspectRatio) {
setStyle($video, 'width', null);
@@ -10,9 +10,6 @@ export default function attachUrlMix(art, player) {
get() {
return $video.src;
},
set() {
errorHandle(false, 'You should use this method: art.attachUrl()');
},
});
def(player, 'attachUrl', {
+2 -2
View File
@@ -64,14 +64,14 @@ export default function eventInit(art, player) {
sleep(1000).then(() => {
reconnectTime += 1;
player.attachUrl(option.url);
notice.show(`${i18n.get('Reconnect')}: ${reconnectTime}`);
notice.show = `${i18n.get('Reconnect')}: ${reconnectTime}`;
});
} else {
art.loading.show = false;
art.controls.show = false;
addClass($player, 'art-error');
sleep(1000).then(() => {
notice.show(i18n.get('Video load failed'), false);
notice.show = i18n.get('Video load failed');
art.destroy();
});
}
@@ -14,7 +14,7 @@ export default function fullscreenMix(art, player) {
};
const screenfullError = () => {
notice.show(i18n.get('Does not support fullscreen'));
notice.show = i18n.get('Does not support fullscreen');
};
if (player.fullscreenIsEnabled) {
+1 -1
View File
@@ -14,7 +14,7 @@ export default function pauseMin(art, player) {
set(value) {
if (value) {
$video.pause();
notice.show(i18n.get('Pause'));
notice.show = i18n.get('Pause');
art.emit('pause');
} else {
player.play = true;
+6 -6
View File
@@ -15,14 +15,14 @@ function nativePip(art, player) {
},
set(value) {
if (value) {
$video.requestPictureInPicture().catch(error => {
notice.show(error);
throw error;
$video.requestPictureInPicture().catch(err => {
notice.show = err;
throw err;
});
} else {
document.exitPictureInPicture().catch(error => {
notice.show(error);
throw error;
document.exitPictureInPicture().catch(err => {
notice.show = err;
throw err;
});
}
},
+3 -3
View File
@@ -2,10 +2,10 @@ import { def } from '../utils';
export default function playMix(art, player) {
const {
template: { $video },
i18n,
notice,
option: { mutex },
template: { $video },
} = art;
def(player, 'play', {
@@ -14,7 +14,7 @@ export default function playMix(art, player) {
const promise = $video.play();
if (promise !== undefined) {
promise.then().catch(err => {
notice.show(err, true, 3000);
notice.show = err;
throw err;
});
}
@@ -27,7 +27,7 @@ export default function playMix(art, player) {
});
}
notice.show(i18n.get('Play'));
notice.show = i18n.get('Play');
art.emit('play');
} else {
player.pause = true;
@@ -13,16 +13,12 @@ export default function playbackRateMix(art, player) {
},
set(rate) {
if (rate) {
if (rate === $player.dataset.playbackRate) return;
const rateList = [0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0];
errorHandle(rateList.includes(rate), `'playbackRate' only accept ${rateList.toString()} as parameters`);
if (rate === $player.dataset.playbackRate) {
return;
}
$video.playbackRate = rate;
$player.dataset.playbackRate = rate;
notice.show(`${i18n.get('Rate')}: ${rate === 1.0 ? i18n.get('Normal') : `${rate}x`}`);
notice.show = `${i18n.get('Rate')}: ${rate === 1.0 ? i18n.get('Normal') : `${rate}x`}`;
art.emit('playbackRateChange', rate);
} else if (player.playbackRate) {
player.playbackRate = 1;
@@ -15,9 +15,9 @@ export default function screenshotMix(art, player) {
canvas.height = $video.videoHeight;
canvas.getContext('2d').drawImage($video, 0, 0);
return canvas.toDataURL('image/png');
} catch (error) {
notice.show(error);
throw error;
} catch (err) {
notice.show = err;
throw err;
}
},
});
@@ -33,9 +33,9 @@ export default function screenshotMix(art, player) {
canvas.toBlob(blob => {
resolve(URL.createObjectURL(blob));
});
} catch (error) {
notice.show(error);
reject(error);
} catch (err) {
notice.show = err;
reject(err);
}
}),
});
+1 -1
View File
@@ -6,7 +6,7 @@ export default function seekMix(art, player) {
def(player, 'seek', {
set(time) {
player.currentTime = time;
notice.show(`${secondToTime(time)} / ${secondToTime(player.duration)}`);
notice.show = `${secondToTime(time)} / ${secondToTime(player.duration)}`;
art.emit('seek', time);
},
});
+22 -40
View File
@@ -3,53 +3,35 @@ import { def } from '../utils';
export default function switchMix(art, player) {
const { i18n, notice, option } = art;
function switchUrl(url, name, currentTime) {
if (url === player.url) return Promise.resolve(url);
URL.revokeObjectURL(player.url);
return player.attachUrl(url).then(() => {
option.url = url;
player.playbackRate = false;
player.aspectRatio = false;
art.once('video:canplay', () => {
player.currentTime = currentTime;
});
if (player.playing) {
player.play = true;
}
if (name) {
notice.show = `${i18n.get('Switch video')}: ${name}`;
}
art.emit('switch', url);
});
}
def(player, 'switchQuality', {
value: (url, name) => {
if (url !== player.url) {
URL.revokeObjectURL(player.url);
const { currentTime, playing } = player;
return player.attachUrl(url).then(() => {
option.url = url;
player.playbackRate = false;
player.aspectRatio = false;
art.on('ready', () => {
player.currentTime = currentTime;
});
if (playing) {
player.play = true;
}
if (name) {
notice.show(`${i18n.get('Switch video')}: ${name}`);
}
art.emit('switch', url);
});
}
return null;
return switchUrl(url, name, player.currentTime);
},
});
def(player, 'switchUrl', {
value: (url, name) => {
if (url !== player.url) {
URL.revokeObjectURL(player.url);
const { playing } = player;
return player.attachUrl(url).then(() => {
option.url = url;
player.playbackRate = false;
player.aspectRatio = false;
art.on('ready', () => {
player.currentTime = 0;
});
if (playing) {
player.play = true;
}
if (name) {
notice.show(`${i18n.get('Switch video')}: ${name}`);
}
art.emit('switch', url);
});
}
return null;
return switchUrl(url, name, 0);
},
});
}
+1 -1
View File
@@ -12,7 +12,7 @@ export default function volumeMix(art, player) {
get: () => $video.volume || 0,
set: percentage => {
$video.volume = clamp(percentage, 0, 1);
notice.show(`${i18n.get('Volume')}: ${parseInt($video.volume * 100, 10)}`);
notice.show = `${i18n.get('Volume')}: ${parseInt($video.volume * 100, 10)}`;
if ($video.volume !== 0) {
storage.set('volume', $video.volume);
}
@@ -66,13 +66,13 @@ export default function localSubtitle(art) {
name: 'localSubtitle',
index: 40,
html: `
<div class="art-setting-header">
${i18n.get('Local Subtitle')}
</div>
<div class="art-setting-upload">
<div class="art-upload-btn">${i18n.get('Open')}</div>
<div class="art-upload-value"></div>
</div>
<div class="art-setting-header">
${i18n.get('Local Subtitle')}
</div>
<div class="art-setting-upload">
<div class="art-upload-btn">${i18n.get('Open')}</div>
<div class="art-upload-value"></div>
</div>
`,
mounted: $setting => {
const $btn = query('.art-upload-btn', $setting);
+7 -7
View File
@@ -57,13 +57,13 @@ export default function localVideo(art) {
name: 'localVideo',
index: 30,
html: `
<div class="art-setting-header">
${i18n.get('Local Video')}
</div>
<div class="art-setting-upload">
<div class="art-upload-btn">${i18n.get('Open')}</div>
<div class="art-upload-value"></div>
</div>
<div class="art-setting-header">
${i18n.get('Local Video')}
</div>
<div class="art-setting-upload">
<div class="art-upload-btn">${i18n.get('Open')}</div>
<div class="art-upload-value"></div>
</div>
`,
mounted: $setting => {
const $btn = query('.art-upload-btn', $setting);
@@ -12,12 +12,12 @@ function settingMix(art) {
name: 'subtitleOffset',
index: 20,
html: `
<div class="art-setting-header">
${i18n.get('Subtitle offset time')}: <span class="art-subtitle-value">0</span>s
</div>
<div class="art-setting-range">
<input class="art-subtitle-range" value="0" type="range" min="-5" max="5" step="0.5">
</div>
<div class="art-setting-header">
${i18n.get('Subtitle offset time')}: <span class="art-subtitle-value">0</span>s
</div>
<div class="art-setting-range">
<input class="art-subtitle-range" value="0" type="range" min="-5" max="5" step="0.5">
</div>
`,
mounted: $setting => {
const $range = query('.art-setting-range input', $setting);
@@ -70,10 +70,10 @@ export default function subtitleOffset(art) {
cue.startTime = clamp(cuesCache[index].startTime + time, 0, player.duration);
cue.endTime = clamp(cuesCache[index].endTime + time, 0, player.duration);
});
notice.show(`${i18n.get('Subtitle offset time')}: ${value}s`);
notice.show = `${i18n.get('Subtitle offset time')}: ${value}s`;
art.emit('subtitleOffset', value);
} else {
notice.show(`${i18n.get('No subtitles found')}`);
notice.show = `${i18n.get('No subtitles found')}`;
art.emit('subtitleOffset', 0);
}
},
+12 -12
View File
@@ -6,18 +6,18 @@ export default function aspectRatio(option) {
return {
...option,
html: `
<div class="art-setting-header">${i18n.get('Aspect ratio')}</div>
<div class="art-setting-radio">
<div class="art-radio-item current">
<button type="button" data-value="default">${i18n.get('Default')}</button>
</div>
<div class="art-radio-item">
<button type="button" data-value="4:3">4:3</button>
</div>
<div class="art-radio-item">
<button type="button" data-value="16:9">16:9</button>
</div>
</div>
<div class="art-setting-header">${i18n.get('Aspect ratio')}</div>
<div class="art-setting-radio">
<div class="art-radio-item current">
<button type="button" data-value="default">${i18n.get('Default')}</button>
</div>
<div class="art-radio-item">
<button type="button" data-value="4:3">4:3</button>
</div>
<div class="art-radio-item">
<button type="button" data-value="16:9">16:9</button>
</div>
</div>
`,
click: (setting, event) => {
const { value } = event.target.dataset;
+12 -12
View File
@@ -6,18 +6,18 @@ export default function flip(option) {
return {
...option,
html: `
<div class="art-setting-header">${i18n.get('Flip')}</div>
<div class="art-setting-radio">
<div class="art-radio-item current">
<button type="button" data-value="normal">${i18n.get('Normal')}</button>
</div>
<div class="art-radio-item">
<button type="button" data-value="horizontal">${i18n.get('Horizontal')}</button>
</div>
<div class="art-radio-item">
<button type="button" data-value="vertical">${i18n.get('Vertical')}</button>
</div>
</div>
<div class="art-setting-header">${i18n.get('Flip')}</div>
<div class="art-setting-radio">
<div class="art-radio-item current">
<button type="button" data-value="normal">${i18n.get('Normal')}</button>
</div>
<div class="art-radio-item">
<button type="button" data-value="horizontal">${i18n.get('Horizontal')}</button>
</div>
<div class="art-radio-item">
<button type="button" data-value="vertical">${i18n.get('Vertical')}</button>
</div>
</div>
`,
click: (setting, event) => {
const { value } = event.target.dataset;
@@ -10,12 +10,12 @@ export default function playbackRate(option) {
return {
...option,
html: `
<div class="art-setting-header">
${i18n.get('Play speed')}: <span class="art-subtitle-value">1.0</span>x
</div>
<div class="art-setting-range">
<input class="art-subtitle-range" value="1" type="range" min="0.5" max="2" step="0.25">
</div>
<div class="art-setting-header">
${i18n.get('Play speed')}: <span class="art-subtitle-value">1.0</span>x
</div>
<div class="art-setting-range">
<input class="art-subtitle-range" value="1" type="range" min="0.5" max="2" step="0.25">
</div>
`,
mounted: $setting => {
const $range = query('.art-setting-range input', $setting);
+5 -7
View File
@@ -1,17 +1,15 @@
export default class Storage {
constructor(art) {
this.art = art;
this.name = 'artplayer_settings';
const { option } = art;
const volume = this.get('volume');
if (volume) {
option.volume = volume;
art.option.volume = volume;
}
}
get(key) {
const storage = JSON.parse(window.localStorage.getItem(this.name)) || {};
const storage = JSON.parse(localStorage.getItem(this.name)) || {};
return key ? storage[key] : {};
}
@@ -19,16 +17,16 @@ export default class Storage {
const storage = Object.assign({}, this.get(), {
[key]: value,
});
window.localStorage.setItem(this.name, JSON.stringify(storage));
localStorage.setItem(this.name, JSON.stringify(storage));
}
del(key) {
const storage = this.get();
delete storage[key];
window.localStorage.setItem(this.name, JSON.stringify(storage));
localStorage.setItem(this.name, JSON.stringify(storage));
}
clean() {
window.localStorage.removeItem(this.name);
localStorage.removeItem(this.name);
}
}
+2 -2
View File
@@ -47,7 +47,7 @@ export default class Subtitle extends Component {
const { i18n, notice } = this.art;
return this.init(url).then(subUrl => {
if (name) {
notice.show(`${i18n.get('Switch subtitle')}: ${name}`);
notice.show = `${i18n.get('Switch subtitle')}: ${name}`;
}
this.art.emit('subtitle:switch', subUrl);
return subUrl;
@@ -85,7 +85,7 @@ export default class Subtitle extends Component {
return subUrl;
})
.catch(err => {
notice.show(err);
notice.show = err;
this.art.emit('subtitle:err', err);
throw err;
});
+66 -66
View File
@@ -34,69 +34,69 @@ export default class Template {
initDesktop() {
this.$container.innerHTML = `
<div class="art-video-player art-subtitle-show art-layer-show" style="--theme: ${this.art.option.theme}">
<video class="art-video">
<track default kind="metadata"></track>
</video>
<div class="art-subtitle"></div>
<div class="art-danmuku"></div>
<div class="art-layers"></div>
<div class="art-mask">
<div class="art-state"></div>
</div>
<div class="art-bottom">
<div class="art-progress"></div>
<div class="art-controls">
<div class="art-controls-left"></div>
<div class="art-controls-right"></div>
</div>
</div>
<div class="art-loading"></div>
<div class="art-notice">
<div class="art-notice-inner"></div>
</div>
<div class="art-settings">
<div class="art-setting-inner art-backdrop-filter">
<div class="art-setting-body"></div>
</div>
</div>
<div class="art-info art-backdrop-filter">
<div class="art-info-panel">
<div class="art-info-item">
<div class="art-info-title">Player version:</div>
<div class="art-info-content">__VERSION__</div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video url:</div>
<div class="art-info-content" data-video="src"></div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video volume:</div>
<div class="art-info-content" data-video="volume"></div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video time:</div>
<div class="art-info-content" data-video="currentTime"></div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video duration:</div>
<div class="art-info-content" data-video="duration"></div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video resolution:</div>
<div class="art-info-content">
<span data-video="videoWidth"></span> x <span data-video="videoHeight"></span>
</div>
</div>
</div>
<div class="art-info-close">[x]</div>
</div>
<div class="art-pip-header">
<div class="art-pip-title"></div>
<div class="art-pip-close">×</div>
</div>
<div class="art-contextmenus art-backdrop-filter"></div>
</div>
<div class="art-video-player art-subtitle-show art-layer-show" style="--theme: ${this.art.option.theme}">
<video class="art-video">
<track default kind="metadata"></track>
</video>
<div class="art-subtitle"></div>
<div class="art-danmuku"></div>
<div class="art-layers"></div>
<div class="art-mask">
<div class="art-state"></div>
</div>
<div class="art-bottom">
<div class="art-progress"></div>
<div class="art-controls">
<div class="art-controls-left"></div>
<div class="art-controls-right"></div>
</div>
</div>
<div class="art-loading"></div>
<div class="art-notice">
<div class="art-notice-inner"></div>
</div>
<div class="art-settings">
<div class="art-setting-inner art-backdrop-filter">
<div class="art-setting-body"></div>
</div>
</div>
<div class="art-info art-backdrop-filter">
<div class="art-info-panel">
<div class="art-info-item">
<div class="art-info-title">Player version:</div>
<div class="art-info-content">__VERSION__</div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video url:</div>
<div class="art-info-content" data-video="src"></div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video volume:</div>
<div class="art-info-content" data-video="volume"></div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video time:</div>
<div class="art-info-content" data-video="currentTime"></div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video duration:</div>
<div class="art-info-content" data-video="duration"></div>
</div>
<div class="art-info-item">
<div class="art-info-title">Video resolution:</div>
<div class="art-info-content">
<span data-video="videoWidth"></span> x <span data-video="videoHeight"></span>
</div>
</div>
</div>
<div class="art-info-close">[x]</div>
</div>
<div class="art-pip-header">
<div class="art-pip-title"></div>
<div class="art-pip-close">×</div>
</div>
<div class="art-contextmenus art-backdrop-filter"></div>
</div>
`;
this.$player = this.query('.art-video-player');
this.$video = this.query('.art-video');
@@ -128,9 +128,9 @@ export default class Template {
initMobile() {
this.$container.innerHTML = `
<div class="art-video-player">
<video class="art-video"></video>
</div>
<div class="art-video-player">
<video class="art-video"></video>
</div>
`;
this.$player = this.query('.art-video-player');
this.$video = this.query('.art-video');
+2 -22
View File
@@ -1,6 +1,4 @@
import { hasClass, addClass, removeClass, append, setStyle, setStyles, tooltip } from './dom';
import { has, def } from './property';
import { errorHandle } from './error';
import { hasClass, addClass, removeClass, append, setStyles, tooltip } from './dom';
export default class Component {
constructor(art) {
@@ -15,7 +13,6 @@ export default class Component {
}
set show(value) {
errorHandle(value === false || value === true, 'The show attribute expects a boolean value');
const { $player } = this.art.template;
const className = `art-${this.name}-show`;
if (value) {
@@ -32,10 +29,9 @@ export default class Component {
add(getOption, callback) {
const option = typeof getOption === 'function' ? getOption(this.art) : getOption;
if (!this.$parent || option.disable) return {};
if (!this.$parent || option.disable) return;
this.id += 1;
const name = option.name || `${this.name}${this.id}`;
errorHandle(!has(this, name), `Cannot add a component that already has the same name: ${name}`);
const $ref = document.createElement('div');
$ref.classList.value = `art-${this.name} art-${this.name}-${name}`;
@@ -75,22 +71,6 @@ export default class Component {
callback($ref, this, this.art);
}
def(this, name, {
value: {
get $ref() {
return $ref;
},
set show(value) {
if (value) {
setStyle($ref, 'display', 'block');
} else {
setStyle($ref, 'display', 'none');
}
},
},
});
this.art.emit(`${this.name}:add`, option);
return this[name];
}
}
File renamed without changes.
+9 -7
View File
@@ -1,20 +1,22 @@
export default class Whitelist {
constructor(art) {
const { kindOf } = art.constructor;
const { whitelist } = art.option;
this.userAgent = window.navigator.userAgent;
this.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(this.userAgent);
const {
constructor: { kindOf },
option: { whitelist },
} = art;
this.ua = window.navigator.userAgent;
this.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(this.ua);
this.state =
!this.isMobile ||
whitelist.some(item => {
const type = kindOf(item);
switch (type) {
case 'string':
return this.userAgent.indexOf(item) > -1;
return this.ua.indexOf(item) > -1;
case 'function':
return item(this.userAgent);
return item(this.ua);
case 'regexp':
return item.test(this.userAgent);
return item.test(this.ua);
default:
return false;
}