组件添加add方法

This commit is contained in:
Harvey committed 2019-11-22 16:34:31 +08:00
1 parent 1d859e2049
commit 2fcd44e8e7
28 files changed
+303 -328

No files matched your search

+4 -9
View File
@@ -1,6 +1,5 @@
import { setStyle } from '../utils';
import Component from '../utils/components';
import component from '../utils/component';
import Component from '../utils/component';
import playbackRate from './playbackRate';
import aspectRatio from './aspectRatio';
import info from './info';
@@ -11,6 +10,8 @@ export default class Contextmenu extends Component {
constructor(art) {
super(art);
this.$parent = art.template.$contextmenu;
art.on('ready', () => {
const {
option,
@@ -65,7 +66,7 @@ export default class Contextmenu extends Component {
proxy($player, 'contextmenu', event => {
event.preventDefault();
this.show = true;
const mouseX = event.clientX;
const mouseY = event.clientY;
const { height: cHeight, width: cWidth, left: cLeft, top: cTop } = $player.getBoundingClientRect();
@@ -96,10 +97,4 @@ export default class Contextmenu extends Component {
this.show = false;
});
}
add(item, callback) {
this.id += 1;
const { $contextmenu } = this.art.template;
return component(this.art, this, $contextmenu, item, callback, 'contextmenu');
}
}
@@ -1,6 +1,5 @@
import { errorHandle, addClass } from '../utils';
import Component from '../utils/components';
import component from '../utils/component';
import Component from '../utils/component';
import fullscreen from './fullscreen';
import fullscreenWeb from './fullscreenWeb';
import pip from './pip';
@@ -14,10 +13,10 @@ import thumbnails from './thumbnails';
import screenshot from './screenshot';
import quality from './quality';
export default class Controls extends Component {
export default class Control extends Component {
constructor(art) {
super(art);
art.on('ready', () => {
const { option } = art;
@@ -135,27 +134,27 @@ export default class Controls extends Component {
});
}
add(item, callback) {
const option = typeof item === 'function' ? item(this.art) : item;
add(getOption, callback) {
const option = typeof getOption === 'function' ? getOption(this.art) : getOption;
errorHandle(option.position, 'Controls option.position can not be empty');
const { $progress, $controlsLeft, $controlsRight } = this.art.template;
let parent;
switch (option.position) {
case 'top':
parent = $progress;
this.$parent = $progress;
break;
case 'left':
parent = $controlsLeft;
this.$parent = $controlsLeft;
break;
case 'right':
parent = $controlsRight;
this.$parent = $controlsRight;
break;
default:
break;
}
this.id += 1;
errorHandle(option.position, 'Controls option.position can not be empty');
const control = component(this.art, this, parent, option, callback, 'control');
const control = super.add(option, callback);
if (
!option.disable &&
option.position !== 'top' &&
@@ -163,6 +162,7 @@ export default class Controls extends Component {
) {
addClass(control.$ref, 'art-control-onlyText');
}
return control;
}
}
File renamed without changes.
+4 -4
View File
@@ -8,13 +8,13 @@ import Whitelist from './whitelist';
import Template from './template';
import I18n from './i18n';
import Player from './player';
import Controls from './controls';
import Control from './control';
import Contextmenu from './contextmenu';
import Info from './info';
import Subtitle from './subtitle';
import Events from './events';
import Hotkey from './hotkey';
import Layers from './layers';
import Layer from './layer';
import Loading from './loading';
import Notice from './notice';
import Mask from './mask';
@@ -40,8 +40,8 @@ class Artplayer extends Emitter {
this.i18n = new I18n(this);
this.notice = new Notice(this);
this.player = new Player(this);
this.layers = new Layers(this);
this.controls = new Controls(this);
this.layers = new Layer(this);
this.controls = new Control(this);
this.contextmenu = new Contextmenu(this);
this.subtitle = new Subtitle(this);
this.info = new Info(this);
+1 -1
View File
@@ -1,5 +1,5 @@
import { queryAll } from './utils';
import Component from './utils/components';
import Component from './utils/component';
export default class Info extends Component {
constructor(art) {
+13
View File
@@ -0,0 +1,13 @@
import Component from './utils/component';
export default class Layer extends Component {
constructor(art) {
super(art);
this.$parent = art.template.$layers;
art.on('ready', () => {
art.option.layers.forEach(item => {
this.add(item);
});
});
}
}
-20
View File
@@ -1,20 +0,0 @@
import component from './utils/component';
import Component from './utils/components';
export default class Layers extends Component {
constructor(art) {
super(art);
this.add = this.add.bind(this);
this.art.on('ready', () => {
this.art.option.layers.forEach(item => {
this.add(item);
});
});
}
add(item, callback) {
this.id += 1;
const { $layers } = this.art.template;
return component(this.art, this, $layers, item, callback, 'layer');
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { append } from './utils';
import Component from './utils/components';
import Component from './utils/component';
export default class Loading extends Component {
constructor(art) {
+1 -1
View File
@@ -1,5 +1,5 @@
import { append } from './utils';
import Component from './utils/components';
import Component from './utils/component';
export default class Mask extends Component {
constructor(art) {
+8 -13
View File
@@ -1,5 +1,4 @@
import Component from '../utils/components';
import component from '../utils/component';
import Component from '../utils/component';
import flip from './flip';
import aspectRatio from './aspectRatio';
import playbackRate from './playbackRate';
@@ -8,14 +7,16 @@ export default class Setting extends Component {
constructor(art) {
super(art);
this.$parent = art.template.$settingBody;
const {
option,
template: { $setting },
events: { proxy },
} = this.art;
} = art;
if (art.option.setting) {
this.art.on('ready', () => {
art.on('ready', () => {
proxy($setting, 'click', e => {
if (e.target === $setting) {
this.show = false;
@@ -43,16 +44,10 @@ export default class Setting extends Component {
}),
);
});
this.art.on('blur', () => {
this.show = false;
});
}
}
add(item, callback) {
this.id += 1;
const { $settingBody } = this.art.template;
return component(this.art, this, $settingBody, item, callback, 'setting');
art.on('blur', () => {
this.show = false;
});
}
}
+12 -14
View File
@@ -1,5 +1,5 @@
import { setStyles, srtToVtt, vttToBlob, getExt, assToVtt } from './utils';
import Component from './utils/components';
import Component from './utils/component';
export default class Subtitle extends Component {
constructor(art) {
@@ -12,7 +12,17 @@ export default class Subtitle extends Component {
} = art;
setStyles($subtitle, subtitle.style);
proxy(this.textTrack, 'cuechange', this.update.bind(this));
proxy(this.textTrack, 'cuechange', () => {
$subtitle.innerHTML = '';
if (this.activeCue) {
$subtitle.innerHTML = this.activeCue.text
.split(/\r?\n/)
.map(item => `<p>${item}</p>`)
.join('');
art.emit('subtitle:update', this.activeCue.text);
}
});
if (subtitle.url) {
this.init(subtitle.url);
@@ -31,18 +41,6 @@ export default class Subtitle extends Component {
return this.textTrack.activeCues[0];
}
update() {
const { $subtitle } = this.art.template;
$subtitle.innerHTML = '';
if (this.activeCue) {
$subtitle.innerHTML = this.activeCue.text
.split(/\r?\n/)
.map(item => `<p>${item}</p>`)
.join('');
this.art.emit('subtitle:update', this.activeCue.text);
}
}
switch(url, name = 'unknown') {
const { i18n, notice } = this.art;
return this.init(url).then(subUrl => {
+83 -60
View File
@@ -1,73 +1,96 @@
import { append, setStyles, setStyle, tooltip } from './dom';
import { hasClass, addClass, removeClass, append, setStyle, setStyles, tooltip } from './dom';
import { hasOwnProperty, defineProperty } from './property';
import { errorHandle } from './error';
import { hasOwnProperty } from './property';
export default function component(art, parent, target, getOption, callback, title) {
const option = typeof getOption === 'function' ? getOption(art) : getOption;
if (option.disable) return {};
const componentID = parent.id;
const name = option.name || `${title}${componentID}`;
errorHandle(
!hasOwnProperty(parent, name),
`Cannot create a component that already has the same name: ${title} -> ${name}`,
);
const $element = document.createElement('div');
$element.classList.value = `art-${title} art-${title}-${name}`;
if (option.html) {
append($element, option.html);
export default class Component {
constructor(art) {
this.id = 0;
this.art = art;
this.add = this.add.bind(this);
this.name = this.constructor.name.toLowerCase();
}
if (option.style) {
setStyles($element, option.style);
get show() {
return hasClass(this.art.template.$player, `art-${this.name}-show`);
}
if (option.tooltip) {
tooltip($element, option.tooltip);
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) {
addClass($player, className);
} else {
removeClass($player, className);
}
this.art.emit(`${this.name}:toggle`, value);
}
const childs = Array.from(target.children);
$element.dataset.index = option.index || componentID;
const nextChild = childs.find(item => Number(item.dataset.index) >= Number($element.dataset.index));
if (nextChild) {
nextChild.insertAdjacentElement('beforebegin', $element);
} else {
append(target, $element);
toggle() {
this.show = !this.show;
}
if (option.click) {
art.events.proxy($element, 'click', event => {
event.preventDefault();
option.click.call(art, parent, event);
add(getOption, callback) {
const option = typeof getOption === 'function' ? getOption(this.art) : getOption;
if (!this.$parent || option.disable) return {};
this.id += 1;
const name = option.name || `${this.name}${this.id}`;
errorHandle(!hasOwnProperty(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}`;
if (option.html) {
append($ref, option.html);
}
if (option.style) {
setStyles($ref, option.style);
}
if (option.tooltip) {
tooltip($ref, option.tooltip);
}
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.click) {
this.art.events.proxy($ref, 'click', event => {
event.preventDefault();
option.click.call(this.art, this, event);
});
}
if (option.mounted) {
option.mounted($ref, this, this.art);
}
if (callback) {
callback($ref, this, this.art);
}
defineProperty(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];
}
if (option.mounted) {
option.mounted($element, parent, art);
}
if (callback) {
callback($element, parent, art);
}
Object.defineProperty(parent, name, {
value: {
get id() {
return componentID;
},
get $ref() {
return $element;
},
set show(value) {
if (value) {
setStyle($element, 'display', 'block');
} else {
setStyle($element, 'display', 'none');
}
},
},
});
art.emit(`${title}:add`, option);
return parent[name];
}
@@ -1,30 +0,0 @@
import { hasClass, addClass, removeClass } from './dom';
import { errorHandle } from './error';
export default class Component {
constructor(art) {
this.id = 0;
this.art = art;
this.$player = art.template.$player;
this.name = this.constructor.name.toLowerCase();
this.showClassName = `art-${this.name}-show`;
}
get show() {
return hasClass(this.$player, this.showClassName);
}
set show(value) {
errorHandle(value === false || value === true, 'The show attribute expects a boolean value');
if (value) {
addClass(this.$player, this.showClassName);
} else {
removeClass(this.$player, this.showClassName);
}
this.art.emit(`${this.name}:toggle`, value);
}
toggle() {
this.show = !this.show;
}
}