1/* 2 jQuery zAccordion Plugin v2.1.0 3 Copyright (c) 2010 - 2012 Nate Armagost, http://www.armagost.com/zaccordion 4 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 7*/ 8(function ($) { 9 "use strict"; 10 $.fn.zAccordion = function (method) { 11 var defaults = { 12 timeout: 6000, /* Time between each slide (in ms). */ 13 width: null, /* Width of the container. This option is required. */ 14 slideWidth: null, /* Width of each slide in pixels or width of each slide compared to a 100% container. */ 15 tabWidth: null, /* Width of each slide's "tab" (when clicked it opens the slide) or width of each tab compared to a 100% container. */ 16 height: null, /* Height of the container. This option is required. */ 17 startingSlide: 0, /* Zero-based index of which slide should be displayed. */ 18 slideClass: null, /* Class prefix of each slide. If left null, no classes will be set. */ 19 easing: null, /* Easing method. */ 20 speed: 1200, /* Speed of the slide transition (in ms). */ 21 auto: true, /* Whether or not the slideshow should play automatically. */ 22 trigger: "click", /* Event type that will bind to the "tab" (click, mouseover, etc.). */ 23 pause: true, /* Pause on hover. */ 24 invert: false, /* Whether or not to invert the slideshow, so the last slide stays in the same position, rather than the first slide. */ 25 animationStart: function () {}, /* Function called when animation starts. */ 26 animationComplete: function () {}, /* Function called when animation completes. */ 27 buildComplete: function () {}, /* Function called after the accordion is finished building. */ 28 errors: false /* Display zAccordion specific errors. */ 29 }, helpers = { 30 displayError: function (msg, e) { 31 if (window.console && e) { 32 console.log("zAccordion: " + msg + "."); 33 } 34 }, 35 findChildElements: function (t) { /* Function to find the number of child elements. */ 36 if (t.children().get(0) === undefined) { 37 return false; 38 } else { 39 return true; 40 } 41 }, 42 getNext: function (s, c) { /* Returns the 0-index of the next slide. */ 43 var next = c + 1; 44 if (next >= s) { 45 next = 0; 46 } 47 return next; 48 }, 49 fixHeight: function (o) { 50 if ((o.height === null) && (o.slideHeight !== undefined)) { /* Removed slideHeight. */ 51 o.height = o.slideHeight; 52 return true; 53 } else if ((o.height !== null) && (o.slideHeight === undefined)) { 54 return true; 55 } else if ((o.height === null) && (o.slideHeight === undefined)) { 56 return false; 57 } 58 }, 59 getUnits: function (o) { 60 if (o !== null) { 61 if (o.toString().indexOf("%") > -1) { 62 return "%"; 63 } else if (o.toString().indexOf("px") > -1) { 64 return "px"; 65 } else { 66 return "px"; 67 } 68 } 69 }, 70 toInteger: function (o) { 71 if (o !== null) { 72 return parseInt(o, 10); 73 } 74 }, 75 sizeAccordion: function (t, o) { /* Calculate the sizes of the tabs and slides */ 76 if ((o.width === undefined) && (o.slideWidth === undefined) && (o.tabWidth === undefined)) { 77 /* Nothing is defined. */ 78 helpers.displayError("width must be defined", o.errors); 79 return false;
80 } else if ((o.width !== undefined) && (o.slideWidth === undefined) && (o.tabWidth === undefined)) { 81 /* Only width is defined. */ 82 /* Check for errors. */ 83 if ((o.width > 100) && (o.widthUnits === "%")) { /* Check for a width percentage of over 100. */ 84 helpers.displayError("width cannot be over 100%", o.errors); 85 return false; 86 } else { 87 o.slideWidthUnits = o.widthUnits; 88 o.tabWidthUnits = o.widthUnits; 89 if (o.widthUnits === "%") { /* Percentages. */ 90 o.tabWidth = 100 / (t.children().size() + 1); /* Use 100% instead of the defined width. */ 91 o.slideWidth = 100 - ((t.children().size() - 1) * o.tabWidth); 92 } else { /* Pixels. */ 93 o.tabWidth = o.width / (t.children().size() + 1); 94 o.slideWidth = o.width - ((t.children().size() - 1) * o.tabWidth); 95 } 96 return true; 97 } 98 } else if ((o.width === undefined) && (o.slideWidth !== undefined) && (o.tabWidth === undefined)) { 99 /* Only slideWidth is defined. */ 100 helpers.displayError("width must be defined", o.errors); 101 return false; 102 } else if ((o.width === undefined) && (o.slideWidth === undefined) && (o.tabWidth !== undefined)) { 103 /* Only tabWidth is defined. */ 104 helpers.displayError("width must be defined", o.errors); 105 return false; 106 } else if ((o.width !== undefined) && (o.slideWidth === undefined) && (o.tabWidth !== undefined)) { 107 /* width and tabWidth defined. */ 108 /* Check for errors */ 109 if (o.widthUnits !== o.tabWidthUnits) { 110 helpers.displayError("Units do not match", o.errors); 111 return false; 112 } else if ((o.width > 100) && (o.widthUnits === "%")) { 113 helpers.displayError("width cannot be over 100%", o.errors); 114 return false; 115 } else if ((((t.children().size() * o.tabWidth) > 100) && (o.widthUnits === "%")) || (((t.children().size() * o.tabWidth) > o.width) && (o.widthUnits === "px"))) { 116 helpers.displayError("tabWidth too large for accordion", o.errors); 117 return false; 118 } else { 119 /* Need to define the remaining slideWidth */ 120 o.slideWidthUnits = o.widthUnits; /* Set the units to be consistent */ 121 if (o.widthUnits === "%") { /* Percentages */ 122 o.slideWidth = 100 - ((t.children().size() - 1) * o.tabWidth); /* Use 100% instead of the defined width */ 123 } else { /* Pixels */ 124 o.slideWidth = o.width - ((t.children().size() - 1) * o.tabWidth); 125 } 126 return true; 127 } 128 } else if ((o.width !== undefined) && (o.slideWidth !== undefined) && (o.tabWidth === undefined)) { 129 /* width and slideWidth defined. */ 130 /* Check for errors. */ 131 if (o.widthUnits !== o.slideWidthUnits) { 132 helpers.displayError("Units do not match", o.errors); 133 return false; 134 } else if ((o.width > 100) && (o.widthUnits === "%")) { 135 helpers.displayError("width cannot be over 100%", o.errors); 136 return false; 137 } else if (o.slideWidth >= o.width) { 138 helpers.displayError("slideWidth cannot be greater than or equal to width", o.errors); 139 return false; 140 } else if ((((t.children().size() * o.slideWidth) < 100) && (o.widthUnits === "%")) || (((t.children().size() * o.slideWidth) < o.width) && (o.widthUnits === "px"))) { /* Prevents gaps in the accordion. For example, a slider with 4 slides at 150 pixels wide. 4 * 150 = 600. Needs to fill an 800px space. */ 141 helpers.displayError("slideWidth too small for accordion", o.errors); 142 return false; 143 } else { 144 /* Need to define the remaining tabWidth. */ 145 o.tabWidthUnits = o.widthUnits; /* Set the units to be consistent. */ 146 if (o.widthUnits === "%") { /* Percentages. */ 147 o.tabWidth = (100 - o.slideWidth) / (t.children().size() - 1); /* Use 100% instead of the defined width. */ 148 } else { /* Pixels. */ 149 o.tabWidth = (o.width - o.slideWidth) / (t.children().size() - 1); 150 } 151 return true; 152 } 153 } else if ((o.width === undefined) && (o.slideWidth !== undefined) && (o.tabWidth !== undefined)) { 154 /* slideWidth and tabWidth defined. */ 155 helpers.displayError("width must be defined", o.errors); 156 return false;
157 } else if ((o.width !== undefined) && (o.slideWidth !== undefined) && (o.tabWidth !== undefined)) { 158 /* width, slideWidth, and tabWidth defined. */ 159 helpers.displayError("At maximum two of three attributes (width, slideWidth, and tabWidth) should be defined", o.errors); 160 return false; 161 } 162 }, 163 timer: function (obj) { 164 var n = obj.data("next") + 1; 165 if (obj.data("pause") && obj.data("inside") && obj.data("auto")) { 166 try { 167 clearTimeout(obj.data("interval")); 168 } catch (e) {} 169 } else if (obj.data("pause") && !obj.data("inside") && obj.data("auto")) { 170 try { 171 clearTimeout(obj.data("interval")); 172 } catch (f) {} 173 obj.data("interval", setTimeout(function () { 174 obj.children(obj.children().get(0).tagName + ":nth-child(" + n + ")").trigger(obj.data("trigger")); 175 }, obj.data("timeout"))); 176 } else if (!obj.data("pause") && obj.data("auto")) { 177 try { 178 clearTimeout(obj.data("interval")); 179 } catch (g) {} 180 obj.data("interval", setTimeout(function () { 181 obj.children(obj.children().get(0).tagName + ":nth-child(" + n + ")").trigger(obj.data("trigger")); 182 }, obj.data("timeout"))); 183 } 184 } 185 }, methods = { 186 init: function (options) { 187 var f, fixattr = ["slideWidth", "tabWidth", "startingSlide", "slideClass", "animationStart", "animationComplete", "buildComplete"]; 188 for (f = 0; f < fixattr.length; f += 1) { 189 if ($(this).data(fixattr[f].toLowerCase()) !== undefined) { 190 $(this).data(fixattr[f], $(this).data(fixattr[f].toLowerCase())); 191 $(this).removeData(fixattr[f].toLowerCase()); 192 } 193 } 194 /* Add new properties to options. */ 195 options = $.extend(defaults, options, $(this).data()); 196 /* Check for a height */ 197 if (this.length <= 0) { 198 helpers.displayError("Selector does not exist", options.errors); 199 return false; 200 } else if (!helpers.fixHeight(options)) { 201 helpers.displayError("height must be defined", options.errors); 202 return false; 203 } else if (!helpers.findChildElements(this)) { 204 helpers.displayError("No child elements available", options.errors); 205 return false; 206 } else if (options.speed > options.timeout) { 207 helpers.displayError("Speed cannot be greater than timeout", options.errors); 208 return false; 209 } else { 210 /* Get the correct units */ 211 options.heightUnits = helpers.getUnits(options.height); 212 options.height = helpers.toInteger(options.height); 213 options.widthUnits = helpers.getUnits(options.width); 214 options.width = helpers.toInteger(options.width); 215 options.slideWidthUnits = helpers.getUnits(options.slideWidth); 216 options.slideWidth = helpers.toInteger(options.slideWidth); 217 options.tabWidthUnits = helpers.getUnits(options.tabWidth); 218 options.tabWidth = helpers.toInteger(options.tabWidth); 219 if (options.slideClass !== null) { 220 options.slideOpenClass = options.slideClass + "-open"; /* Class of open slides. */ 221 options.slideClosedClass = options.slideClass + "-closed"; /* Class of closed slides. */ 222 options.slidePreviousClass = options.slideClass + "-previous"; /* Class of the slide that was previously open before a new one was triggered. */ 223 } 224 /* Check for inconsistencies in size. */ 225 if (!helpers.sizeAccordion(this, options)) { 226 return false; 227 } else { 228 return this.each(function () { 229 var o = options, obj = $(this), originals = [], /* inside = false, */ animate, tag, childtag, size, previous = -1; /* o: all of the options (defaults, user options, settings) */ 230 animate = o.slideWidth - o.tabWidth; /* Number of pixels yet do be displayed on a hidden slide. */ 231 tag = obj.get(0).tagName; /* Tag type of the container. */ 232 childtag = obj.children().get(0).tagName; /* Tag type of the children. */ 233 size = obj.children().size(); /* Number of children. */ 234 obj.data($.extend({}, { 235 auto: o.auto, 236 interval: null, 237 timeout: o.timeout, 238 trigger: o.trigger, 239 current: o.startingSlide, 240 previous: previous, 241 next: helpers.getNext(size, o.startingSlide), 242 slideClass: o.slideClass, /* Keeping this around right now only for the sake of the destroy function. */ 243 inside: false, 244 pause: o.pause 245 })); 246 if (o.heightUnits === "%") { 247 o.height = (obj.parent().get(0).tagName === "BODY") ? o.height * 0.01 * $(window).height() : o.height * 0.01 * obj.parent().height(); 248 o.heightUnits = "px"; /* Need to revert to pixels because CSS 100% height does not cooperate. */ 249 } 250 /* Loop through each of the slides and set the layers. */ 251 obj.children().each(function (childindex) { 252 var zindex, xpos, y; 253 xpos = o.invert ? xpos = ((size - 1) * o.tabWidth) - (childindex * o.tabWidth) : childindex * o.tabWidth; /* Used for the position of each slide. */ 254 originals[childindex] = xpos; /* px position of each open slide. */ 255 zindex = o.invert ? ((size - 1) - childindex) * 10 : childindex * 10; /* Increase each slide's z-index by 10 so they sit on top of each other. */ 256 if (o.slideClass !== null) { 257 $(this).addClass(o.slideClass); /* Add the slide class to each of the slides. */ 258 } 259 $(this).css({ 260 "top": 0, 261 "z-index": zindex, 262 "margin": 0, 263 "padding": 0, 264 "float": "left", 265 "display": "block", 266 "position": "absolute", 267 "overflow": "hidden", 268 "width": o.slideWidth + o.widthUnits, 269 "height": o.height + o.heightUnits 270 }); 271 if (childtag === "LI") { 272 $(this).css({ 273 "text-indent": 0 274 }); 275 } 276 if (o.invert) { 277 $(this).css({ "right": xpos + o.widthUnits, "float": "right" }); 278 } else {
279 $(this).css({ "left": xpos + o.widthUnits, "float": "left" }); 280 } 281 if (childindex === (o.startingSlide)) { 282 $(this).css("cursor", "default"); 283 if (o.slideClass !== null) { 284 $(this).addClass(o.slideOpenClass); 285 } 286 } else { 287 $(this).css("cursor", "pointer"); 288 if (o.slideClass !== null) { 289 $(this).addClass(o.slideClosedClass); 290 } 291 if ((childindex > (o.startingSlide)) && (!o.invert)) { 292 y = childindex + 1; 293 obj.children(childtag + ":nth-child(" + y + ")").css({ 294 left: originals[y - 1] + animate + o.widthUnits 295 }); 296 } else if ((childindex < (o.startingSlide)) && (o.invert)) { 297 y = childindex + 1; 298 obj.children(childtag + ":nth-child(" + y + ")").css({ 299 right: originals[y - 1] + animate + o.widthUnits 300 }); 301 } 302 } 303 }); 304 /* Modify the CSS of the main container. */ 305 obj.css({ 306 "display": "block", 307 "height": o.height + o.heightUnits, 308 "width": o.width + o.widthUnits, 309 "padding": 0, 310 "position": "relative", 311 "overflow": "hidden" 312 }); 313 /* If the container is a list, get rid of any bullets. */ 314 if ((tag === "UL") || (tag === "OL")) { 315 obj.css({ 316 "list-style": "none" 317 }); 318 } 319 obj.hover(function () { 320 obj.data("inside", true); 321 /* If pause on hover, clear the timer. */ 322 if (obj.data("pause")) { 323 try { 324 clearTimeout(obj.data("interval")); 325 } catch (e) {} 326 } 327 }, function () { 328 obj.data("inside", false); 329 /* Restart the accordion when user moves mouse out of the slides. */ 330 if (obj.data("auto") && obj.data("pause")) { 331 helpers.timer(obj); 332 } 333 }); 334 /* Set up the listener to change slides when triggered. */ 335 obj.children().bind(o.trigger, function () { 336 /* Don't do anything if the slide is already open. */ 337 if ($(this).index() !== obj.data("current")) { 338 var i, j, p, c; /* p and c are 1-indexes */ 339 p = previous + 1; /* Using the 1-index for nth selector. */ 340 c = obj.data("current") + 1; /* Using the 1-index for nth selector. */ 341 if ((p !== 0) && (o.slideClass !== null)) { 342 obj.children(childtag + ":nth-child(" + p + ")").removeClass(o.slidePreviousClass); /* Remove class for previous slide if previous slide exists. */ 343 } 344 obj.children(childtag + ":nth-child(" + c + ")"); 345 if (o.slideClass !== null) { 346 obj.children(childtag + ":nth-child(" + c + ")").addClass(o.slidePreviousClass); 347 } 348 previous = obj.data("current"); 349 obj.data("previous", obj.data("current")); 350 p = previous; 351 p += 1; 352 obj.data("current", $(this).index()); 353 c = obj.data("current"); 354 c += 1; 355 obj.children().css("cursor", "pointer"); 356 $(this).css("cursor", "default"); /* Add the open class to the slide tab that was just triggered */ 357 if (o.slideClass !== null) { 358 obj.children().addClass(o.slideClosedClass).removeClass(o.slideOpenClass); 359 $(this).addClass(o.slideOpenClass).removeClass(o.slideClosedClass); /* Add the open class to the slide tab that was just triggered */ 360 } 361 obj.data("next", helpers.getNext(size, $(this).index())); 362 /* If the slide is not open... */ 363 helpers.timer(obj); 364 o.animationStart(); 365 if (o.invert) { 366 obj.children(childtag + ":nth-child(" + c + ")").stop().animate({ right: originals[obj.data("current")] + o.widthUnits }, o.speed, o.easing, o.animationComplete); 367 } else { 368 obj.children(childtag + ":nth-child(" + c + ")").stop().animate({ left: originals[obj.data("current")] + o.widthUnits }, o.speed, o.easing, o.animationComplete); 369 } 370 /* Closing other slides. */ 371 for (i = 0; i < size; i += 1) { 372 j = i + 1; 373 if (i < obj.data("current")) { 374 if (o.invert) { 375 obj.children(childtag + ":nth-child(" + j + ")").stop().animate({ 376 right: o.width - (j * o.tabWidth) + o.widthUnits 377 }, o.speed, o.easing); 378 } else { 379 obj.children(childtag + ":nth-child(" + j + ")").stop().animate({ 380 left: originals[i] + o.widthUnits 381 }, o.speed, o.easing); 382 } 383 } 384 if (i > obj.data("current")) { 385 if (o.invert) { 386 obj.children(childtag + ":nth-child(" + j + ")").stop().animate({ 387 right: (size - j) * o.tabWidth + o.widthUnits 388 }, o.speed, o.easing); 389 } else { 390 obj.children(childtag + ":nth-child(" + j + ")").stop().animate({ 391 left: originals[i] + animate + o.widthUnits 392 }, o.speed, o.easing); 393 } 394 } 395 } 396 return false; /* This is important. If a visible link is clicked within the slide, it will open the slide instead of redirecting the link. */ 397 } 398 }); 399 /* Set up the original timer. */ 400 if (obj.data("auto")) { 401 helpers.timer(obj); 402 } 403 o.buildComplete(); 404 }); 405 } 406 } 407 }, 408 stop: function () { /* This will stop the accordion unless the slides are clicked, however, it will not resume the autoplay. */ 409 if ($(this).data("auto")) { 410 clearTimeout($(this).data("interval")); 411 $(this).data("auto", false); 412 } 413 }, 414 start: function () { /* This will start the accordion back up if it has been stopped. */ 415 if (!$(this).data("auto")) { 416 var n = $(this).data("next") + 1; 417 $(this).data("auto", true); 418 $(this).children($(this).children().get(0).tagName + ":nth-child(" + n + ")").trigger($(this).data("trigger")); 419 } 420 }, 421 trigger: function (x) { 422 if ((x >= $(this).children().size()) || (x < 0)) { /* If the triggered slide is out of range, trigger the first slide. */ 423 x = 0; 424 } 425 x += 1; /* Use nth-child to trigger slide. */ 426 $(this).children($(this).children().get(0).tagName + ":nth-child(" + x + ")").trigger($(this).data("trigger")); 427 }, 428 destroy: function (o) { 429 var removestyle, removeclasses, prefix = $(this).data("slideClass"); 430 if (o !== undefined) { 431 removestyle = (o.removeStyleAttr !== undefined) ? o.removeStyleAttr : true; 432 removeclasses = (o.removeClasses !== undefined) ? o.removeClasses : false;
433 } 434 clearTimeout($(this).data("interval")); 435 $(this).children().stop().unbind($(this).data("trigger")); 436 $(this).unbind("mouseenter mouseleave mouseover mouseout"); 437 if (removestyle) { 438 $(this).removeAttr("style"); 439 $(this).children().removeAttr("style"); 440 } 441 if (removeclasses) { 442 $(this).children().removeClass(prefix); 443 $(this).children().removeClass(prefix + "-open"); 444 $(this).children().removeClass(prefix + "-closed"); 445 $(this).children().removeClass(prefix + "-previous"); 446 } 447 $(this).removeData(); 448 if (o !== undefined) { 449 if (o.destroyComplete !== "undefined") { 450 if (typeof(o.destroyComplete.afterDestroy) !== "undefined") { 451 o.destroyComplete.afterDestroy(); 452 } 453 if (o.destroyComplete.rebuild) { 454 return methods.init.apply(this, [o.destroyComplete.rebuild]); 455 } 456 } 457 } 458 } 459 }; 460 if (methods[method]) { 461 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 462 } else if (typeof method === "object" || !method) { 463 return methods.init.apply(this, arguments); 464 } else { 465 $.error("zAccordion: " + method + " does not exist."); 466 } 467 }; 468}(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.