Comparar commits

..

1 Commits

Autor SHA1 Mensagem Data
Pat O'Neill c40ea4186b feat: Add a noConflict method. 2017-10-18 12:54:35 -04:00
4 arquivos alterados com 95 adições e 129 exclusões
+61 -85
Ver Arquivo
@@ -1,6 +1,6 @@
# Hooks
Hooks exist so that users can globally hook into certain Video.js lifecycle moments.
Hooks exist so that users can "hook" on to certain Video.js player lifecycle
## Table of Contents
@@ -18,153 +18,129 @@ Currently, the following hooks are available:
### beforesetup
`beforesetup` occurs just before a player is created. This allows:
`beforesetup` is called just before the player is created. This allows:
* Modification of the options passed to the Video.js function (e.g., `videojs('some-id, options)`).
* Modification of the DOM video element that will be used for the player that will be created.
* modification of the options passed to the Video.js function (`videojs('some-id, options)`)
* modification of the dom video element that will be used for the player
`beforesetup` hook functions should:
* Take two arguments:
1. `videoEl`: DOM `<video>` element that Video.js is going to use to create a player.
1. `options`: The options object that Video.js was called with and will be passed to the player during creation.
* Return an options object that will be merged with the originally provided options.
* take two arguments
1. videoEl: dom video element that Video.js is going to use to create a player
1. options: options that Video.js was intialized with and will later pass to the player during creation
* return options that will merge and override options that Video.js with intialized with
#### Example
Example: adding beforesetup hook
```js
videojs.hook('beforesetup', function(videoEl, options) {
// videoEl will be the video element with id="some-id" since that
// gets passed to videojs() below. On subsequent calls, it will be
// different.
var beforeSetup = function(videoEl, options) {
// videoEl.id will be some-id here, since that is what Video.js
// was created with
videoEl.className += ' some-super-class';
// autoplay will be true here, since we passed it as such.
if (options.autoplay) {
// autoplay will be true here, since we passed in as such
(options.autoplay) {
options.autoplay = false
}
// Options that are returned here will be merged with old options.
//
// In this example options will now be:
// {autoplay: false, controls: true}
//
// This has the practical effect of always disabling autoplay no matter
// what options are passed to videojs().
// options that are returned here will be merged with old options
// in this example options will now be
// {autoplay: false, controls: true}
return options;
});
};
// Create a new player.
videojs.hook('beforesetup', beforeSetup);
videojs('some-id', {autoplay: true, controls: true});
```
### setup
`setup` occurs just after a player is created. This allows:
`setup` is called just after the player is created. This allows:
* Plugins or other custom functionality to initialize on the player.
* Changes to the player object itself.
* plugin or custom functionality to intialize on the player
* changes to the player object itself
`setup` hook functions:
* Take one argument:
1. `player`: the player that Video.js created
* Take one argument
* player: the player that Video.js created
* Don't have to return anything
#### Example
Example: adding a setup hook
```js
videojs.registerPlugin('foo', function() {
var setup = function(player) {
// initialize the foo plugin
player.foo();
};
var foo = function() {};
// This basic plugin will add the "some-super-class" class to a player.
this.addClass('some-super-class');
});
videojs.hook('setup', function(player) {
// Initialize the foo plugin after any player is created.
player.foo();
});
// Create a new player.
videojs('some-id', {autoplay: true, controls: true});
videojs.registerPlugin('foo', foo);
videojs.hook('setup', setup);
var player = videojs('some-id', {autoplay: true, controls: true});
```
## Usage
### Adding
Hooks can be added using `videojs.hook(<name>, function)` before running the `videojs()` function.
In order to use hooks you must first include Video.js in the page or script that you are using. Then you add hooks using `videojs.hook(<name>, function)` before running the `videojs()` function.
#### Example
Example: adding hooks
```js
videojs.hook('beforesetup', function(videoEl, options) {
// This hook will be called twice. Once for "vid1" and once for "vid2".
// The options will match what is passed to videojs() for each of them.
// videoEl will be the element with id=vid1
// options will contain {autoplay: false}
});
videojs.hook('setup', function(player) {
// This hook will be called twice. Once for "vid1" and once for "vid2".
// The player value will be the player that is created for each element.
// player will be the same player that is defined below
// as `var player`
});
videojs('vid1', {autoplay: false});
videojs('vid2', {autoplay: true});
var player = videojs('vid1', {autoplay: false});
```
After adding your hooks, they will automatically be run at the correct time in the Video.js lifecycle.
### Adding Once
In some cases, you may only want your hook to run once. In these cases, use `videojs.hookOnce(<name>, function)` before running the `videojs()` function.
#### Example
```js
videojs.hookOnce('beforesetup', function(videoEl, options) {
// This hook will be called once for "vid1", but not for "vid2".
// The options will match what is passed to videojs().
});
videojs.hookOnce('setup', function(player) {
// This hook will be called once for "vid1", but not for "vid2".
// The player value will be the player that is created for each element.
});
videojs('vid1', {autoplay: false});
videojs('vid2', {autoplay: true});
```
After adding your hooks they will automatically be run at the correct time in the Video.js lifecycle.
### Getting
To access the array of functions that currently exists for any hook, use the `videojs.hooks` function.
To access the array of hooks that currently exists and will be run on the Video.js object you can use the `videojs.hooks` function.
#### Example
Example: getting all hooks attached to Video.js
```js
// Get an array of all the 'beforesetup' hooks.
var beforeSetupHooks = videojs.hooks('beforesetup');
// Get an array of all the 'setup' hooks.
var setupHooks = videojs.hooks('setup');
```
### Removing
To stop hooks from being executed during any future Video.js lifecycles you can remove them using `videojs.removeHook`.
To stop hooks from being executed during the Video.js lifecycle you will remove them using `videojs.removeHook`.
#### Example
Example: remove a hook that was defined by you
```js
var beforeSetup = function(videoEl, options) {};
// Add the hook.
// add the hook
videojs.hook('beforesetup', beforeSetup);
// Remove the same hook.
// remove that same hook
videojs.removeHook('beforesetup', beforeSetup);
```
You can also use `videojs.hooks` in conjunction with `videojs.removeHook` but it may have unexpected results if used during an asynchronous callbacks as other plugins/functionality may have added hooks.
Example: using `videojs.hooks` and `videojs.removeHook` to remove a hook
```js
// add the hook
videojs.hook('setup', function(videoEl, options) {});
var setupHooks = videojs.hooks('setup');
// remove the hook you just added
videojs.removeHook('setup', setupHooks[setupHooks.length - 1]);
```
+19 -22
Ver Arquivo
@@ -127,6 +127,23 @@ function videojs(id, options, ready) {
return player;
}
// Cache the previous videojs global in case it's overwritten.
const previousVideojs = window.videojs;
/**
* Removes this `videojs` global from the global namespace and returns it, so
* it can be re-used under a different name.
*
* @return {Function}
* Returns `videojs`.
*/
videojs.noConflict = function() {
if (window.videojs === videojs) {
window.videojs = previousVideojs;
}
return videojs;
};
/**
* An Object that contains lifecycle hooks as keys which point to an array
* of functions that are run when a lifecycle is triggered
@@ -140,8 +157,8 @@ videojs.hooks_ = {};
* @param {string} type
* the lifecyle to get hooks from
*
* @param {Function|Function[]} [fn]
* Optionally add a hook (or hooks) to the lifecycle that your are getting.
* @param {Function} [fn]
* Optionally add a hook to the lifecycle that your are getting.
*
* @return {Array}
* an array of hooks, or an empty array if there are none.
@@ -167,26 +184,6 @@ videojs.hook = function(type, fn) {
videojs.hooks(type, fn);
};
/**
* Add a function hook that will only run once to a specific videojs lifecycle.
*
* @param {string} type
* the lifecycle to hook the function to.
*
* @param {Function|Function[]}
* The function or array of functions to attach.
*/
videojs.hookOnce = function(type, fn) {
videojs.hooks(type, [].concat(fn).map(original => {
const wrapper = (...args) => {
videojs.removeHook(type, wrapper);
original(...args);
};
return wrapper;
}));
};
/**
* Remove a hook from a specific videojs lifecycle.
*
+12
Ver Arquivo
@@ -3,6 +3,7 @@ import videojs from '../../src/js/video.js';
import * as Dom from '../../src/js/utils/dom.js';
import log from '../../src/js/utils/log.js';
import document from 'global/document';
import window from 'global/window';
import sinon from 'sinon';
QUnit.module('video.js', {
@@ -331,3 +332,14 @@ QUnit.test('should create a new tag for movingMediaElementInDOM', function(asser
Html5.isSupported = oldIS;
Html5.nativeSourceHandler.canPlayType = oldCPT;
});
QUnit.test('noConflict', function(assert) {
// The test build does not expose a global videojs, so we need to fake it.
window.videojs = videojs;
const vjs = videojs.noConflict();
assert.strictEqual(window.videojs, undefined);
assert.strictEqual(vjs, videojs);
});
+3 -22
Ver Arquivo
@@ -1,7 +1,6 @@
/* eslint-env qunit */
import videojs from '../../src/js/video.js';
import document from 'global/document';
import sinon from 'sinon';
import log from '../../src/js/utils/log.js';
QUnit.module('video.js:hooks ', {
@@ -24,7 +23,9 @@ QUnit.test('should be able to add a hook', function(assert) {
assert.equal(videojs.hooks_.bar.length, 2, 'should have 2 bar hooks');
assert.equal(videojs.hooks_.foo.length, 1, 'should have 1 foo hook');
videojs.hook('foo', [function() {}, function() {}, function() {}]);
videojs.hook('foo', function() {});
videojs.hook('foo', function() {});
videojs.hook('foo', function() {});
assert.equal(videojs.hooks_.foo.length, 4, 'should have 4 foo hooks');
assert.equal(videojs.hooks_.bar.length, 2, 'should have 2 bar hooks');
});
@@ -103,26 +104,6 @@ QUnit.test('should be get all hooks for a type and add at the same time', functi
assert.deepEqual(videojs.hooks_.bar, barHooks, 'should return the exact bar list from videojs.hooks_');
});
QUnit.test('should be able to add a hook that runs once', function(assert) {
const spies = [
sinon.spy(),
sinon.spy(),
sinon.spy()
];
videojs.hookOnce('foo', spies);
assert.equal(videojs.hooks_.foo.length, 3, 'should have 3 foo hooks');
videojs.hooks('foo').forEach(fn => fn());
spies.forEach((spy, i) => {
assert.ok(spy.calledOnce, `spy #${i + 1} was called`);
});
assert.equal(videojs.hooks_.foo.length, 0, 'should have 0 foo hooks');
});
QUnit.test('should trigger beforesetup and setup during videojs setup', function(assert) {
const vjsOptions = {techOrder: ['techFaker']};
let setupCalled = false;