/*global CN, jQuery */ /* for jsLint */
/**
* CN.dart.js
* @library cn-fe-ads-1.3.12
* @requires CN, jQuery
* @author Russell Munson
* @author Joe Hartoularos
*/
CN.dart = (function($, CN, $D) {
var
/**
* {Object} $window
* A jQuery wrapped set of the window object. Saves rendering time.
* @private
*/
$window = $(window),
/**
* {Object} ads
* A collection of ad calls requested on CN.dart
* @private
*/
ads = {},
/**
* {Boolean} isDrawing
* Flag indicating that CN.dart is in the process of drawing ads
* @private
*/
isDrawing = false,
/**
* {Object} common
* The common ad object. Used as a base class for plugin methods for easy read/write access to
* shared ad values.
* @private
*/
common = {
ad : {},
params : {},
charmap : {},
container : '_frame', /* Individual ad container div suffix */
dcopt : true, /* allow dcopt param to be appended to tile 1 */
frameurl : '/ads/newad.html', /* Iframe base-url - Used for generating contained dynamic script tags for ad calls. */
embed : false, /* If set to true, embed ads in page rather than in an iframe */
initialized : false,
ready : false,
ord : Math.floor(Math.random()*10e12),
remote : '/services/dart/',
retry : false,
site : "",
tiles : [],
tile : 0,
transparency : true, /* allowtransparency to fix white background on ads in IE */
url : location.protocol + '//web.archive.org/web/20120704043319/http://ad.doubleclick.net/adj/',
zone : ""
},
/**
* {RegExp} kwregex
* @private
*/
kwregex = /kw=/g,
/**
* {String} msg_pre
* Shared message prefix used in generating debug info.
* @private
*/
msg_pre = "CN Ad ",
/**
* {Object} msg
* Message object for easily generating debug info.
* @private
*/
msg = {
/* These are for good! */
'true' : {
gen : 'Success',
call : 'Request Fired',
embed : 'Set to Embedded Mode. Operating with degraded feature-set.',
queue : 'Request Added to Queue',
plug : 'Plugin Registered',
valid : 'Plugin Action Passed Validation',
finished : 'All Plugins Finished Running.',
drawing : 'All Ads Have Completed Drawing',
drawn : 'Ad Drawn'
},
/* These are for bad =( */
'false' : {
gen : 'Error',
call : 'Request Aborted',
embed : 'Set to Iframe Mode. Good job.',
queue : 'Request Faled To Be Added to Queue',
plug : 'Plugin Skipped',
valid : 'Plugin Action Failed Validation',
finished : 'Plugins Still Running',
drawing : 'Ads Still Drawing',
drawn : 'Ad Failed To Draw'
}
},
/**
* {Object} timer
* A timer object used to record function performance.
* @public
*/
timer = {
/**
* Marks a point in execution by creating a timestamp. The value of milestone dictates the key.
* The milestone 'start' is used as the initial timestamp. All other timestamps are stored as
* a difference to show the time in miliseconds each function call has taken from start.
* @param {String} milestone A string denoting the milestone key
* @example:
* timer.mark('start'); // Creates a timestamp stored in timer.start
* timer.mark('init'); // Creates a timestamp, then stores the difference of start and init in timer.init
* @private
*/
mark : function(milestone) {
this[milestone] = (milestone === 'start') ? (new Date()).getTime() : (new Date()).getTime() - this.start;
}
},
/**
* {Object} nakedFrame
* A jQuery wrapped set containing a blank iframe element.
* @private
*/
nakedFrame = $('').attr({
allowtransparency : common.transparency,
frameBorder : 0,
scrolling : 'no'
}).css({
border : 'none',
margin : 0,
padding : 0
}),
/**
* Generates debug messages.
* @param {String} type Message type defined in @msg
* @param {Boolean} [state] Optional Boolean value to indicate state [true = success, false = error]
* @returns {String} A formatted debug message
* @private
*/
messager = function(type, state) {
return msg_pre + msg[(state !== false).toString()][type || 'gen'];
},
/**
* Constructs the ad request url.
* @param {Object} ad DART ad object
* @param {String} [url] Optional url to use in place of ad object properties
* @returns {String} The ad request url
* @public
*/
buildurl = function(ad, url) {
return common.url + common.site +
'/' +
(url || ad.zone || common.zone) +
'sz=' + ad.sz + ';' +
'tile=' + ad.tile + ';' +
(ad.tile === 1 && common.dcopt === true ? 'dcopt=ist;' : '') +
(!url ? keywordString(ad) : '') +
buildParams(ad) +
'ord=' + common.ord + '?';
},
/**
* Formats key=value string of params to add to the ad url. Iterates over common.params, using the default value
* or calling refresh on the param object if the value of the param is dependent on something volatile (i.e. keywords).
* @param {Object} ad DART ad object
* @returns {String} Formatted key=value string
* @private
*/
buildParams = function(ad) {
var
cParams = common.params,
paramStr = '',
param;
for (param in cParams) {
if (cParams.hasOwnProperty(param)) {
paramStr += param + '=';
paramStr += (cParams[param].refresh && (ad.kws.length !== common.ad.kws.length)) ? cParams[param].refresh(ad) : cParams[param].defaultValue;
}
}
return paramStr;
},
/**
* Creates and stores individual ad objects by extending the base common.ad.
* @param {String} name Unique name prefix for storage, container div, and iframe id generation
* @param {Object} [pars] Additional ad params to extend or override common.ad values
* @returns {CN.dart}
* @public
*/
call = function(name, pars) {
var
key = name + pars.sz,
zone,
ad = ads[key] = {
tile : common.tiles.push(key),
el : $('#' + key + common.container),
kws : unique(common.ad.kws, test.kws(pars.kws) || []),
store : pars.store === false ? false : common.ad.store,
sz : pars.sz,
isDrawn : false,
xkws : test.kws(pars.kws) || [],
zone : pars.zone ? test.adzone(pars.zone) : false,
collapse : pars.collapse === true
};
// If ads have already been drawn, call draw again to render the new ad
if (common.embed) {
drawEmbedded(key);
}
else if (common.ready) {
if (!isDrawing) {
draw();
}
}
else {
$D.info(messager('queue'), [key,ad]);
}
return this;
},
/**
* Generates an iframe for the ad, and appends it to the container [placement][common.container]
* For iframed ads this is the actual call execution.
* @param {String} placement DART ad placement identifier
* @param {String} [url] Url to be used in place of ad pars
* @returns {CN.dart}
* @private
*/
drawFrame = function(placement, url) {
var
ad = ads[placement],
dims = ad.sz.split('x');
ad.url = buildurl(ad, url);
ad.el.html(ad.frame = nakedFrame.clone().attr({
id : placement,
name : placement,
height : ad.collapse ? 1 : dims[1],
width : dims[0],
src : ad.url && common.frameurl + '#' + encodeURIComponent(ad.url)
}).bind('load', { key : placement, ad : ad }, function(e) {
if (e.data.ad.tile === 1) {
$window.trigger('CN.customEvents.dartAdDrawn', [placement, "#" + placement, ad]);
}
onFrameDraw(e);
})
);
ad.isDrawn = true;
$D.info(messager('call'), [placement, ad]);
return this;
},
/**
* Iterates over ads using placement keys from common.tiles. To throttle rendering, break the iteration on the
* first ad, and use the dartAdDrawn event to dispatch draw again for the rest of the queue
* @param {Object} e The event object
* @private
**/
draw = function(e) {
var
i = 0,
tiles = common.tiles,
len = tiles.length;
isDrawing = (len > 0);
for (; i < len; i++) {
if (ads[tiles[i]].isDrawn === false) {
drawFrame(tiles[i]);
if (i === 0) {
break;
}
}
if (i === len - 1) {
isDrawing = false;
timer.mark('rendered');
}
}
},
/**
* Initialize CN.dart, setting common ad parameters and kicking off all registered plug-ins.
* @param {Object} pars Shared params - ex: site, zone, shared kws.
* @public
*/
init = function(pars) {
if (common.initialized) {
$D.warn(msg_pre+'Initialization called more than once. This should only happen once per page.');
return false;
}
test.charmap(pars.charmap);
common.initialized = true;
common.site = pars.site;
common.zone = test.adzone(pars.zone);
common.ad = {
store : true,
kws : test.kws(pars.kws),
tile : common.tile
};
updateKws();
plugin.run();
common.embed = (pars.embed || common.embed);
if (common.embed) {
$D.info(messager('embed', true), []);
}
timer.mark('init');
$D.info(msg_pre + 'Initialized', [ads]);
$window.bind('CN.customEvents.dartRequest', function(e) { draw(e); })
.bind('CN.customEvents.dartAdDrawn', function(e) { draw(e); })
.trigger('CN.customEvents.dartInitialized');
},
/**
* Translate kw array into a semicolon-delimited string.
* @param {Object} ad Ad object to grab keywords for translation.
* @returns {String}
* @private
*/
keywordString = function(ad) {
return 'kw=' + ad.kws.join(';kw=') + ';' + (ad.xkws.length ? '!c=' + ad.xkws.join(';!c=') + ';' : '');
},
/**
* Callback event dispatcher, executed on frame-load. If initialPause is true, the draw requests
* are throttled to ensure that ads are drawn out, sequentially, in the order that they were
* requested. This had to be implemented for V8 and Nitro engines.
* @param {Object} e The event object
* @public
*/
onFrameDraw = function(e) {
var
key = e.data.key,
ad = ads[key];
try {
ad.doc = ad.frame.contents();
}
catch (err) {
$D.user(e, [e.target, e.target.id]);
}
$D.info(messager('drawn'), [key, ad]);
resize(e);
},
/**
* {Object} plugin
* Encapsulates plug-in logic
* @private
*/
plugin = {
/**
* {Array} queue
* Plug-in holder array. Registered plug-ins are stored here.
* @private
*/
queue : [],
/**
* Adds plugins to the queue if they meet the required criteria.
* @param {Object} plug The plug-in to install
* @returns {Boolean}
* @private
*/
register : function(plug) {
if (!plug || !plug.init || plug.isFinished === undefined || !plug.callbacks){
$D.info(messager('plug',false), [plug ? plug.name : '', plug || {}]);
return false;
}
this.queue.push(plug);
$D.info(messager('plug'), [plug.name || '', plug]);
$window.unbind('CN.customEvents.dartInitialized');
return true;
},
/**
* Iterates over installed plug-ins and calls their init methods, passing in an object containing
* the queue, the plug-in's position in the queue, and its own plug-in object reference.
* @private
*/
run : function() {
var
i = 0,
len = this.queue.length,
passed = false,
plug,
val;
for (; i < len; i++) {
plug = this.queue[i];
$D.info(msg_pre + 'Running Plugin', [plug.name]);
plug.init({
queue : this.queue,
position : i,
plugin : plug
});
}
},
/**
* Iterates over installed plug-ins and checks their isFinished property. If all plug-ins have finished,
* call ready to signal the start of DART requests.
* Note: This function is a callback of the CN.customEvents.dartPlugin event. It re-scopes to the parent
* 'plugin' object.
* @param {Object} event The event object
* @param {Object} plugin The plug-in that triggered the event
* @param {Object} val The plug-in's "return" value
* @private
*/
finished : function(event, plugin, val) {
var
i = 0,
scope = event.data,
len = scope.queue.length,
passed = scope.validate(val);
$D.info(messager('valid', passed), [plugin.name, val]);
for (; i< len; i++) {
if (scope.queue[i].isFinished === false) {
$D.info(messager('finished', false), [plugin.name]);
return false;
}
}
$D.info(messager('finished', true));
ready.call(CN.dart);
},
/**
* Validates a plug-in's return value against a defined set of rules, which in turn modify the common object
* properties.
* @param {Object} ret The plug-in's return value
* @returns {Boolean}
* @private
*/
validate : function(ret) {
var
pass = true,
key;
for (key in ret) {
if(ret.hasOwnProperty(key)) {
pass = (test[key] && test[key](ret[key]) && pass);
}
}
return pass || false;
}
},
/**
* Puts CN.dart in a ready state by setting its common.ready property and triggering CN.customEvents.dartRequest
* to allow queued CN.dart.call invocations to begin drawing their ads.
* @returns {CN.dart}
* @public
*/
ready = function(e) {
common.ready = true;
timer.mark('ready');
$D.info(msg_pre + 'Call State Set to Ready');
$window.trigger('CN.customEvents.dartRequest');
return this;
},
/**
* Refreshes ad params or with the url pars (if provided).
* @param {String} ads Array, CSV or space-delimited list of ads id's
* @param {object} [pars] Params to override ad values, or url path to replace serialized params
*
* @example CN.dart.refresh('header728x90',{tile:20});
* CN.dart.refresh('header728x90','');
* @returns {CN.dart}
* @public
*/
refresh = function(placement, pars) {
if (common.embed) {
return this;
}
var
p = placement ? placement.toString().split(/,|\s+/) : common.tiles,
len = p.length,
merge = CN.isObject(pars),
i = 0,
key,
ad;
common.ord = Math.floor(Math.random()*10e12);
// The next line removes any references to a doubleclick frame busting ads
if (len === common.tiles.length){
$('script[id*="prscr"], .prWrap').remove();
}
for (; i < len; i++) {
ad = ads[key = p[i]];
if (ad && ad.store) {
// Add a fixed height to the parent el for the duration of the refresh.
ad.el.height('').height(ad.el.height());
ad.isDrawn = false;
}
}
if (common.ready) {
$window.trigger('CN.customEvents.dartRequest');
}
return this;
},
/**
* Resizes iFrame height to fit content on load.
* @private
*/
resize = function(e) {
var
frame = e.data && e.data.key ? ads[e.data.key].frame : $(e.target),
key = frame.attr('name'),
ad = ads[key],
textAd = false,
body,
bHeight;
if (ad.doc) {
body = ad.doc.find('body');
bHeight = body.outerHeight();
textAd = $('.textAd', body);
}
else {
return this;
}
if (textAd.length) {
textAd.clone().appendTo(ad.el);
textAd.remove();
}
if (bHeight === 1) {
ad.el.removeClass("ad-served").addClass("ad-not-served");
}
else {
ad.el.removeClass("ad-not-served").addClass("ad-served");
}
frame.css({
width : ad.el.width(),
height : body.outerHeight()
});
// We clear the parent el height here. It's fixed during
// the refresh process to prevent page jumping.
ad.el.height('');
$window.trigger('CN.customEvents.dartResize.' + key, [key,'#' + key, ad]);
$D.info('CN Ad Frame Resize', [key, frame.css('height') + ' x ' + frame.css('width')]);
},
/**
* Resize iFrame height to fit content after ad is loaded. Call to function is made on newad page.
* @param {Number} tile The tile number of the ad.
* @public
*/
recalSize = function(tile) {
var
adKey = CN.dart.get('tiles')[tile - 1],
ad = ads[adKey],
body,
bHeight;
try {
ad.doc = ad.frame.contents();
}
catch (err) {
$D.warn("Failed to retrieve iframe content (err.descr.): " + err.description);
}
if (ad.doc) {
body = ad.doc.find('body');
bHeight = body.outerHeight();
}
else {
return this;
}
if (bHeight === 1) {
ad.el.removeClass("ad-served").addClass("ad-not-served");
}
else {
ad.el.removeClass("ad-not-served").addClass("ad-served");
}
ad.frame.css({
width : ad.el.width(),
height : bHeight
});
$D.info('CN Ad Frame Recalculate Size', [adKey,ad.frame.css('height') + ' x ' + ad.frame.css('width')]);
},
/**
* Updates the kws property of every ad in ads with common.ad.kws.
* @private
*/
updateKws = function() {
var ad;
for (ad in ads) {
if (ads.hasOwnProperty(ad)) {
ads[ad].kws = unique(common.ad.kws, ads[ad].kws);
}
}
},
/**
* {Object} test
* Used during plugin evaluation to ensure proper value replacement. All tests must return
* true or false to indicate failure or success. All test conditions are necessary for properly
* allowing modifications to values in the common object.
* @public
*/
test = (function() {
var
/**
* {RegExp} reserved
* Match any js-reserved characters
* @private
*/
reserved = /([\?\+\\\^\$\*\.\(\)\[\]\|])/g,
/**
* Combines sites with common.site and returns a period-delimited string.
* @param {String} val A site value.
* @returns {String}
* @private
*/
siteResolver = function(val) {
if (CN.site.testads) {
return common.site;
}
var
$val = val.split('.'),
$site = common.site.split('.'),
i = 0,
len = $site.length > $val.length ? $site.length : $val.length,
result = [];
for (; i < len; i++){
result[i] = ($val[i] || $site[i]);
}
return result.join('.');
},
/**
* {RegExp} urlPat
* @private
*/
urlPat = /^https?:/,
/**
* {RegExp} zoneEnd
* @private
*/
zoneEnd = /;$|$/,
/**
* {RegExp} zonePat
* @private
*/
zonePat = new RegExp(CN.site.testads ? "testads;" + "$" : "[\\w_;]+$"),
/**
* Sanitizes a zone value.
* @param {String} val A zone value
* @returns {String}
* @private
*/
zoneResolver = function(val) {
var
prop,
map = common.charmap;
if (zonePat.test(val)) {
for (prop in map) {
if (map.hasOwnProperty(prop)) {
val = val.replace(new RegExp(prop, "gi"), map[prop]);
}
}
return val.replace(zoneEnd, ';');
}
$D.warn("CN Dart zoneResolver", ["Invalid Dart Zone", val]);
return val;
},
/**
* Sanitizes a kw value.
* @param {String} val A kw value
* @returns {String}
* @private
*/
kwResolver = function(val) {
var
prop,
map = common.charmap;
for (prop in map) {
if (map.hasOwnProperty(prop)) {
val = val.replace(new RegExp(prop, "gi"), map[prop]);
}
}
return val;
};
return {
/**
* Allows modifications to the common.ad.kws
* @param {Object} val A hash containing a kws array.
* @returns {Boolean}
* @public
*/
ad : function(val) {
if (!val.kws) {
return false;
}
else {
common.ad.kws = jQuery.isArray(val.kws) ? unique(val.kws) : common.ad.kws;
updateKws();
return true;
}
},
/**
* Adds a valid param object to common.params.
* @param {Object} param An object containing the param, its default value, and (optionally) a function to
* refresh itself should the value depend on the current state of certain properties.
* @returns {Boolean}
* @public
*/
addparam : function(param) {
var
add = {};
if (!param && !param.pKey) {
return false;
}
add.defaultValue = param.pValue;
add.refresh = param.refresh;
common.params[param.pKey] = add;
return true;
},
/**
* Maps reserved characters to a value, and places them in common.charmap.
* @param {Object} val A hash of reserved characters and their replacements
* @returns {Boolean}
* @public
*/
charmap : function(val){
var
prop,
map = common.charmap = {};
for (prop in val) {
if (val.hasOwnProperty(prop)) {
map[prop.replace(reserved, '\\$1')] = val[prop];
}
}
return true;
},
/**
* Sets the common.dcopt flag.
* @param {Boolean} val If this is a dcopt ad
* @returns {Boolean}
* @public
*/
dcopt : function(val) {
if (CN.isBoolean(val)) {
common.dcopt = val;
return true;
}
else {
return false;
}
},
/**
* Sets the common.embed flag.
* @param {Boolean} val If this is an embedded ad
* @returns {Boolean}
* @public
*/
embed : function(val) {
if (CN.isBoolean(val)) {
common.embed = val;
return true;
}
else {
return false;
}
},
/**
* Sets the common.site value.
* @param {String} val The site string to be resolved and set
* @returns {Boolean}
* @public
*/
site : function(val){
common.site = siteResolver(val);
return true;
},
/**
* Sets the common.url value.
* @param {String} val The url string to format and set
* @returns {Boolean}
* @public
*/
url : function(val){
if(CN.isString(val)){
common.url = val.replace(urlPat,location.protocol);
return true;
}
return false;
},
/**
* Sets the common.zone value.
* @param {String} val The zone string to resolve and set
* @returns {Boolean}
* @public
*/
zone : function(val){
var ret = zoneResolver(val);
if (ret) {
common.zone = ret;
return true;
}
return false;
},
/**
* Publicizes test.zoneResolver.
* @param {String} val The zone string to resolve.
* @returns {String}
* @public
*/
adzone : zoneResolver,
/**
* Publicizes test.kwResolver.
* @param {String} val The kw string to resolve.
* @returns {String}
* @public
*/
kws : function(kws) {
var
arr = (kws) ? [].concat(kws) : [],
i = 0,
len = arr.length;
for (; i ');
},
/**
* Calls draw using the key from the event data
* @param {Object} e The event object
* @deprecated
* @private
*/
requestQueue = function(e) {
draw(e.data.key);
},
/**
* Event interface for refresh
* @param {object} e The event object
* @deprecated
* @private
*/
refreshQueue = function(e){
/* Map the event object e's data property for refresh */
draw(e.data.key,e.data.url);
},
/**
* DART request event handler.
* @param {Object} e The event object.
* @deprecated An anonymous function should call draw directly.
* @private
*/
requestHandler = function(e) {
draw(e.data.key);
};
/**
* Have ready be the default callback to CN.customEvents.dartInitialized.
* Registering a plugin unbinds this event.
*/
$window.one('CN.customEvents.dartInitialized', ready);
// Allow plugins to asynchronously send back data when they've completed
$window.bind('CN.customEvents.dartPlugin', plugin, plugin.finished);
timer.mark('start');
return {
/**
* Publicize buildurl.
* @param {Object} ad DART ad object
* @param {String} [url] Optional url to use in place of ad object properties
* @returns {String}
* @public
*/
buildurl : buildurl,
/**
* Fetches an ad call from the ads object.
* @param {String} key The property name
* @returns {Object}
* @public
*/
calls : function(key) {
return $.extend({}, (key === true ? ads : (CN.isNumber(key) ? ads[common.tiles[key]] : ads[key] || {})));
},
/**
* Publicize call.
* @param {String} name Unique name prefix for storage, container div, and iframe id generation
* @param {Object} [pars] Additional ad params to extend or override common.ad values
* @returns {CN.dart}
* @public
*/
call : call,
/**
* Publicize timer
* @public
*/
timer : timer,
/**
* Invokes call method when ads exist in the common tiles object.
* @param {String} name Unique name prefix for storage, container div, and iframe id generation
* @param {String} placement The dimensions of the ad
* @returns {CN.dart}
* @public
*/
clone : function(placement, name){
if (common.tiles.length) {
return call(name, {
sz : placement,
kws : ads[common.tiles[0]].kws
});
}
return false;
},
/**
* Publicizes refresh
* @param {String} ads Array, CSV or space-delimited list of ads id's
* @returns {CN.dart}
* @public
*/
refresh : refresh,
/**
* Returns a common object property
* @param {Array} props Array of properties to fetch.
* @returns {Object}
* @public
*/
get : function(props){
props = [].concat(props);
var
i = 0,
len = props.length,
ret = {},
prop;
for (; i < len; i++) {
prop = props[i];
ret[prop] = (common[prop] || common[prop] === false ? common[prop] : undefined);
}
return len > 1 ? ret : ret[prop];
},
/**
* Publicizes init
* @param {Object} pars Shared params - ex: site, zone, shared kws.
* @public
*/
init : init,
/**
* Publicizes the onFrameDraw callback if CN.dart is configured to draw iframed ads.
* @public
*/
ondraw : common.embed ? false : onFrameDraw,
/**
* Publicizes ready
* @public
*/
ready : ready,
/**
* Publicizes recalSize
* @param {Number} tile The tile number of the ad.
* @public
*/
recalSize : recalSize,
/**
* Allows plug-ins to be installed on CN.dart.plugin
* @param {Object} install The plug-in to install
* @returns {CN.dart}
* @public
*/
register : function(install) {
var
i = 0,
len;
if (!install) {
return this;
}
install = [].concat(install);
len = install.length;
for (; i < len; i++) {
plugin.register(install[i]);
}
return this;
},
/**
* {Object} remote
* Publicizes remote object.
* @deprecated
* @public
*/
remote : remote,
/**
* {Object} test
* Publicizes test object.
* @public
*/
test : test
};
}(jQuery, CN, CN.debug));
/**
* CN.dart.ipad
* CN.dart plug-in for iPad
* @author Russell Munson
* @requires CN, jQuery
*/
CN.dart.ipad = (function(ua) {
var
suff = ".ipad",
init = function(obj){
var
i = 0,
len = plugin.callbacks.length;
plugin.isFinished = true;
jQuery(window).trigger('CN.customEvents.dartPlugin', [plugin, {
site : CN.dart.get('site') + suff
}]);
for (; i < len; i++) {
plugin.callbacks[i]["func"].apply((plugin.callbacks[i]["scope"] || null), (plugin.callbacks[i]["args"] || []));
}
},
plugin = {
init : ua.indexOf('ipad') !== -1 ? init : false,
name : 'CN Ad User Agent Plugin',
callbacks : [],
isFinished : ua.indexOf('ipad') === -1
};
return plugin;
}(navigator.userAgent.toLowerCase()));
/**
* CN.dart.suppression
* @author Russell Munson
* @requires CN, jQuery
*/
CN.dart.suppression = (function() {
var
pars = CN.url.params(),
ret = false,
//Plugin interface method
init = function(obj) {
var
i = 0,
len = plugin.callbacks.length;
plugin.isFinished = true;
jQuery(window).trigger('CN.customEvents.dartPlugin', [plugin, ret]);
for (; i < len; i++) {
plugin.callbacks[i]["func"].apply((plugin.callbacks[i]["scope"] || null), (plugin.callbacks[i]["args"] || []));
}
},
plugin;
// Check for npu param, and toggle dcopt off if present
if (pars.npu === '1' || (pars.mbid && pars.mbid.match(/yhoo|google[1-5]?$/))){
ret = {
dcopt : false
};
}
plugin = {
// If conditions exist to modify ad common settings, define interface
// or return false to skip processing
init : ret ? init : false,
name : 'CN Ad Param-based Modifiers',
callbacks : [],
isFinished : !ret
};
return plugin;
}());
CN.dart.register([CN.dart.ipad,CN.dart.suppression]);