Skip to content

Commit

Permalink
fix: Avoid multiple-registration warning messages by accepting only t…
Browse files Browse the repository at this point in the history
…he first contrib-ads per context. (#421)
  • Loading branch information
misteroneill authored Aug 23, 2018
1 parent a533bbb commit c46ed1a
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 12 deletions.
21 changes: 9 additions & 12 deletions src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ that live in in separate files.

import videojs from 'video.js';

import {version as adsVersion} from '../package.json';

import getAds from './ads.js';
import redispatch from './redispatch.js';
import initializeContentupdate from './contentupdate.js';
import adMacroReplacement from './macros.js';
import cueTextTracks from './cueTextTracks.js';
import initCancelContentPlay from './cancelContentPlay.js';
import playMiddlewareFeature from './playMiddleware.js';
import register from './register.js';

import {BeforePreroll, StitchedContentPlayback} from './states.js';

const { playMiddleware, isMiddlewareMediatorSupported } = playMiddlewareFeature;
const { isMiddlewareMediatorSupported } = playMiddlewareFeature;
const VIDEO_EVENTS = videojs.getTech('Html5').Events;

// Default settings
Expand Down Expand Up @@ -261,17 +264,11 @@ const contribAdsPlugin = function(options) {

};

const registerPlugin = videojs.registerPlugin || videojs.plugin;

// Register this plugin with videojs
registerPlugin('ads', contribAdsPlugin);
// Expose the contrib-ads version before it is initialized. Will be replaced
// after initialization in ads.js
contribAdsPlugin.VERSION = adsVersion;

// Register the Play Middleware with video.js on script execution,
// to avoid a new playMiddleware factory being created on
// videojs for each player created.
if (isMiddlewareMediatorSupported()) {
// Register the play middleware
videojs.use('*', playMiddleware);
}
// Attempt to register the plugin, if we can.
register(contribAdsPlugin);

export default contribAdsPlugin;
73 changes: 73 additions & 0 deletions src/register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import videojs from 'video.js';
import playMiddlewareFeature from './playMiddleware.js';

const {playMiddleware, isMiddlewareMediatorSupported} = playMiddlewareFeature;

/**
* Whether or not this copy of Video.js has the ads plugin.
*
* @return {boolean}
* If `true`, has the plugin. `false` otherwise.
*/
const hasAdsPlugin = () => {

// Video.js 6 and 7 have a getPlugin method.
if (videojs.getPlugin) {
return Boolean(videojs.getPlugin('ads'));
}

// Video.js 5 does not have a getPlugin method, so check the player prototype.
const Player = videojs.getComponent('Player');

return Boolean(Player && Player.prototype.ads);
};

/**
* Register contrib-ads with Video.js, but provide protection for duplicate
* copies of the plugin. This could happen if, for example, a stitched ads
* plugin and a client-side ads plugin are included simultaneously with their
* own copies of contrib-ads.
*
* If contrib-ads detects a pre-existing duplicate, it will not register
* itself.
*
* Ad plugins using contrib-ads and anticipating that this could come into
* effect should verify that the contrib-ads they are using is of a compatible
* version.
*
* @param {Function} contribAdsPlugin
* The plugin function.
*
* @return {boolean}
* When `true`, the plugin was registered. When `false`, the plugin
* was not registered.
*/
function register(contribAdsPlugin) {

// If the ads plugin already exists, do not overwrite it.
if (hasAdsPlugin(videojs)) {
return false;
}

// Cross-compatibility with Video.js 6/7 and 5.
const registerPlugin = videojs.registerPlugin || videojs.plugin;

// Register this plugin with Video.js.
registerPlugin('ads', contribAdsPlugin);

// Register the play middleware with Video.js on script execution,
// to avoid a new playMiddleware factory being added for each player.
// The `usingContribAdsMiddleware_` flag is used to ensure that we only ever
// register the middleware once - despite the ability to de-register and
// re-register the plugin itself.
if (isMiddlewareMediatorSupported() && !videojs.usingContribAdsMiddleware_) {
// Register the play middleware
videojs.use('*', playMiddleware);
videojs.usingContribAdsMiddleware_ = true;
}

return true;
}

export default register;
export {hasAdsPlugin};
46 changes: 46 additions & 0 deletions test/unit/test.register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import videojs from 'video.js';
import contribAdsPlugin from '../../src/plugin.js';
import register from '../../src/register.js';
import { hasAdsPlugin} from '../../src/register.js';

// Cross-compatible plugin de-registration.
const deregister = () => {

// Video.js 7.2+
if (videojs.deregisterPlugin) {
return videojs.deregisterPlugin('ads');
}

// Video.js 6.0 thru 7.1
if (videojs.getPlugin) {
const Plugin = videojs.getPlugin('plugin');

if (Plugin && Plugin.deregisterPlugin) {
return Plugin.deregisterPlugin('ads');
}
}

// Video.js 5
const Player = videojs.getComponent('Player');

if (Player && Player.prototype.ads) {
delete Player.prototype.ads;
}
};

QUnit.module('Register');

QUnit.test('registration fails if plugin exists, succeeds otherwise', function(assert) {

// The plugin is already registered here.
assert.notOk(register(contribAdsPlugin), 'plugin was already registered');
assert.ok(hasAdsPlugin(), 'plugin exists');

// De-register the plugin and verify that it no longer exists.
deregister();
assert.notOk(hasAdsPlugin(), 'plugin does not exist');

// Re-register the plugin and verify that it exists.
assert.ok(register(contribAdsPlugin), 'plugin was registered');
assert.ok(hasAdsPlugin(), 'plugin exists');
});

0 comments on commit c46ed1a

Please sign in to comment.