if(typeof CN==='undefined'){
var CN = {};
}
/**
* @requires CN, jQuery
*/
CN.dart = (function($, $D){
/* OBJECTS, CONSTANTS, PRIVATE VARS */
var ads={},
/** Common ad value object
* Used in get and plugin methods for easy read/write access
* to shared ad values.
*/
common={
ad : {},
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,
ord : Math.random() * 10000000000000000,
pause : [true], /* Store paused queue - used to manage multiple use of pause functionality
by unknown # of entities. First value in queue is for CN.dart. */
remote : '/services/dart/',
retry : false,
site : "",
tiles : [],
tile : 0,
url : (location.protocol || 'http:') + '//web.archive.org/web/20101027161406/http://ad.doubleclick.net/adj/',
zone : ""
},
kwregex=/kw=/g,
/**
* Shared message prefix
* Used in generating debug info.
*/
msg_pre="CN Ad ",
/**
* Message object for easily generating debug info.
*/
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',
pause : 'Pause queue emptied, unpausing ads.',
plug : 'Plugin Registered',
valid : 'Plugin Action Passed Validation'
},
/* These are for bad =( */
'false' : {
gen : 'Error',
call : 'Request Aborted',
queue : 'Request Faled To Be Added to Queue',
pause : 'Pause queue still contains ' + common.pause.length+ ' calls. Ads still paused',
plug : 'Plugin Skipped',
valid : 'Plugin Action Failed Validation'
}
},
/**
* Generate debug messages
* @param {string} type Message type defined in @msg
* @param {boolean} [state] Optional boolean value to indicate state [true=success,false=error]
* @memberOf CN.dart
* @private
*/
messager = function(type,state){
return msg_pre + msg[(state!==false).toString()][type || 'gen'];
},
nakedFrame=$('').attr({
frameBorder : 0,
scrolling : 'no'
}).css({
border : 'none',
margin : 0,
padding : 0
}),
/* METHODS */
/**
* Construct the ad request url
* @param {object} ad Dart ad object
* @param {string} [url] Optional url to use inplace of ad object properties
* @memberOf CN.dart
* @private
*/
buildurl = function(ad,url){
return common.url + common.site
+ '/' + (ad.zone || common.zone)
+ 'sz='+ ad.sz + ';'
+ (url || 'tile=' + ad.tile + ';'
+ (ad.tile===1 && common.dcopt===true ? 'dcopt=ist;' : '')
+ keywordString(ad)
+ 'ord='+common.ord+';'
);
},
/**
* Create and store individual ad objects by extending the base common.ad.
* Initiates ad call, or ads ad call to queue.
* @param {string} name Unique name prefix for storage, container div, and iframe id generation
* @param {object} [pars] Addtion ad params to extend/overide common.ad values.
* @memberOf CN.dart
* @private
*/
call = function(name,pars){
var key= name+pars.sz,
zone;
ads[key] = {
el : $('div#'+key+common.container),
sz : pars.sz,
kws : unique(common.ad.kws,pars.kws || []),
xkws : pars.kws || [],
store : pars.store===false ? false : common.ad.store,
tile : common.tiles.push(key),
collapse : pars.collapse===true,
cc : 0
};
if(pars.zone){
zone=test.adzone(pars.zone);
zone ? ads[key].zone=zone : false;
}
/* If intialization is complete, and we're not in paused-state
* execute ad call immediatly.
*/
if(common.embed || common.initialized && !common.pause.length){
return draw(key);
}
$D.info(messager('queue'), [key,ads[key]]);
/* Add to the request queue to be executed on CN.dart.ready() */
$(window).one('CN.customEvents.dartRequest',{key:key},function(){draw(key);});
return this;
},
/**
* Generate an script tag the adcall, and append to the container [placement][common.container]
* This is the actual call execution for embedded ads
* @param {string} placement Dart ad placement identifier
* @param {string} [url] Url to be used in place of ad pars
*/
drawEmbedded = function(placement,url) {
var ad = ads[placement],
src=(ad.url=buildurl(ad,url)) && ad.url;
ad.frame=false;
document.write('');
$D.info(messager('call'), [placement,ad]);
return this;
},
/**
* Generate an iframe for the ad, and append to the container [placement][common.container]
* This is the actual call execution for iframed ads
* @param {string} placement Dart ad placement identifier
* @param {string} [url] Url to be used in place of ad pars
*/
drawFrame = function(placement,url) {
var ad = ads[placement],
dims=ad.sz.split('x'),
frsrc=(ad.url=buildurl(ad,url)) && common.frameurl + '#' + encodeURIComponent(ad.url);
ad.el.html(ad.frame=nakedFrame.clone().attr({
id : placement,
name : placement,
height : ad.collapse ? 0 : dims[1],
width : dims[0],
src : frsrc
}).bind('load',{key:placement},onFrameDraw)
);
$D.info(messager('call'), [placement,ad]);
return this;
},
/**
* Default method for drawing ads defined here.
* If common.emed=true, init will set draw=drawEmbedded.
* The rest of the operations should be seamless.
*/
draw=drawFrame,
/**
* Generate a script el for embedded ads
* @param {script} src Ad source.
*/
embedScript = function(src){
var scp = document.createElement('script');
return scp.type="text/javascript",
scp.src=src,
scp;
},
/**
* Initialize CN.dart, setting common ad parameters and evaluating all registered plug-ins.
* Once plug-ins are all evaluated, CN.dart is put in a ready state, which signals the begining
* of ad calls. Any calls made before the ready stat is set will be placed in a queue.
* @param {object} pars Shared params - ex: Site, Zone, shared kws.
* @param {string} [url] Url to be used in place of ad pars
*/
init = function(pars){
common.site = pars.site,
common.zone = pars.zone,
common.ad = {
store : true,
kws : pars.kws,
tile : common.tile
};
updateKws();
test.charmap(pars.charmap);
plugin.run();
if(common.embed) {
draw=drawEmbedded;
$D.info(messager('embed',true),[]);
}
$(window).trigger('CN.customEvents.dartInitialized');
return ready();
},
/**
* Translate kw array into a ';'-delimited query string
* @param {object} ad Ad object to grab keywords from for translation.
* @param {string} [url] Url to be used in place of ad pars.
*/
keywordString = function(ad){
return 'kw=' + ad.kws.join(';kw=') + ';' + (ad.xkws.length ? '!c=' + ad.xkws.join(';!c=') + ';' : '');
},
/**
* Callback even dispatcher, executed on frame-load
* @param {object} e Event object for callback
*/
onFrameDraw = function(e){
var ad = ads[e.data.key];
try {
ad.doc=ad.frame.contents();
} catch(err) {
$D.user(e, [e.target, e.target.id]);
}
$(window).trigger('CN.customEvents.dartAdDrawn',[e.data.key,"#"+e.data.key, ad]);
_resize(e);
},
plugin = {
/**
* Plug-in holder array.
* Registered plug-ins are stored here.
* @see CN.dart.register
*/
queue : [],
register : function(plug){
if(!plug || !plug.init){
$D.info(messager('plug',false), [plug ? plug.name : '', plug || {}]);
return false;
}
this.queue.push(plug);
$D.info(messager('plug'), [plug.name || '', plug]);
return true;
},
run : function(){
var i=0,
len=this.queue.length,
val,
passed=false,
plug;
for(; i (adtop + ad.frame.height()) || (top + win.height()) < adtop);
},
updateKws = function(){
for (var ad in ads){
ads[ad].kws = unique(common.kws,ads[ad].kws)
}
},
/**
* All test conditions necessary for properly allowing modifications to
* values in the common object.
* @description Used during plugin evaluation to ensure proper value replacement.
* All tests must return true or false to indicated falure or success.
* @memberOf CN.dart
* @private
* @event
*/
test = (function(){
var
// Match any js-reserved characters
reserved=/([\?\+\\\^\$\*\.\(\)\[\]\|])/g,
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 1 ? ret : ret[prop];
},
init : init,
ondraw : common.embed ? false : onFrameDraw,
ready : ready,
register : function(install){
if(!install){
return this;
}
install = [].concat(install);
var i=0,
len=install.length;
for(;i