Skip to content

Commit

Permalink
[update] put common function of dispatcher and chimee together
Browse files Browse the repository at this point in the history
what: move function like $emit, $on, $off etc to videoWrapper
why: keep it dry
how:
  • Loading branch information
toxic-johann committed Jul 28, 2017
1 parent 315634e commit 2b69dd9
Show file tree
Hide file tree
Showing 12 changed files with 294 additions and 224 deletions.
8 changes: 4 additions & 4 deletions __tests__/dispatcher/plugin.js
Expand Up @@ -329,7 +329,7 @@ describe('dispatcher/plugin', () => {
const pluginE = new Plugin({
id: 'e'
}, dispatcher);
expect(() => pluginE.$emit()).toThrow('$emit key parameter must be String');
expect(() => pluginE.$emit()).toThrow('emit key parameter must be String');
pluginE.$emit('click');
pluginE.$emit('xx_click');
pluginE.$destroy();
Expand All @@ -339,7 +339,7 @@ describe('dispatcher/plugin', () => {
const pluginE = new Plugin({
id: 'e'
}, dispatcher);
expect(() => pluginE.$emitSync()).toThrow('$emitSync key parameter must be String');
expect(() => pluginE.$emitSync()).toThrow('emitSync key parameter must be String');
expect(pluginE.$emitSync('hello')).toBe(true);
pluginE.$destroy();
});
Expand Down Expand Up @@ -542,8 +542,8 @@ describe('dispatcher/plugin', () => {
test('$attr on video property', () => {
plugin.$attr('video', 'controls', true);
expect(plugin.$attr('video', 'controls')).toBe(null);
expect(Log.data.warn[0]).toEqual([ 'plugin',
'Plugin normal is tring to set attribute on video before video inited. Please wait until the inited event has benn trigger' ]);
expect(Log.data.warn[0]).toEqual([ 'chimee',
'normal is tring to set attribute on video before video inited. Please wait until the inited event has benn trigger' ]);
dispatcher.videoConfigReady = true;
plugin.$attr('video', 'controls', true);
expect(plugin.$attr('video', 'controls')).toBe('');
Expand Down
2 changes: 1 addition & 1 deletion demo/base/index.js
Expand Up @@ -51,7 +51,7 @@
hls: window.chimeeKernelHls
},
volume: 0.1,
autoplay: true,
// autoplay: true,
controls: true
});
window.player = player;
Expand Down
3 changes: 3 additions & 0 deletions demo/silentload/README.md
@@ -0,0 +1,3 @@
# Base demo of Chimee

You can use this base demo to know how Chimee work.
57 changes: 57 additions & 0 deletions demo/silentload/index.css
@@ -0,0 +1,57 @@
html, body {
width: 100%;
margin: 0;
padding: 0;
}
html {
background-color: #FFFBE6;
font-family: "Oswald", "HelveticaNeue-CondensedBold", "Arial Narrow", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
background-repeat: no-repeat;
min-height: 100%;
}
body {
padding: 10px;
box-sizing: border-box;
color: #36384A;
max-width: 800px;
margin: auto;
}
#wrapper {
position: relative;
width: 100%;
height: 100%;
}
container {
position: relative;
display: block;
width: 100%;
height: 100%;
}
video {
width: 100%;
height: 100%;
display: block;
background-color: #000;
}
button {
color: #fff;
background-color: #3F4F68;
padding: 6px 12px;
text-decoration: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
border-radius: 4px;
text-transform: none;
outline: none;
border: none;
margin-bottom: 2px;
}
h1 {
color: #9D295A;
}
button:active {
background-color: #36384A;
}

23 changes: 23 additions & 0 deletions demo/silentload/index.html
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title>Simplest Demo</title>
<meta charset="utf-8">
<meta name="description" content="Chimee Player Demo">
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1, maximum-scale=1">
<meta name="mobile-web-app-capable" content="yes">
<link rel="stylesheet" type="text/css" href="./index.css">
</head>
<body>
<header>
<h1>Simplest Demo</h1>
<p>The simplest demo for Chimee with only one button</p>
</header>
<section id="wrapper"></section>
</body>
<script type="text/javascript" src="/lib/index.dev.js"></script>
<script type="text/javascript" src="/node_modules/chimee-kernel-flv/lib/index.browser.js"></script>
<script type="text/javascript" src="/node_modules/chimee-kernel-hls/lib/index.browser.js"></script>
<!--<script type="text/javascript" src="/lib/player.umd.js"></script>-->
<script type="text/javascript" src="./index.js"></script>
</html>
43 changes: 43 additions & 0 deletions demo/silentload/index.js
@@ -0,0 +1,43 @@
// const Chimee = window.Chimee;
// const nativeSwtich = {
// name: 'native-switch',
// // 插件实体为按钮
// el: '<button>native switch</button>',
// // 在插件创建的阶段,我们为插件绑定事件。
// create () {
// this.$dom.addEventListener('click', () => {
// this.
// });
// },
// // 插件会在播放暂停操作发生后改变自己的文案及相应的行为
// events: {
// pause () {
// this.changeButtonText('play');
// },
// play () {
// this.changeButtonText('pause');
// },
// c_contextmenu (evt) {
// console.log(evt);
// }
// }
// };
// Chimee.install(plugin);
// const player = new Chimee({
// // 播放地址
// src: 'http://cdn.toxicjohann.com/lostStar.mp4',
// // src: 'http://cdn.toxicjohann.com/%E4%BA%8E%E6%98%AF.mp4',
// // src: 'http://yunxianchang.live.ujne7.com/vod-system-bj/TL1ce1196bce348070bfeef2116efbdea6.flv',
// // src: 'http://yunxianchang.live.ujne7.com/vod-system-bj/79_3041054cc65-ae8c-4b63-8937-5ccb05f79720.m3u8',
// // dom容器
// wrapper: '#wrapper',
// plugin: ['controller'],
// preset: {
// flv: window.chimeeKernelFlv,
// hls: window.chimeeKernelHls
// },
// volume: 0.1,
// // autoplay: true,
// controls: true
// });
// window.player = player;
2 changes: 1 addition & 1 deletion flow/base.js
@@ -1,4 +1,4 @@
import type Plugin from 'dispatcher/index';
import type Plugin from 'dispatcher/plugin';
import type Dispatcher from 'dispatcher/index';
import type Bus from 'dispatcher/bus';
import type Dom from 'dispatcher/dom';
Expand Down
14 changes: 10 additions & 4 deletions src/dispatcher/bus.js
@@ -1,6 +1,6 @@
// @flow
import {isEmpty, isArray, runRejectableQueue, runStoppableQueue, camelize, bind, isError, isVoid, isFunction, deepClone, Log} from 'chimee-helper';
import {videoEvents, kernelMethods, domEvents, domMethods} from 'helper/const';
import {videoEvents, kernelMethods, domEvents, domMethods, dispatcherMethods, noTriggerEvents} from 'helper/const';
const secondaryReg = /^(before|after|_)/;
/**
* <pre>
Expand Down Expand Up @@ -324,10 +324,16 @@ export default class Bus {
_eventProcessor (key: string, {sync}: {sync: boolean}, ...args: any) {
const isKernelMethod: boolean = kernelMethods.indexOf(key) > -1;
const isDomMethod: boolean = domMethods.indexOf(key) > -1;
if(isKernelMethod || isDomMethod) {
this.__dispatcher[isKernelMethod ? 'kernel' : 'dom'][key](...args);
const isDispatcherMethod: boolean = dispatcherMethods.indexOf(key) > -1;
if(isKernelMethod || isDomMethod || isDispatcherMethod) {
if(isDispatcherMethod) {
this.__dispatcher[key](...args);
} else {
this.__dispatcher[isKernelMethod ? 'kernel' : 'dom'][key](...args);
}
if(videoEvents.indexOf(key) > -1 ||
domEvents.indexOf(key) > -1) return true;
domEvents.indexOf(key) > -1 ||
noTriggerEvents.indexOf(key) > -1) return true;
}
// $FlowFixMe: flow do not support computed sytax on classs, but it's ok here
return this[sync ? 'triggerSync' : 'trigger'](key, ...args);
Expand Down
125 changes: 4 additions & 121 deletions src/dispatcher/plugin.js
@@ -1,8 +1,6 @@
// @flow
import {isError, isString, isFunction, isEmpty, isObject, isBoolean, isInteger, isPromise, deepAssign, bind, isArray, Log} from 'chimee-helper';
import {before, accessor, applyDecorators, frozen, autobindClass, nonenumerable, nonextendable} from 'toxic-decorators';
import {eventBinderCheck, attrAndStyleCheck} from 'helper/checker';
import {domEvents} from 'helper/const';
import {isError, isString, isFunction, isEmpty, isObject, isBoolean, isInteger, isPromise, deepAssign, bind, Log} from 'chimee-helper';
import {accessor, applyDecorators, frozen, autobindClass} from 'toxic-decorators';
import VideoWrapper from 'dispatcher/video-wrapper';

/**
Expand All @@ -24,7 +22,6 @@ export default @autobindClass() class Plugin extends VideoWrapper {
readySync: boolean;
destroyed: boolean;
$dom: HTMLElement;
__events: PluginEvents;
$level: number;
__level: number;
$operable: boolean;
Expand All @@ -39,7 +36,6 @@ export default @autobindClass() class Plugin extends VideoWrapper {
destroyed = false;
VERSION = process.env.PLAYER_VERSION;
__operable = true;
__events = {};
__level = 0;
/**
* <pre>
Expand Down Expand Up @@ -247,37 +243,7 @@ export default @autobindClass() class Plugin extends VideoWrapper {
});
return this.readySync || this.ready;
}
/**
* set style
* @param {string} element optional, default to be video, you can choose from video | container | wrapper
* @param {string} attribute the atrribue name
* @param {any} value optional, when it's no offer, we consider you want to get the attribute's value. When it's offered, we consider you to set the attribute's value, if the value you passed is undefined, that means you want to remove the value;
*/
@before(attrAndStyleCheck)
$css (method: string, ...args: Array<any>): string {
return this.__dispatcher.dom[method + 'Style'](...args);
}
/**
* set attr
* @param {string} element optional, default to be video, you can choose from video | container | wrapper
* @param {string} attribute the atrribue name
* @param {any} value optional, when it's no offer, we consider you want to get the attribute's value. When it's offered, we consider you to set the attribute's value, if the value you passed is undefined, that means you want to remove the value;
*/
@before(attrAndStyleCheck)
$attr (method: string, ...args: Array<any>): string {
if(method === 'set' && /video/.test(args[0])) {
if(!this.__dispatcher.videoConfigReady) {
Log.warn('plugin', `Plugin ${this.__id} is tring to set attribute on video before video inited. Please wait until the inited event has benn trigger`);
return args[2];
}
if(this.$videoConfig._realDomAttr.indexOf(args[1]) > -1) {
const [, key, val] = args;
this.$videoConfig[key] = val;
return val;
}
}
return this.__dispatcher.dom[method + 'Attr'](...args);
}

/**
* call fullscreen api on some specific element
* @param {boolean} flag true means fullscreen and means exit fullscreen
Expand All @@ -293,63 +259,7 @@ export default @autobindClass() class Plugin extends VideoWrapper {
const topLevel = this.__dispatcher._getTopLevel(this.$inner);
this.$level = topLevel + 1;
}
/**
* bind event handler through this function
* @param {string} key event's name
* @param {Function} fn event's handler
*/
@before(eventBinderCheck)
$on (key: string, fn: Function) {
this.__dispatcher.bus.on(this.__id, key, fn);
// set on __events as mark so that i can destroy it when i destroy
this.__addEvents(key, fn);
}
/**
* remove event handler through this function
* @param {string} key event's name
* @param {Function} fn event's handler
*/
@before(eventBinderCheck)
$off (key: string, fn: Function) {
this.__dispatcher.bus.off(this.__id, key, fn);
this.__removeEvents(key, fn);
}
/**
* bind one time event handler
* @param {string} key event's name
* @param {Function} fn event's handler
*/
@before(eventBinderCheck)
$once (key: string, fn: Function) {
const self = this;
const boundFn = function (...args) {
bind(fn, this)(...args);
self.__removeEvents(key, boundFn);
};
self.__addEvents(key, boundFn);
this.__dispatcher.bus.once(this.__id, key, boundFn);
}
/**
* emit an event
* @param {string} key event's name
* @param {...args} args
*/
$emit (key: string, ...args: any) {
if(!isString(key)) throw new TypeError('$emit key parameter must be String');
if(domEvents.indexOf(key.replace(/^\w_/, '')) > -1) {
Log.warn('plugin', `You are using $emit to emit ${key} event. As $emit is wrapped in Promise. It make you can't use event.preventDefault and event.stopPropagation. So we advice you to use $emitSync`);
}
this.__dispatcher.bus.emit(key, ...args);
}
/**
* emit a sync event
* @param {string} key event's name
* @param {...args} args
*/
$emitSync (key: string, ...args: any) {
if(!isString(key)) throw new TypeError('$emitSync key parameter must be String');
return this.__dispatcher.bus.emitSync(key, ...args);
}

$throwError (error: Error | string) {
this.__dispatcher.throwError(error);
}
Expand All @@ -360,27 +270,11 @@ export default @autobindClass() class Plugin extends VideoWrapper {
$destroy () {
isFunction(this.destroy) && this.destroy();
super.__destroy();
Object.keys(this.__events)
.forEach(key => {
if(!isArray(this.__events[key])) return;
this.__events[key].forEach(fn => this.$off(key, fn));
});
delete this.__events;
this.__dispatcher.dom.removePlugin(this.__id);
delete this.__dispatcher;
delete this.$dom;
this.destroyed = true;
}
@nonenumerable
@nonextendable
get $plugins (): plugins {
return this.__dispatcher.plugins;
}
@nonenumerable
@nonextendable
get $pluginOrder (): Array<string> {
return this.__dispatcher.order;
}
/**
* to tell us if the plugin can be operable, can be dynamic change
* @type {boolean}
Expand All @@ -405,15 +299,4 @@ export default @autobindClass() class Plugin extends VideoWrapper {
get $level (): number {
return this.__level;
}
__addEvents (key: string, fn: Function) {
this.__events[key] = this.__events[key] || [];
this.__events[key].push(fn);
}
__removeEvents (key: string, fn: Function) {
if(isEmpty(this.__events[key])) return;
const index = this.__events[key].indexOf(fn);
if(index < 0) return;
this.__events[key].splice(index, 1);
if(isEmpty(this.__events[key])) delete this.__events[key];
}
};

0 comments on commit 2b69dd9

Please sign in to comment.