1// SpryContentSlideShow.js - version 0.10 - Spry Pre-Release 1.7 2// 3// Copyright (c) 2010. Adobe Systems Incorporated. 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are met: 8// 9// * Redistributions of source code must retain the above copyright notice, 10// this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above copyright notice, 12// this list of conditions and the following disclaimer in the documentation 13// and/or other materials provided with the distribution. 14// * Neither the name of Adobe Systems Incorporated nor the names of its 15// contributors may be used to endorse or promote products derived from this 16// software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28// POSSIBILITY OF SUCH DAMAGE. 29 30(function() { // BeginSpryComponent 31 32if (typeof Spry == "undefined" || !Spry.Widget || !Spry.Widget.Base) 33{ 34 alert("SpryContentSlideShow.js requires SpryWidget.js!"); 35 return; 36} 37 38var defaultConfig = { 39 plugIns: [], 40 41 injectionType: "inside", // "inside" or "replace" 42 extractionType: "element", // "element" or "content" 43 repeatingElementSelector: null, 44 45 useButtonControls: false, // true == <button>, false == <a> 46 47 dropFrames: true, 48 49 autoPlay: true, 50 transitionDuration: 2000, // msecs 51 displayInterval: 6000, // msecs 52 53 widgetID: null, 54 55 widgetClass: "SlideShow", // Sliceable 56 playingClass: "SSPlaying", 57 clipClass: "SSClip", 58 viewClass: "SSView", 59 slideClass: "SSSlide", // Sliceable 60 slideVisibleClass: "SSSlideVisible", 61 slideHiddenClass: "SSSlideHidden", 62 slideTitleClass: "SSSlideTitle", // Sliceable 63 slideDescriptionClass: "SSSlideDescription", // Sliceable 64 countClass: "SSSlideCount", // Sliceable 65 slideLinksClass: "SSSlideLinks", // Sliceable 66 slideLinkClass: "SSSlideLink", // Sliceable 67 controlsClass: "SSControls", // Sliceable 68 firstBtnClass: "SSFirstButton", // Sliceable 69 prevBtnClass: "SSPreviousButton", // Sliceable 70 playBtnClass: "SSPlayButton", // Sliceable 71 nextBtnClass: "SSNextButton", // Sliceable 72 lastBtnClass: "SSLastButton", // Sliceable 73 playLabelClass: "SSPlayLabel", 74 pauseLabelClass: "SSPauseLabel", 75 slideShowBusy: "SSBusy", 76 slideLoading: "SSSlideLoading", 77 78 sliceMap: {}, 79 componentOrder: [ "view", "controls", "links", "title", "description", "count" ] 80}; 81 82Spry.Widget.ContentSlideShow = function(ele, opts) 83{ 84 Spry.Widget.Base.call(this); 85 86 this.element = Spry.$$(ele)[0]; 87 this.isPlaying = false; 88 89 // Initialize the accordion object with the global defaults. 90 91 this.setOptions(this, Spry.Widget.ContentSlideShow.config); 92 93 // Override the defaults with any options passed into the constructor. 94 95 this.setOptions(this, opts); 96 97 var self = this; 98 99 this.firstFunc = function(e) { return self.showFirstSlide(); }; 100 this.prevFunc = function(e) { return self.showPreviousSlide(); }; 101 this.playFunc = function(e) { return self.togglePlayMode(); }; 102 this.nextFunc = function(e) { return self.showNextSlide(); }; 103 this.lastFunc = function(e) { return self.showLastSlide(); }; 104 105 this.initializePlugIns(Spry.Widget.ContentSlideShow.config.plugIns, opts); 106 107 var evt = new Spry.Widget.Event(this); 108 this.notifyObservers("onPreInitialize", evt); 109 if (!evt.performDefaultAction) 110 return; 111 112 this.transformMarkup(); 113 this.attachBehaviors();
114 115 this.updateSlideCountLabel(); 116 117 if (this.autoPlay) 118 this.triggerCallbackAfterOnLoad(this.play, this); 119 120 this.notifyObservers("onPostInitialize", evt); 121}; 122 123Spry.Widget.ContentSlideShow.prototype = new Spry.Widget.Base(); 124Spry.Widget.ContentSlideShow.prototype.constructor = Spry.Widget.ContentSlideShow; 125 126Spry.Widget.ContentSlideShow.config = defaultConfig; 127 128Spry.Widget.ContentSlideShow.prototype.showSlide = function(eleOrIndex) 129{ 130 var ps = this.panelSet; 131 if (ps && ps.showPanel) 132 ps.showPanel(eleOrIndex); 133}; 134 135Spry.Widget.ContentSlideShow.prototype.hideSlide = function(eleOrIndex) 136{ 137 var ps = this.panelSet; 138 if (ps && ps.hidePanel) 139 ps.hidePanel(eleOrIndex); 140}; 141 142Spry.Widget.ContentSlideShow.prototype.showFirstSlide = function() 143{ 144 var evt = new Spry.Widget.Event(this); 145 this.notifyObservers("onPreShowFirstSlide", evt); 146 if (!evt.performDefaultAction) 147 return false; 148 149 if (this.panelSet) 150 this.panelSet.showFirstPanel(); 151 152 this.notifyObservers("onPostShowFirstSlide", evt); 153 154 return false; 155}; 156 157Spry.Widget.ContentSlideShow.prototype.showPreviousSlide = function() 158{ 159 var evt = new Spry.Widget.Event(this); 160 this.notifyObservers("onPreShowPreviousSlide", evt); 161 if (!evt.performDefaultAction) 162 return false; 163 164 if (this.panelSet) 165 this.panelSet.showPreviousPanel(); 166 167 this.notifyObservers("onPostShowPreviousSlide", evt); 168 169 return false; 170}; 171 172Spry.Widget.ContentSlideShow.prototype.showNextSlide = function() 173{ 174 var evt = new Spry.Widget.Event(this); 175 this.notifyObservers("onPreShowNextSlide", evt); 176 if (!evt.performDefaultAction) 177 return false; 178 179 if (this.panelSet) 180 this.panelSet.showNextPanel(); 181 182 this.notifyObservers("onPostShowNextSlide", evt); 183 184 return false; 185}; 186 187Spry.Widget.ContentSlideShow.prototype.showLastSlide = function() 188{ 189 var evt = new Spry.Widget.Event(this); 190 this.notifyObservers("onPreShowLastSlide", evt); 191 if (!evt.performDefaultAction) 192 return false; 193 194 if (this.panelSet) 195 this.panelSet.showLastPanel(); 196 197 this.notifyObservers("onPostShowLastSlide", evt); 198 199 return false; 200}; 201 202Spry.Widget.ContentSlideShow.prototype.play = function() 203{ 204 var evt = new Spry.Widget.Event(this); 205 this.notifyObservers("onPreStartSlideShow", evt); 206 if (!evt.performDefaultAction) 207 return false; 208 209 if (this.panelSet) 210 this.panelSet.play(); 211 212 this.notifyObservers("onPostStartSlideShow", evt); 213 214 return false; 215}; 216 217Spry.Widget.ContentSlideShow.prototype.stop = function() 218{ 219 var evt = new Spry.Widget.Event(this); 220 this.notifyObservers("onPreStopSlideShow", evt); 221 if (!evt.performDefaultAction) 222 return false; 223 224 if (this.panelSet) 225 this.panelSet.stop(); 226 227 this.notifyObservers("onPostStopSlideShow", evt); 228 229 return false; 230}; 231 232Spry.Widget.ContentSlideShow.prototype.togglePlayMode = function() 233{ 234 if (this.element) 235 { 236 if (Spry.Utils.hasClassName(this.element, this.playingClass)) 237 this.stop(); 238 else 239 this.play(); 240 } 241 return false; 242}; 243 244Spry.Widget.ContentSlideShow.prototype.getCurrentSlide = function() 245{ 246 return this.panelSet ? this.panelSet.getCurrentPanel() : null; 247}; 248 249Spry.Widget.ContentSlideShow.prototype.getCurrentSlideIndex = function(idx) 250{ 251 var ps = this.panelSet; 252 return ps && ps.getCurrentPanelIndex ? ps.getCurrentPanelIndex() : -1; 253}; 254 255Spry.Widget.ContentSlideShow.prototype.getSlideIndex = function(ele) 256{ 257 var ps = this.panelSet; 258 return ps && ps.getPanelIndex ? ps.getPanelIndex(ele) : -1; 259}; 260 261Spry.Widget.ContentSlideShow.prototype.getSlides = function() 262{ 263 var results = []; 264 var clip = Spry.$$("." + this.clipClass, this.element)[0]; 265 if (clip) 266 return Spry.$$("." + this.slideClass, clip); 267 return results; 268}; 269 270Spry.Widget.ContentSlideShow.prototype.isInPlayMode = function() 271{ 272 return this.isPlaying; 273}; 274 275Spry.Widget.ContentSlideShow.prototype.handlePanelSetStart = function(e) 276{ 277 this.isPlaying = true; 278 this.addClassName(this.element, this.playingClass); 279 return false; 280}; 281 282Spry.Widget.ContentSlideShow.prototype.handlePanelSetStop = function(e) 283{ 284 this.isPlaying = false; 285 this.removeClassName(this.element, this.playingClass); 286 return false; 287}; 288 289Spry.Widget.ContentSlideShow.prototype.handlePanelSetPreShowPanel = function(e) 290{ 291 var evt = new Spry.Widget.Event(this, { target: e.panelElement }); 292 this.notifyObservers("onPreShowSlide", evt); 293 if (!evt.performDefaultAction) 294 { 295 e.preventDefault(); 296 return false; 297 } 298 299 return false; 300}; 301 302Spry.Widget.ContentSlideShow.prototype.handlePanelSetPostShowPanel = function(e) 303{ 304 this.updateSlideCountLabel(); 305 306 var evt = new Spry.Widget.Event(this, { target: e.target, slideIndex: e.targetIndex }); 307 this.notifyObservers("onPostShowSlide", evt); 308 309 return false; 310}; 311 312Spry.Widget.ContentSlideShow.prototype.updateSlideCountLabel = function() 313{ 314 var self = this;
315 Spry.$$("." + this.countClass).forEach(function(n) 316 { 317 if (n.contentContainer) 318 n.contentContainer.innerHTML = self.getSlideCountLabel(); 319 }); 320}; 321 322Spry.Widget.ContentSlideShow.prototype.getSlideCountLabel = function() 323{ 324 var str = ""; 325 var ps = this.panelSet; 326 if (ps) 327 str += (ps.getCurrentPanelIndex() + 1) + " of " + ps.getPanelCount(); 328 return str; 329}; 330 331Spry.Widget.ContentSlideShow.prototype.createButtonElement = function(label, className, clickFunc, useLink) 332{ 333 var btn = this.createOptionalSlicedStructure(null, useLink ? "a" : "button", className, null, "span"); 334 335 if (useLink) 336 btn.href = "#"; 337 else 338 btn.setAttribute("type", "button"); 339 340 this.addClassName(btn, className); 341 btn.contentContainer.appendChild(document.createTextNode(label)); 342 343 return btn; 344}; 345 346Spry.Widget.ContentSlideShow.prototype.transformMarkup = function() 347{ 348 var evt = new Spry.Widget.Event(this); 349 this.notifyObservers("onPreTransformMarkup", evt); 350 if (!evt.performDefaultAction) 351 return; 352 353 var elements = []; 354 355 if (!this.repeatingElementSelector) 356 elements = this.getElementChildren(this.element); 357 else 358 elements = Spry.$$(this.repeatingElementSelector, this.element); 359 360 // Create the 9-Sliced top-level element for the widget. 361 362 var root = this.createOptionalSlicedStructure(null, "div", this.widgetClass); 363 var rootCC = root.contentContainer; 364 365 if (this.widgetID) 366 root.id = this.widgetID; 367 368 // Create a clip + view combination and stick it into the content container of the root element. 369 370 var clip = this.createElement("div", this.clipClass, null); 371 var view = this.createElement("div", this.viewClass, clip); 372 373 374 for (var i = 0; i < this.componentOrder.length; i++) 375 { 376 var itemName = this.componentOrder[i]; 377 switch (itemName) 378 { 379 case "view": 380 var extractElement = this.extractionType == "element"; 381 382 for (var j = 0; j < elements.length; j++) 383 { 384 var p = this.createOptionalSlicedStructure(null, "div", this.slideClass); 385 view.appendChild(p); 386 387 if (extractElement) 388 p.contentContainer.appendChild(elements[j]); 389 else 390 this.appendChildNodes(p.contentContainer, this.extractChildNodes(elements[j])); 391 } 392 393 rootCC.appendChild(clip); 394 break; 395 case "controls": 396 // Create the slide show control buttons. 397 398 var controls = this.createOptionalSlicedStructure(null, "div", this.controlsClass); 399 var controlsCC = controls.contentContainer; 400 401 controlsCC.appendChild(this.firstBtn = this.createButtonElement("First", this.firstBtnClass, this.firstFunc)); 402 controlsCC.appendChild(this.prevBtn = this.createButtonElement("Previous", this.prevBtnClass, this.prevFunc)); 403 controlsCC.appendChild(this.playBtn = this.createButtonElement("", this.playBtnClass, this.playFunc)); 404 controlsCC.appendChild(this.nextBtn = this.createButtonElement("Next", this.nextBtnClass, this.nextFunc)); 405 controlsCC.appendChild(this.lastBtn = this.createButtonElement("Last", this.lastBtnClass, this.lastFunc)); 406 407 this.playBtn.contentContainer.innerHTML = "<span class=\"" + this.playLabelClass + "\">Play</span><span class=\"" + this.pauseLabelClass + "\">Pause</span>"; 408 409 rootCC.appendChild(controls); 410 break; 411 case "links": 412 // Now create a 9-sliced panel and link button for each set of elements that were matched. 413 414 var links = this.createOptionalSlicedStructure(null, "div", this.slideLinksClass); 415 var linksCC = links.contentContainer; 416 417 for (var j = 0; j < elements.length; j++) 418 linksCC.appendChild(this.createButtonElement((j+1)+"", this.slideLinkClass, null, true)); 419 420 rootCC.appendChild(links); 421 break; 422 case "title": 423 rootCC.appendChild(this.createOptionalSlicedStructure(null, "div", this.slideTitleClass)); 424 break; 425 case "description": 426 rootCC.appendChild(this.createOptionalSlicedStructure(null, "div", this.slideDescriptionClass)); 427 break; 428 case "count": 429 rootCC.appendChild(this.createOptionalSlicedStructure(null, "div", this.countClass)); 430 break; 431 } 432 } 433 434 if (this.injectionType == "replace") 435 { 436 var parent = this.element.parentNode; 437 parent.replaceChild(root, this.element); 438 this.element = root; 439 } 440 else // "inside" 441 { 442 this.element.innerHTML = ""; 443 this.element.appendChild(root); 444 } 445 446 this.notifyObservers("onPostTransformMarkup", evt); 447};
448 449Spry.Widget.ContentSlideShow.prototype.attachViewBehaviors = function() 450{ 451 var evt = new Spry.Widget.Event(this); 452 this.notifyObservers("onPreAttachViewBehaviors", evt); 453 if (!evt.performDefaultAction) 454 return; 455 456 this.panelSet = new Spry.Widget.FadingPanels(Spry.$$("." + this.slideClass, this.element), 457 { 458 dropFrames: this.dropFrames, 459 minDuration: this.transitionDuration, 460 maxDuration: this.transitionDuration, 461 displayInterval: this.displayInterval, 462 visibleClass: this.slideVisibleClass, 463 hiddenClass: this.slideHiddenClass 464 }); 465 466 var self = this; 467 this.panelSet.addObserver( 468 { 469 onPreStartSlideShowMode: function(n,evt){ self.handlePanelSetStart(evt); }, 470 onPreStopSlideShowMode: function(n,evt){ self.handlePanelSetStop(evt); }, 471 onPreShowPanel: function(n,evt){ self.handlePanelSetPreShowPanel(evt); }, 472 onPostShowPanel: function(n,evt){ self.handlePanelSetPostShowPanel(evt); } 473 }); 474 475 this.notifyObservers("onPostAttachViewBehaviors", evt); 476}; 477 478Spry.Widget.ContentSlideShow.prototype.attachButtonBehavior = function(ele, className, clickFunc) 479{ 480 var w = new Spry.Widget.Button(ele, 481 { 482 downClass: className + "Down", 483 hoverClass: className + "Hover", 484 disabledClass: className + "Disabled", 485 onclick: clickFunc 486 }); 487}; 488 489Spry.Widget.ContentSlideShow.prototype.attachControlBehaviors = function() 490{ 491 var evt = new Spry.Widget.Event(this); 492 this.notifyObservers("onPreAttachControlBehaviors", evt); 493 if (!evt.performDefaultAction) 494 return; 495 496 // Search for the buttons by class name. We do this just in case a 497 // plugin altered the default markup to add or remove controls. 498 499 var self = this; 500 Spry.$$("." + this.firstBtnClass, this.element).forEach(function(n){ self.attachButtonBehavior(n, self.firstBtnClass, self.firstFunc); }); 501 Spry.$$("." + this.prevBtnClass, this.element).forEach(function(n){ self.attachButtonBehavior(n, self.prevBtnClass, self.prevFunc); }); 502 Spry.$$("." + this.playBtnClass, this.element).forEach(function(n){ self.attachButtonBehavior(n, self.playBtnClass, self.playFunc); }); 503 Spry.$$("." + this.nextBtnClass, this.element).forEach(function(n){ self.attachButtonBehavior(n, self.nextBtnClass, self.nextFunc); }); 504 Spry.$$("." + this.lastBtnClass, this.element).forEach(function(n){ self.attachButtonBehavior(n, self.lastBtnClass, self.lastFunc); }); 505 506 this.notifyObservers("onPostAttachControlBehaviors", evt); 507}; 508 509Spry.Widget.ContentSlideShow.prototype.attachLinkBehaviors = function() 510{ 511 var links = Spry.$$("." + this.slideLinkClass, this.element); 512 if (links.length > 0) 513 { 514 var evt = new Spry.Widget.Event(this); 515 this.notifyObservers("onPreAttachLinkBehaviors", evt); 516 if (!evt.performDefaultAction) 517 return; 518 519 this.panelSelector = new Spry.Widget.PanelSelector(links, this.panelSet, 520 { 521 selectedClass: this.slideLinkClass + "Selected", 522 unselectedClass: this.slideLinkClass + "Unselected", 523 hoverClass: this.slideLinkClass + "Hover" 524 }); 525 526 this.notifyObservers("onPostAttachLinkBehaviors", evt); 527 } 528}; 529 530Spry.Widget.ContentSlideShow.prototype.attachBehaviors = function(link) 531{ 532 var evt = new Spry.Widget.Event(this); 533 this.notifyObservers("onPreAttachBehaviors", evt); 534 if (!evt.performDefaultAction) 535 return; 536 537 this.attachViewBehaviors(); 538 this.attachLinkBehaviors(); 539 this.attachControlBehaviors(); 540 541 this.notifyObservers("onPostAttachBehaviors", evt); 542}; 543 544 545///////////////////////////////////////////////////////// 546//////////////////////// PLUGINS //////////////////////// 547///////////////////////////////////////////////////////// 548 549// 550// slideTransitionPlugin 551// 552// Replaces the default fading transition used within the slideshow 553// widget with a slider panels transition. 554// 555 556Spry.Widget.ContentSlideShow.slideTransitionPlugin = { 557 initialize: function(slideshow) 558 { 559 // Add the plugin as an observer on the slideshow. 560 561 slideshow.addObserver(this); 562 }, 563 564 onPreAttachViewBehaviors: function(slideshow, evt) 565 { 566 slideshow.panelSet = new Spry.Widget.SliderPanels(Spry.$$("." + slideshow.clipClass, slideshow.element), 567 { 568 displayInterval: slideshow.displayInterval, 569 visibleClass: slideshow.slideVisibleClass, 570 hiddenClass: slideshow.slideHiddenClass 571 }); 572 573 slideshow.panelSet.addObserver( 574 { 575 onPreStartSlideShowMode: function(n,evt){ slideshow.handlePanelSetStart(evt); }, 576 onStop: function(n,evt){ slideshow.handlePanelSetStop(evt); }, 577 onPreShowPanel: function(n,evt){ slideshow.handlePanelSetPreShowPanel(evt); }, 578 onPostShowPanel: function(n,evt){ slideshow.handlePanelSetPostShowPanel(evt); } 579 }); 580 581 evt.preventDefault(); 582 } 583}; 584 585// 586// imageListPlugin 587// 588// Converts a list of image links into a slideshow that displays the 589// full-resolution images. It is assumed that the @href of each link 590// is a URL to the full-resolution image. 591// 592// Expected input markup: 593// 594// <ul> 595// <li><a href="foo.jpg" title="image caption"> ... </a></li> 596// ... 597// <li>
597<a href="bar.jpg" title="image caption"> ... </a></li> 598// </ul> 599// 600 601Spry.Widget.ContentSlideShow.imageListPlugin = { 602 slideLoadingClass: "SlideLoading", 603 604 initialize: function(slideshow) 605 { 606 // Our input is a list. We need to replace it with 607 // the top-level <div> used by the slideshow since a 608 // <div> is not allowed inside a <ul>. 609 610 slideshow.injectionType = "replace"; 611 612 // Set the slideshow extraction and selector so that it 613 // treats all <a> elements as the slide content. We'll post 614 // process the links and convert them to real images during 615 // the onPostTransformMarkup notification. 616 617 slideshow.extractionType = "element"; 618 slideshow.repeatingElementSelector = "a"; 619 620 // If the image loader is available, use it! 621 622 if (typeof Spry.Utils.ImageLoader != "undefined") 623 slideshow.ilpLoader = new Spry.Utils.ImageLoader(); 624 625 // Add ourself as an observer. 626 627 slideshow.addObserver(this); 628 }, 629 630 createImage: function(slideshow, src, title) 631 { 632 var img = document.createElement("img"); 633 if (slideshow.ilpLoader) 634 { 635 slideshow.ilpLoader.load(src, function(){ img.src = src; }); 636 } 637 else 638 img.src = src; 639 img.title = title; 640 }, 641 642 onPostTransformMarkup: function(slideshow, evt) 643 { 644 // The slideshow has already transformed the markup. Each slide 645 // panel now contains a link to the large images we want to display. 646 // simply replace each link with an image element that points to the 647 // large image. 648 649 var imgLinks = Spry.$$("." + slideshow.slideClass + " a",slideshow.element).forEach(function(n) 650 { 651 var bigImg = document.createElement("img"); 652 bigImg.src = n.href; 653 bigImg.title = n.title; 654 n.parentNode.replaceChild(bigImg, n); 655 }); 656 } 657}; 658 659})(); // EndSpryComponent
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.