// detect-zoom is dual-licensed under the WTFPL and MIT license,
// at the recipient's choice.
// https://github.com/yonran/detect-zoom/
var DetectZoom = {
mediaQueryBinarySearch: function(
property, unit, a, b, maxIter, epsilon) {
var matchMedia, head, style, div, binarySearch;
binarySearch = function(a, b, maxIter) {
var mid = (a + b)/2;
if (maxIter == 0 || b - a < epsilon) return mid;
var query = "(" + property + ":" + mid + unit + ")";
if (matchMedia(query).matches) {
return binarySearch(mid, b, maxIter-1);
} else {
return binarySearch(a, mid, maxIter-1);
}
};
if (window.matchMedia) {
matchMedia = window.matchMedia;
} else {
head = document.getElementsByTagName('head')[0];
style = document.createElement('style');
div = document.createElement('div');
div.className = 'mediaQueryBinarySearch';
head.appendChild(style);
div.style.display = 'none';
document.body.appendChild(div);
matchMedia = function(query) {
style.sheet.insertRule('@media ' + query +
'{.mediaQueryBinarySearch ' +
'{text-decoration: underline} }', 0);
var matched = getComputedStyle(div, null).textDecoration
== 'underline';
style.sheet.deleteRule(0);
return {matches:matched};
};
}
var r = binarySearch(a, b, maxIter);
if (div) {
head.removeChild(style);
document.body.removeChild(div);
}
return r;
},
_zoomIe7: function() {
// the trick: body's offsetWidth was in CSS pixels, while
// getBoundingClientRect() was in system pixels in IE7.
// Thanks to http://help.dottoro.com/ljgshbne.php
var rect = document.body.getBoundingClientRect();
var z = (rect.right-rect.left)/document.body.offsetWidth;
z = Math.round(z * 100) / 100;
return {zoom: z, devicePxPerCssPx: z};
},
_zoomIe8: function() {
// IE 8+: no trick needed!
// TODO: MSDN says that logicalXDPI and deviceXDPI existed since IE6
// (which didn't even have whole-page zoom). Check to see whether
// this method would also work in IE7.
var zoom = screen.deviceXDPI / screen.logicalXDPI;
return {
zoom: zoom,
devicePxPerCssPx: zoom
};
},
_zoomWebkitMobile: function() {
// the trick: window.innerWIdth is in CSS pixels, while
// screen.width and screen.height are in system pixels.
// And there are no scrollbars to mess up the measurement.
var devicePixelRatio = window.devicePixelRatio != null ? window.devicePixelRatio : 1
, deviceWidth;
if ( Math.abs(window.orientation) == 90 ) {
deviceWidth = screen.height;
} else {
deviceWidth = screen.width;
}
var z = deviceWidth / window.innerWidth;
// return immediately; don't round at the end.
return {zoom: z, devicePxPerCssPx: z*devicePixelRatio};
},
_zoomWebkit: function() {
// the trick: an element's clientHeight is in CSS pixels, while you can
// set its line-height in system pixels using font-size and
// -webkit-text-size-adjust:none.
// device-pixel-ratio: http://www.webkit.org/blog/55/high-dpi-web-sites/
// Previous trick (used before http://trac.webkit.org/changeset/100847):
// documentElement.scrollWidth is in CSS pixels, while
// document.width was in system pixels. Note that this is the
// layout width of the document, which is slightly different from viewport
// because document width does not include scrollbars and might be wider
// due to big elements.
var devicePixelRatio = window.devicePixelRatio != null ? window.devicePixelRatio : 1;
// The container exists so that the div will be laid out in its own flow
// while not impacting the layout, viewport size, or display of the
// webpage as a whole.
var container = document.createElement('div')
, div = document.createElement('div');
// Add !important and relevant CSS rule resets
// so that other rules cannot affect the results.
var important = function(str){ return str.replace(/;/g, " !important;"); };
container.setAttribute('style', important('width:0; height:0; overflow:hidden; visibility:hidden; position: absolute;'));
div.innerHTML = "1
2
3
4
5
6
7
8
9
0";
div.setAttribute('style', important('font: 100px/1em sans-serif; -webkit-text-size-adjust: none; height: auto; width: 1em; padding: 0; overflow: visible;'));
container.appendChild(div);
document.body.appendChild(container);
var z = 1000 / div.clientHeight;
z = Math.round(z * 100) / 100;
var r = {
zoom: z,
devicePxPerCssPx: devicePixelRatio * z
};
document.body.removeChild(container);
return r;
},
_zoomFF35: function() {
// the trick for FF3.5 ONLY: device-width gives CSS pixels, while
// screen.width gave system pixels. Thanks to QuirksMode's widths table,
// which called it a bug. http://www.quirksmode.org/m/widths.html
var z = screen.width /
this.mediaQueryBinarySearch('min-device-width', 'px', 0, 6000, 20, .0001);
z = Math.round(z * 100) / 100;
return {zoom: z, devicePxPerCssPx: z};
},
_zoomFF36: function() {
// the hack for FF3.6: you can measure scrollbar's width in CSS pixels,
// while in system pixels it's 15px (verified in Ubuntu).
// TODO: verify for every platform that a scrollbar is exactly 15px wide.
var container = document.createElement('div')
, outerDiv = document.createElement('div');
// The container exists so that the div will be laid out in its own flow
// while not impacting the layout, viewport size, or display of the
// webpage as a whole.
container.setAttribute('style', 'width:0; height:0; overflow:hidden;' +
'visibility:hidden; position: absolute');
outerDiv.style.width = outerDiv.style.height = '500px'; // enough for all the scrollbars
var div = outerDiv;
for (var i = 0; i < 10; ++i) {
var child = document.createElement('div');
child.style.overflowY = 'scroll';
div.appendChild(child);
div = child;
}
container.appendChild(outerDiv);
document.body.appendChild(container);
var outerDivWidth = outerDiv.clientWidth;
var innerDivWidth = div.clientWidth;
var scrollbarWidthCss = (outerDivWidth - innerDivWidth)/10;
document.body.removeChild(container);
var scrollbarWidthDevice = 15; // Mac and Linux: scrollbars are 15px wide
if (-1 != navigator.platform.indexOf('Win')){
scrollbarWidthDevice = 17;
}
var z = scrollbarWidthDevice / scrollbarWidthCss;
z = Math.round(z * 100) / 100;
return {zoom: z, devicePxPerCssPx: z};
},
_zoomFF4: function() {
// no real trick; device-pixel-ratio is the ratio of device dpi / css dpi.
// (Note that this is a different interpretation than Webkit's device
// pixel ratio, which is the ratio device dpi / system dpi).
// TODO: is mozmm vs. mm promising?
var z = this.mediaQueryBinarySearch(
'min--moz-device-pixel-ratio',
'', 0, 10, 20, .0001);
z = Math.round(z * 100) / 100;
return {zoom: z, devicePxPerCssPx: z};
},
_zoomOperaOlder: function() {
// 10.00 (or before) to 11.01:
// the trick: a div with position:fixed;width:100%'s offsetWidth is the
// viewport width in CSS pixels, while window.innerWidth was in system
// pixels. Thanks to:
// http://virtuelvis.com/2005/05/how-to-detect-zoom-level-in-opera/
// TODO: fix bug: when there is a scrollbar, fixed div does NOT
// include the scrollbar, while window.outerWidth DOES. This causes the
// calculation to be off by a few percent.
var fixedDiv = document.createElement('div');
fixedDiv.style.position = 'fixed';
fixedDiv.style.width = '100%';
fixedDiv.style.height = '100%';
fixedDiv.style.top = fixedDiv.style.left = '0';
fixedDiv.style.visibility = 'hidden';
document.body.appendChild(fixedDiv);
var z = window.innerWidth / fixedDiv.offsetWidth;
document.body.removeChild(fixedDiv);
return {zoom: z, devicePxPerCssPx: z};
},
_zoomOpera11: function() {
// works starting Opera 11.11
// the trick: outerWidth is the viewport width including scrollbars in
// system px, while innerWidth is the viewport width including scrollbars
// in CSS px;
var z = window.outerWidth / window.innerWidth;
z = Math.round(z * 100) / 100;
return {zoom: z, devicePxPerCssPx: z};
},
ratios: function() {
var r;
if (! isNaN(screen.logicalXDPI) && ! isNaN(screen.systemXDPI) ) {
return this._zoomIe8();
} else if ('ontouchstart' in window && document.body.style.webkitTextSizeAdjust != null) {
return this._zoomWebkitMobile();
} else if (document.body.style.webkitTextSizeAdjust != null) { // webkit
return this._zoomWebkit();
} else if (-1 != navigator.userAgent.indexOf('Firefox/3.5')) {
return this._zoomFF35();
} else if (-1 != navigator.userAgent.indexOf('Firefox/3.6')) {
return this._zoomFF36();
} else if (-1 != navigator.appVersion.indexOf("MSIE 7.")) {
return this._zoomIe7();
} else if (-1 != navigator.userAgent.indexOf('Opera')) {
var versionIdx = navigator.userAgent.indexOf('Version/');
if (11.01 < parseFloat(navigator.userAgent.substr(versionIdx + 8)))
return this._zoomOpera11();
else
return this._zoomOperaOlder();
} else if (0.001 < (r = this._zoomFF4()).zoom) {
return r;
} else {
return {zoom: 1, devicePxPerCssPx: 1}
}
},
zoom: function() {
return this.ratios().zoom;
},
device: function() {
return this.ratios().devicePxPerCssPx;
}
};
var wpcom_img_zoomer = {
zoomed: false,
timer: null,
interval: 1000, // zoom polling interval in millisecond
// Should we apply width/height attributes to control the image size?
imgNeedsSizeAtts: function( img ) {
// Do not overwrite existing width/height attributes.
if ( img.getAttribute('width') !== null || img.getAttribute('height') !== null )
return false;
// Do not apply the attributes if the image is already constrained by a parent element.
if ( img.width < img.naturalWidth || img.height < img.naturalHeight )
return false;
return true;
},
init: function() {
var t = this;
try{
t.zoomImages();
t.timer = setInterval( function() { t.zoomImages(); }, t.interval );
}
catch(e){
}
},
stop: function() {
if ( this.timer )
clearInterval( this.timer );
},
getScale: function() {
var scale = DetectZoom.device();
// Round up to 1.5 or the next integer below the cap.
if ( scale <= 1.0 ) scale = 1.0;
else if ( scale <= 1.5 ) scale = 1.5;
else if ( scale <= 2.0 ) scale = 2.0;
else if ( scale <= 3.0 ) scale = 3.0;
else if ( scale <= 4.0 ) scale = 4.0;
else scale = 5.0;
return scale;
},
shouldZoom: function( scale ) {
var t = this;
// Do not operate on hidden frames.
if ( "innerWidth" in window && !window.innerWidth )
return false;
// Don't do anything until scale > 1
if ( scale == 1.0 && t.zoomed == false )
return false;
return true;
},
zoomImages: function() {
var t = this;
var scale = t.getScale();
if ( ! t.shouldZoom( scale ) ){
return;
}
t.zoomed = true;
// Loop through all the
elements on the page.
var imgs = document.getElementsByTagName("img");
for ( var i = 0; i < imgs.length; i++ ) {
// Skip images that don't need processing.
var imgScale = imgs[i].getAttribute("scale");
if ( imgScale == scale || imgScale == "0" )
continue;
// Skip images that have already failed at this scale
var scaleFail = imgs[i].getAttribute("scale-fail");
if ( scaleFail && scaleFail <= scale )
continue;
// Skip images that have no dimensions yet.
if ( ! ( imgs[i].width && imgs[i].height ) )
continue;
if ( t.scaleImage( imgs[i], scale ) ) {
// Mark the img as having been processed at this scale.
imgs[i].setAttribute("scale", scale);
}
else {
// Set the flag to skip this image.
imgs[i].setAttribute("scale", "0");
}
}
},
scaleImage: function( img, scale ) {
var t = this;
var newSrc = img.src;
// Skip slideshow images
if ( img.parentNode.className.match(/slideshow-slide/) )
return false;
// Scale gravatars that have ?s= or ?size=
if ( img.src.match( /^https?:\/\/([^\/]*\.)?gravatar\.com\/.+[?&](s|size)=/ ) ) {
newSrc = img.src.replace( /([?&](s|size)=)(\d+)/, function( $0, $1, $2, $3 ) {
// Stash the original size
var originalAtt = "originals",
originalSize = img.getAttribute(originalAtt);
if ( originalSize === null ) {
originalSize = $3;
img.setAttribute(originalAtt, originalSize);
if ( t.imgNeedsSizeAtts( img ) ) {
// Fix width and height attributes to rendered dimensions.
img.width = img.width;
img.height = img.height;
}
}
// Get the width/height of the image in CSS pixels
var size = img.clientWidth;
// Convert CSS pixels to device pixels
var targetSize = Math.ceil(img.clientWidth * scale);
// Don't go smaller than the original size
targetSize = Math.max( targetSize, originalSize );
// Don't go larger than the service supports
targetSize = Math.min( targetSize, 512 );
return $1 + targetSize;
});
}
// Scale resize queries (*.files.wordpress.com) that have ?w= or ?h=
else if ( img.src.match( /^https?:\/\/([^\/]+)\.files\.wordpress\.com\/.+[?&][wh]=/ ) ) {
var changedAttrs = {};
var matches = img.src.match( /([?&]([wh])=)(\d+)/g );
for ( var i = 0; i < matches.length; i++ ) {
var lr = matches[i].split( '=' );
var thisAttr = lr[0].replace(/[?&]/g, '' );
var thisVal = lr[1];
// Stash the original size
var originalAtt = 'original' + thisAttr, originalSize = img.getAttribute( originalAtt );
if ( originalSize === null ) {
originalSize = thisVal;
img.setAttribute(originalAtt, originalSize);
if ( t.imgNeedsSizeAtts( img ) ) {
// Fix width and height attributes to rendered dimensions.
img.width = img.width;
img.height = img.height;
}
}
// Get the width/height of the image in CSS pixels
var size = thisAttr == 'w' ? img.clientWidth : img.clientHeight;
var naturalSize = ( thisAttr == 'w' ? img.naturalWidth : img.naturalHeight );
// Convert CSS pixels to device pixels
var targetSize = Math.ceil(size * scale);
// Don't go smaller than the original size
targetSize = Math.max( targetSize, originalSize );
// Don't go bigger unless the current one is actually lacking
if ( scale > img.getAttribute("scale") && targetSize <= naturalSize )
targetSize = thisVal;
// Don't try to go bigger if the image is already smaller than was requested
if ( naturalSize < thisVal )
targetSize = thisVal;
if ( targetSize != thisVal )
changedAttrs[ thisAttr ] = targetSize;
}
var w = changedAttrs.w || false;
var h = changedAttrs.h || false;
if ( w ) {
newSrc = img.src.replace(/([?&])w=\d+/g, function( $0, $1 ) {
return $1 + 'w=' + w;
});
}
if ( h ) {
newSrc = newSrc.replace(/([?&])h=\d+/g, function( $0, $1 ) {
return $1 + 'h=' + h;
});
}
}
// Scale mshots that have width
else if ( img.src.match(/^https?:\/\/([^\/]+\.)*(wordpress|wp)\.com\/mshots\/.+[?&]w=\d+/) ) {
newSrc = img.src.replace( /([?&]w=)(\d+)/, function($0, $1, $2) {
// Stash the original size
var originalAtt = 'originalw', originalSize = img.getAttribute(originalAtt);
if ( originalSize === null ) {
originalSize = $2;
img.setAttribute(originalAtt, originalSize);
if ( t.imgNeedsSizeAtts( img ) ) {
// Fix width and height attributes to rendered dimensions.
img.width = img.width;
img.height = img.height;
}
}
// Get the width of the image in CSS pixels
var size = img.clientWidth;
// Convert CSS pixels to device pixels
var targetSize = Math.ceil(size * scale);
// Don't go smaller than the original size
targetSize = Math.max( targetSize, originalSize );
// Don't go bigger unless the current one is actually lacking
if ( scale > img.getAttribute("scale") && targetSize <= img.naturalWidth )
targetSize = $2;
if ( $2 != targetSize )
return $1 + targetSize;
});
}
// Scale simple imgpress queries (s0.wp.com) that only specify w/h/fit
else if ( img.src.match(/^https?:\/\/([^\/.]+\.)*(wp|wordpress)\.com\/imgpress\?(.+)/) ) {
var imgpressSafeFunctions = ["zoom", "url", "h", "w", "fit", "filter", "brightness", "contrast", "colorize", "smooth", "unsharpmask"];
// Search the query string for unsupported functions.
var qs = RegExp.$3.split('&');
for ( var q in qs ) {
q = qs[q].split('=')[0];
if ( imgpressSafeFunctions.indexOf(q) == -1 ) {
return false;
}
}
// Fix width and height attributes to rendered dimensions.
img.width = img.width;
img.height = img.height;
// Compute new src
if ( scale == 1 )
newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?');
else
newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?zoom=' + scale + '&');
}
// Scale LaTeX images
else if ( img.src.match(/^https?:\/\/([^\/.]+\.)*(wp|wordpress)\.com\/latex\.php\?(latex|zoom)=(.+)/) ) {
// Fix width and height attributes to rendered dimensions.
img.width = img.width;
img.height = img.height;
// Compute new src
if ( scale == 1 )
newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?');
else
newSrc = img.src.replace(/\?(zoom=[^&]+&)?/, '?zoom=' + scale + '&');
}
// Scale static assets that have a name matching *-1x.png or *@1x.png
else if ( img.src.match(/^https?:\/\/[^\/]+\/.*[-@]([12])x\.(gif|jpeg|jpg|png)(\?|$)/) ) {
// Fix width and height attributes to rendered dimensions.
img.width = img.width;
img.height = img.height;
var currentSize = RegExp.$1, newSize = currentSize;
if ( scale <= 1 )
newSize = 1;
else
newSize = 2;
if ( currentSize != newSize )
newSrc = img.src.replace(/([-@])[12]x\.(gif|jpeg|jpg|png)(\?|$)/, '$1'+newSize+'x.$2$3');
}
else {
return false;
}
// Don't set img.src unless it has changed. This avoids unnecessary reloads.
if ( newSrc != img.src ) {
// Store the original img.src
var prevSrc, origSrc = img.getAttribute("src-orig");
if ( !origSrc ) {
origSrc = img.src;
img.setAttribute("src-orig", origSrc);
}
// In case of error, revert img.src
if ( img.complete )
prevSrc = img.src;
else
prevSrc = origSrc;
img.onerror = function(){
img.src = prevSrc;
if ( img.getAttribute("scale-fail") < scale )
img.setAttribute("scale-fail", scale);
img.onerror = null;
};
// Finally load the new image
img.src = newSrc;
}
return true;
}
};
wpcom_img_zoomer.init();
;
/*
* Thickbox 3.1 - One Box To Rule Them All.
* By Cody Lindley (http://www.codylindley.com)
* Copyright (c) 2007 cody lindley
* Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
*/
if ( typeof tb_pathToImage != 'string' ) {
var tb_pathToImage = thickboxL10n.loadingAnimation;
}
if ( typeof tb_closeImage != 'string' ) {
var tb_closeImage = thickboxL10n.closeImage;
}
/*!!!!!!!!!!!!!!!!! edit below this line at your own risk !!!!!!!!!!!!!!!!!!!!!!!*/
//on page load call tb_init
jQuery(document).ready(function(){
tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox
imgLoader = new Image();// preload image
imgLoader.src = tb_pathToImage;
});
//add thickbox to href & area elements that have a class of .thickbox
function tb_init(domChunk){
jQuery(domChunk).live('click', tb_click);
}
function tb_click(){
var t = this.title || this.name || null;
var a = this.href || this.alt;
var g = this.rel || false;
tb_show(t,a,g);
this.blur();
return false;
}
function tb_show(caption, url, imageGroup) {//function called when the user clicks on a thickbox link
try {
if (typeof document.body.style.maxHeight === "undefined") {//if IE 6
jQuery("body","html").css({height: "100%", width: "100%"});
jQuery("html").css("overflow","hidden");
if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6
jQuery("body").append("
");
jQuery("#TB_overlay").click(tb_remove);
}
}else{//all others
if(document.getElementById("TB_overlay") === null){
jQuery("body").append("");
jQuery("#TB_overlay").click(tb_remove);
}
}
if(tb_detectMacXFF()){
jQuery("#TB_overlay").addClass("TB_overlayMacFFBGHack");//use png overlay so hide flash
}else{
jQuery("#TB_overlay").addClass("TB_overlayBG");//use background and opacity
}
if(caption===null){caption="";}
jQuery("body").append("
");//add loader to the page
jQuery('#TB_load').show();//show loader
var baseURL;
if(url.indexOf("?")!==-1){ //ff there is a query string involved
baseURL = url.substr(0, url.indexOf("?"));
}else{
baseURL = url;
}
var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$/;
var urlType = baseURL.toLowerCase().match(urlString);
if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images
TB_PrevCaption = "";
TB_PrevURL = "";
TB_PrevHTML = "";
TB_NextCaption = "";
TB_NextURL = "";
TB_NextHTML = "";
TB_imageCount = "";
TB_FoundURL = false;
if(imageGroup){
TB_TempArray = jQuery("a[rel="+imageGroup+"]").get();
for (TB_Counter = 0; ((TB_Counter < TB_TempArray.length) && (TB_NextHTML === "")); TB_Counter++) {
var urlTypeTemp = TB_TempArray[TB_Counter].href.toLowerCase().match(urlString);
if (!(TB_TempArray[TB_Counter].href == url)) {
if (TB_FoundURL) {
TB_NextCaption = TB_TempArray[TB_Counter].title;
TB_NextURL = TB_TempArray[TB_Counter].href;
TB_NextHTML = " "+thickboxL10n.next+"";
} else {
TB_PrevCaption = TB_TempArray[TB_Counter].title;
TB_PrevURL = TB_TempArray[TB_Counter].href;
TB_PrevHTML = " "+thickboxL10n.prev+"";
}
} else {
TB_FoundURL = true;
TB_imageCount = thickboxL10n.image + ' ' + (TB_Counter + 1) + ' ' + thickboxL10n.of + ' ' + (TB_TempArray.length);
}
}
}
imgPreloader = new Image();
imgPreloader.onload = function(){
imgPreloader.onload = null;
// Resizing large images - orginal by Christian Montoya edited by me.
var pagesize = tb_getPageSize();
var x = pagesize[0] - 150;
var y = pagesize[1] - 150;
var imageWidth = imgPreloader.width;
var imageHeight = imgPreloader.height;
if (imageWidth > x) {
imageHeight = imageHeight * (x / imageWidth);
imageWidth = x;
if (imageHeight > y) {
imageWidth = imageWidth * (y / imageHeight);
imageHeight = y;
}
} else if (imageHeight > y) {
imageWidth = imageWidth * (y / imageHeight);
imageHeight = y;
if (imageWidth > x) {
imageHeight = imageHeight * (x / imageWidth);
imageWidth = x;
}
}
// End Resizing
TB_WIDTH = imageWidth + 30;
TB_HEIGHT = imageHeight + 60;
jQuery("#TB_window").append("
" + ""+caption+"
" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "
");
jQuery("#TB_closeWindowButton").click(tb_remove);
if (!(TB_PrevHTML === "")) {
function goPrev(){
if(jQuery(document).unbind("click",goPrev)){jQuery(document).unbind("click",goPrev);}
jQuery("#TB_window").remove();
jQuery("body").append("");
tb_show(TB_PrevCaption, TB_PrevURL, imageGroup);
return false;
}
jQuery("#TB_prev").click(goPrev);
}
if (!(TB_NextHTML === "")) {
function goNext(){
jQuery("#TB_window").remove();
jQuery("body").append("");
tb_show(TB_NextCaption, TB_NextURL, imageGroup);
return false;
}
jQuery("#TB_next").click(goNext);
}
jQuery(document).bind('keydown.thickbox', function(e){
e.stopImmediatePropagation();
if ( e.which == 27 ){ // close
if ( ! jQuery(document).triggerHandler( 'wp_CloseOnEscape', [{ event: e, what: 'thickbox', cb: tb_remove }] ) )
tb_remove();
} else if ( e.which == 190 ){ // display previous image
if(!(TB_NextHTML == "")){
jQuery(document).unbind('thickbox');
goNext();
}
} else if ( e.which == 188 ){ // display next image
if(!(TB_PrevHTML == "")){
jQuery(document).unbind('thickbox');
goPrev();
}
}
return false;
});
tb_position();
jQuery("#TB_load").remove();
jQuery("#TB_ImageOff").click(tb_remove);
jQuery("#TB_window").css({'visibility':'visible'}); //for safari using css instead of show
};
imgPreloader.src = url;
}else{//code to show html
var queryString = url.replace(/^[^\?]+\??/,'');
var params = tb_parseQuery( queryString );
TB_WIDTH = (params['width']*1) + 30 || 630; //defaults to 630 if no paramaters were added to URL
TB_HEIGHT = (params['height']*1) + 40 || 440; //defaults to 440 if no paramaters were added to URL
ajaxContentW = TB_WIDTH - 30;
ajaxContentH = TB_HEIGHT - 45;
if(url.indexOf('TB_iframe') != -1){// either iframe or ajax window
urlNoQuery = url.split('TB_');
jQuery("#TB_iframeContent").remove();
if(params['modal'] != "true"){//iframe no modal
jQuery("#TB_window").append("");
}else{//iframe modal
jQuery("#TB_overlay").unbind();
jQuery("#TB_window").append("");
}
}else{// not an iframe, ajax
if(jQuery("#TB_window").css("visibility") != "visible"){
if(params['modal'] != "true"){//ajax no modal
jQuery("#TB_window").append("");
}else{//ajax modal
jQuery("#TB_overlay").unbind();
jQuery("#TB_window").append("");
}
}else{//this means the window is already up, we are just loading new content via ajax
jQuery("#TB_ajaxContent")[0].style.width = ajaxContentW +"px";
jQuery("#TB_ajaxContent")[0].style.height = ajaxContentH +"px";
jQuery("#TB_ajaxContent")[0].scrollTop = 0;
jQuery("#TB_ajaxWindowTitle").html(caption);
}
}
jQuery("#TB_closeWindowButton").click(tb_remove);
if(url.indexOf('TB_inline') != -1){
jQuery("#TB_ajaxContent").append(jQuery('#' + params['inlineId']).children());
jQuery("#TB_window").bind('tb_unload', function () {
jQuery('#' + params['inlineId']).append( jQuery("#TB_ajaxContent").children() ); // move elements back when you're finished
});
tb_position();
jQuery("#TB_load").remove();
jQuery("#TB_window").css({'visibility':'visible'});
}else if(url.indexOf('TB_iframe') != -1){
tb_position();
if(jQuery.browser.safari){//safari needs help because it will not fire iframe onload
jQuery("#TB_load").remove();
jQuery("#TB_window").css({'visibility':'visible'});
}
}else{
jQuery("#TB_ajaxContent").load(url += "&random=" + (new Date().getTime()),function(){//to do a post change this load method
tb_position();
jQuery("#TB_load").remove();
tb_init("#TB_ajaxContent a.thickbox");
jQuery("#TB_window").css({'visibility':'visible'});
});
}
}
if(!params['modal']){
jQuery(document).bind('keyup.thickbox', function(e){
if ( e.which == 27 ){ // close
e.stopImmediatePropagation();
if ( ! jQuery(document).triggerHandler( 'wp_CloseOnEscape', [{ event: e, what: 'thickbox', cb: tb_remove }] ) )
tb_remove();
return false;
}
});
}
} catch(e) {
//nothing here
}
}
//helper functions below
function tb_showIframe(){
jQuery("#TB_load").remove();
jQuery("#TB_window").css({'visibility':'visible'});
}
function tb_remove() {
jQuery("#TB_imageOff").unbind("click");
jQuery("#TB_closeWindowButton").unbind("click");
jQuery("#TB_window").fadeOut("fast",function(){jQuery('#TB_window,#TB_overlay,#TB_HideSelect').trigger("tb_unload").unbind().remove();});
jQuery("#TB_load").remove();
if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
jQuery("body","html").css({height: "auto", width: "auto"});
jQuery("html").css("overflow","");
}
jQuery(document).unbind('.thickbox');
return false;
}
function tb_position() {
var isIE6 = typeof document.body.style.maxHeight === "undefined";
jQuery("#TB_window").css({marginLeft: '-' + parseInt((TB_WIDTH / 2),10) + 'px', width: TB_WIDTH + 'px'});
if ( ! isIE6 ) { // take away IE6
jQuery("#TB_window").css({marginTop: '-' + parseInt((TB_HEIGHT / 2),10) + 'px'});
}
}
function tb_parseQuery ( query ) {
var Params = {};
if ( ! query ) {return Params;}// return empty object
var Pairs = query.split(/[;&]/);
for ( var i = 0; i < Pairs.length; i++ ) {
var KeyVal = Pairs[i].split('=');
if ( ! KeyVal || KeyVal.length != 2 ) {continue;}
var key = unescape( KeyVal[0] );
var val = unescape( KeyVal[1] );
val = val.replace(/\+/g, ' ');
Params[key] = val;
}
return Params;
}
function tb_getPageSize(){
var de = document.documentElement;
var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
arrayPageSize = [w,h];
return arrayPageSize;
}
function tb_detectMacXFF() {
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) {
return true;
}
}
;
/*!
* jQuery Cycle Plugin (core)
* Examples and documentation at: http://jquery.malsup.com/cycle/
* Copyright (c) 2007-2010 M. Alsup
* Version: 2.86 (05-APR-2010)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
* Requires: jQuery v1.2.6 or later
*/
;(function($) {
var ver = '2.86';
// if $.support is not defined (pre jQuery 1.3) add what I need
if ($.support == undefined) {
$.support = {
opacity: !($.browser.msie)
};
}
function debug(s) {
if ($.fn.cycle.debug)
log(s);
}
function log() {
if (window.console && window.console.log)
window.console.log('[cycle] ' + Array.prototype.join.call(arguments,' '));
};
// the options arg can be...
// a number - indicates an immediate transition should occur to the given slide index
// a string - 'pause', 'resume', 'toggle', 'next', 'prev', 'stop', 'destroy' or the name of a transition effect (ie, 'fade', 'zoom', etc)
// an object - properties to control the slideshow
//
// the arg2 arg can be...
// the name of an fx (only used in conjunction with a numeric value for 'options')
// the value true (only used in first arg == 'resume') and indicates
// that the resume should occur immediately (not wait for next timeout)
$.fn.cycle = function(options, arg2) {
var o = { s: this.selector, c: this.context };
// in 1.3+ we can fix mistakes with the ready state
if (this.length === 0 && options != 'stop') {
if (!$.isReady && o.s) {
log('DOM not ready, queuing slideshow');
$(function() {
$(o.s,o.c).cycle(options,arg2);
});
return this;
}
// is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
return this;
}
// iterate the matched nodeset
return this.each(function() {
var opts = handleArguments(this, options, arg2);
if (opts === false)
return;
opts.updateActivePagerLink = opts.updateActivePagerLink || $.fn.cycle.updateActivePagerLink;
// stop existing slideshow for this container (if there is one)
if (this.cycleTimeout)
clearTimeout(this.cycleTimeout);
this.cycleTimeout = this.cyclePause = 0;
var $cont = $(this);
var $slides = opts.slideExpr ? $(opts.slideExpr, this) : $cont.children();
var els = $slides.get();
if (els.length < 2) {
log('terminating; too few slides: ' + els.length);
return;
}
var opts2 = buildOptions($cont, $slides, els, opts, o);
if (opts2 === false)
return;
var startTime = opts2.continuous ? 10 : getTimeout(opts2.currSlide, opts2.nextSlide, opts2, !opts2.rev);
// if it's an auto slideshow, kick it off
if (startTime) {
startTime += (opts2.delay || 0);
if (startTime < 10)
startTime = 10;
debug('first timeout: ' + startTime);
this.cycleTimeout = setTimeout(function(){go(els,opts2,0,!opts2.rev)}, startTime);
}
});
};
// process the args that were passed to the plugin fn
function handleArguments(cont, options, arg2) {
if (cont.cycleStop == undefined)
cont.cycleStop = 0;
if (options === undefined || options === null)
options = {};
if (options.constructor == String) {
switch(options) {
case 'destroy':
case 'stop':
var opts = $(cont).data('cycle.opts');
if (!opts)
return false;
cont.cycleStop++; // callbacks look for change
if (cont.cycleTimeout)
clearTimeout(cont.cycleTimeout);
cont.cycleTimeout = 0;
$(cont).removeData('cycle.opts');
if (options == 'destroy')
destroy(opts);
return false;
case 'toggle':
cont.cyclePause = (cont.cyclePause === 1) ? 0 : 1;
checkInstantResume(cont.cyclePause, arg2, cont);
return false;
case 'pause':
cont.cyclePause = 1;
return false;
case 'resume':
cont.cyclePause = 0;
checkInstantResume(false, arg2, cont);
return false;
case 'prev':
case 'next':
var opts = $(cont).data('cycle.opts');
if (!opts) {
log('options not found, "prev/next" ignored');
return false;
}
$.fn.cycle[options](opts);
return false;
default:
options = { fx: options };
};
return options;
}
else if (options.constructor == Number) {
// go to the requested slide
var num = options;
options = $(cont).data('cycle.opts');
if (!options) {
log('options not found, can not advance slide');
return false;
}
if (num < 0 || num >= options.elements.length) {
log('invalid slide index: ' + num);
return false;
}
options.nextSlide = num;
if (cont.cycleTimeout) {
clearTimeout(cont.cycleTimeout);
cont.cycleTimeout = 0;
}
if (typeof arg2 == 'string')
options.oneTimeFx = arg2;
go(options.elements, options, 1, num >= options.currSlide);
return false;
}
return options;
function checkInstantResume(isPaused, arg2, cont) {
if (!isPaused && arg2 === true) { // resume now!
var options = $(cont).data('cycle.opts');
if (!options) {
log('options not found, can not resume');
return false;
}
if (cont.cycleTimeout) {
clearTimeout(cont.cycleTimeout);
cont.cycleTimeout = 0;
}
go(options.elements, options, 1, 1);
}
}
};
function removeFilter(el, opts) {
if (!$.support.opacity && opts.cleartype && el.style.filter) {
try { el.style.removeAttribute('filter'); }
catch(smother) {} // handle old opera versions
}
};
// unbind event handlers
function destroy(opts) {
if (opts.next)
$(opts.next).unbind(opts.prevNextEvent);
if (opts.prev)
$(opts.prev).unbind(opts.prevNextEvent);
if (opts.pager || opts.pagerAnchorBuilder)
$.each(opts.pagerAnchors || [], function() {
this.unbind().remove();
});
opts.pagerAnchors = null;
if (opts.destroy) // callback
opts.destroy(opts);
};
// one-time initialization
function buildOptions($cont, $slides, els, options, o) {
// support metadata plugin (v1.0 and v2.0)
var opts = $.extend({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta ? $cont.data() : {});
if (opts.autostop)
opts.countdown = opts.autostopCount || els.length;
var cont = $cont[0];
$cont.data('cycle.opts', opts);
opts.$cont = $cont;
opts.stopCount = cont.cycleStop;
opts.elements = els;
opts.before = opts.before ? [opts.before] : [];
opts.after = opts.after ? [opts.after] : [];
opts.after.unshift(function(){ opts.busy=0; });
// push some after callbacks
if (!$.support.opacity && opts.cleartype)
opts.after.push(function() { removeFilter(this, opts); });
if (opts.continuous)
opts.after.push(function() { go(els,opts,0,!opts.rev); });
saveOriginalOpts(opts);
// clearType corrections
if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
clearTypeFix($slides);
// container requires non-static position so that slides can be position within
if ($cont.css('position') == 'static')
$cont.css('position', 'relative');
if (opts.width)
$cont.width(opts.width);
if (opts.height && opts.height != 'auto')
$cont.height(opts.height);
if (opts.startingSlide)
opts.startingSlide = parseInt(opts.startingSlide);
// if random, mix up the slide array
if (opts.random) {
opts.randomMap = [];
for (var i = 0; i < els.length; i++)
opts.randomMap.push(i);
opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
opts.randomIndex = 1;
opts.startingSlide = opts.randomMap[1];
}
else if (opts.startingSlide >= els.length)
opts.startingSlide = 0; // catch bogus input
opts.currSlide = opts.startingSlide || 0;
var first = opts.startingSlide;
// set position and zIndex on all the slides
$slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) {
var z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i;
$(this).css('z-index', z)
});
// make sure first slide is visible
$(els[first]).css('opacity',1).show(); // opacity bit needed to handle restart use case
removeFilter(els[first], opts);
// stretch slides
if (opts.fit && opts.width)
$slides.width(opts.width);
if (opts.fit && opts.height && opts.height != 'auto')
$slides.height(opts.height);
// stretch container
var reshape = opts.containerResize && !$cont.innerHeight();
if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9
var maxw = 0, maxh = 0;
for(var j=0; j < els.length; j++) {
var $e = $(els[j]), e = $e[0], w = $e.outerWidth(), h = $e.outerHeight();
if (!w) w = e.offsetWidth || e.width || $e.attr('width')
if (!h) h = e.offsetHeight || e.height || $e.attr('height');
maxw = w > maxw ? w : maxw;
maxh = h > maxh ? h : maxh;
}
if (maxw > 0 && maxh > 0)
$cont.css({width:maxw+'px',height:maxh+'px'});
}
if (opts.pause)
$cont.hover(function(){this.cyclePause++;},function(){this.cyclePause--;});
if (supportMultiTransitions(opts) === false)
return false;
// apparently a lot of people use image slideshows without height/width attributes on the images.
// Cycle 2.50+ requires the sizing info for every slide; this block tries to deal with that.
var requeue = false;
options.requeueAttempts = options.requeueAttempts || 0;
$slides.each(function() {
// try to get height/width of each slide
var $el = $(this);
this.cycleH = (opts.fit && opts.height) ? opts.height : ($el.height() || this.offsetHeight || this.height || $el.attr('height') || 0);
this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || this.offsetWidth || this.width || $el.attr('width') || 0);
if ( $el.is('img') ) {
// sigh.. sniffing, hacking, shrugging... this crappy hack tries to account for what browsers do when
// an image is being downloaded and the markup did not include sizing info (height/width attributes);
// there seems to be some "default" sizes used in this situation
var loadingIE = ($.browser.msie && this.cycleW == 28 && this.cycleH == 30 && !this.complete);
var loadingFF = ($.browser.mozilla && this.cycleW == 34 && this.cycleH == 19 && !this.complete);
var loadingOp = ($.browser.opera && ((this.cycleW == 42 && this.cycleH == 19) || (this.cycleW == 37 && this.cycleH == 17)) && !this.complete);
var loadingOther = (this.cycleH == 0 && this.cycleW == 0 && !this.complete);
// don't requeue for images that are still loading but have a valid size
if (loadingIE || loadingFF || loadingOp || loadingOther) {
if (o.s && opts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { // track retry count so we don't loop forever
log(options.requeueAttempts,' - img slide not loaded, requeuing slideshow: ', this.src, this.cycleW, this.cycleH);
setTimeout(function() {$(o.s,o.c).cycle(options)}, opts.requeueTimeout);
requeue = true;
return false; // break each loop
}
else {
log('could not determine size of image: '+this.src, this.cycleW, this.cycleH);
}
}
}
return true;
});
if (requeue)
return false;
opts.cssBefore = opts.cssBefore || {};
opts.animIn = opts.animIn || {};
opts.animOut = opts.animOut || {};
$slides.not(':eq('+first+')').css(opts.cssBefore);
if (opts.cssFirst)
$($slides[first]).css(opts.cssFirst);
if (opts.timeout) {
opts.timeout = parseInt(opts.timeout);
// ensure that timeout and speed settings are sane
if (opts.speed.constructor == String)
opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed);
if (!opts.sync)
opts.speed = opts.speed / 2;
var buffer = opts.fx == 'shuffle' ? 500 : 250;
while((opts.timeout - opts.speed) < buffer) // sanitize timeout
opts.timeout += opts.speed;
}
if (opts.easing)
opts.easeIn = opts.easeOut = opts.easing;
if (!opts.speedIn)
opts.speedIn = opts.speed;
if (!opts.speedOut)
opts.speedOut = opts.speed;
opts.slideCount = els.length;
opts.currSlide = opts.lastSlide = first;
if (opts.random) {
if (++opts.randomIndex == els.length)
opts.randomIndex = 0;
opts.nextSlide = opts.randomMap[opts.randomIndex];
}
else
opts.nextSlide = opts.startingSlide >= (els.length-1) ? 0 : opts.startingSlide+1;
// run transition init fn
if (!opts.multiFx) {
var init = $.fn.cycle.transitions[opts.fx];
if ($.isFunction(init))
init($cont, $slides, opts);
else if (opts.fx != 'custom' && !opts.multiFx) {
log('unknown transition: ' + opts.fx,'; slideshow terminating');
return false;
}
}
// fire artificial events
var e0 = $slides[first];
if (opts.before.length)
opts.before[0].apply(e0, [e0, e0, opts, true]);
if (opts.after.length > 1)
opts.after[1].apply(e0, [e0, e0, opts, true]);
if (opts.next)
$(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,opts.rev?-1:1)});
if (opts.prev)
$(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,opts.rev?1:-1)});
if (opts.pager || opts.pagerAnchorBuilder)
buildPager(els,opts);
exposeAddSlide(opts, els);
return opts;
};
// save off original opts so we can restore after clearing state
function saveOriginalOpts(opts) {
opts.original = { before: [], after: [] };
opts.original.cssBefore = $.extend({}, opts.cssBefore);
opts.original.cssAfter = $.extend({}, opts.cssAfter);
opts.original.animIn = $.extend({}, opts.animIn);
opts.original.animOut = $.extend({}, opts.animOut);
$.each(opts.before, function() { opts.original.before.push(this); });
$.each(opts.after, function() { opts.original.after.push(this); });
};
function supportMultiTransitions(opts) {
var i, tx, txs = $.fn.cycle.transitions;
// look for multiple effects
if (opts.fx.indexOf(',') > 0) {
opts.multiFx = true;
opts.fxs = opts.fx.replace(/\s*/g,'').split(',');
// discard any bogus effect names
for (i=0; i < opts.fxs.length; i++) {
var fx = opts.fxs[i];
tx = txs[fx];
if (!tx || !txs.hasOwnProperty(fx) || !$.isFunction(tx)) {
log('discarding unknown transition: ',fx);
opts.fxs.splice(i,1);
i--;
}
}
// if we have an empty list then we threw everything away!
if (!opts.fxs.length) {
log('No valid transitions named; slideshow terminating.');
return false;
}
}
else if (opts.fx == 'all') { // auto-gen the list of transitions
opts.multiFx = true;
opts.fxs = [];
for (p in txs) {
tx = txs[p];
if (txs.hasOwnProperty(p) && $.isFunction(tx))
opts.fxs.push(p);
}
}
if (opts.multiFx && opts.randomizeEffects) {
// munge the fxs array to make effect selection random
var r1 = Math.floor(Math.random() * 20) + 30;
for (i = 0; i < r1; i++) {
var r2 = Math.floor(Math.random() * opts.fxs.length);
opts.fxs.push(opts.fxs.splice(r2,1)[0]);
}
debug('randomized fx sequence: ',opts.fxs);
}
return true;
};
// provide a mechanism for adding slides after the slideshow has started
function exposeAddSlide(opts, els) {
opts.addSlide = function(newSlide, prepend) {
var $s = $(newSlide), s = $s[0];
if (!opts.autostopCount)
opts.countdown++;
els[prepend?'unshift':'push'](s);
if (opts.els)
opts.els[prepend?'unshift':'push'](s); // shuffle needs this
opts.slideCount = els.length;
$s.css('position','absolute');
$s[prepend?'prependTo':'appendTo'](opts.$cont);
if (prepend) {
opts.currSlide++;
opts.nextSlide++;
}
if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
clearTypeFix($s);
if (opts.fit && opts.width)
$s.width(opts.width);
if (opts.fit && opts.height && opts.height != 'auto')
$slides.height(opts.height);
s.cycleH = (opts.fit && opts.height) ? opts.height : $s.height();
s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width();
$s.css(opts.cssBefore);
if (opts.pager || opts.pagerAnchorBuilder)
$.fn.cycle.createPagerAnchor(els.length-1, s, $(opts.pager), els, opts);
if ($.isFunction(opts.onAddSlide))
opts.onAddSlide($s);
else
$s.hide(); // default behavior
};
}
// reset internal state; we do this on every pass in order to support multiple effects
$.fn.cycle.resetState = function(opts, fx) {
fx = fx || opts.fx;
opts.before = []; opts.after = [];
opts.cssBefore = $.extend({}, opts.original.cssBefore);
opts.cssAfter = $.extend({}, opts.original.cssAfter);
opts.animIn = $.extend({}, opts.original.animIn);
opts.animOut = $.extend({}, opts.original.animOut);
opts.fxFn = null;
$.each(opts.original.before, function() { opts.before.push(this); });
$.each(opts.original.after, function() { opts.after.push(this); });
// re-init
var init = $.fn.cycle.transitions[fx];
if ($.isFunction(init))
init(opts.$cont, $(opts.elements), opts);
};
// this is the main engine fn, it handles the timeouts, callbacks and slide index mgmt
function go(els, opts, manual, fwd) {
// opts.busy is true if we're in the middle of an animation
if (manual && opts.busy && opts.manualTrump) {
// let manual transitions requests trump active ones
debug('manualTrump in go(), stopping active transition');
$(els).stop(true,true);
opts.busy = false;
}
// don't begin another timeout-based transition if there is one active
if (opts.busy) {
debug('transition active, ignoring new tx request');
return;
}
var p = opts.$cont[0], curr = els[opts.currSlide], next = els[opts.nextSlide];
// stop cycling if we have an outstanding stop request
if (p.cycleStop != opts.stopCount || p.cycleTimeout === 0 && !manual)
return;
// check to see if we should stop cycling based on autostop options
if (!manual && !p.cyclePause &&
((opts.autostop && (--opts.countdown <= 0)) ||
(opts.nowrap && !opts.random && opts.nextSlide < opts.currSlide))) {
if (opts.end)
opts.end(opts);
return;
}
// if slideshow is paused, only transition on a manual trigger
var changed = false;
if ((manual || !p.cyclePause) && (opts.nextSlide != opts.currSlide)) {
changed = true;
var fx = opts.fx;
// keep trying to get the slide size if we don't have it yet
curr.cycleH = curr.cycleH || $(curr).height();
curr.cycleW = curr.cycleW || $(curr).width();
next.cycleH = next.cycleH || $(next).height();
next.cycleW = next.cycleW || $(next).width();
// support multiple transition types
if (opts.multiFx) {
if (opts.lastFx == undefined || ++opts.lastFx >= opts.fxs.length)
opts.lastFx = 0;
fx = opts.fxs[opts.lastFx];
opts.currFx = fx;
}
// one-time fx overrides apply to: $('div').cycle(3,'zoom');
if (opts.oneTimeFx) {
fx = opts.oneTimeFx;
opts.oneTimeFx = null;
}
$.fn.cycle.resetState(opts, fx);
// run the before callbacks
if (opts.before.length)
$.each(opts.before, function(i,o) {
if (p.cycleStop != opts.stopCount) return;
o.apply(next, [curr, next, opts, fwd]);
});
// stage the after callacks
var after = function() {
$.each(opts.after, function(i,o) {
if (p.cycleStop != opts.stopCount) return;
o.apply(next, [curr, next, opts, fwd]);
});
};
debug('tx firing; currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide);
// get ready to perform the transition
opts.busy = 1;
if (opts.fxFn) // fx function provided?
opts.fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
else if ($.isFunction($.fn.cycle[opts.fx])) // fx plugin ?
$.fn.cycle[opts.fx](curr, next, opts, after, fwd, manual && opts.fastOnEvent);
else
$.fn.cycle.custom(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
}
if (changed || opts.nextSlide == opts.currSlide) {
// calculate the next slide
opts.lastSlide = opts.currSlide;
if (opts.random) {
opts.currSlide = opts.nextSlide;
if (++opts.randomIndex == els.length)
opts.randomIndex = 0;
opts.nextSlide = opts.randomMap[opts.randomIndex];
if (opts.nextSlide == opts.currSlide)
opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : opts.currSlide + 1;
}
else { // sequence
var roll = (opts.nextSlide + 1) == els.length;
opts.nextSlide = roll ? 0 : opts.nextSlide+1;
opts.currSlide = roll ? els.length-1 : opts.nextSlide-1;
}
}
if (changed && opts.pager)
opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass);
// stage the next transition
var ms = 0;
if (opts.timeout && !opts.continuous)
ms = getTimeout(curr, next, opts, fwd);
else if (opts.continuous && p.cyclePause) // continuous shows work off an after callback, not this timer logic
ms = 10;
if (ms > 0)
p.cycleTimeout = setTimeout(function(){ go(els, opts, 0, !opts.rev) }, ms);
};
// invoked after transition
$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) {
$(pager).each(function() {
$(this).children().removeClass(clsName).eq(currSlide).addClass(clsName);
});
};
// calculate timeout value for current transition
function getTimeout(curr, next, opts, fwd) {
if (opts.timeoutFn) {
// call user provided calc fn
var t = opts.timeoutFn(curr,next,opts,fwd);
while ((t - opts.speed) < 250) // sanitize timeout
t += opts.speed;
debug('calculated timeout: ' + t + '; speed: ' + opts.speed);
if (t !== false)
return t;
}
return opts.timeout;
};
// expose next/prev function, caller must pass in state
$.fn.cycle.next = function(opts) { advance(opts, opts.rev?-1:1); };
$.fn.cycle.prev = function(opts) { advance(opts, opts.rev?1:-1);};
// advance slide forward or back
function advance(opts, val) {
var els = opts.elements;
var p = opts.$cont[0], timeout = p.cycleTimeout;
if (timeout) {
clearTimeout(timeout);
p.cycleTimeout = 0;
}
if (opts.random && val < 0) {
// move back to the previously display slide
opts.randomIndex--;
if (--opts.randomIndex == -2)
opts.randomIndex = els.length-2;
else if (opts.randomIndex == -1)
opts.randomIndex = els.length-1;
opts.nextSlide = opts.randomMap[opts.randomIndex];
}
else if (opts.random) {
opts.nextSlide = opts.randomMap[opts.randomIndex];
}
else {
opts.nextSlide = opts.currSlide + val;
if (opts.nextSlide < 0) {
if (opts.nowrap) return false;
opts.nextSlide = els.length - 1;
}
else if (opts.nextSlide >= els.length) {
if (opts.nowrap) return false;
opts.nextSlide = 0;
}
}
var cb = opts.onPrevNextEvent || opts.prevNextClick; // prevNextClick is deprecated
if ($.isFunction(cb))
cb(val > 0, opts.nextSlide, els[opts.nextSlide]);
go(els, opts, 1, val>=0);
return false;
};
function buildPager(els, opts) {
var $p = $(opts.pager);
$.each(els, function(i,o) {
$.fn.cycle.createPagerAnchor(i,o,$p,els,opts);
});
opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePagerClass);
};
$.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
var a;
if ($.isFunction(opts.pagerAnchorBuilder)) {
a = opts.pagerAnchorBuilder(i,el);
debug('pagerAnchorBuilder('+i+', el) returned: ' + a);
}
else
a = ''+(i+1)+'';
if (!a)
return;
var $a = $(a);
// don't reparent if anchor is in the dom
if ($a.parents('body').length === 0) {
var arr = [];
if ($p.length > 1) {
$p.each(function() {
var $clone = $a.clone(true);
$(this).append($clone);
arr.push($clone[0]);
});
$a = $(arr);
}
else {
$a.appendTo($p);
}
}
opts.pagerAnchors = opts.pagerAnchors || [];
opts.pagerAnchors.push($a);
$a.bind(opts.pagerEvent, function(e) {
e.preventDefault();
opts.nextSlide = i;
var p = opts.$cont[0], timeout = p.cycleTimeout;
if (timeout) {
clearTimeout(timeout);
p.cycleTimeout = 0;
}
var cb = opts.onPagerEvent || opts.pagerClick; // pagerClick is deprecated
if ($.isFunction(cb))
cb(opts.nextSlide, els[opts.nextSlide]);
go(els,opts,1,opts.currSlide < i); // trigger the trans
// return false; // <== allow bubble
});
if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble)
$a.bind('click.cycle', function(){return false;}); // suppress click
if (opts.pauseOnPagerHover)
$a.hover(function() { opts.$cont[0].cyclePause++; }, function() { opts.$cont[0].cyclePause--; } );
};
// helper fn to calculate the number of slides between the current and the next
$.fn.cycle.hopsFromLast = function(opts, fwd) {
var hops, l = opts.lastSlide, c = opts.currSlide;
if (fwd)
hops = c > l ? c - l : opts.slideCount - l;
else
hops = c < l ? l - c : l + opts.slideCount - c;
return hops;
};
// fix clearType problems in ie6 by setting an explicit bg color
// (otherwise text slides look horrible during a fade transition)
function clearTypeFix($slides) {
debug('applying clearType background-color hack');
function hex(s) {
s = parseInt(s).toString(16);
return s.length < 2 ? '0'+s : s;
};
function getBg(e) {
for ( ; e && e.nodeName.toLowerCase() != 'html'; e = e.parentNode) {
var v = $.css(e,'background-color');
if (v.indexOf('rgb') >= 0 ) {
var rgb = v.match(/\d+/g);
return '#'+ hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
}
if (v && v != 'transparent')
return v;
}
return '#ffffff';
};
$slides.each(function() { $(this).css('background-color', getBg(this)); });
};
// reset common props before the next transition
$.fn.cycle.commonReset = function(curr,next,opts,w,h,rev) {
$(opts.elements).not(curr).hide();
opts.cssBefore.opacity = 1;
opts.cssBefore.display = 'block';
if (w !== false && next.cycleW > 0)
opts.cssBefore.width = next.cycleW;
if (h !== false && next.cycleH > 0)
opts.cssBefore.height = next.cycleH;
opts.cssAfter = opts.cssAfter || {};
opts.cssAfter.display = 'none';
$(curr).css('zIndex',opts.slideCount + (rev === true ? 1 : 0));
$(next).css('zIndex',opts.slideCount + (rev === true ? 0 : 1));
};
// the actual fn for effecting a transition
$.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) {
var $l = $(curr), $n = $(next);
var speedIn = opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.easeOut;
$n.css(opts.cssBefore);
if (speedOverride) {
if (typeof speedOverride == 'number')
speedIn = speedOut = speedOverride;
else
speedIn = speedOut = 1;
easeIn = easeOut = null;
}
var fn = function() {$n.animate(opts.animIn, speedIn, easeIn, cb)};
$l.animate(opts.animOut, speedOut, easeOut, function() {
if (opts.cssAfter) $l.css(opts.cssAfter);
if (!opts.sync) fn();
});
if (opts.sync) fn();
};
// transition definitions - only fade is defined here, transition pack defines the rest
$.fn.cycle.transitions = {
fade: function($cont, $slides, opts) {
$slides.not(':eq('+opts.currSlide+')').css('opacity',0);
opts.before.push(function(curr,next,opts) {
$.fn.cycle.commonReset(curr,next,opts);
opts.cssBefore.opacity = 0;
});
opts.animIn = { opacity: 1 };
opts.animOut = { opacity: 0 };
opts.cssBefore = { top: 0, left: 0 };
}
};
$.fn.cycle.ver = function() { return ver; };
// override these globally if you like (they are all optional)
$.fn.cycle.defaults = {
fx: 'fade', // name of transition effect (or comma separated names, ex: 'fade,scrollUp,shuffle')
timeout: 4000, // milliseconds between slide transitions (0 to disable auto advance)
timeoutFn: null, // callback for determining per-slide timeout value: function(currSlideElement, nextSlideElement, options, forwardFlag)
continuous: 0, // true to start next transition immediately after current one completes
speed: 1000, // speed of the transition (any valid fx speed value)
speedIn: null, // speed of the 'in' transition
speedOut: null, // speed of the 'out' transition
next: null, // selector for element to use as event trigger for next slide
prev: null, // selector for element to use as event trigger for previous slide
// prevNextClick: null, // @deprecated; please use onPrevNextEvent instead
onPrevNextEvent: null, // callback fn for prev/next events: function(isNext, zeroBasedSlideIndex, slideElement)
prevNextEvent:'click.cycle',// event which drives the manual transition to the previous or next slide
pager: null, // selector for element to use as pager container
//pagerClick null, // @deprecated; please use onPagerEvent instead
onPagerEvent: null, // callback fn for pager events: function(zeroBasedSlideIndex, slideElement)
pagerEvent: 'click.cycle', // name of event which drives the pager navigation
allowPagerClickBubble: false, // allows or prevents click event on pager anchors from bubbling
pagerAnchorBuilder: null, // callback fn for building anchor links: function(index, DOMelement)
before: null, // transition callback (scope set to element to be shown): function(currSlideElement, nextSlideElement, options, forwardFlag)
after: null, // transition callback (scope set to element that was shown): function(currSlideElement, nextSlideElement, options, forwardFlag)
end: null, // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options)
easing: null, // easing method for both in and out transitions
easeIn: null, // easing for "in" transition
easeOut: null, // easing for "out" transition
shuffle: null, // coords for shuffle animation, ex: { top:15, left: 200 }
animIn: null, // properties that define how the slide animates in
animOut: null, // properties that define how the slide animates out
cssBefore: null, // properties that define the initial state of the slide before transitioning in
cssAfter: null, // properties that defined the state of the slide after transitioning out
fxFn: null, // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag)
height: 'auto', // container height
startingSlide: 0, // zero-based index of the first slide to be displayed
sync: 1, // true if in/out transitions should occur simultaneously
random: 0, // true for random, false for sequence (not applicable to shuffle fx)
fit: 0, // force slides to fit container
containerResize: 1, // resize container to fit largest slide
pause: 0, // true to enable "pause on hover"
pauseOnPagerHover: 0, // true to pause when hovering over pager link
autostop: 0, // true to end slideshow after X transitions (where X == slide count)
autostopCount: 0, // number of transitions (optionally used with autostop to define X)
delay: 0, // additional delay (in ms) for first transition (hint: can be negative)
slideExpr: null, // expression for selecting slides (if something other than all children is required)
cleartype: !$.support.opacity, // true if clearType corrections should be applied (for IE)
cleartypeNoBg: false, // set to true to disable extra cleartype fixing (leave false to force background color setting on slides)
nowrap: 0, // true to prevent slideshow from wrapping
fastOnEvent: 0, // force fast transitions when triggered manually (via pager or prev/next); value == time in ms
randomizeEffects: 1, // valid when multiple effects are used; true to make the effect sequence random
rev: 0, // causes animations to transition in reverse
manualTrump: true, // causes manual transition to stop an active transition instead of being ignored
requeueOnImageNotLoaded: true, // requeue the slideshow if any image slides are not yet loaded
requeueTimeout: 250, // ms delay for requeue
activePagerClass: 'activeSlide', // class name used for the active pager link
updateActivePagerLink: null // callback fn invoked to update the active pager link (adds/removes activePagerClass style)
};
})(jQuery);
;
function SlideShow( element, width, height, transition ) {
this.element = element;
this.images = [];
this.controls = {};
this.transition = transition || 'fade';
var currentWidth = this.element.width();
if ( !width || width > currentWidth ) {
width = currentWidth;
}
this.width = width;
this.height = height;
this.element.css( {
'height': this.height + 'px'
} );
}
SlideShow.prototype.showLoadingImage = function( toggle ) {
if ( toggle ) {
this.loadingImage_ = document.createElement( 'div' );
this.loadingImage_.className = 'slideshow-loading';
var img = document.createElement( 'img' );
img.src = WP_SLIDESHOW_IMAGES.load;
this.loadingImage_.appendChild( img );
this.loadingImage_.appendChild( this.makeZeroWidthSpan() );
this.loadingImage_.style.lineHeight = this.height + 'px';
this.element.append( this.loadingImage_ );
} else if ( this.loadingImage_ ) {
this.loadingImage_.parentNode.removeChild( this.loadingImage_ );
this.loadingImage_ = null;
}
};
SlideShow.prototype.init = function() {
this.showLoadingImage(true);
var self = this;
// Set up DOM.
for ( var i = 0; i < this.images.length; i++ ) {
var imageInfo = this.images[i];
var img = document.createElement( 'img' );
img.src = imageInfo.src + '?w=' + this.width;
img.align = 'middle';
var caption = document.createElement( 'div' );
caption.className = 'slideshow-slide-caption';
caption.innerHTML = imageInfo.caption;
var container = document.createElement('div');
container.className = 'slideshow-slide';
container.style.lineHeight = this.height + 'px';
// Hide loading image once first image has loaded.
if ( i == 0 ) {
if ( img.complete ) {
// IE, image in cache
setTimeout( function() {
self.finishInit_();
}, 1);
} else {
jQuery( img ).load(function() {
self.finishInit_();
});
}
}
container.appendChild( img );
// I'm not sure where these were coming from, but IE adds
// bad values for width/height for portrait-mode images
img.removeAttribute('width');
img.removeAttribute('height');
container.appendChild( this.makeZeroWidthSpan() );
container.appendChild( caption );
this.element.append( container );
}
};
SlideShow.prototype.makeZeroWidthSpan = function() {
var emptySpan =
document.createElement( 'span' );
emptySpan.className = 'slideshow-line-height-hack';
// Having a NBSP makes IE act weird during transitions, but other
// browsers ignore a text node with a space in it as whitespace.
if (jQuery.browser.msie) {
emptySpan.appendChild(document.createTextNode(' '));
} else {
emptySpan.innerHTML = ' ';
}
return emptySpan;
};
SlideShow.prototype.finishInit_ = function() {
this.showLoadingImage( false );
this.renderControls_();
var self = this;
// Initialize Cycle instance.
this.element.cycle( {
fx: this.transition,
prev: this.controls.prev,
next: this.controls.next,
slideExpr: '.slideshow-slide',
onPrevNextEvent: function() {
return self.onCyclePrevNextClick_.apply(
self, arguments);
}
} );
var slideshow = this.element;
jQuery( this.controls['stop'] ).click( function() {
var button = jQuery(this);
var icon;
if ( !button.hasClass( 'paused' ) ) {
slideshow.cycle( 'pause' );
button.removeClass( ' running ');
button.addClass( 'paused' );
icon = 'play';
} else {
button.addClass( 'running' );
button.removeClass( 'paused' );
slideshow.cycle( 'resume', true );
icon = 'stop';
}
button.children( 'img' ).attr( 'src', WP_SLIDESHOW_IMAGES[icon] );
return false;
} );
var controls = jQuery( this.controlsDiv_ );
slideshow.mouseenter( function() {
controls.fadeIn();
} );
slideshow.mouseleave( function() {
controls.fadeOut();
} );
this.initialized_ = true;
};
SlideShow.prototype.renderControls_ = function() {
if ( this.controlsDiv_ ) {
return;
}
var controlsDiv = document.createElement( 'div' );
controlsDiv.className = 'slideshow-controls';
controls = [ 'prev', 'stop', 'next' ];
for ( var i = 0; i < controls.length; i++ ) {
var controlName = controls[i];
var a = document.createElement( 'a' );
a.href = '#';
controlsDiv.appendChild( a );
this.controls[controlName] = a;
}
this.element.append( controlsDiv );
this.controlsDiv_ = controlsDiv;
};
SlideShow.prototype.onCyclePrevNextClick_ = function( isNext, i, slideElement ) {
var postid = this.images[i].id;
var stats = new Image();
stats.src = document.location.protocol +
'//stats.wordpress.com/g.gif?host=' +
escape( document.location.host ) +
'&rand=' + Math.random() +
'&blog=' + WP_SLIDESHOW_BLOG_INFO.blogId +
'&subd=' + WP_SLIDESHOW_BLOG_INFO.subDomain +
'&user_id=' + WP_SLIDESHOW_BLOG_INFO.userId +
'&post=' + postid +
'&ref=' + escape( document.location );
};
;