/* •••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
   ••  Project: jQuery LazyLoad For Advertisement                   ••
   ••  Author:  delarueguillaume@gmail.com                          ••
   ••  WebSite : http://www.web2ajax.fr/                            ••
   ••  Date:    2010                                                ••
   ••  Version: 1.2 (30 march 2010) : Hight Imporvements of code    ••   
   ••  Version: 1.1 (25 march 2010) : Improve IE compatibility      ••
   ••  Version: 1.0 (24 march 2010)                                 ••
   •••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••   
   
    Defer Advertisement loading and load only if the ad is in the visible part of
    the page like lazyLoad for pictures.
    -> Highly improve general page load
    -> Improve cpu load of visitor in case of displaying flash banners (only displayed if necessary)
    –> Compatibility with AdSense and many other advertisers
    -> Cross Browser suupprt (IE5.5+, Firefox, Opera, Chrome, Safari)
    
    A big thanks to Mika Tuupola for the Lazy load part
    -> http://www.appelsiini.net/projects/lazyload 
    
    Another big thanks to Thomas Aylott -- SubtleGradient.com and his MooTools based document.write replacement
    -> http://SubtleGradient.com/
    
---------------------------------------------------------------------- */
(function($){$.lazyLoadAdRunning=false;$.lazyLoadAdTimers=[];$.fn.lazyLoadAd=function(options){var settings={threshold:0,failurelimit:1,forceLoad:false,event:"scroll",viewport:window,onComplete:false,timeout:2000,debug:false};if(options){$.extend(settings,options);}
function _debug(){if(typeof console!='undefined'&&settings.debug){var args=[];for(var i=0;i<arguments.length;i++){args.push(arguments[i]);}
try{console.log('LazyLoadAD |',args);}catch(e){};}}
var elements=this;$(settings.viewport).bind("checkLazyLoadAd",function(){var counter=0;elements.each(function(){if($.lazyLoadAdRunning){if($.lazyLoadAdTimers['runTimeOut'])clearTimeout($.lazyLoadAdTimers['runTimeOut']);$.lazyLoadAdTimers['runTimeOut']=setTimeout(function(){$(settings.viewport).trigger("checkLazyLoadAd");},800);return false;}else if(settings.forceLoad==true){$(this).trigger("load");}else if(!$.belowthefold(this,settings)&&!$.abovethetop(this,settings)){$(this).trigger("load");}else{if(counter++>settings.failurelimit){return false;}}});var temp=$.grep(elements,function(element){return!element.loaded;});elements=$(temp);});if("scroll"==settings.event){$(settings.viewport).bind("scroll",function(event){$(settings.viewport).trigger("checkLazyLoadAd");});}
this.each(function(){var self=this;if(undefined==$(self).attr("original")){$(self).attr("original",$(self).attr("src"));}
if("scroll"!=settings.event||undefined==$(self).attr("src")||($.abovethetop(self,settings)||$.belowthefold(self,settings))){$(self).removeAttr("src");self.loaded=false;}else{self.loaded=true;}
$(self).one("load",function(){if(!this.loaded){$.lazyLoadAdRunning=true;$(self).one('lazyLoadComplete',function(){$.lazyLoadAdRunning=false;$(self).attr("src",$(self).attr("original"));$(self).removeAttr("original");self.loaded=true;if(typeof settings.onComplete=='function'){try{settings.onComplete()}catch(e){};}});var scripts=[],script,regexp=/<code[^>]*>([\s\S]*?)<\/code>/gi;while((script=regexp.exec($(self).html()))){scripts.push(script[1].replace('<!--','').replace('//-->',''));}
if(scripts.length)scripts=scripts.join('\n');else scripts='';try{if(scripts!='')eval(scripts);}catch(e){};var wrapper=$('<div>'),fragment=document.createDocumentFragment(),numWrappers=0,isDocumentWriteOverload=false;document._writeOriginal=document.write;document.write=function(){var args=arguments,id='document_write'+new Date().getTime().toString(36);id=$('<span>',{id:id});$(document.write.context).append(id);_debug('Overload document.write : ',id,document.write.context,args);isDocumentWriteOverload=true;numWrappers++;function documentWrite(){numWrappers--;var html='';for(var i=0;i<args.length;i++)html+=args[i];_debug("Fragment append : ",numWrappers,id.attr('id'),html);fragment.appendChild($(wrapper.html(html))[0]);id.replaceWith(fragment);if(numWrappers==0)$(document.write.context).trigger('lazyLoadComplete');}
setTimeout(documentWrite,0);};document.write.context=$(self)[0];_debug('------------------------------  Lazy Load Ad CALL ----');_debug('Context : '+document.write.context);var script=document.createElement("script"),url=$(self).attr("original");script.src=url;script.type="text/javascript";document.write.context.appendChild(script);var callback=function(){_debug('Load Ad Code',url);setTimeout(function(){if(!isDocumentWriteOverload){_debug('... is considred as injected');$(document.write.context).trigger('lazyLoadComplete');}
$(script).remove();},300);};script.onreadystatechange=function(){if(script.readyState=='loaded'||script.readyState=='complete'){callback();}}
script.onload=function(){callback();return;}
try{if((Prototype.Browser.WebKit&&!navigator.userAgent.match(/Version\/3/))||Prototype.Browser.Opera){$.lazyLoadAdTimers[url]=setInterval(function(){if(/loaded|complete/.test(document.readyState)){clearInterval($.lazyLoadAdTimers[url]);callback();}},10);}}catch(e){};if($.lazyLoadAdTimers['failBack'])clearTimeout($.lazyLoadAdTimers['failBack']);$.lazyLoadAdTimers['failBack']=setTimeout(function(){if($.lazyLoadAdRunning){_debug('Fail back actioned after '+settings.timeout+' ms');callback();}},settings.timeout);};});if("scroll"!=settings.event){$(self).bind(settings.event,function(event){if(!self.loaded){$(self).trigger("load");}});}});$(settings.viewport).trigger('checkLazyLoadAd');return this;};$.belowthefold=function(element,settings){if(settings.viewport===undefined||settings.viewport===window){var fold=$(window).height()+$(window).scrollTop();}else{var fold=$(settings.viewport).offset().top+$(settings.viewport).height();}
return fold<=$(element).offset().top-settings.threshold;};$.abovethetop=function(element,settings){if(settings.viewport===undefined||settings.viewport===window){var fold=$(window).scrollTop();}else{var fold=$(settings.viewport).offset().top;}
return fold>=$(element).offset().top+settings.threshold+$(element).height();};})(jQuery);
