1(function($) { 2 3/* 4* debouncedresize: special jQuery event that happens once after a window resize 5* 6* latest version and complete README available on Github: 7* https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js 8* 9* Copyright 2011 @louis_remi 10* Licensed under the MIT license. 11*/ 12var $event = $.event, 13$special, 14resizeTimeout; 15 16$special = $event.special.debouncedresize = { 17 setup: function() { 18 $( this ).on( "resize", $special.handler ); 19 }, 20 teardown: function() { 21 $( this ).off( "resize", $special.handler ); 22 }, 23 handler: function( event, execAsap ) { 24 // Save the context 25 var context = this, 26 args = arguments, 27 dispatch = function() { 28 // set correct event type 29 event.type = "debouncedresize"; 30 $event.dispatch.apply( context, args ); 31 }; 32 33 if ( resizeTimeout ) { 34 clearTimeout( resizeTimeout ); 35 } 36 37 execAsap ? 38 dispatch() : 39 resizeTimeout = setTimeout( dispatch, $special.threshold ); 40 }, 41 threshold: 250 42}; 43 44// ======================= imagesLoaded Plugin =============================== 45// https://github.com/desandro/imagesloaded 46 47// $('#my-container').imagesLoaded(myFunction) 48// execute a callback when all images have loaded. 49// needed because .load() doesn't work on cached images 50 51// callback function gets image collection as argument 52// this is the container 53 54// original: MIT license. Paul Irish. 2010. 55// contributors: Oren Solomianik, David DeSandro, Yiannis Chatzikonstantinou 56 57// blank image data-uri bypasses webkit log warning (thx doug jones) 58var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='; 59 60$.fn.imagesLoaded = function( callback ) { 61 var $this = this, 62 deferred = $.isFunction($.Deferred) ? $.Deferred() : 0, 63 hasNotify = $.isFunction(deferred.notify), 64 $images = $this.find('img').add( $this.filter('img') ), 65 loaded = [], 66 proper = [], 67 broken = []; 68 69 // Register deferred callbacks 70 if ($.isPlainObject(callback)) { 71 $.each(callback, function (key, value) { 72 if (key === 'callback') { 73 callback = value; 74 } else if (deferred) { 75 deferred[key](value); 76 } 77 }); 78 } 79 80 function doneLoading() { 81 var $proper = $(proper), 82 $broken = $(broken); 83 84 if ( deferred ) { 85 if ( broken.length ) { 86 deferred.reject( $images, $proper, $broken ); 87 } else { 88 deferred.resolve( $images ); 89 } 90 } 91 92 if ( $.isFunction( callback ) ) { 93 callback.call( $this, $images, $proper, $broken ); 94 } 95 } 96 97 function imgLoaded( img, isBroken ) { 98 // don't proceed if BLANK image, or image is already loaded 99 if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) { 100 return; 101 } 102 103 // store element in loaded images array 104 loaded.push( img ); 105 106 // keep track of broken and properly loaded images 107 if ( isBroken ) { 108 broken.push( img ); 109 } else { 110 proper.push( img ); 111 } 112 113 // cache image and its state for future calls 114 $.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } ); 115 116 // trigger deferred progress method if present 117 if ( hasNotify ) { 118 deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] ); 119 } 120 121 // call doneLoading and clean listeners if all images are loaded 122 if ( $images.length === loaded.length ){ 123 setTimeout( doneLoading ); 124 $images.unbind( '.imagesLoaded' ); 125 } 126 } 127 128 // if no images, trigger immediately 129 if ( !$images.length ) { 130 doneLoading(); 131 } else { 132 $images.bind( 'load.imagesLoaded error.imagesLoaded', function( event ){ 133 // trigger imgLoaded 134 imgLoaded( event.target, event.type === 'error' ); 135 }).each( function( i, el ) { 136 var src = el.src; 137 138 // find out if this image has been already checked for status 139 // if it was, and src has not changed, call imgLoaded on it 140 var cached = $.data( el, 'imagesLoaded' ); 141 if ( cached && cached.src === src ) { 142 imgLoaded( el, cached.isBroken ); 143 return; 144 } 145 146 // if complete is true and browser supports natural sizes, try 147 // to check for image status manually
148 if ( el.complete && el.naturalWidth !== undefined ) { 149 imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 ); 150 return; 151 } 152 153 // cached images don't fire load sometimes, so we reset src, but only when 154 // dealing with IE, or image is complete (loaded) and failed manual check 155 // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f 156 if ( el.readyState || el.complete ) { 157 el.src = BLANK; 158 el.src = src; 159 } 160 }); 161 } 162 163 return deferred ? deferred.promise( $this ) : $this; 164}; 165 166var Grid = (function() { 167 168 // list of items 169 var $grid = $( '#og-grid' ), 170 // the items 171 $items = $grid.children( 'li' ), 172 // current expanded item's index 173 current = -1, 174 // position (top) of the expanded item 175 // used to know if the preview will expand in a different row 176 previewPos = -1, 177 // extra amount of pixels to scroll the window 178 scrollExtra = 0, 179 // extra margin when expanded (between preview overlay and the next items) 180 marginExpanded = 0, 181 $window = $( window ), winsize, 182 $body = $( 'html, body' ), 183 // transitionend events 184 transEndEventNames = { 185 'WebkitTransition' : 'webkitTransitionEnd', 186 'MozTransition' : 'transitionend', 187 'OTransition' : 'oTransitionEnd', 188 'msTransition' : 'MSTransitionEnd', 189 'transition' : 'transitionend' 190 }, 191 transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ], 192 // support for csstransitions 193 support = Modernizr.csstransitions, 194 // default settings 195 settings = { 196 minHeight : 600, 197 speed : 350, 198 easing : 'ease' 199 }; 200 201 function init( config ) { 202 203 // the settings.. 204 settings = $.extend( true, {}, settings, config ); 205 206 // preload all images 207 $grid.imagesLoaded( function() { 208 209 // save item´s size and offset 210 saveItemInfo( true ); 211 // get window´s size 212 getWinSize(); 213 // initialize some events 214 initEvents(); 215 216 } ); 217 218 } 219 220 // add more items to the grid. 221 // the new items need to appended to the grid. 222 // after that call Grid.addItems(theItems); 223 function addItems( $newitems ) { 224 225 $items = $items.add( $newitems ); 226 227 $newitems.each( function() { 228 var $item = $( this ); 229 $item.data( { 230 offsetTop : $item.offset().top, 231 height : $item.height() 232 } ); 233 } ); 234 235 initItemsEvents( $newitems ); 236 237 } 238 239 // saves the item´s offset top and height (if saveheight is true) 240 function saveItemInfo( saveheight ) { 241 $items.each( function() { 242 var $item = $( this ); 243 $item.data( 'offsetTop', $item.offset().top ); 244 if( saveheight ) { 245 $item.data( 'height', $item.height() ); 246 } 247 } ); 248 } 249 250 function initEvents() { 251 252 // when clicking an item, show the preview with the item´s info and large image. 253 // close the item if already expanded. 254 // also close if clicking on the item´s cross 255 initItemsEvents( $items ); 256 257 // on window resize get the window´s size again 258 // reset some values.. 259 $window.on( 'debouncedresize', function() { 260 261 scrollExtra = 0; 262 previewPos = -1; 263 // save item´s offset 264 saveItemInfo(); 265 getWinSize(); 266 var preview = $.data( this, 'preview' ); 267 if( typeof preview != 'undefined' ) { 268 hidePreview(); 269 } 270 271 } ); 272 273 } 274 275 function initItemsEvents( $items ) { 276 $items.on( 'click', 'span.og-close', function() { 277 hidePreview(); 278 return false; 279 } ).children( 'a' ).on( 'click', function(e) { 280 281 var $item = $( this ).parent(); 282 // check if item already opened 283 current === $item.index() ? hidePreview() : showPreview( $item ); 284 return false; 285 286 } ); 287 } 288 289 function getWinSize() { 290 winsize = { width : $window.width(), height : $window.height() }; 291 } 292 293 function showPreview( $item ) { 294 295 var preview = $.data( this, 'preview' ), 296 // item´s offset top 297 position = $item.data( 'offsetTop' ); 298 299 scrollExtra = 0; 300 301 // if a preview exists and previewPos is different (different row) from item´s top then close it 302 if( typeof preview != 'undefined' ) { 303 304 // not in the same row 305 if( previewPos !== position ) { 306 // if position > previewPos then we need to take te current preview´s height in consideration when scrolling the window 307 if( position > previewPos ) { 308 scrollExtra = preview.height; 309 } 310 hidePreview(); 311 } 312 // same row 313 else { 314 preview.update( $item ); 315 return false;
316 } 317 318 } 319 320 // update previewPos 321 previewPos = position; 322 // initialize new preview for the clicked item 323 preview = $.data( this, 'preview', new Preview( $item ) ); 324 // expand preview overlay 325 preview.open(); 326 327 } 328 329 function hidePreview() { 330 current = -1; 331 var preview = $.data( this, 'preview' ); 332 preview.close(); 333 $.removeData( this, 'preview' ); 334 } 335 336 // the preview obj / overlay 337 function Preview( $item ) { 338 this.$item = $item; 339 this.expandedIdx = this.$item.index(); 340 this.create(); 341 this.update(); 342 } 343 344 Preview.prototype = { 345 create : function() { 346 // create Preview structure: 347 this.$title = $( '<h2></h2>' ); 348 this.$description = $( '<div></div>' ); 349 //this.$href = $( '<a href="#">Visit website</a>' ); 350 this.$href = $( '' ); 351 this.$details = $( '<div class="og-details"></div>' ).append( this.$title, this.$description, this.$href ); 352 this.$loading = $( '<div class="og-loading"></div>' ); 353 this.$fullimage = $( '<div class="og-fullimg"></div>' ).append( this.$loading ); 354 this.$closePreview = $( '<span class="og-close"></span>' ); 355 this.$previewInner = $( '<div class="og-expander-inner"></div>' ).append( this.$closePreview, this.$fullimage, this.$details ); 356 this.$previewEl = $( '<div class="og-expander"></div>' ).append( this.$previewInner ); 357 // append preview element to the item 358 this.$item.append( this.getEl() ); 359 // set the transitions for the preview and the item 360 if( support ) { 361 this.setTransition(); 362 } 363 }, 364 update : function( $item ) { 365 366 if( $item ) { 367 this.$item = $item; 368 } 369 370 // if already expanded remove class "og-expanded" from current item and add it to new item 371 if( current !== -1 ) { 372 var $currentItem = $items.eq( current ); 373 $currentItem.removeClass( 'og-expanded' ); 374 this.$item.addClass( 'og-expanded' ); 375 // position the preview correctly 376 this.positionPreview(); 377 } 378 379 // update current value 380 current = this.$item.index(); 381 382 var $ajax_content = $('<div>'); 383 384 // update preview´s content 385 var $itemEl = this.$item.children( 'a' ), 386 eldata = { 387 href : $itemEl.attr( 'href' ), 388 largesrc : $itemEl.data( 'largesrc' ), 389 title : $itemEl.data( 'title' ), 390 description : $itemEl.data( 'description' ) 391 //description : content, 392 }; 393 394 395 396 var desc = this.$title.html( eldata.title ).hide(); 397 this.$description.hide(); 398 this.$description.load('/node/' + eldata.description + ' .og-details-bio', function() { 399 desc.fadeIn(); 400 $(this).fadeIn(); 401 }); 402 //this.$href.attr( 'href', eldata.href ); 403 404 var self = this; 405 406 // remove the current image in the preview 407 if( typeof self.$largeImg != 'undefined' ) { 408 self.$largeImg.remove(); 409 } 410 411 // preload large image and add it to the preview 412 // for smaller screens we don´t display the large image (the media query will hide the fullimage wrapper) 413 if( self.$fullimage.is( ':visible' ) ) { 414 this.$loading.show(); 415 $( '<img/>' ).load( function() { 416 var $img = $( this ); 417 if( $img.attr( 'src' ) === self.$item.children('a').data( 'largesrc' ) ) { 418 self.$loading.hide();
419 self.$fullimage.find( 'img' ).remove(); 420 self.$largeImg = $img.fadeIn( 350 ); 421 self.$fullimage.append( self.$largeImg ); 422 } 423 } ).attr( 'src', eldata.largesrc ); 424 } 425 426 }, 427 open : function() { 428 429 setTimeout( $.proxy( function() { 430 // set the height for the preview and the item 431 this.setHeights(); 432 // scroll to position the preview in the right place 433 this.positionPreview(); 434 }, this ), 25 ); 435 436 }, 437 close : function() { 438 439 var self = this, 440 onEndFn = function() { 441 if( support ) { 442 $( this ).off( transEndEventName ); 443 } 444 self.$item.removeClass( 'og-expanded' ); 445 self.$previewEl.remove(); 446 }; 447 448 setTimeout( $.proxy( function() { 449 450 if( typeof this.$largeImg !== 'undefined' ) { 451 this.$largeImg.fadeOut( 'fast' ); 452 } 453 this.$previewEl.css( 'height', 0 ); 454 // the current expanded item (might be different from this.$item) 455 var $expandedItem = $items.eq( this.expandedIdx ); 456 $expandedItem.css( 'height', $expandedItem.data( 'height' ) ).on( transEndEventName, onEndFn ); 457 458 if( !support ) { 459 onEndFn.call(); 460 } 461 462 }, this ), 25 ); 463 464 return false; 465 466 }, 467 calcHeight : function() { 468 469 var heightPreview = winsize.height - this.$item.data( 'height' ) - marginExpanded, 470 itemHeight = winsize.height; 471 472 if( heightPreview < settings.minHeight ) { 473 heightPreview = settings.minHeight; 474 itemHeight = settings.minHeight + this.$item.data( 'height' ) + marginExpanded; 475 } 476 477 this.height = heightPreview; 478 this.itemHeight = itemHeight; 479 480 }, 481 setHeights : function() { 482 483 var self = this, 484 onEndFn = function() { 485 if( support ) { 486 self.$item.off( transEndEventName ); 487 } 488 }; 489 490 this.calcHeight(); 491 this.$previewEl.css( 'height', this.height ); 492 self.$item.addClass( 'og-expanded' ); 493 this.$item.css( 'height', this.itemHeight ).on( transEndEventName, onEndFn ); 494 495 if( !support ) { 496 onEndFn.call(); 497 } 498 499 }, 500 positionPreview : function() { 501 502 // scroll page 503 // case 1 : preview height + item height fits in window´s height 504 // case 2 : preview height + item height does not fit in window´s height and preview height is smaller than window´s height 505 // case 3 : preview height + item height does not fit in window´s height and preview height is bigger than window´s height 506 var position = this.$item.data( 'offsetTop' ), 507 previewOffsetT = this.$previewEl.offset().top - scrollExtra, 508 scrollVal = this.height + this.$item.data( 'height' ) + marginExpanded <= winsize.height ? position : this.height < winsize.height ? previewOffsetT - ( winsize.height - this.height ) : previewOffsetT; 509 510 $body.animate( { scrollTop : scrollVal }, settings.speed ); 511 512 }, 513 setTransition : function() { 514 this.$previewEl.css( 'transition', 'height ' + settings.speed + 'ms ' + settings.easing ); 515 this.$item.css( 'transition', 'height ' + settings.speed + 'ms ' + settings.easing ); 516 }, 517 getEl : function() { 518 return this.$previewEl; 519 } 520 } 521 522 return { 523 init : init, 524 addItems : addItems 525 }; 526 527})(); 528 529 Grid.init(); 530 531})(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.