1/* theme-scripts.min.js */ 2var breakingStart=true;var breakingSpeed=40;var breakingScroll=[0,0,0,0,0,0,0,0,0,0];var breakingOffset=[0,0,0,0,0,0,0,0,0,0];var elementsToClone=[true,true,true,true,true,true,true,true,true,true];var elementsActive=[];var theCount=[0,0,0,0,0,0,0,0,0,0];(function($){"use strict";function ot_Slider_move(itemid){var thisel=itemid,currentb=thisel.parent().parent().children(".ot-slides").children(".ot-slide").eq(thisel.index());thisel.addClass("active").siblings("a").removeClass("active");currentb.addClass("active").siblings(".ot-slide").removeClass("active");thisel.parent().parent().css("height",currentb.attr("rel")+"px");}var sliderwidth=0;jQuery(document).scroll(function(){var position=jQuery(window).scrollTop();if(position>=jQuery('.header #main-menu.thisisfixed').attr("rel")){jQuery('.header #main-menu.thisisfixed').addClass("floatingmainmenu");}else{jQuery('.header #main-menu.thisisfixed').removeClass("floatingmainmenu");}});jQuery(window).resize(function(){var difference=(100/sliderwidth*jQuery(".ot-slider").width())/100;jQuery(".ot-slider .ot-slides .ot-slide-overlay").css("zoom",difference);jQuery(".ot-slider .ot-slide").each(function(){var thisel=jQuery(this);jQuery(thisel).find("img").one('load',function(){thisel.attr("rel",thisel.height());jQuery(".ot-slider").each(function(){var thisel=jQuery(this),curel=thisel.find(".ot-slides").children(".ot-slide").eq(0);thisel.find(".ot-slider-thumbs").children("a").eq(0).addClass("active");curel.addClass("active");thisel.css("height",curel.attr("rel")+"px");});}).each(function(){if(this.complete){jQuery(this).load();}});});});jQuery(window).ready(function(){jQuery("body").append("<div class='menu-block'></div>");jQuery('.header #main-menu.thisisfixed').each(function(){var thiselement=jQuery(this);jQuery(this).children(".wrapper").wrap("<div class='subset'></div>");if(!thiselement.hasClass("thisisfloat")){thiselement.attr("rel",thiselement.offset().top);}});
2jQuery("#main-menu .wrapper").prepend("<a href='#' class='menu-dropy'><i class='fa fa-align-justify'></i> Toggle menu</a>");jQuery(".menu-dropy").click(function(){var thisel=jQuery(this).siblings("ul");thisel.toggle();return false;});jQuery("#main-menu .wrapper > ul > li.overlay").hover(function(){jQuery(".boxed.active .header .header-topmenu").css("z-index","0");jQuery(".menu-overlay").fadeIn(200);}).mouseleave(function(){jQuery(".menu-overlay").fadeOut(200);jQuery(".boxed.active .header .header-topmenu").css("z-index","1002");});jQuery("a[href=#open-jumplist]").click(function(){jQuery(".ot-jumplist").addClass("active");return false;});jQuery("a[href=#close-jumplist]").click(function(){jQuery(".ot-jumplist").removeClass("active");return false;});jQuery(".ot-slider .ot-slide").each(function(){var difference=(100/sliderwidth*jQuery(".ot-slider").width())/100,thisel=jQuery(this);jQuery(".ot-slider .ot-slides .ot-slide-overlay").css("zoom",difference);sliderwidth=1200;jQuery(thisel).find("img").one('load',function(){thisel.attr("rel",thisel.height());jQuery(".ot-slider").each(function(){var thisel=jQuery(this),curel=thisel.find(".ot-slides").children(".ot-slide").eq(0);thisel.find(".ot-slider-thumbs").children("a").eq(0).addClass("active");curel.addClass("active");thisel.css("height",curel.attr("rel")+"px");});}).each(function(){if(this.complete){jQuery(this).load();}});});jQuery(".ot-slider-thumbs a").click(function(){ot_Slider_move(jQuery(this));return false;});jQuery(".ot-slider .page-move.move-left").click(function(){var thisel=jQuery(this).parent(),nextind=thisel.find(".ot-slider-thumbs").children("a.active");if(nextind.prev().index()>=0){ot_Slider_move(nextind.prev());}else{ot_Slider_move(nextind.parent().children("a").last());}return false;});jQuery(".ot-slider .page-move.move-right").click(function(){var thisel=jQuery(this).parent(),nextind=thisel.find(".ot-slider-thumbs").children("a.active");if(nextind.next().index()>=0){ot_Slider_move(nextind.next());}else{ot_Slider_move(nextind.parent().children("a").eq(0));}return false;});jQuery("#main-menu .big-drop-2").each(function(){jQuery(this).find("ul.sub-menu > li > ul > li").eq(0).addClass("active");});jQuery("#main-menu .big-drop-2 > ul.sub-menu > li > ul > li > a").click(function(){var thisel=jQuery(this).parent(),thisindex=thisel.index();thisel.addClass("active").siblings("li").removeClass("active");jQuery("#main-menu .big-drop-2 > ul.sub-menu > li > ul.sub-menu").each(function(){var thisel=jQuery(this);thisel.css("height",thisel.find("li.active .menu-content-inner").height());});return false;});jQuery("#main-menu .big-drop-2").hover(function(){jQuery("#main-menu .big-drop-2 > ul.sub-menu > li > ul.sub-menu").each(function(){var thisel=jQuery(this);thisel.css("height",thisel.find("li.active .menu-content-inner").height());});});jQuery('a[href="#close-alert"]').click(function(){jQuery(this).parent().animate({opacity:0,padding:"0px 13px",margin:"0px",height:"0px"},300,function(){});return false;});jQuery(".accordion > div > a").click(function(){var thisel=jQuery(this).parent();if(thisel.hasClass("active")){thisel.removeClass("active").children("div").animate({"height":"toggle","opacity":"toggle","padding-top":"toggle"},300);return false;}thisel.siblings("div").each(function(){var tz=jQuery(this);if(tz.hasClass("active")){tz.removeClass("active").children("div").animate({"height":"toggle","opacity":"toggle","padding-top":"toggle"},300);}});thisel.addClass("active").children("div").animate({"height":"toggle","opacity":"toggle","padding-top":"toggle"},300);return false;});jQuery(".short-tabs").each(function(){var thisel=jQuery(this);thisel.children("div").eq(0).addClass("active");thisel.children("ul").children("li").eq(0).addClass("active");});jQuery(".short-tabs > ul > li a").click(function(){var thisel=jQuery(this).parent();thisel.siblings(".active").removeClass("active");thisel.addClass("active");thisel.parent().siblings("div.active").removeClass("active");thisel.parent().siblings("div").eq(thisel.index()).addClass("active");return false;});jQuery(".lightbox").click(function(){jQuery(".lightbox").css('overflow','hidden');jQuery("body").css('overflow','auto');jQuery(".lightbox .lightcontent").fadeOut('fast');jQuery(".lightbox").fadeOut('slow');}).children().click(function(e){return false;});jQuery("a[href='#font-size-up']").click(function(){var cursize=jQuery('.f-size-number').html();if(parseInt(cursize)<24){jQuery('.f-size-number').html(parseInt(cursize)+2);jQuery('.article-text p').css("font-size",(parseInt(cursize)+2)+"px");}return false;});jQuery("a[href='#font-size-down']").click(function(){var cursize=jQuery('.f-size-number').html();if(parseInt(cursize)>16){jQuery('.f-size-number').html(parseInt(cursize)-2);jQuery('.article-text p').css("font-size",(parseInt(cursize)-2)+"px");}return false;});jQuery(".breaking-news .breaking-block").each(function(){var thisitem=jQuery(this);thisitem.find("ul li").css("width",thisitem.width()+"px");});
2jQuery(".breaking-controls a").click(function(){var thisitem=jQuery(this),itemul=thisitem.parent().parent().find(".breaking-block ul"),items=itemul.find("li"),sega=(items.size()-1)*(items.width()+parseInt(items.css("margin-right")));if(thisitem.hasClass("breaking-arrow-left")){if(0>=Math.abs(parseInt(itemul.css("margin-left")))){itemul.css("margin-left",(sega*(-1))+"px");}else{itemul.css("margin-left",(parseInt(itemul.css("margin-left"))+(items.width()+parseInt(items.css("margin-right"))))+"px");}}else{if(sega<=Math.abs(parseInt(itemul.css("margin-left")))){itemul.css("margin-left","0px");}else{itemul.css("margin-left",(parseInt(itemul.css("margin-left"))+(items.width()+parseInt(items.css("margin-right")))*(-1))+"px");}}return false;});jQuery(".breaking-news").mouseenter(function(){var thisindex=jQuery(this).attr("rel");clearTimeout(elementsActive[thisindex]);}).mouseleave(function(){var thisindex=jQuery(this).attr("rel");elementsActive[thisindex]=false;});start();jQuery('.ot-star-rating').each(function(i){var bottom_of_object=jQuery(this).offset().top+jQuery(this).outerHeight(),bottom_of_window=jQuery(window).scrollTop()+jQuery(window).height();if(bottom_of_window<=bottom_of_object){var thisel=jQuery(this).children("span");thisel.addClass("setforanimate").attr("rel",thisel.css("width")).css("width","0px");}});jQuery(window).scroll(function(){jQuery('.ot-star-rating').each(function(i){var bottom_of_object=jQuery(this).offset().top+jQuery(this).outerHeight(),bottom_of_window=jQuery(window).scrollTop()+jQuery(window).height();if(bottom_of_window>bottom_of_object){var thisel=jQuery(this).children("span.setforanimate");thisel.removeClass("setforanimate").css("display","block").animate({'width':thisel.attr("rel")},500);}});});});})(jQuery);function start(){var z=0;jQuery('.breaking-block ul').each(function(){var thisitem=jQuery(this),thisindex=z;z=z+1;if(thisitem.find("li").size()>0){if(!breakingStart){return false;}var theBreakingMargin=parseInt(thisitem.find("li").css("margin-right")),theBreakingWidth=parseInt(thisitem.parent().css("width"));theCount[thisindex]=((Math.ceil(thisitem.find("li").size())/2)*(theBreakingWidth+theBreakingMargin));if(elementsToClone[thisindex]){jQuery(this).parent().parent().addClass("isscrolling");jQuery('.breaking-block').eq(thisindex).parent().attr("rel",thisindex);thisitem.find("li").clone().appendTo(this);elementsToClone[thisindex]=false;}var theNumber=theCount[thisindex]+breakingOffset[thisindex];if(Math.abs(theNumber)<=(Math.abs(breakingScroll[thisindex]))){cloneBreakingLine(thisindex);}if(!elementsActive[thisindex]){elementsActive[thisindex]=setInterval(function(){beginScrolling(thisitem,thisindex);},breakingSpeed);}}});setTimeout("start()",breakingSpeed);}function beginScrolling(thisitem,thisindex){breakingScroll[thisindex]=breakingScroll[thisindex]-1;thisitem.css("left",breakingScroll[thisindex]+'px');}function cloneBreakingLine(thisindex){breakingScroll[thisindex]=0;jQuery('.breaking-block').eq(thisindex).find('ul').css("left","0px");}function lightboxclose(){jQuery(".lightbox").css('overflow','hidden');jQuery(".lightbox .lightcontent").fadeOut('fast');jQuery(".lightbox").fadeOut('slow');jQuery("body").css('overflow','auto');} 3 4/* lightbox.min.js */ 5var imageSrc="",thisimage=""; 6jQuery(document).ready(function(){var c=jQuery(".lightbox-photo").length;jQuery(".lightbox-photo").click(function(){var a=jQuery(this).attr("href"),d=jQuery(this).offset();jQuery("body").before("<div id='lightbox-box'><a href='#'>Close</a><div style='top:"+d.top+"px;left:"+d.left+"px;width:"+jQuery(this).find("img").width()+"px;height:"+jQuery(this).find("img").height()+"px;'><img src='images/px.gif' alt='' title='' /></div><span class='lightbox-bg'></span></div>");jQuery(this).attr("title")&&jQuery("#lightbox-box > div > img").before("<span>"+ 7jQuery(this).attr("title")+"</span>");1<c&&jQuery("#lightbox-box > div > img").before("<font><a href='#' id='lightbox-left'><-</a><a href='#' id='lightbox-right'>-></a></font>");setTimeout("setImageSize('"+a+"')",500);return!1})});function takeNextPhoto(c){c=jQuery(".lightbox-photo").eq(c).attr("href");setTimeout("setImageSize('"+c+"')",500)}jQuery(window).resize(function(){});var thetop=0; 8jQuery(document).scroll(function(){if(jQuery("#lightbox-box > div")){var c=parseInt($(window).scrollTop());jQuery("#lightbox-box > div").css("top",parseInt(c+thetop)+"px")}}); 9function setImageSize(c){var a=new Image;a.onload=function(){if(jQuery(window).height()-150>=a.height&&jQuery(window).width()>=a.width-150)var d=a.height,b=a.width;else jQuery(window).width()<=jQuery(window).height()?a.width<=a.height?(b=a.width/a.height*(jQuery(window).height()-150),d=a.height/a.width*b):(d=a.height/a.width*(jQuery(window).width()-150),b=a.width/a.height*d):(b=a.width/a.height*(jQuery(window).height()-150),d=a.height/a.width*b);
9var e=$(window).scrollTop();jQuery("#lightbox-box > div > img").attr("src", 10"images/px.gif");jQuery("#lightbox-box > div").css("height",d+"px").css("width",b+"px").css("top",jQuery(window).height()/2-d/2+e+"px").css("left",jQuery(window).width()/2-b/2+"px");jQuery("#lightbox-box").addClass("blackout");thetop=parseInt(jQuery(window).height()/2-d/2);setTimeout(function(){jQuery("#lightbox-box > a").fadeIn("slow");jQuery("#lightbox-box > div > span").fadeIn("slow");jQuery("#lightbox-box > div > font").fadeIn("slow");jQuery("#lightbox-box > div > img").attr("src",c);thisimage= 11c},500)};jQuery(".lightbox-bg").click(function(){jQuery(this).parent().remove()}).children().click(function(a){return!1});jQuery("#lightbox-box > a").click(function(){jQuery(this).parent().remove();return!1});jQuery("#lightbox-left").click(function(){jQuery("#lightbox-box").removeClass("blackout");var a=jQuery(".lightbox-photo").length;for(n=0;n<a;n++)if(jQuery(".lightbox-photo").eq(n).attr("href")==thisimage)var b=0>=n-1?a-1:n-1;jQuery("#lightbox-box > div > span").remove();jQuery(".lightbox-photo").eq(b).attr("title")&& 12jQuery("#lightbox-box > div > img").before("<span>"+jQuery(".lightbox-photo").eq(b).attr("title")+"</span>");takeNextPhoto(b);return!1});jQuery("#lightbox-right").click(function(){jQuery("#lightbox-box").removeClass("blackout");var a=jQuery(".lightbox-photo").length;for(n=0;n<a;n++)if(jQuery(".lightbox-photo").eq(n).attr("href")==thisimage)var b=n+1>=a?0:parseInt(n)+1;jQuery("#lightbox-box > div > span").remove();jQuery(".lightbox-photo").eq(b).attr("title")&&jQuery("#lightbox-box > div > img").before("<span>"+ 13jQuery(".lightbox-photo").eq(b).attr("title")+"</span>");takeNextPhoto(b);return!1});a.src=c}; 14 15/* ot-menus.js */ 16var _otmenu_ipad = (typeof _otmenu_ipad != 'undefined')?_otmenu_ipad:true; 17var _otmenu_iphone = (typeof _otmenu_iphone != 'undefined')?_otmenu_iphone:true; 18 19(function( $ ) { 20 "use strict"; 21 22 if(_otmenu_ipad) jQuery("body").addClass("ot-menu-ipad-enable"); 23 if(_otmenu_iphone) jQuery("body").addClass("ot-menu-iphone-enable"); 24 25 var _ot_menulist = ""; 26 27 jQuery(".ot-menu-add").each(function(){ 28 var thisel = jQuery(this); 29 _ot_menulist = _ot_menulist+"<li><h3>"+thisel.attr('rel')+"</h3></li>"+thisel.html()+"<li><br /></li>"; 30 }); 31
vendor: 6,010 bytes, lines 32-252
32 jQuery("body").prepend("<a href='#' class='ot-menu-toggle'>"+$('.header-logo a').html()+"</a>").prepend("<ul id='ot-menu-list' class='ot-menu-list'></ul>").find("#ot-menu-list").html(_ot_menulist); 33 34 jQuery(".ot-menu-toggle").click(function(){ 35 jQuery("body").toggleClass("ot-menu-active"); 36 return false; 37 }); 38 39})(jQuery); 40 41/* fancybox.js */ 42/*! 43 * fancyBox - jQuery Plugin 44 * version: 2.1.4 (Thu, 10 Jan 2013) 45 * @requires jQuery v1.6 or later 46 * 47 * Examples at http://fancyapps.com/fancybox/ 48 * License: www.fancyapps.com/fancybox/#license 49 * 50 * Copyright 2012 Janis Skarnelis - [email protected] 51 * 52 */ 53 54(function (window, document, $, undefined) { 55 "use strict"; 56 57 var W = $(window), 58 D = $(document), 59 F = $.fancybox = function () { 60 F.open.apply( this, arguments ); 61 }, 62 IE = navigator.userAgent.match(/msie/), 63 didUpdate = null, 64 isTouch = document.createTouch !== undefined, 65 66 isQuery = function(obj) { 67 return obj && obj.hasOwnProperty && obj instanceof $; 68 }, 69 isString = function(str) { 70 return str && $.type(str) === "string"; 71 }, 72 isPercentage = function(str) { 73 return isString(str) && str.indexOf('%') > 0; 74 }, 75 isScrollable = function(el) { 76 return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight))); 77 }, 78 getScalar = function(orig, dim) { 79 var value = parseInt(orig, 10) || 0; 80 81 if (dim && isPercentage(orig)) { 82 value = F.getViewport()[ dim ] / 100 * value; 83 } 84 85 return Math.ceil(value); 86 }, 87 getValue = function(value, dim) { 88 return getScalar(value, dim) + 'px'; 89 }; 90 91 $.extend(F, { 92 // The current version of fancyBox 93 version: '2.1.4', 94 95 defaults: { 96 padding : 15, 97 margin : 20, 98 99 width : 800, 100 height : 600, 101 minWidth : 100, 102 minHeight : 100, 103 maxWidth : 9999, 104 maxHeight : 9999, 105 106 autoSize : true, 107 autoHeight : false, 108 autoWidth : false, 109 110 autoResize : true, 111 autoCenter : !isTouch, 112 fitToView : true, 113 aspectRatio : false, 114 topRatio : 0.5, 115 leftRatio : 0.5, 116 117 scrolling : 'auto', // 'auto', 'yes' or 'no' 118 wrapCSS : '', 119 120 arrows : true, 121 closeBtn : true, 122 closeClick : false, 123 nextClick : false, 124 mouseWheel : true, 125 autoPlay : false, 126 playSpeed : 3000, 127 preload : 3, 128 modal : false, 129 loop : true, 130 131 ajax : { 132 dataType : 'html', 133 headers : { 'X-fancyBox': true } 134 }, 135 iframe : { 136 scrolling : 'auto', 137 preload : true 138 }, 139 swf : { 140 wmode: 'transparent', 141 allowfullscreen : 'true', 142 allowscriptaccess : 'always' 143 }, 144 145 keys : { 146 next : { 147 13 : 'left', // enter 148 34 : 'up', // page down 149 39 : 'left', // right arrow 150 40 : 'up' // down arrow 151 }, 152 prev : { 153 8 : 'right', // backspace 154 33 : 'down', // page up 155 37 : 'right', // left arrow 156 38 : 'down' // up arrow 157 }, 158 close : [27], // escape key 159 play : [32], // space - start/stop slideshow 160 toggle : [70] // letter "f" - toggle fullscreen 161 }, 162 163 direction : { 164 next : 'left', 165 prev : 'right' 166 }, 167 168 scrollOutside : true, 169 170 // Override some properties 171 index : 0, 172 type : null, 173 href : null, 174 content : null, 175 title : null, 176 177 // HTML templates 178 tpl: { 179 wrap : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 180 image : '<img class="fancybox-image" src="{href}" alt="" />', 181 iframe : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>', 182 error : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', 183 closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>', 184 next : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>', 185 prev : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>' 186 }, 187 188 // Properties for each animation type 189 // Opening fancyBox 190 openEffect : 'fade', // 'elastic', 'fade' or 'none' 191 openSpeed : 250, 192 openEasing : 'swing', 193 openOpacity : true, 194 openMethod : 'zoomIn', 195 196 // Closing fancyBox 197 closeEffect : 'fade', // 'elastic', 'fade' or 'none' 198 closeSpeed : 250, 199 closeEasing : 'swing', 200 closeOpacity : true, 201 closeMethod : 'zoomOut', 202 203 // Changing next gallery item 204 nextEffect : 'elastic', // 'elastic', 'fade' or 'none' 205 nextSpeed : 250, 206 nextEasing : 'swing', 207 nextMethod : 'changeIn', 208 209 // Changing previous gallery item 210 prevEffect : 'elastic', // 'elastic', 'fade' or 'none' 211 prevSpeed : 250, 212 prevEasing : 'swing', 213 prevMethod : 'changeOut', 214 215 // Enable default helpers 216 helpers : { 217 overlay : true, 218 title : true 219 }, 220 221 // Callbacks 222 onCancel : $.noop, // If canceling 223 beforeLoad : $.noop, // Before loading 224 afterLoad : $.noop, // After loading 225 beforeShow : $.noop, // Before changing in current item 226 afterShow : $.noop, // After opening 227 beforeChange : $.noop, // Before changing gallery item 228 beforeClose : $.noop, // Before closing 229 afterClose : $.noop // After closing 230 }, 231 232 //Current state 233 group : {}, // Selected group 234 opts : {}, // Group options 235 previous : null, // Previous element 236 coming : null, // Element being loaded 237 current : null, // Currently loaded element 238 isActive : false, // Is activated 239 isOpen : false, // Is currently open 240 isOpened : false, // Have been fully opened at least once 241 242 wrap : null, 243 skin : null, 244 outer : null, 245 inner : null, 246 247 player : { 248 timer : null, 249 isActive : false 250 }, 251 252 // Loaders
vendor: 34,999 bytes, lines 253-1730
253 ajaxLoad : null, 254 imgPreload : null, 255 256 // Some collections 257 transitions : {}, 258 helpers : {}, 259 260 /* 261 * Static methods 262 */ 263 264 open: function (group, opts) { 265 if (!group) { 266 return; 267 } 268 269 if (!$.isPlainObject(opts)) { 270 opts = {}; 271 } 272 273 // Close if already active 274 if (false === F.close(true)) { 275 return; 276 } 277 278 // Normalize group 279 if (!$.isArray(group)) { 280 group = isQuery(group) ? $(group).get() : [group]; 281 } 282 283 // Recheck if the type of each element is `object` and set content type (image, ajax, etc) 284 $.each(group, function(i, element) { 285 var obj = {}, 286 href, 287 title, 288 content, 289 type, 290 rez, 291 hrefParts, 292 selector; 293 294 if ($.type(element) === "object") { 295 // Check if is DOM element 296 if (element.nodeType) { 297 element = $(element); 298 } 299 300 if (isQuery(element)) { 301 obj = { 302 href : element.data('fancybox-href') || element.attr('href'), 303 title : element.data('fancybox-title') || element.attr('title'), 304 isDom : true, 305 element : element 306 }; 307 308 if ($.metadata) { 309 $.extend(true, obj, element.metadata()); 310 } 311 312 } else { 313 obj = element; 314 } 315 } 316 317 href = opts.href || obj.href || (isString(element) ? element : null); 318 title = opts.title !== undefined ? opts.title : obj.title || ''; 319 320 content = opts.content || obj.content; 321 type = content ? 'html' : (opts.type || obj.type); 322 323 if (!type && obj.isDom) { 324 type = element.data('fancybox-type'); 325 326 if (!type) { 327 rez = element.prop('class').match(/fancybox\.(\w+)/); 328 type = rez ? rez[1] : null; 329 } 330 } 331 332 if (isString(href)) { 333 // Try to guess the content type 334 if (!type) { 335 if (F.isImage(href)) { 336 type = 'image'; 337 338 } else if (F.isSWF(href)) { 339 type = 'swf'; 340 341 } else if (href.charAt(0) === '#') { 342 type = 'inline'; 343 344 } else if (isString(element)) { 345 type = 'html'; 346 content = element; 347 } 348 } 349 350 // Split url into two pieces with source url and content selector, e.g, 351 // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id" 352 if (type === 'ajax') { 353 hrefParts = href.split(/\s+/, 2); 354 href = hrefParts.shift(); 355 selector = hrefParts.shift(); 356 } 357 } 358 359 if (!content) { 360 if (type === 'inline') { 361 if (href) { 362 content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7 363 364 } else if (obj.isDom) { 365 content = element; 366 } 367 368 } else if (type === 'html') { 369 content = href; 370 371 } else if (!type && !href && obj.isDom) { 372 type = 'inline'; 373 content = element; 374 } 375 } 376 377 $.extend(obj, { 378 href : href, 379 type : type, 380 content : content, 381 title : title, 382 selector : selector 383 }); 384 385 group[ i ] = obj; 386 }); 387 388 // Extend the defaults 389 F.opts = $.extend(true, {}, F.defaults, opts); 390 391 // All options are merged recursive except keys 392 if (opts.keys !== undefined) { 393 F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false; 394 } 395 396 F.group = group; 397 398 return F._start(F.opts.index); 399 }, 400 401 // Cancel image loading or abort ajax request 402 cancel: function () { 403 var coming = F.coming; 404 405 if (!coming || false === F.trigger('onCancel')) { 406 return; 407 } 408 409 F.hideLoading(); 410 411 if (F.ajaxLoad) { 412 F.ajaxLoad.abort(); 413 } 414 415 F.ajaxLoad = null; 416 417 if (F.imgPreload) { 418 F.imgPreload.onload = F.imgPreload.onerror = null; 419 } 420 421 if (coming.wrap) { 422 coming.wrap.stop(true, true).trigger('onReset').remove(); 423 } 424 425 F.coming = null; 426 427 // If the first item has been canceled, then clear everything 428 if (!F.current) { 429 F._afterZoomOut( coming ); 430 } 431 }, 432 433 // Start closing animation if is open; remove immediately if opening/closing 434 close: function (event) { 435 F.cancel(); 436 437 if (false === F.trigger('beforeClose')) { 438 return; 439 } 440 441 F.unbindEvents(); 442 443 if (!F.isActive) { 444 return; 445 } 446 447 if (!F.isOpen || event === true) { 448 $('.fancybox-wrap').stop(true).trigger('onReset').remove(); 449 450 F._afterZoomOut(); 451 452 } else { 453 F.isOpen = F.isOpened = false; 454 F.isClosing = true; 455 456 $('.fancybox-item, .fancybox-nav').remove(); 457 458 F.wrap.stop(true, true).removeClass('fancybox-opened'); 459 460 F.transitions[ F.current.closeMethod ](); 461 } 462 }, 463 464 // Manage slideshow: 465 // $.fancybox.play(); - toggle slideshow 466 // $.fancybox.play( true ); - start 467 // $.fancybox.play( false ); - stop 468 play: function ( action ) { 469 var clear = function () { 470 clearTimeout(F.player.timer); 471 }, 472 set = function () { 473 clear(); 474 475 if (F.current && F.player.isActive) { 476 F.player.timer = setTimeout(F.next, F.current.playSpeed); 477 } 478 }, 479 stop = function () { 480 clear(); 481 482 $('body').unbind('.player'); 483 484 F.player.isActive = false; 485 486 F.trigger('onPlayEnd'); 487 }, 488 start = function () { 489 if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) { 490 F.player.isActive = true; 491 492 $('body').bind({ 493 'afterShow.player onUpdate.player' : set, 494 'onCancel.player beforeClose.player' : stop, 495 'beforeLoad.player' : clear 496 }); 497 498 set(); 499 500 F.trigger('onPlayStart'); 501 } 502 }; 503 504 if (action === true || (!F.player.isActive && action !== false)) { 505 start(); 506 } else { 507 stop(); 508 } 509 }, 510 511 // Navigate to next gallery item 512 next: function ( direction ) { 513 var current = F.current; 514 515 if (current) { 516 if (!isString(direction)) { 517 direction = current.direction.next; 518 } 519 520 F.jumpto(current.index + 1, direction, 'next'); 521 } 522 }, 523 524 // Navigate to previous gallery item 525 prev: function ( direction ) { 526 var current = F.current; 527 528 if (current) { 529 if (!isString(direction)) { 530 direction = current.direction.prev; 531 } 532 533 F.jumpto(current.index - 1, direction, 'prev'); 534 } 535 }, 536 537 // Navigate to gallery item by index 538 jumpto: function ( index, direction, router ) { 539 var current = F.current; 540 541 if (!current) { 542 return; 543 } 544 545 index = getScalar(index); 546 547 F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ]; 548 F.router = router || 'jumpto'; 549 550 if (current.loop) { 551 if (index < 0) { 552 index = current.group.length + (index % current.group.length); 553 } 554 555 index = index % current.group.length; 556 } 557 558 if (current.group[ index ] !== undefined) { 559 F.cancel(); 560 561 F._start(index); 562 } 563 }, 564 565 // Center inside viewport and toggle position type to fixed or absolute if needed 566 reposition: function (e, onlyAbsolute) { 567 var current = F.current, 568 wrap = current ? current.wrap : null, 569 pos; 570 571 if (wrap) { 572 pos = F._getPosition(onlyAbsolute); 573 574 if (e && e.type === 'scroll') { 575 delete pos.position; 576 577 wrap.stop(true, true).animate(pos, 200); 578 579 } else { 580 wrap.css(pos); 581 582 current.pos = $.extend({}, current.dim, pos); 583 } 584 } 585 }, 586 587 update: function (e) { 588 var type = (e && e.type), 589 anyway = !type || type === 'orientationchange'; 590 591 if (anyway) { 592 clearTimeout(didUpdate); 593 594 didUpdate = null; 595 } 596 597 if (!F.isOpen || didUpdate) { 598 return; 599 } 600 601 didUpdate = setTimeout(function() { 602 var current = F.current; 603 604 if (!current || F.isClosing) { 605 return; 606 } 607 608 F.wrap.removeClass('fancybox-tmp'); 609 610 if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) { 611 F._setDimension(); 612 } 613 614 if (!(type === 'scroll' && current.canShrink)) { 615 F.reposition(e); 616 } 617 618 F.trigger('onUpdate'); 619 620 didUpdate = null; 621 622 }, (anyway && !isTouch ? 0 : 300)); 623 }, 624 625 // Shrink content to fit inside viewport or restore if resized 626 toggle: function ( action ) { 627 if (F.isOpen) { 628 F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView; 629 630 // Help browser to restore document dimensions 631 if (isTouch) { 632 F.wrap.removeAttr('style').addClass('fancybox-tmp'); 633 634 F.trigger('onUpdate'); 635 } 636 637 F.update(); 638 } 639 }, 640 641 hideLoading: function () { 642 D.unbind('.loading'); 643 644 $('#fancybox-loading').remove(); 645 }, 646 647 showLoading: function () { 648 var el, viewport; 649 650 F.hideLoading(); 651 652 el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body'); 653 654 // If user will press the escape-button, the request will be canceled 655 D.bind('keydown.loading', function(e) { 656 if ((e.which || e.keyCode) === 27) { 657 e.preventDefault(); 658 659 F.cancel(); 660 } 661 }); 662 663 if (!F.defaults.fixed) { 664 viewport = F.getViewport(); 665 666 el.css({ 667 position : 'absolute', 668 top : (viewport.h * 0.5) + viewport.y, 669 left : (viewport.w * 0.5) + viewport.x 670 }); 671 } 672 }, 673 674 getViewport: function () { 675 var locked = (F.current && F.current.locked) || false, 676 rez = { 677 x: W.scrollLeft(), 678 y: W.scrollTop() 679 }; 680 681 if (locked) { 682 rez.w = locked[0].clientWidth; 683 rez.h = locked[0].clientHeight; 684 685 } else { 686 // See http://bugs.jquery.com/ticket/6724 687 rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width(); 688 rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height(); 689 } 690 691 return rez; 692 }, 693 694 // Unbind the keyboard / clicking actions 695 unbindEvents: function () { 696 if (F.wrap && isQuery(F.wrap)) { 697 F.wrap.unbind('.fb'); 698 } 699 700 D.unbind('.fb'); 701 W.unbind('.fb'); 702 }, 703 704 bindEvents: function () { 705 var current = F.current, 706 keys; 707 708 if (!current) { 709 return; 710 } 711 712 // Changing document height on iOS devices triggers a 'resize' event, 713 // that can change document height... repeating infinitely 714 W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update); 715 716 keys = current.keys; 717 718 if (keys) { 719 D.bind('keydown.fb', function (e) { 720 var code = e.which || e.keyCode, 721 target = e.target || e.srcElement; 722 723 // Skip esc key if loading, because showLoading will cancel preloading 724 if (code === 27 && F.coming) { 725 return false; 726 } 727 728 // Ignore key combinations and key events within form elements 729 if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) { 730 $.each(keys, function(i, val) { 731 if (current.group.length > 1 && val[ code ] !== undefined) { 732 F[ i ]( val[ code ] ); 733 734 e.preventDefault(); 735 return false; 736 } 737 738 if ($.inArray(code, val) > -1) { 739 F[ i ] (); 740 741 e.preventDefault(); 742 return false; 743 } 744 }); 745 } 746 }); 747 } 748 749 if ($.fn.mousewheel && current.mouseWheel) { 750 F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) { 751 var target = e.target || null, 752 parent = $(target), 753 canScroll = false; 754 755 while (parent.length) { 756 if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) { 757 break; 758 } 759 760 canScroll = isScrollable( parent[0] ); 761 parent = $(parent).parent(); 762 } 763 764 if (delta !== 0 && !canScroll) { 765 if (F.group.length > 1 && !current.canShrink) { 766 if (deltaY > 0 || deltaX > 0) { 767 F.prev( deltaY > 0 ? 'down' : 'left' ); 768 769 } else if (deltaY < 0 || deltaX < 0) { 770 F.next( deltaY < 0 ? 'up' : 'right' ); 771 } 772 773 e.preventDefault(); 774 } 775 } 776 }); 777 } 778 }, 779 780 trigger: function (event, o) { 781 var ret, obj = o || F.coming || F.current; 782 783 if (!obj) { 784 return; 785 } 786 787 if ($.isFunction( obj[event] )) { 788 ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1)); 789 } 790 791 if (ret === false) { 792 return false; 793 } 794 795 if (obj.helpers) { 796 $.each(obj.helpers, function (helper, opts) { 797 if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) { 798 opts = $.extend(true, {}, F.helpers[helper].defaults, opts); 799 800 F.helpers[helper][event](opts, obj); 801 } 802 }); 803 } 804 805 $.event.trigger(event + '.fb'); 806 }, 807 808 isImage: function (str) { 809 return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp)((\?|#).*)?$)/i); 810 }, 811 812 isSWF: function (str) { 813 return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i); 814 }, 815 816 _start: function (index) { 817 var coming = {}, 818 obj, 819 href, 820 type, 821 margin, 822 padding; 823 824 index = getScalar( index ); 825 obj = F.group[ index ] || null; 826 827 if (!obj) { 828 return false; 829 } 830 831 coming = $.extend(true, {}, F.opts, obj); 832 833 // Convert margin and padding properties to array - top, right, bottom, left 834 margin = coming.margin; 835 padding = coming.padding; 836 837 if ($.type(margin) === 'number') { 838 coming.margin = [margin, margin, margin, margin]; 839 } 840 841 if ($.type(padding) === 'number') { 842 coming.padding = [padding, padding, padding, padding]; 843 } 844 845 // 'modal' propery is just a shortcut 846 if (coming.modal) { 847 $.extend(true, coming, { 848 closeBtn : false, 849 closeClick : false, 850 nextClick : false, 851 arrows : false, 852 mouseWheel : false, 853 keys : null, 854 helpers: { 855 overlay : { 856 closeClick : false 857 } 858 } 859 }); 860 } 861 862 // 'autoSize' property is a shortcut, too 863 if (coming.autoSize) { 864 coming.autoWidth = coming.autoHeight = true; 865 } 866 867 if (coming.width === 'auto') { 868 coming.autoWidth = true; 869 } 870 871 if (coming.height === 'auto') { 872 coming.autoHeight = true; 873 } 874 875 /* 876 * Add reference to the group, so it`s possible to access from callbacks, example: 877 * afterLoad : function() { 878 * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : ''); 879 * } 880 */ 881 882 coming.group = F.group; 883 coming.index = index; 884 885 // Give a chance for callback or helpers to update coming item (type, title, etc) 886 F.coming = coming; 887 888 if (false === F.trigger('beforeLoad')) { 889 F.coming = null; 890 891 return; 892 } 893 894 type = coming.type; 895 href = coming.href; 896 897 if (!type) { 898 F.coming = null; 899 900 //If we can not determine content type then drop silently or display next/prev item if looping through gallery 901 if (F.current && F.router && F.router !== 'jumpto') { 902 F.current.index = index; 903 904 return F[ F.router ]( F.direction ); 905 } 906 907 return false; 908 } 909 910 F.isActive = true; 911 912 if (type === 'image' || type === 'swf') { 913 coming.autoHeight = coming.autoWidth = false; 914 coming.scrolling = 'visible'; 915 } 916 917 if (type === 'image') { 918 coming.aspectRatio = true; 919 } 920 921 if (type === 'iframe' && isTouch) { 922 coming.scrolling = 'scroll'; 923 } 924 925 // Build the neccessary markup 926 coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' ); 927 928 $.extend(coming, { 929 skin : $('.fancybox-skin', coming.wrap), 930 outer : $('.fancybox-outer', coming.wrap), 931 inner : $('.fancybox-inner', coming.wrap) 932 }); 933 934 $.each(["Top", "Right", "Bottom", "Left"], function(i, v) { 935 coming.skin.css('padding' + v, getValue(coming.padding[ i ])); 936 }); 937 938 F.trigger('onReady'); 939 940 // Check before try to load; 'inline' and 'html' types need content, others - href 941 if (type === 'inline' || type === 'html') { 942 if (!coming.content || !coming.content.length) { 943 return F._error( 'content' ); 944 } 945 946 } else if (!href) { 947 return F._error( 'href' ); 948 } 949 950 if (type === 'image') { 951 F._loadImage(); 952 953 } else if (type === 'ajax') { 954 F._loadAjax(); 955 956 } else if (type === 'iframe') { 957 F._loadIframe(); 958 959 } else { 960 F._afterLoad(); 961 } 962 }, 963 964 _error: function ( type ) { 965 $.extend(F.coming, { 966 type : 'html', 967 autoWidth : true, 968 autoHeight : true, 969 minWidth : 0, 970 minHeight : 0, 971 scrolling : 'no', 972 hasError : type, 973 content : F.coming.tpl.error 974 }); 975 976 F._afterLoad(); 977 }, 978 979 _loadImage: function () { 980 // Reset preload image so it is later possible to check "complete" property 981 var img = F.imgPreload = new Image(); 982 983 img.onload = function () { 984 this.onload = this.onerror = null; 985 986 F.coming.width = this.width; 987 F.coming.height = this.height; 988 989 F._afterLoad(); 990 }; 991 992 img.onerror = function () { 993 this.onload = this.onerror = null; 994 995 F._error( 'image' ); 996 }; 997 998 img.src = F.coming.href; 999 1000 if (img.complete !== true) { 1001 F.showLoading(); 1002 } 1003 }, 1004 1005 _loadAjax: function () { 1006 var coming = F.coming; 1007 1008 F.showLoading(); 1009 1010 F.ajaxLoad = $.ajax($.extend({}, coming.ajax, { 1011 url: coming.href, 1012 error: function (jqXHR, textStatus) { 1013 if (F.coming && textStatus !== 'abort') { 1014 F._error( 'ajax', jqXHR ); 1015 1016 } else { 1017 F.hideLoading(); 1018 } 1019 }, 1020 success: function (data, textStatus) { 1021 if (textStatus === 'success') { 1022 coming.content = data; 1023 1024 F._afterLoad(); 1025 } 1026 } 1027 })); 1028 }, 1029 1030 _loadIframe: function() { 1031 var coming = F.coming, 1032 iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime())) 1033 .attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling) 1034 .attr('src', coming.href); 1035 1036 // This helps IE 1037 $(coming.wrap).bind('onReset', function () { 1038 try { 1039 $(this).find('iframe').hide().attr('src', '//about:blank').end().empty(); 1040 } catch (e) {} 1041 }); 1042 1043 if (coming.iframe.preload) { 1044 F.showLoading(); 1045 1046 iframe.one('load', function() { 1047 $(this).data('ready', 1); 1048 1049 // iOS will lose scrolling if we resize 1050 if (!isTouch) { 1051 $(this).bind('load.fb', F.update); 1052 } 1053 1054 // Without this trick: 1055 // - iframe won't scroll on iOS devices 1056 // - IE7 sometimes displays empty iframe 1057 $(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show(); 1058 1059 F._afterLoad(); 1060 }); 1061 } 1062 1063 coming.content = iframe.appendTo( coming.inner ); 1064 1065 if (!coming.iframe.preload) { 1066 F._afterLoad(); 1067 } 1068 }, 1069 1070 _preloadImages: function() { 1071 var group = F.group, 1072 current = F.current, 1073 len = group.length, 1074 cnt = current.preload ? Math.min(current.preload, len - 1) : 0, 1075 item, 1076 i; 1077 1078 for (i = 1; i <= cnt; i += 1) { 1079 item = group[ (current.index + i ) % len ]; 1080 1081 if (item.type === 'image' && item.href) { 1082 new Image().src = item.href; 1083 } 1084 } 1085 }, 1086 1087 _afterLoad: function () { 1088 var coming = F.coming, 1089 previous = F.current, 1090 placeholder = 'fancybox-placeholder', 1091 current, 1092 content, 1093 type, 1094 scrolling, 1095 href, 1096 embed; 1097 1098 F.hideLoading(); 1099 1100 if (!coming || F.isActive === false) { 1101 return; 1102 } 1103 1104 if (false === F.trigger('afterLoad', coming, previous)) { 1105 coming.wrap.stop(true).trigger('onReset').remove(); 1106 1107 F.coming = null; 1108 1109 return; 1110 } 1111 1112 if (previous) { 1113 F.trigger('beforeChange', previous); 1114 1115 previous.wrap.stop(true).removeClass('fancybox-opened') 1116 .find('.fancybox-item, .fancybox-nav') 1117 .remove(); 1118 } 1119 1120 F.unbindEvents(); 1121 1122 current = coming; 1123 content = coming.content; 1124 type = coming.type; 1125 scrolling = coming.scrolling; 1126 1127 $.extend(F, { 1128 wrap : current.wrap, 1129 skin : current.skin, 1130 outer : current.outer, 1131 inner : current.inner, 1132 current : current, 1133 previous : previous 1134 }); 1135 1136 href = current.href; 1137 1138 switch (type) { 1139 case 'inline': 1140 case 'ajax': 1141 case 'html': 1142 if (current.selector) { 1143 content = $('<div>').html(content).find(current.selector); 1144 1145 } else if (isQuery(content)) { 1146 if (!content.data(placeholder)) { 1147 content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() ); 1148 } 1149 1150 content = content.show().detach(); 1151 1152 current.wrap.bind('onReset', function () { 1153 if ($(this).find(content).length) { 1154 content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false); 1155 } 1156 }); 1157 } 1158 break; 1159 1160 case 'image': 1161 content = current.tpl.image.replace('{href}', href); 1162 break; 1163 1164 case 'swf': 1165 content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>'; 1166 embed = ''; 1167 1168 $.each(current.swf, function(name, val) { 1169 content += '<param name="' + name + '" value="' + val + '"></param>'; 1170 embed += ' ' + name + '="' + val + '"'; 1171 }); 1172 1173 content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>'; 1174 break; 1175 } 1176 1177 if (!(isQuery(content) && content.parent().is(current.inner))) { 1178 current.inner.append( content ); 1179 } 1180 1181 // Give a chance for helpers or callbacks to update elements 1182 F.trigger('beforeShow'); 1183 1184 // Set scrolling before calculating dimensions 1185 current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling)); 1186 1187 // Set initial dimensions and start position 1188 F._setDimension(); 1189 1190 F.reposition(); 1191 1192 F.isOpen = false; 1193 F.coming = null; 1194 1195 F.bindEvents(); 1196 1197 if (!F.isOpened) { 1198 $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove(); 1199 1200 } else if (previous.prevMethod) { 1201 F.transitions[ previous.prevMethod ](); 1202 } 1203 1204 F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ](); 1205 1206 F._preloadImages(); 1207 }, 1208 1209 _setDimension: function () { 1210 var viewport = F.getViewport(), 1211 steps = 0, 1212 canShrink = false, 1213 canExpand = false, 1214 wrap = F.wrap, 1215 skin = F.skin, 1216 inner = F.inner, 1217 current = F.current, 1218 width = current.width, 1219 height = current.height, 1220 minWidth = current.minWidth, 1221 minHeight = current.minHeight, 1222 maxWidth = current.maxWidth, 1223 maxHeight = current.maxHeight, 1224 scrolling = current.scrolling, 1225 scrollOut = current.scrollOutside ? current.scrollbarWidth : 0, 1226 margin = current.margin, 1227 wMargin = getScalar(margin[1] + margin[3]), 1228 hMargin = getScalar(margin[0] + margin[2]), 1229 wPadding, 1230 hPadding, 1231 wSpace, 1232 hSpace, 1233 origWidth, 1234 origHeight, 1235 origMaxWidth, 1236 origMaxHeight, 1237 ratio, 1238 width_, 1239 height_, 1240 maxWidth_, 1241 maxHeight_, 1242 iframe, 1243 body; 1244 1245 // Reset dimensions so we could re-check actual size 1246 wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp'); 1247 1248 wPadding = getScalar(skin.outerWidth(true) - skin.width()); 1249 hPadding = getScalar(skin.outerHeight(true) - skin.height()); 1250 1251 // Any space between content and viewport (margin, padding, border, title) 1252 wSpace = wMargin + wPadding; 1253 hSpace = hMargin + hPadding; 1254 1255 origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width; 1256 origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height; 1257 1258 if (current.type === 'iframe') { 1259 iframe = current.content; 1260 1261 if (current.autoHeight && iframe.data('ready') === 1) { 1262 try { 1263 if (iframe[0].contentWindow.document.location) { 1264 inner.width( origWidth ).height(9999); 1265 1266 body = iframe.contents().find('body'); 1267 1268 if (scrollOut) { 1269 body.css('overflow-x', 'hidden'); 1270 } 1271 1272 origHeight = body.height(); 1273 } 1274 1275 } catch (e) {} 1276 } 1277 1278 } else if (current.autoWidth || current.autoHeight) { 1279 inner.addClass( 'fancybox-tmp' ); 1280 1281 // Set width or height in case we need to calculate only one dimension 1282 if (!current.autoWidth) { 1283 inner.width( origWidth ); 1284 } 1285 1286 if (!current.autoHeight) { 1287 inner.height( origHeight ); 1288 } 1289 1290 if (current.autoWidth) { 1291 origWidth = inner.width(); 1292 } 1293 1294 if (current.autoHeight) { 1295 origHeight = inner.height(); 1296 } 1297 1298 inner.removeClass( 'fancybox-tmp' ); 1299 } 1300 1301 width = getScalar( origWidth ); 1302 height = getScalar( origHeight ); 1303 1304 ratio = origWidth / origHeight; 1305 1306 // Calculations for the content 1307 minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth); 1308 maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth); 1309 1310 minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight); 1311 maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight); 1312 1313 // These will be used to determine if wrap can fit in the viewport 1314 origMaxWidth = maxWidth; 1315 origMaxHeight = maxHeight; 1316 1317 if (current.fitToView) { 1318 maxWidth = Math.min(viewport.w - wSpace, maxWidth); 1319 maxHeight = Math.min(viewport.h - hSpace, maxHeight); 1320 } 1321 1322 maxWidth_ = viewport.w - wMargin; 1323 maxHeight_ = viewport.h - hMargin; 1324 1325 if (current.aspectRatio) { 1326 if (width > maxWidth) { 1327 width = maxWidth; 1328 height = getScalar(width / ratio); 1329 } 1330 1331 if (height > maxHeight) { 1332 height = maxHeight; 1333 width = getScalar(height * ratio); 1334 } 1335 1336 if (width < minWidth) { 1337 width = minWidth; 1338 height = getScalar(width / ratio); 1339 } 1340 1341 if (height < minHeight) { 1342 height = minHeight; 1343 width = getScalar(height * ratio); 1344 } 1345 1346 } else { 1347 width = Math.max(minWidth, Math.min(width, maxWidth)); 1348 1349 if (current.autoHeight && current.type !== 'iframe') { 1350 inner.width( width ); 1351 1352 height = inner.height(); 1353 } 1354 1355 height = Math.max(minHeight, Math.min(height, maxHeight)); 1356 } 1357 1358 // Try to fit inside viewport (including the title) 1359 if (current.fitToView) { 1360 inner.width( width ).height( height ); 1361 1362 wrap.width( width + wPadding ); 1363 1364 // Real wrap dimensions 1365 width_ = wrap.width(); 1366 height_ = wrap.height(); 1367 1368 if (current.aspectRatio) { 1369 while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) { 1370 if (steps++ > 19) { 1371 break; 1372 } 1373 1374 height = Math.max(minHeight, Math.min(maxHeight, height - 10)); 1375 width = getScalar(height * ratio); 1376 1377 if (width < minWidth) { 1378 width = minWidth; 1379 height = getScalar(width / ratio); 1380 } 1381 1382 if (width > maxWidth) { 1383 width = maxWidth; 1384 height = getScalar(width / ratio); 1385 } 1386 1387 inner.width( width ).height( height ); 1388 1389 wrap.width( width + wPadding ); 1390 1391 width_ = wrap.width(); 1392 height_ = wrap.height(); 1393 } 1394 1395 } else { 1396 width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_))); 1397 height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_))); 1398 } 1399 } 1400 1401 if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) { 1402 width += scrollOut; 1403 } 1404 1405 inner.width( width ).height( height ); 1406 1407 wrap.width( width + wPadding ); 1408 1409 width_ = wrap.width(); 1410 height_ = wrap.height(); 1411 1412 canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight; 1413 canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight)); 1414 1415 $.extend(current, { 1416 dim : { 1417 width : getValue( width_ ), 1418 height : getValue( height_ ) 1419 }, 1420 origWidth : origWidth, 1421 origHeight : origHeight, 1422 canShrink : canShrink, 1423 canExpand : canExpand, 1424 wPadding : wPadding, 1425 hPadding : hPadding, 1426 wrapSpace : height_ - skin.outerHeight(true), 1427 skinSpace : skin.height() - height 1428 }); 1429 1430 if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) { 1431 inner.height('auto'); 1432 } 1433 }, 1434 1435 _getPosition: function (onlyAbsolute) { 1436 var current = F.current, 1437 viewport = F.getViewport(), 1438 margin = current.margin, 1439 width = F.wrap.width() + margin[1] + margin[3], 1440 height = F.wrap.height() + margin[0] + margin[2], 1441 rez = { 1442 position: 'absolute', 1443 top : margin[0], 1444 left : margin[3] 1445 }; 1446 1447 if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) { 1448 rez.position = 'fixed'; 1449 1450 } else if (!current.locked) { 1451 rez.top += viewport.y; 1452 rez.left += viewport.x; 1453 } 1454 1455 rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))); 1456 rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio))); 1457 1458 return rez; 1459 }, 1460 1461 _afterZoomIn: function () { 1462 var current = F.current; 1463 1464 if (!current) { 1465 return; 1466 } 1467 1468 F.isOpen = F.isOpened = true; 1469 1470 F.wrap.css('overflow', 'visible').addClass('fancybox-opened'); 1471 1472 F.update(); 1473 1474 // Assign a click event 1475 if ( current.closeClick || (current.nextClick && F.group.length > 1) ) { 1476 F.inner.css('cursor', 'pointer').bind('click.fb', function(e) { 1477 if (!$(e.target).is('a') && !$(e.target).parent().is('a')) { 1478 e.preventDefault(); 1479 1480 F[ current.closeClick ? 'close' : 'next' ](); 1481 } 1482 }); 1483 } 1484 1485 // Create a close button 1486 if (current.closeBtn) { 1487 $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) { 1488 e.preventDefault(); 1489 1490 F.close(); 1491 }); 1492 } 1493 1494 // Create navigation arrows 1495 if (current.arrows && F.group.length > 1) { 1496 if (current.loop || current.index > 0) { 1497 $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev); 1498 } 1499 1500 if (current.loop || current.index < F.group.length - 1) { 1501 $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next); 1502 } 1503 } 1504 1505 F.trigger('afterShow'); 1506 1507 // Stop the slideshow if this is the last item 1508 if (!current.loop && current.index === current.group.length - 1) { 1509 F.play( false ); 1510 1511 } else if (F.opts.autoPlay && !F.player.isActive) { 1512 F.opts.autoPlay = false; 1513 1514 F.play(); 1515 } 1516 }, 1517 1518 _afterZoomOut: function ( obj ) { 1519 obj = obj || F.current; 1520 1521 $('.fancybox-wrap').trigger('onReset').remove(); 1522 1523 $.extend(F, { 1524 group : {}, 1525 opts : {}, 1526 router : false, 1527 current : null, 1528 isActive : false, 1529 isOpened : false, 1530 isOpen : false, 1531 isClosing : false, 1532 wrap : null, 1533 skin : null, 1534 outer : null, 1535 inner : null 1536 }); 1537 1538 F.trigger('afterClose', obj); 1539 } 1540 }); 1541 1542 /* 1543 * Default transitions 1544 */ 1545 1546 F.transitions = { 1547 getOrigPosition: function () { 1548 var current = F.current, 1549 element = current.element, 1550 orig = current.orig, 1551 pos = {}, 1552 width = 50, 1553 height = 50, 1554 hPadding = current.hPadding, 1555 wPadding = current.wPadding, 1556 viewport = F.getViewport(); 1557 1558 if (!orig && current.isDom && element.is(':visible')) { 1559 orig = element.find('img:first'); 1560 1561 if (!orig.length) { 1562 orig = element; 1563 } 1564 } 1565 1566 if (isQuery(orig)) { 1567 pos = orig.offset(); 1568 1569 if (orig.is('img')) { 1570 width = orig.outerWidth(); 1571 height = orig.outerHeight(); 1572 } 1573 1574 } else { 1575 pos.top = viewport.y + (viewport.h - height) * current.topRatio; 1576 pos.left = viewport.x + (viewport.w - width) * current.leftRatio; 1577 } 1578 1579 if (F.wrap.css('position') === 'fixed' || current.locked) { 1580 pos.top -= viewport.y; 1581 pos.left -= viewport.x; 1582 } 1583 1584 pos = { 1585 top : getValue(pos.top - hPadding * current.topRatio), 1586 left : getValue(pos.left - wPadding * current.leftRatio), 1587 width : getValue(width + wPadding), 1588 height : getValue(height + hPadding) 1589 }; 1590 1591 return pos; 1592 }, 1593 1594 step: function (now, fx) { 1595 var ratio, 1596 padding, 1597 value, 1598 prop = fx.prop, 1599 current = F.current, 1600 wrapSpace = current.wrapSpace, 1601 skinSpace = current.skinSpace; 1602 1603 if (prop === 'width' || prop === 'height') { 1604 ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start); 1605 1606 if (F.isClosing) { 1607 ratio = 1 - ratio; 1608 } 1609 1610 padding = prop === 'width' ? current.wPadding : current.hPadding; 1611 value = now - padding; 1612 1613 F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) ); 1614 F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) ); 1615 } 1616 }, 1617 1618 zoomIn: function () { 1619 var current = F.current, 1620 startPos = current.pos, 1621 effect = current.openEffect, 1622 elastic = effect === 'elastic', 1623 endPos = $.extend({opacity : 1}, startPos); 1624 1625 // Remove "position" property that breaks older IE 1626 delete endPos.position; 1627 1628 if (elastic) { 1629 startPos = this.getOrigPosition(); 1630 1631 if (current.openOpacity) { 1632 startPos.opacity = 0.1; 1633 } 1634 1635 } else if (effect === 'fade') { 1636 startPos.opacity = 0.1; 1637 } 1638 1639 F.wrap.css(startPos).animate(endPos, { 1640 duration : effect === 'none' ? 0 : current.openSpeed, 1641 easing : current.openEasing, 1642 step : elastic ? this.step : null, 1643 complete : F._afterZoomIn 1644 }); 1645 }, 1646 1647 zoomOut: function () { 1648 var current = F.current, 1649 effect = current.closeEffect, 1650 elastic = effect === 'elastic', 1651 endPos = {opacity : 0.1}; 1652 1653 if (elastic) { 1654 endPos = this.getOrigPosition(); 1655 1656 if (current.closeOpacity) { 1657 endPos.opacity = 0.1; 1658 } 1659 } 1660 1661 F.wrap.animate(endPos, { 1662 duration : effect === 'none' ? 0 : current.closeSpeed, 1663 easing : current.closeEasing, 1664 step : elastic ? this.step : null, 1665 complete : F._afterZoomOut 1666 }); 1667 }, 1668 1669 changeIn: function () { 1670 var current = F.current, 1671 effect = current.nextEffect, 1672 startPos = current.pos, 1673 endPos = { opacity : 1 }, 1674 direction = F.direction, 1675 distance = 200, 1676 field; 1677 1678 startPos.opacity = 0.1; 1679 1680 if (effect === 'elastic') { 1681 field = direction === 'down' || direction === 'up' ? 'top' : 'left'; 1682 1683 if (direction === 'down' || direction === 'right') { 1684 startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance); 1685 endPos[ field ] = '+=' + distance + 'px'; 1686 1687 } else { 1688 startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance); 1689 endPos[ field ] = '-=' + distance + 'px'; 1690 } 1691 } 1692 1693 // Workaround for http://bugs.jquery.com/ticket/12273 1694 if (effect === 'none') { 1695 F._afterZoomIn(); 1696 1697 } else { 1698 F.wrap.css(startPos).animate(endPos, { 1699 duration : current.nextSpeed, 1700 easing : current.nextEasing, 1701 complete : F._afterZoomIn 1702 }); 1703 } 1704 }, 1705 1706 changeOut: function () { 1707 var previous = F.previous, 1708 effect = previous.prevEffect, 1709 endPos = { opacity : 0.1 }, 1710 direction = F.direction, 1711 distance = 200; 1712 1713 if (effect === 'elastic') { 1714 endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px'; 1715 } 1716 1717 previous.wrap.animate(endPos, { 1718 duration : effect === 'none' ? 0 : previous.prevSpeed, 1719 easing : previous.prevEasing, 1720 complete : function () { 1721 $(this).trigger('onReset').remove(); 1722 } 1723 }); 1724 } 1725 }; 1726 1727 /* 1728 * Overlay helper 1729 */ 1730
1731 F.helpers.overlay = { 1732 defaults : { 1733 closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay 1734 speedOut : 200, // duration of fadeOut animation 1735 showEarly : true, // indicates if should be opened immediately or wait until the content is ready 1736 css : {}, // custom CSS properties 1737 locked : !isTouch, // if true, the content will be locked into overlay 1738 fixed : true // if false, the overlay CSS position property will not be set to "fixed" 1739 }, 1740 1741 overlay : null, // current handle 1742 fixed : false, // indicates if the overlay has position "fixed" 1743 1744 // Public methods 1745 create : function(opts) { 1746 opts = $.extend({}, this.defaults, opts); 1747 1748 if (this.overlay) { 1749 this.close(); 1750 } 1751 1752 this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( 'body' ); 1753 this.fixed = false; 1754 1755 if (opts.fixed && F.defaults.fixed) { 1756 this.overlay.addClass('fancybox-overlay-fixed'); 1757 1758 this.fixed = true; 1759 } 1760 }, 1761 1762 open : function(opts) { 1763 var that = this; 1764 1765 opts = $.extend({}, this.defaults, opts); 1766 1767 if (this.overlay) { 1768 this.overlay.unbind('.overlay').width('auto').height('auto'); 1769 1770 } else { 1771 this.create(opts); 1772 } 1773 1774 if (!this.fixed) { 1775 W.bind('resize.overlay', $.proxy( this.update, this) ); 1776 1777 this.update(); 1778 } 1779 1780 if (opts.closeClick) { 1781 this.overlay.bind('click.overlay', function(e) { 1782 if ($(e.target).hasClass('fancybox-overlay')) { 1783 if (F.isActive) { 1784 F.close(); 1785 } else { 1786 that.close(); 1787 } 1788 } 1789 }); 1790 } 1791 1792 this.overlay.css( opts.css ).show(); 1793 }, 1794 1795 close : function() { 1796 $('.fancybox-overlay').remove(); 1797 1798 W.unbind('resize.overlay'); 1799 1800 this.overlay = null; 1801 1802 if (this.margin !== false) { 1803 $('body').css('margin-right', this.margin); 1804 1805 this.margin = false; 1806 } 1807 1808 if (this.el) { 1809 this.el.removeClass('fancybox-lock'); 1810 } 1811 }, 1812 1813 // Private, callbacks 1814 1815 update : function () { 1816 var width = '100%', offsetWidth; 1817 1818 // Reset width/height so it will not mess 1819 this.overlay.width(width).height('100%'); 1820 1821 // jQuery does not return reliable result for IE 1822 if (IE) { 1823 offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth); 1824 1825 if (D.width() > offsetWidth) { 1826 width = D.width(); 1827 } 1828 1829 } else if (D.width() > W.width()) { 1830 width = D.width(); 1831 } 1832 1833 this.overlay.width(width).height(D.height()); 1834 }, 1835 1836 // This is where we can manipulate DOM, because later it would cause iframes to reload 1837 onReady : function (opts, obj) { 1838 $('.fancybox-overlay').stop(true, true); 1839 1840 if (!this.overlay) { 1841 this.margin = D.height() > W.height() || $('body').css('overflow-y') === 'scroll' ? $('body').css('margin-right') : false; 1842 this.el = document.all && !document.querySelector ? $('html') : $('body'); 1843 1844 this.create(opts); 1845 } 1846 1847 if (opts.locked && this.fixed) { 1848 obj.locked = this.overlay.append( obj.wrap ); 1849 obj.fixed = false; 1850 } 1851 1852 if (opts.showEarly === true) { 1853 this.beforeShow.apply(this, arguments); 1854 } 1855 }, 1856 1857 beforeShow : function(opts, obj) { 1858 if (obj.locked) { 1859 this.el.addClass('fancybox-lock'); 1860 1861 if (this.margin !== false) { 1862 $('body').css('margin-right', getScalar( this.margin ) + obj.scrollbarWidth); 1863 } 1864 } 1865 1866 this.open(opts); 1867 }, 1868 1869 onUpdate : function() { 1870 if (!this.fixed) { 1871 this.update(); 1872 } 1873 }, 1874 1875 afterClose: function (opts) { 1876 // Remove overlay if exists and fancyBox is not opening 1877 // (e.g., it is not being open using afterClose callback) 1878 if (this.overlay && !F.isActive) { 1879 this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this )); 1880 } 1881 } 1882 }; 1883 1884 /* 1885 * Title helper 1886 */ 1887 1888 F.helpers.title = { 1889 defaults : { 1890 type : 'float', // 'float', 'inside', 'outside' or 'over', 1891 position : 'bottom' // 'top' or 'bottom' 1892 }, 1893 1894 beforeShow: function (opts) { 1895 var current = F.current, 1896 text = current.title, 1897 type = opts.type, 1898 title, 1899 target; 1900 1901 if ($.isFunction(text)) { 1902 text = text.call(current.element, current); 1903 } 1904 1905 if (!isString(text) || $.trim(text) === '') { 1906 return; 1907 } 1908 1909 title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">
1909' + text + '</div>'); 1910 1911 switch (type) { 1912 case 'inside': 1913 target = F.skin; 1914 break; 1915 1916 case 'outside': 1917 target = F.wrap; 1918 break; 1919 1920 case 'over': 1921 target = F.inner; 1922 break; 1923 1924 default: // 'float' 1925 target = F.skin; 1926 1927 title.appendTo('body'); 1928 1929 if (IE) { 1930 title.width( title.width() ); 1931 } 1932 1933 title.wrapInner('<span class="child"></span>'); 1934 1935 //Increase bottom margin so this title will also fit into viewport 1936 F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) ); 1937 break; 1938 } 1939 1940 title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target); 1941 } 1942 }; 1943 1944 // jQuery plugin initialization 1945 $.fn.fancybox = function (options) { 1946 var index, 1947 that = $(this), 1948 selector = this.selector || '', 1949 run = function(e) { 1950 var what = $(this).blur(), idx = index, relType, relVal; 1951 1952 if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) { 1953 relType = options.groupAttr || 'data-fancybox-group'; 1954 relVal = what.attr(relType); 1955 1956 if (!relVal) { 1957 relType = 'rel'; 1958 relVal = what.get(0)[ relType ]; 1959 } 1960 1961 if (relVal && relVal !== '' && relVal !== 'nofollow') { 1962 what = selector.length ? $(selector) : that; 1963 what = what.filter('[' + relType + '="' + relVal + '"]'); 1964 idx = what.index(this); 1965 } 1966 1967 options.index = idx; 1968 1969 // Stop an event from bubbling if everything is fine 1970 if (F.open(what, options) !== false) { 1971 e.preventDefault(); 1972 } 1973 } 1974 }; 1975 1976 options = options || {}; 1977 index = options.index || 0; 1978 1979 if (!selector || options.live === false) { 1980 that.unbind('click.fb-start').bind('click.fb-start', run); 1981 1982 } else { 1983 D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); 1984 } 1985 1986 this.filter('[data-fancybox-start=1]').trigger('click'); 1987 1988 return this; 1989 }; 1990 1991 // Tests that need a body at doc ready 1992 D.ready(function() { 1993 if ( $.scrollbarWidth === undefined ) { 1994 // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth 1995 $.scrollbarWidth = function() { 1996 var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'), 1997 child = parent.children(), 1998 width = child.innerWidth() - child.height( 99 ).innerWidth(); 1999 2000 parent.remove(); 2001 2002 return width; 2003 }; 2004 } 2005 2006 if ( $.support.fixedPosition === undefined ) { 2007 $.support.fixedPosition = (function() { 2008 var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'), 2009 fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 ); 2010 2011 elem.remove(); 2012 2013 return fixed; 2014 }()); 2015 } 2016 2017 $.extend(F.defaults, { 2018 scrollbarWidth : $.scrollbarWidth(), 2019 fixed : $.support.fixedPosition, 2020 parent : $('body') 2021 }); 2022 }); 2023 2024}(window, document, jQuery)); 2025 2026/* attrchange.js */ 2027(function($) { 2028 function isDOMAttrModifiedSupported() { 2029 var p = document.createElement('p'); 2030 var flag = false; 2031 2032 if (p.addEventListener) { 2033 p.addEventListener('DOMAttrModified', function() { 2034 flag = true 2035 }, false); 2036 } else if (p.attachEvent) { 2037 p.attachEvent('onDOMAttrModified', function() { 2038 flag = true 2039 }); 2040 } else { return false; } 2041 p.setAttribute('id', 'target'); 2042 return flag; 2043 } 2044 2045 function checkAttributes(chkAttr, e) { 2046 if (chkAttr) { 2047 var attributes = this.data('attr-old-value'); 2048 2049 if (e.attributeName.indexOf('style') >= 0) { 2050 if (!attributes['style']) 2051 attributes['style'] = {}; //initialize 2052 var keys = e.attributeName.split('.'); 2053 e.attributeName = keys[0]; 2054 e.oldValue = attributes['style'][keys[1]]; //old value 2055 e.newValue = keys[1] + ':' 2056 + this.prop("style")[$.camelCase(keys[1])]; //new value 2057 attributes['style'][keys[1]] = e.newValue; 2058 } else { 2059 e.oldValue = attributes[e.attributeName]; 2060 e.newValue = this.attr(e.attributeName); 2061 attributes[e.attributeName] = e.newValue; 2062 } 2063 2064 this.data('attr-old-value', attributes); //update the old value object 2065 } 2066 } 2067 2068 //initialize Mutation Observer 2069 var MutationObserver = window.MutationObserver 2070 || window.WebKitMutationObserver; 2071 2072 $.fn.attrchange = function(a, b) { 2073 if (typeof a == 'object') {//core 2074 var cfg = { 2075 trackValues : false, 2076 callback : $.noop 2077 }; 2078 //backward compatibility 2079 if (typeof a === "function") { cfg.callback = a; } else { $.extend(cfg, a); } 2080 2081 if (cfg.trackValues) { //get attributes old value 2082 this.each(function(i, el) { 2083 var attributes = {}; 2084 for ( var attr, i = 0, attrs = el.attributes, l = attrs.length; i < l; i++) { 2085 attr = attrs.item(i); 2086 attributes[attr.nodeName] = attr.value; 2087 } 2088 $(this).data('attr-old-value', attributes); 2089 }); 2090 } 2091 2092 if (MutationObserver) { //Modern Browsers supporting MutationObserver 2093 var mOptions = { 2094 subtree : false, 2095 attributes : true, 2096 attributeOldValue : cfg.trackValues 2097 }; 2098 var observer = new MutationObserver(function(mutations) { 2099 mutations.forEach(function(e) { 2100 var _this = e.target; 2101 //get new value if trackValues is true 2102 if (cfg.trackValues) { 2103 e.newValue = $(_this).attr(e.attributeName); 2104 } 2105 if ($(_this).data('attrchange-status') === 'connected') { //execute if connected 2106 cfg.callback.call(_this, e); 2107 } 2108 }); 2109 }); 2110 2111 return this.data('attrchange-method', 'Mutation Observer').data('attrchange-status', 'connected') 2112 .data('attrchange-obs', observer).each(function() { 2113 observer.observe(this, mOptions); 2114 }); 2115 } else if (isDOMAttrModifiedSupported()) { //Opera 2116 //Good old Mutation Events 2117 return this.data('attrchange-method', 'DOMAttrModified').data('attrchange-status', 'connected').on('DOMAttrModified', function(event) { 2118 if (event.originalEvent) { event = event.originalEvent; }//jQuery normalization is not required 2119 event.attributeName = event.attrName; //property names to be consistent with MutationObserver 2120 event.oldValue = event.prevValue; //property names to be consistent with MutationObserver 2121 if ($(this).data('attrchange-status') === 'connected') { //disconnected logically 2122 cfg.callback.call(this, event); 2123 } 2124 }); 2125 } else if ('onpropertychange' in document.body) { //works only in IE 2126 return this.data('attrchange-method', 'propertychange').data('attrchange-status', 'connected').on('propertychange', function(e) { 2127 e.attributeName = window.event.propertyName; 2128 //to set the attr old value 2129 checkAttributes.call($(this), cfg.trackValues, e); 2130 if ($(this).data('attrchange-status') === 'connected') { //disconnected logically 2131 cfg.callback.call(this, e); 2132 } 2133 }); 2134 } 2135 return this; 2136 } else if (typeof a == 'string' && $.fn.attrchange.hasOwnProperty('extensions') && 2137 $.fn.attrchange['extensions'].hasOwnProperty(a)) { //extensions/options 2138 return $.fn.attrchange['extensions'][a].call(this, b); 2139 } 2140 } 2141})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.