vpaid-html5-client
Version:
1,005 lines (850 loc) • 25.4 kB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
;
var METHODS = [
'handshakeVersion',
'initAd',
'startAd',
'stopAd',
'skipAd', // VPAID 2.0 new method
'resizeAd',
'pauseAd',
'resumeAd',
'expandAd',
'collapseAd',
'subscribe',
'unsubscribe'
];
var EVENTS = [
'AdLoaded',
'AdStarted',
'AdStopped',
'AdSkipped',
'AdSkippableStateChange', // VPAID 2.0 new event
'AdSizeChange', // VPAID 2.0 new event
'AdLinearChange',
'AdDurationChange', // VPAID 2.0 new event
'AdExpandedChange',
'AdRemainingTimeChange', // [Deprecated in 2.0] but will be still fired for backwards compatibility
'AdVolumeChange',
'AdImpression',
'AdVideoStart',
'AdVideoFirstQuartile',
'AdVideoMidpoint',
'AdVideoThirdQuartile',
'AdVideoComplete',
'AdClickThru',
'AdInteraction', // VPAID 2.0 new event
'AdUserAcceptInvitation',
'AdUserMinimize',
'AdUserClose',
'AdPaused',
'AdPlaying',
'AdLog',
'AdError'
];
var GETTERS = [
'getAdLinear',
'getAdWidth', // VPAID 2.0 new getter
'getAdHeight', // VPAID 2.0 new getter
'getAdExpanded',
'getAdSkippableState', // VPAID 2.0 new getter
'getAdRemainingTime',
'getAdDuration', // VPAID 2.0 new getter
'getAdVolume',
'getAdCompanions', // VPAID 2.0 new getter
'getAdIcons' // VPAID 2.0 new getter
];
var SETTERS = [
'setAdVolume'
];
/**
* This callback is displayed as global member. The callback use nodejs error-first callback style
* @callback NodeStyleCallback
* @param {string|null}
* @param {undefined|object}
*/
/**
* IVPAIDAdUnit
*
* @class
*
* @param {object} creative
* @param {HTMLElement} el
* @param {HTMLVideoElement} video
*/
function IVPAIDAdUnit(creative, el, video) {}
/**
* handshakeVersion
*
* @param {string} VPAIDVersion
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.handshakeVersion = function (VPAIDVersion, callback) {};
/**
* initAd
*
* @param {number} width
* @param {number} height
* @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'
* @param {number} desiredBitrate indicates the desired bitrate in kbps
* @param {object} [creativeData] used for additional initialization data
* @param {object} [environmentVars] used for passing implementation-specific of js version
* @param {NodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.initAd = function(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {};
/**
* startAd
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.startAd = function(callback) {};
/**
* stopAd
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.stopAd = function(callback) {};
/**
* skipAd
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.skipAd = function(callback) {};
/**
* resizeAd
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.resizeAd = function(width, height, viewMode, callback) {};
/**
* pauseAd
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.pauseAd = function(callback) {};
/**
* resumeAd
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.resumeAd = function(callback) {};
/**
* expandAd
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.expandAd = function(callback) {};
/**
* collapseAd
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.collapseAd = function(callback) {};
/**
* subscribe
*
* @param {string} event
* @param {nodeStyleCallback} handler
* @param {object} context
*/
IVPAIDAdUnit.prototype.subscribe = function(event, handler, context) {};
/**
* startAd
*
* @param {string} event
* @param {function} handler
*/
IVPAIDAdUnit.prototype.unsubscribe = function(event, handler) {};
/**
* getAdLinear
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdLinear = function(callback) {};
/**
* getAdWidth
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdWidth = function(callback) {};
/**
* getAdHeight
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdHeight = function(callback) {};
/**
* getAdExpanded
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdExpanded = function(callback) {};
/**
* getAdSkippableState
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdSkippableState = function(callback) {};
/**
* getAdRemainingTime
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdRemainingTime = function(callback) {};
/**
* getAdDuration
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdDuration = function(callback) {};
/**
* getAdVolume
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdVolume = function(callback) {};
/**
* getAdCompanions
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdCompanions = function(callback) {};
/**
* getAdIcons
*
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.getAdIcons = function(callback) {};
/**
* setAdVolume
*
* @param {number} volume
* @param {nodeStyleCallback} callback
*/
IVPAIDAdUnit.prototype.setAdVolume = function(volume, callback) {};
addStaticToInterface(IVPAIDAdUnit, 'METHODS', METHODS);
addStaticToInterface(IVPAIDAdUnit, 'GETTERS', GETTERS);
addStaticToInterface(IVPAIDAdUnit, 'SETTERS', SETTERS);
addStaticToInterface(IVPAIDAdUnit, 'EVENTS', EVENTS);
var VPAID1_METHODS = METHODS.filter(function(method) {
return ['skipAd'].indexOf(method) === -1;
});
addStaticToInterface(IVPAIDAdUnit, 'checkVPAIDInterface', function checkVPAIDInterface (creative) {
var result = VPAID1_METHODS.every(function(key) {
return typeof creative[key] === 'function';
});
return result;
});
module.exports = IVPAIDAdUnit;
function addStaticToInterface(Interface, name, value) {
Object.defineProperty(Interface, name, {
writable: false,
configurable: false,
value: value
});
}
},{}],2:[function(require,module,exports){
;
var IVPAIDAdUnit = require('./IVPAIDAdUnit');
var Subscriber = require('./subscriber');
var checkVPAIDInterface = IVPAIDAdUnit.checkVPAIDInterface;
var utils = require('./utils');
var METHODS = IVPAIDAdUnit.METHODS;
var ERROR = 'AdError';
var AD_CLICK = 'AdClickThru';
var FILTERED_EVENTS = IVPAIDAdUnit.EVENTS.filter(function (event) {
return event != AD_CLICK;
});
/**
* This callback is displayed as global member. The callback use nodejs error-first callback style
* @callback NodeStyleCallback
* @param {string|null}
* @param {undefined|object}
*/
/**
* VPAIDAdUnit
* @class
*
* @param VPAIDCreative
* @param {HTMLElement} [el] this will be used in initAd environmentVars.slot if defined
* @param {HTMLVideoElement} [video] this will be used in initAd environmentVars.videoSlot if defined
*/
function VPAIDAdUnit(VPAIDCreative, el, video, iframe) {
this._isValid = checkVPAIDInterface(VPAIDCreative);
if (this._isValid) {
this._creative = VPAIDCreative;
this._el = el;
this._videoEl = video;
this._iframe = iframe;
this._subscribers = new Subscriber();
$addEventsSubscribers.call(this);
}
}
VPAIDAdUnit.prototype = Object.create(IVPAIDAdUnit.prototype);
/**
* isValidVPAIDAd will return if the VPAIDCreative passed in constructor is valid or not
*
* @return {boolean}
*/
VPAIDAdUnit.prototype.isValidVPAIDAd = function isValidVPAIDAd() {
return this._isValid;
};
IVPAIDAdUnit.METHODS.forEach(function(method) {
//NOTE: this methods arguments order are implemented differently from the spec
var ignores = [
'subscribe',
'unsubscribe',
'initAd'
];
if (ignores.indexOf(method) !== -1) return;
VPAIDAdUnit.prototype[method] = function () {
var ariaty = IVPAIDAdUnit.prototype[method].length;
// TODO avoid leaking arguments
// https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
var args = Array.prototype.slice.call(arguments);
var callback = (ariaty === args.length) ? args.pop() : undefined;
setTimeout(function () {
var result, error = null;
try {
result = this._creative[method].apply(this._creative, args);
} catch(e) {
error = e;
}
callOrTriggerEvent(callback, this._subscribers, error, result);
}.bind(this), 0);
};
});
/**
* initAd concreate implementation
*
* @param {number} width
* @param {number} height
* @param {string} viewMode can be 'normal', 'thumbnail' or 'fullscreen'
* @param {number} desiredBitrate indicates the desired bitrate in kbps
* @param {object} [creativeData] used for additional initialization data
* @param {object} [environmentVars] used for passing implementation-specific of js version, if el & video was used in constructor slot & videoSlot will be added to the object
* @param {NodeStyleCallback} callback
*/
VPAIDAdUnit.prototype.initAd = function initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars, callback) {
creativeData = creativeData || {};
environmentVars = utils.extend({
slot: this._el,
videoSlot: this._videoEl
}, environmentVars || {});
setTimeout(function () {
var error;
try {
this._creative.initAd(width, height, viewMode, desiredBitrate, creativeData, environmentVars);
} catch (e) {
error = e;
}
callOrTriggerEvent(callback, this._subscribers, error);
}.bind(this), 0);
};
/**
* subscribe
*
* @param {string} event
* @param {nodeStyleCallback} handler
* @param {object} context
*/
VPAIDAdUnit.prototype.subscribe = function subscribe(event, handler, context) {
this._subscribers.subscribe(handler, event, context);
};
/**
* unsubscribe
*
* @param {string} event
* @param {nodeStyleCallback} handler
*/
VPAIDAdUnit.prototype.unsubscribe = function unsubscribe(event, handler) {
this._subscribers.unsubscribe(handler, event);
};
//alias
VPAIDAdUnit.prototype.on = VPAIDAdUnit.prototype.subscribe;
VPAIDAdUnit.prototype.off = VPAIDAdUnit.prototype.unsubscribe;
IVPAIDAdUnit.GETTERS.forEach(function(getter) {
VPAIDAdUnit.prototype[getter] = function (callback) {
setTimeout(function () {
var result, error = null;
try {
result = this._creative[getter]();
} catch(e) {
error = e;
}
callOrTriggerEvent(callback, this._subscribers, error, result);
}.bind(this), 0);
};
});
/**
* setAdVolume
*
* @param volume
* @param {nodeStyleCallback} callback
*/
VPAIDAdUnit.prototype.setAdVolume = function setAdVolume(volume, callback) {
setTimeout(function () {
var result, error = null;
try {
this._creative.setAdVolume(volume);
result = this._creative.getAdVolume();
} catch(e) {
error = e;
}
if (!error) {
error = utils.validate(result === volume, 'failed to apply volume: ' + volume);
}
callOrTriggerEvent(callback, this._subscribers, error, result);
}.bind(this), 0);
};
VPAIDAdUnit.prototype._destroy = function destroy() {
this.stopAd();
this._subscribers.unsubscribeAll();
};
function $addEventsSubscribers() {
// some ads implement
// so they only handle one subscriber
// to handle this we create our one
FILTERED_EVENTS.forEach(function (event) {
this._creative.subscribe($trigger.bind(this, event), event);
}.bind(this));
// map the click event to be an object instead of depending of the order of the arguments
// and to be consistent with the flash
this._creative.subscribe($clickThruHook.bind(this), AD_CLICK);
// because we are adding the element inside the iframe
// the user is not able to click in the video
if (this._videoEl) {
var documentElement = this._iframe.contentDocument.documentElement;
var videoEl = this._videoEl;
documentElement.addEventListener('click', function(e) {
if (e.target === documentElement) {
videoEl.click();
}
});
}
}
function $clickThruHook(url, id, playerHandles) {
this._subscribers.triggerSync(AD_CLICK, {url: url, id: id, playerHandles: playerHandles});
}
function $trigger(event) {
// TODO avoid leaking arguments
// https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
this._subscribers.trigger(event, Array.prototype.slice(arguments, 1));
}
function callOrTriggerEvent(callback, subscribers, error, result) {
if (callback) {
callback(error, result);
} else if (error) {
subscribers.trigger(ERROR, error);
}
}
module.exports = VPAIDAdUnit;
},{"./IVPAIDAdUnit":1,"./subscriber":4,"./utils":5}],3:[function(require,module,exports){
;
var utils = require('./utils');
var unique = utils.unique('vpaidIframe');
var VPAIDAdUnit = require('./VPAIDAdUnit');
var defaultTemplate = '<!DOCTYPE html>' +
'<html lang="en">' +
'<head><meta charset="UTF-8"></head>' +
'<body style="margin:0;padding:0"><div class="ad-element"></div>' +
'<script type="text/javascript" src="{{iframeURL_JS}}"></script>' +
'<script type="text/javascript">' +
'window.parent.postMessage(\'{"event": "ready", "id": "{{iframeID}}"}\', \'{{origin}}\');' +
'</script>' +
'</body>' +
'</html>';
var AD_STOPPED = 'AdStopped';
/**
* This callback is displayed as global member. The callback use nodejs error-first callback style
* @callback NodeStyleCallback
* @param {string|null}
* @param {undefined|object}
*/
/**
* VPAIDHTML5Client
* @class
*
* @param {HTMLElement} el that will contain the iframe to load adUnit and a el to add to adUnit slot
* @param {HTMLVideoElement} video default video element to be used by adUnit
* @param {object} [templateConfig] template: html template to be used instead of the default, extraOptions: to be used when rendering the template
* @param {object} [vpaidOptions] timeout: when loading adUnit
*/
function VPAIDHTML5Client(el, video, templateConfig, vpaidOptions) {
templateConfig = templateConfig || {};
this._id = unique();
this._destroyed = false;
this._frameContainer = utils.createElementInEl(el, 'div');
this._videoEl = video;
this._vpaidOptions = vpaidOptions || {timeout: 10000};
this._templateConfig = {
template: templateConfig.template || defaultTemplate,
extraOptions: templateConfig.extraOptions || {}
};
}
/**
* destroy
*
*/
VPAIDHTML5Client.prototype.destroy = function destroy() {
if (this._destroyed) {
return;
}
this._destroyed = true;
$unloadPreviousAdUnit.call(this);
};
/**
* isDestroyed
*
* @return {boolean}
*/
VPAIDHTML5Client.prototype.isDestroyed = function isDestroyed() {
return this._destroyed;
};
/**
* loadAdUnit
*
* @param {string} adURL url of the js of the adUnit
* @param {nodeStyleCallback} callback
*/
VPAIDHTML5Client.prototype.loadAdUnit = function loadAdUnit(adURL, callback) {
$throwIfDestroyed.call(this);
$unloadPreviousAdUnit.call(this);
var that = this;
var frame = utils.createIframeWithContent(
this._frameContainer,
this._templateConfig.template,
utils.extend({
iframeURL_JS: adURL,
iframeID: this.getID(),
origin: getOrigin()
}, this._templateConfig.extraOptions)
);
this._frame = frame;
this._onLoad = utils.callbackTimeout(
this._vpaidOptions.timeout,
onLoad.bind(this),
onTimeout.bind(this)
);
window.addEventListener('message', this._onLoad);
function onLoad (e) {
/*jshint validthis: false */
//don't clear timeout
if (e.origin !== getOrigin()) return;
var result = JSON.parse(e.data);
//don't clear timeout
if (result.id !== that.getID()) return;
var adUnit, error, createAd;
if (!that._frame.contentWindow) {
error = 'the iframe is not anymore in the DOM tree';
} else {
createAd = that._frame.contentWindow.getVPAIDAd;
error = utils.validate(typeof createAd === 'function', 'the ad didn\'t return a function to create an ad');
}
if (!error) {
var adEl = that._frame.contentWindow.document.querySelector('.ad-element');
adUnit = new VPAIDAdUnit(createAd(), adEl, that._videoEl, that._frame);
adUnit.subscribe(AD_STOPPED, $adDestroyed.bind(that));
error = utils.validate(adUnit.isValidVPAIDAd(), 'the add is not fully complaint with VPAID specification');
}
that._adUnit = adUnit;
$destroyLoadListener.call(that);
callback(error, error ? null : adUnit);
//clear timeout
return true;
}
function onTimeout() {
callback('timeout', null);
}
};
/**
* unloadAdUnit
*
*/
VPAIDHTML5Client.prototype.unloadAdUnit = function unloadAdUnit() {
$unloadPreviousAdUnit.call(this);
};
/**
* getID will return the unique id
*
* @return {string}
*/
VPAIDHTML5Client.prototype.getID = function () {
return this._id;
};
/**
* $removeEl
*
* @param {string} key
*/
function $removeEl(key) {
var el = this[key];
if (el) {
el.remove();
delete this[key];
}
}
function $adDestroyed() {
$removeAdElements.call(this);
delete this._adUnit;
}
function $unloadPreviousAdUnit() {
$removeAdElements.call(this);
$destroyAdUnit.call(this);
}
function $removeAdElements() {
$removeEl.call(this, '_frame');
$destroyLoadListener.call(this);
}
/**
* $destroyLoadListener
*
*/
function $destroyLoadListener() {
if (this._onLoad) {
window.removeEventListener('message', this._onLoad);
utils.clearCallbackTimeout(this._onLoad);
delete this._onLoad;
}
}
function $destroyAdUnit() {
if (this._adUnit) {
this._adUnit.stopAd();
delete this._adUnit;
}
}
/**
* $throwIfDestroyed
*
*/
function $throwIfDestroyed() {
if (this._destroyed) {
throw new Error ('VPAIDHTML5Client already destroyed!');
}
}
function getOrigin() {
if( window.location.origin ) {
return window.location.origin;
}
else {
return window.location.protocol + "//" +
window.location.hostname +
(window.location.port ? ':' + window.location.port: '');
}
}
module.exports = VPAIDHTML5Client;
window.VPAIDHTML5Client = VPAIDHTML5Client;
},{"./VPAIDAdUnit":2,"./utils":5}],4:[function(require,module,exports){
;
function Subscriber() {
this._subscribers = {};
}
Subscriber.prototype.subscribe = function subscribe(handler, eventName, context) {
if (!this.isHandlerAttached(handler, eventName)) {
this.get(eventName).push({handler: handler, context: context, eventName: eventName});
}
};
Subscriber.prototype.unsubscribe = function unsubscribe(handler, eventName) {
this._subscribers[eventName] = this.get(eventName).filter(function (subscriber) {
return handler !== subscriber.handler;
});
};
Subscriber.prototype.unsubscribeAll = function unsubscribeAll() {
this._subscribers = {};
};
Subscriber.prototype.trigger = function(eventName, data) {
var that = this;
var subscribers = this.get(eventName)
.concat(this.get('*'));
subscribers.forEach(function (subscriber) {
setTimeout(function () {
if (that.isHandlerAttached(subscriber.handler, subscriber.eventName)) {
subscriber.handler.call(subscriber.context, data);
}
}, 0);
});
};
Subscriber.prototype.triggerSync = function(eventName, data) {
var subscribers = this.get(eventName)
.concat(this.get('*'));
subscribers.forEach(function (subscriber) {
subscriber.handler.call(subscriber.context, data);
});
};
Subscriber.prototype.get = function get(eventName) {
if (!this._subscribers[eventName]) {
this._subscribers[eventName] = [];
}
return this._subscribers[eventName];
};
Subscriber.prototype.isHandlerAttached = function isHandlerAttached(handler, eventName) {
return this.get(eventName).some(function(subscriber) {
return handler === subscriber.handler;
})
};
module.exports = Subscriber;
},{}],5:[function(require,module,exports){
;
/**
* noop a empty function
*/
function noop() {}
/**
* validate if is not validate will return an Error with the message
*
* @param {boolean} isValid
* @param {string} message
*/
function validate(isValid, message) {
return isValid ? null : new Error(message);
}
var timeouts = {};
/**
* clearCallbackTimeout
*
* @param {function} func handler to remove
*/
function clearCallbackTimeout(func) {
var timeout = timeouts[func];
if (timeout) {
clearTimeout(timeout);
delete timeouts[func];
}
}
/**
* callbackTimeout if the onSuccess is not called and returns true in the timelimit then onTimeout will be called
*
* @param {number} timer
* @param {function} onSuccess
* @param {function} onTimeout
*/
function callbackTimeout(timer, onSuccess, onTimeout) {
var callback, timeout;
timeout = setTimeout(function () {
onSuccess = noop;
delete timeout[callback];
onTimeout();
}, timer);
callback = function () {
// TODO avoid leaking arguments
// https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
if (onSuccess.apply(this, arguments)) {
clearCallbackTimeout(callback);
}
};
timeouts[callback] = timeout;
return callback;
}
/**
* createElementInEl
*
* @param {HTMLElement} parent
* @param {string} tagName
* @param {string} id
*/
function createElementInEl(parent, tagName, id) {
var nEl = document.createElement(tagName);
if (id) nEl.id = id;
parent.appendChild(nEl);
return nEl;
}
/**
* createIframeWithContent
*
* @param {HTMLElement} parent
* @param {string} template simple template using {{var}}
* @param {object} data
*/
function createIframeWithContent(parent, template, data) {
var iframe = createIframe(parent);
if (!setIframeContent(iframe, simpleTemplate(template, data))) return;
return iframe;
}
/**
* createIframe
*
* @param {HTMLElement} parent
* @param {string} url
*/
function createIframe(parent, url) {
var nEl = document.createElement('iframe');
nEl.src = url || 'about:blank';
nEl.marginWidth = '0';
nEl.marginHeight = '0';
nEl.frameBorder = '0';
nEl.width = '100%';
nEl.height = '100%';
nEl.style.position = 'absolute';
nEl.style.left = '0';
nEl.style.top = '0';
nEl.style.margin = '0px';
nEl.style.padding = '0px';
nEl.style.border = 'none';
nEl.setAttribute('SCROLLING','NO');
parent.innerHTML = '';
parent.appendChild(nEl);
return nEl;
}
/**
* simpleTemplate
*
* @param {string} template
* @param {object} data
*/
function simpleTemplate(template, data) {
Object.keys(data).forEach(function (key) {
var value = (typeof value === 'object') ? JSON.stringify(data[key]) : data[key];
template = template.replace(new RegExp('{{' + key + '}}', 'g'), value);
});
return template;
}
/**
* setIframeContent
*
* @param {HTMLIframeElement} iframeEl
* @param content
*/
function setIframeContent(iframeEl, content) {
var iframeDoc = iframeEl.contentWindow && iframeEl.contentWindow.document;
if (!iframeDoc) return false;
iframeDoc.write(content);
return true;
}
/**
* extend object with keys from another object
*
* @param {object} toExtend
* @param {object} fromSource
*/
function extend(toExtend, fromSource) {
Object.keys(fromSource).forEach(function(key) {
toExtend[key] = fromSource[key];
});
return toExtend;
}
/**
* unique will create a unique string everytime is called, sequentially and prefixed
*
* @param {string} prefix
*/
function unique(prefix) {
var count = -1;
return function () {
return prefix + '_' + (++count);
};
}
module.exports = {
noop: noop,
validate: validate,
clearCallbackTimeout: clearCallbackTimeout,
callbackTimeout: callbackTimeout,
createElementInEl: createElementInEl,
createIframeWithContent: createIframeWithContent,
createIframe: createIframe,
simpleTemplate: simpleTemplate,
setIframeContent: setIframeContent,
extend: extend,
unique: unique
};
},{}]},{},[3])
//# sourceMappingURL=VPAIDHTML5Client.js.map