1/** 2 * jquery.gridrotator.js v1.1.0 3 * http://www.codrops.com 4 * 5 * Licensed under the MIT license. 6 * http://www.opensource.org/licenses/mit-license.php 7 * 8 * Copyright 2012, Codrops 9 * http://www.codrops.com 10 */ 11;( function( $, window, undefined ) { 12 13 'use strict'; 14 15 /* 16 * debouncedresize: special jQuery event that happens once after a window resize 17 * 18 * latest version and complete README available on Github: 19 * https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js 20 * 21 * Copyright 2011 @louis_remi 22 * Licensed under the MIT license. 23 */ 24 var $event = $.event, 25 $special, 26 resizeTimeout; 27 28 $special = $event.special.debouncedresize = { 29 setup: function() { 30 $( this ).on( "resize", $special.handler ); 31 }, 32 teardown: function() { 33 $( this ).off( "resize", $special.handler ); 34 }, 35 handler: function( event, execAsap ) { 36 // Save the context 37 var context = this, 38 args = arguments, 39 dispatch = function() { 40 // set correct event type 41 event.type = "debouncedresize"; 42 $event.dispatch.apply( context, args ); 43 }; 44 45 if ( resizeTimeout ) { 46 clearTimeout( resizeTimeout ); 47 } 48 49 execAsap ? 50 dispatch() : 51 resizeTimeout = setTimeout( dispatch, $special.threshold ); 52 }, 53 threshold: 100 54 }; 55 56 // http://www.hardcode.nl/subcategory_1/article_317-array-shuffle-function 57 Array.prototype.shuffle = function() { 58 var i=this.length,p,t; 59 while (i--) { 60 p = Math.floor(Math.random()*i); 61 t = this[i]; 62 this[i]=this[p]; 63 this[p]=t; 64 } 65 return this; 66 }; 67 68 // HTML5 PageVisibility API 69 // http://www.html5rocks.com/en/tutorials/pagevisibility/intro/ 70 // by Joe Marini (@joemarini) 71 function getHiddenProp(){ 72 var prefixes = ['webkit','moz','ms','o']; 73 74 // if 'hidden' is natively supported just return it 75 if ('hidden' in document) return 'hidden'; 76 77 // otherwise loop over all the known prefixes until we find one 78 for (var i = 0; i < prefixes.length; i++){ 79 if ((prefixes[i] + 'Hidden') in document) 80 return prefixes[i] + 'Hidden'; 81 } 82 83 // otherwise it's not supported 84 return null; 85 } 86 function isHidden() { 87 var prop = getHiddenProp(); 88 if (!prop) return false; 89 90 return document[prop]; 91 } 92 93 function isEmpty( obj ) { 94 return Object.keys(obj).length === 0; 95 } 96 97 // global 98 var $window = $( window ), 99 Modernizr = window.Modernizr; 100 101 $.GridRotator = function( options, element ) { 102 103 this.$el = $( element ); 104 if( Modernizr.backgroundsize ) { 105 106 var self = this; 107 this.$el.addClass( 'ri-grid-loading' ); 108 this._init( options ); 109 110 } 111 112 }; 113 114 // the options 115 $.GridRotator.defaults = { 116 // number of rows 117 rows : 4, 118 // number of columns 119 columns : 10, 120 w1024 : { rows : 3, columns : 8 }, 121 w768 : {rows : 3,columns : 7 }, 122 w480 : {rows : 3,columns : 5 }, 123 w320 : {rows : 2,columns : 4 }, 124 w240 : {rows : 2,columns : 3 }, 125 // step: number of items that are replaced at the same time 126 // random || [some number] 127 // note: for performance issues, the number "can't" be > options.maxStep 128 step : 'random', 129 // change it as you wish.. 130 maxStep : 3, 131 // prevent user to click the items 132 preventClick : true, 133 // animation type 134 // showHide || fadeInOut || 135 // slideLeft || slideRight || slideTop || slideBottom || 136 // rotateBottom || rotateLeft || rotateRight || rotateTop || 137 // scale || 138 // rotate3d || 139 // rotateLeftScale || rotateRightScale || rotateTopScale || rotateBottomScale || 140 // random 141 animType : 'random', 142 // animation speed 143 animSpeed : 800, 144 // animation easings 145 animEasingOut : 'linear', 146 animEasingIn: 'linear', 147 // the item(s) will be replaced every 3 seconds 148 // note: for performance issues, the time "can't" be < 300 ms 149 interval : 3000, 150 // if false the animations will not start 151 // use false if onhover is true for example 152 slideshow : true, 153 // if true the items will switch when hovered 154 onhover : false, 155 // ids of elements that shouldn't change 156 nochange : [], 157 // callback function when drawn 158 onDraw : function(){}, 159 // Height to Width Ratio (Height/Width). A 0.5 ratio would be used for an image that is twice as large as it's height. Default is 1 (square images). 160 heightToWidthRatio : 1, 161 subImg : false 162 }; 163 164 $.GridRotator.prototype = { 165 166 _init : function( options ) { 167 168 // options 169 this.options = $.extend( true, {}, $.GridRotator.defaults, options ); 170 // cache some elements + variables 171 this._config(); 172 173 }, 174 _config : function() { 175 176 var self = this, 177 transEndEventNames = { 178 'WebkitTransition' : 'webkitTransitionEnd', 179 'MozTransition' : 'transitionend', 180 'OTransition' : 'oTransitionEnd', 181 'msTransition' : 'MSTransitionEnd', 182 'transition' : 'transitionend' 183 }; 184 185 // support CSS transitions and 3d transforms 186 this.supportTransitions = Modernizr.csstransitions; 187 this.supportTransforms3D = Modernizr.csstransforms3d; 188 189 this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ] + '.gridrotator'; 190 191 // all animation types for the random option 192 this.animTypes = this.supportTransforms3D ? [ 193 'fadeInOut', 194 'slideLeft', 195 'slideRight', 196 'slideTop', 197 'slideBottom', 198 'rotateLeft', 199 'rotateRight', 200 'rotateTop', 201 'rotateBottom', 202 'scale', 203 'rotate3d', 204 'rotateLeftScale', 205 'rotateRightScale', 206 'rotateTopScale', 207 'rotateBottomScale' ] : 208 [ 'fadeInOut', 'slideLeft', 'slideRight', 'slideTop', 'slideBottom' ]; 209 210 this.animType = this.options.animType; 211 212 if( this.animType !== 'random' && !this.supportTransforms3D && $.inArray( this.animType, this.animTypes ) === -1 && this.animType !== 'showHide' ) { 213 214 // fallback to 'fadeInOut' if user sets a type which is not supported 215 this.animType = 'fadeInOut'; 216 217 } 218 219 this.animTypesTotal = this.animTypes.length; 220 221 // the <ul> where the items are placed 222 this.$list = this.$el.children( 'ul' ); 223 //added to fix DIVI theme page builder visualization 224 this.$list.css("padding-left","0"); 225 // remove images and add background-image to anchors 226 // preload the images before 227 var loaded = 0, 228 subbed = 0,
229 $imgs = this.$list.find( 'img' ), 230 count = $imgs.length, 231 subColors = ["#D92727", "#FFE433", "#0DB8B5"]; 232 233 234 // Check if the substitute image is available 235 if( self.options.subImg ) { 236 237 $( '<img/>' ).error( function() { 238 239 self.options.subImg = false; 240 241 } ).attr('src', self.options.subImg); 242 243 } 244 245 $imgs.each( function() { 246 247 var $img = $( this ), src = $img.attr( 'src' ); 248 249 $( '<img/>' ).load( function() { 250 251 ++loaded; 252 var video = $img.parent().attr('data-video'); 253 if(video==="yes"){ 254 $img.parent().parent().css( 'background-image', 'url(' + GridRotator.pluginsUrl + '/enjoy-instagram-instagram-responsive-images-gallery-and-carousel/img/play_overlay.png' + ')' ); 255 $img.parent().parent().css( 'background-size', 'cover'); 256 $img.parent().css( 'background-image', 'url(' + src + ')' ); 257 $img.parent().css( 'opacity', '0.45'); 258 console.log($img.parent().attr('href')); 259 }else{ 260 $img.parent().css( 'background-image', 'url(' + src + ')' ); 261 } 262 263 /*This conditional block should be moved out to remove redundancy =)*/ 264 if( loaded + subbed === count ) { 265 266 $imgs.remove(); 267 self.$el.removeClass( 'ri-grid-loading' ); 268 // the items 269 self.$items = self.$list.children( 'li' ); 270 // make a copy of the items 271 self.$itemsCache = self.$items.clone(); 272 // total number of items 273 self.itemsTotal = self.$items.length; 274 // the items that will be out of the grid 275 // actually the item's child (anchor element) 276 self.outItems= []; 277 self._layout( function() { 278 self._initEvents(); 279 } ); 280 // replace [options.step] items after [options.interval] time 281 // the items that go out are randomly chosen, while the ones that get in 282 // follow a "First In First Out" logic 283 self._start(); 284 285 } 286 287 } ).attr( 'src', src ); 288 289 // If something is wrong with the image⦠290 $( '<img/>' ).error( function() { 291 292 ++subbed; 293 294 // Are there any substitute images? 295 if( self.options.subImg ) { 296 297 $img.parent().css( 'background-image', 'url(' + self.options.subImg + ')' ); 298 299 } 300 301 else { 302 303 var color = Math.floor(Math.random() * 3) 304 $img.parent().css( 'background', subColors[color] ); 305 306 } 307 308 // console.log(self.options) 309 310 /*This conditional block should be moved out to remove redundancy =)*/ 311 if( loaded + subbed === count ) { 312 313 $imgs.remove(); 314 self.$el.removeClass( 'ri-grid-loading' ); 315 // the items 316 self.$items = self.$list.children( 'li' ); 317 // make a copy of the items 318 self.$itemsCache = self.$items.clone(); 319 // total number of items 320 self.itemsTotal = self.$items.length; 321 // the items that will be out of the grid 322 // actually the item's child (anchor element) 323 self.outItems= []; 324 self._layout( function() { 325 self._initEvents(); 326 } ); 327 // replace [options.step] items after [options.interval] time 328 // the items that go out are randomly chosen, while the ones that get in 329 // follow a "First In First Out" logic 330 self._start(); 331 332 } 333 334 } ).attr( 'src', src ); 335 336 337 338 } ); 339 340 }, 341 _layout : function( callback ) { 342 343 var self = this; 344 345 // sets the grid dimentions based on the container's width 346 this._setGridDim(); 347 348 // reset 349 this.$list.empty(); 350 this.$items = this.$itemsCache.clone().appendTo( this.$list ); 351 352 var $outItems = this.$items.filter( ':gt(' + ( this.showTotal - 1 ) + ')' ), 353 $outAItems = $outItems.children( 'a' ); 354 355 this.outItems.length = 0; 356 357 $outAItems.each( function( i ) { 358 self.outItems.push( $( this ) ); 359 } ); 360 361 $outItems.remove(); 362 363 // container's width 364 var containerWidth = ( document.defaultView ) ? parseInt( document.defaultView.getComputedStyle( this.$el.get( 0 ), null ).width ) : this.$el.width(), 365 // item's width 366 itemWidth = Math.floor( containerWidth / this.columns ), 367 // calculate gap 368 gapWidth = containerWidth - ( this.columns * Math.floor( itemWidth ) ); 369 370 for( var i = 0; i < this.rows; ++i ) { 371
372 for( var j = 0; j < this.columns; ++j ) { 373 374 var idx = this.columns * i + j, 375 $item = this.$items.eq( idx ); 376 377 $item.css( { 378 width : j < Math.floor( gapWidth ) ? itemWidth + 1 : itemWidth, 379 height : Math.floor( itemWidth * this.options.heightToWidthRatio ) 380 } ); 381 382 if( $.inArray( idx, this.options.nochange ) !== -1 ) { 383 $item.addClass( 'ri-nochange' ).data( 'nochange', true ); 384 } 385 386 } 387 388 } 389 390 if( this.options.preventClick ) { 391 392 this.$items.children().css( 'cursor', 'default' ).on( 'click.gridrotator', false ); 393 394 } 395 396 if( callback ) { 397 callback.call(); 398 } 399 400 this.options.onDraw.call(this); 401 402 }, 403 // set the grid rows and columns 404 _setGridDim : function() { 405 406 // container's width 407 var c_w = this.$el.width(); 408 409 // we will choose the number of rows/columns according to the container's width and the values set in the plugin options 410 switch( true ) { 411 case ( c_w < 240 ) : this.rows = this.options.w240.rows; this.columns = this.options.w240.columns; break; 412 case ( c_w < 320 ) : this.rows = this.options.w320.rows; this.columns = this.options.w320.columns; break; 413 case ( c_w < 480 ) : this.rows = this.options.w480.rows; this.columns = this.options.w480.columns; break; 414 case ( c_w < 768 ) : this.rows = this.options.w768.rows; this.columns = this.options.w768.columns; break; 415 case ( c_w < 1024 ) : this.rows = this.options.w1024.rows; this.columns = this.options.w1024.columns; break; 416 default : this.rows = this.options.rows; this.columns = this.options.columns; break; 417 } 418 419 this.showTotal = this.rows * this.columns; 420 421 }, 422 // init window resize event 423 _initEvents : function() { 424 425 var self = this; 426 427 $window.on( 'debouncedresize.gridrotator', function() { 428 self._layout(); 429 } ); 430 431 // use the property name to generate the prefixed event name 432 var visProp = getHiddenProp(); 433 434 // HTML5 PageVisibility API 435 // http://www.html5rocks.com/en/tutorials/pagevisibility/intro/ 436 // by Joe Marini (@joemarini) 437 if (visProp) { 438 439 var evtname = visProp.replace(/[H|h]idden/,'') + 'visibilitychange'; 440 document.addEventListener(evtname, function() { self._visChange(); } ); 441 442 } 443 444 if( !Modernizr.touch && this.options.onhover ) { 445 446 self.$items.on( 'mouseenter.gridrotator', function() { 447 448 var $item = $( this ); 449 if( !$item.data( 'active' ) && !$item.data( 'hovered' ) && !$item.data( 'nochange' ) ) { 450 $item.data( 'hovered', true ); 451 self._replace( $item ); 452 } 453 454 } ).on( 'mouseleave.gridrotator', function() { 455 456 $( this ).data( 'hovered', false ); 457 458 } ); 459 460 } 461 462 }, 463 _visChange : function() { 464 465 isHidden() ? clearTimeout( this.playtimeout ) : this._start(); 466 467 }, 468 // start rotating elements 469 _start : function() { 470 471 if( this.showTotal < this.itemsTotal && this.options.slideshow ) { 472 this._showNext(); 473 } 474 475 }, 476 // get which type of animation 477 _getAnimType : function() { 478 479 return this.animType === 'random' ? this.animTypes[ Math.floor( Math.random() * this.animTypesTotal ) ] : this.animType; 480 481 }, 482 // get css properties for the transition effect 483 _getAnimProperties : function( $out ) { 484 485 var startInProp = {}, startOutProp = {}, endInProp = {}, endOutProp = {}, 486 animType = this._getAnimType(), speed, delay = 0; 487 488 switch( animType ) { 489 490 case 'showHide' : 491 492 speed = 0; 493 endOutProp.opacity = 0; 494 break; 495 496 case 'fadeInOut' : 497 498 endOutProp.opacity = 0; 499 break; 500 501 case 'slideLeft' : 502 503 startInProp.left = $out.width(); 504 endInProp.left = 0; 505 endOutProp.left = -$out.width(); 506 break; 507 508 case 'slideRight' : 509 510 startInProp.left = -$out.width(); 511 endInProp.left = 0; 512 endOutProp.left = $out.width(); 513 break; 514 515 case 'slideTop' : 516 517 startInProp.top = $out.height(); 518 endInProp.top = 0; 519 endOutProp.top = -$out.height(); 520 break; 521 522 case 'slideBottom' : 523 524 startInProp.top = -$out.height(); 525 endInProp.top = 0; 526 endOutProp.top = $out.height(); 527 break; 528 529 case 'rotateLeft' : 530 531 speed = this.options.animSpeed / 2; 532 startInProp.transform = 'rotateY(90deg)'; 533 endInProp.transform = 'rotateY(0deg)';
534 delay = speed; 535 endOutProp.transform = 'rotateY(-90deg)'; 536 break; 537 538 case 'rotateRight' : 539 540 speed = this.options.animSpeed / 2; 541 startInProp.transform = 'rotateY(-90deg)'; 542 endInProp.transform = 'rotateY(0deg)'; 543 delay = speed; 544 endOutProp.transform = 'rotateY(90deg)'; 545 break; 546 547 case 'rotateTop' : 548 549 speed = this.options.animSpeed / 2; 550 startInProp.transform= 'rotateX(90deg)'; 551 endInProp.transform = 'rotateX(0deg)'; 552 delay = speed; 553 endOutProp.transform = 'rotateX(-90deg)'; 554 break; 555 556 case 'rotateBottom' : 557 558 speed = this.options.animSpeed / 2; 559 startInProp.transform = 'rotateX(-90deg)'; 560 endInProp.transform = 'rotateX(0deg)'; 561 delay = speed; 562 endOutProp.transform = 'rotateX(90deg)'; 563 break; 564 565 case 'scale' : 566 567 speed = this.options.animSpeed / 2; 568 startInProp.transform = 'scale(0)'; 569 startOutProp.transform = 'scale(1)'; 570 endInProp.transform = 'scale(1)'; 571 delay = speed; 572 endOutProp.transform = 'scale(0)'; 573 break; 574 575 case 'rotateLeftScale' : 576 577 startOutProp.transform = 'scale(1)'; 578 speed = this.options.animSpeed / 2; 579 startInProp.transform = 'scale(0.3) rotateY(90deg)'; 580 endInProp.transform = 'scale(1) rotateY(0deg)';
581 delay = speed; 582 endOutProp.transform = 'scale(0.3) rotateY(-90deg)'; 583 break; 584 585 case 'rotateRightScale' : 586 587 startOutProp.transform = 'scale(1)'; 588 speed = this.options.animSpeed / 2; 589 startInProp.transform = 'scale(0.3) rotateY(-90deg)'; 590 endInProp.transform = 'scale(1) rotateY(0deg)'; 591 delay = speed; 592 endOutProp.transform = 'scale(0.3) rotateY(90deg)'; 593 break; 594 595 case 'rotateTopScale' : 596 597 startOutProp.transform = 'scale(1)'; 598 speed = this.options.animSpeed / 2; 599 startInProp.transform = 'scale(0.3) rotateX(90deg)'; 600 endInProp.transform = 'scale(1) rotateX(0deg)'; 601 delay = speed; 602 endOutProp.transform = 'scale(0.3) rotateX(-90deg)'; 603 break; 604 605 case 'rotateBottomScale' : 606 607 startOutProp.transform = 'scale(1)'; 608 speed = this.options.animSpeed / 2; 609 startInProp.transform = 'scale(0.3) rotateX(-90deg)'; 610 endInProp.transform = 'scale(1) rotateX(0deg)'; 611 delay = speed; 612 endOutProp.transform = 'scale(0.3) rotateX(90deg)'; 613 break; 614 615 case 'rotate3d' : 616 617 speed = this.options.animSpeed / 2; 618 startInProp.transform = 'rotate3d( 1, 1, 0, 90deg )'; 619 endInProp.transform = 'rotate3d( 1, 1, 0, 0deg )';
620 delay = speed; 621 endOutProp.transform = 'rotate3d( 1, 1, 0, -90deg )'; 622 break; 623 624 } 625 626 return { 627 startInProp : startInProp, 628 startOutProp : startOutProp, 629 endInProp : endInProp, 630 endOutProp : endOutProp, 631 delay : delay, 632 animSpeed : speed != undefined ? speed : this.options.animSpeed 633 }; 634 635 }, 636 // show next [option.step] elements 637 _showNext : function( time ) { 638 639 var self = this; 640 641 clearTimeout( this.playtimeout ); 642 643 this.playtimeout = setTimeout( function() { 644 645 var step = self.options.step, max= self.options.maxStep, min = 1; 646 647 if( max > self.showTotal ) { 648 max = self.showTotal; 649 } 650 651 // number of items to swith at this point of time 652 var nmbOut = step === 'random' ? Math.floor( Math.random() * max + min ) : Math.min( Math.abs( step ) , max ) , 653 // array with random indexes. These will be the indexes of the items we will replace 654 randArr = self._getRandom( nmbOut, self.showTotal ); 655 656 for( var i = 0; i < nmbOut; ++i ) { 657 658 // element to go out 659 var $out = self.$items.eq( randArr[ i ] ); 660 661 // if element is active, which means it is currently animating, 662 // then we need to get different positions.. 663 if( $out.data( 'active' ) || $out.data( 'nochange' ) ) { 664 665 // one of the items is active, call again.. 666 self._showNext( 1 ); 667 return false; 668 669 } 670 671 self._replace( $out ); 672 673 } 674 675 // again and again.. 676 self._showNext(); 677 678 }, time || Math.max( Math.abs( this.options.interval ) , 300 ) ); 679 680 }, 681 _replace : function( $out ) { 682 683 $out.data( 'active', true ); 684 685 var self = this, 686 $outA = $out.children( 'a:last' ), 687 newElProp = { 688 width : $outA.width(), 689 height : $outA.height() 690 }; 691 692 // element stays active 693 $out.data( 'active', true ); 694 695 // get the element (anchor) that will go in (first one inserted in this.outItems) 696 var $inA = this.outItems.shift(); 697 698 // save element that went out 699 this.outItems.push( $outA.clone().css( 'transition', 'none' ) ); 700 701 // prepend in element 702 $inA.css( newElProp ).prependTo( $out ); 703 704 var animProp = this._getAnimProperties( $outA ); 705 706 $inA.css( animProp.startInProp ); 707 $outA.css( animProp.startOutProp ); 708 709 this._setTransition( $inA, 'all', animProp.animSpeed, animProp.delay, this.options.animEasingIn ); 710 this._setTransition( $outA, 'all', animProp.animSpeed, 0, this.options.animEasingOut ); 711 712 this._applyTransition( $inA, animProp.endInProp, animProp.animSpeed, function() { 713 714 var $el = $( this ), 715 t = animProp.animSpeed === self.options.animSpeed && isEmpty( animProp.endInProp ) ? animProp.animSpeed : 0; 716 717 setTimeout( function() { 718 719 if( self.supportTransitions ) { 720 $el.off( self.transEndEventName ); 721 } 722 723 $el.next().remove(); 724 $el.parent().data( 'active', false ); 725 726 }, t ); 727 728 }, animProp.animSpeed === 0 || isEmpty( animProp.endInProp ) ); 729 this._applyTransition( $outA, animProp.endOutProp, animProp.animSpeed ); 730 731 var video = $inA.attr('data-video'); 732 var bg = $inA.attr('style'); 733 if(video==="yes"){ 734 $inA.parent().css( 'background-image', 'url(' + GridRotator.pluginsUrl + '/enjoy-instagram-instagram-responsive-images-gallery-and-carousel/img/play_overlay.png' + ')' ); 735 $inA.parent().css( 'background-size', 'cover' ); 736 $inA.css( 'opacity', '0.45'); 737 } 738 739 }, 740 _getRandom : function( cnt, limit ) { 741 742 var randArray = []; 743 744 for( var i = 0; i < limit; ++i ) { 745 randArray.push( i ) 746 } 747 748 return randArray.shuffle().slice( 0, cnt ); 749 750 }, 751 _setTransition : function( el, prop, speed, delay, easing ) { 752 753 setTimeout( function() { 754 el.css( 'transition', prop + ' ' + speed + 'ms ' + delay + 'ms ' + easing ); 755 }, 25 ); 756 757 }, 758 _applyTransition : function( el, styleCSS, speed, fncomplete, force ) { 759 760 var self = this; 761 setTimeout( function() { 762 $.fn.applyStyle = self.supportTransitions ? $.fn.css : $.fn.animate; 763 764 if( fncomplete && self.supportTransitions ) { 765 766 el.on( self.transEndEventName, fncomplete ); 767 768 if( force ) { 769 fncomplete.call( el ); 770 } 771 772 } 773 774 fncomplete = fncomplete || function() { return false; }; 775 776 el.stop().applyStyle( styleCSS, $.extend( true, [], { duration : speed + 'ms', complete : fncomplete } ) ); 777 }, 25 ); 778 779 } 780 781 }; 782 783 var logError = function( message ) { 784 785 if ( window.console ) { 786 787 window.console.error( message ); 788 789 } 790 791 }; 792 793 $.fn.gridrotator = function( options ) { 794 795 var instance = $.data( this, 'gridrotator' ); 796 797 if ( typeof options === 'string' ) { 798 799 var args = Array.prototype.slice.call( arguments, 1 ); 800 801 this.each(function() { 802 803 if ( !instance ) { 804 805 logError( "cannot call methods on gridrotator prior to initialization; " + 806 "attempted to call method '" + options + "'" ); 807 return; 808 809 } 810 811 if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) { 812 813 logError( "no such method '" + options + "' for gridrotator instance" ); 814 return; 815 816 } 817 818 instance[ options ].apply( instance, args ); 819 820 }); 821 822 } 823 else { 824 825 this.each(function() { 826 827 if ( instance ) { 828 829 instance._init(); 830 831 } 832 else { 833 834 instance = $.data( this, 'gridrotator', new $.GridRotator( options, this ) ); 835 836 } 837 838 }); 839 840 } 841 842 return instance; 843 844 }; 845 846} )( jQuery, window );
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.