1/** 2 * 3 * This file contains various functions and tiny 4 * plugins mainly used by main.js 5 * 6 */ 7 8 9/** 10 * A shorthand for console.log 11 */ 12window.log = function(){ 13 if( this.console ) { 14 if ( arguments.length == 1 ) { 15 console.log( arguments[0] ); 16 } else { 17 console.log( Array.prototype.slice.call( arguments ) ); 18 } 19 } 20}; 21 22 23/** 24 * Detection for various devices and browsers. 25 * 26 * window.device 27 */ 28(function ($) { 29 30 var $html = $('html'), 31 userAgent = window.navigator.userAgent.toLowerCase(), 32 check = function (needle) { 33 return userAgent.indexOf(needle) !== -1 34 }; 35 36 window.device = { 37 iphone: check('iphone'), 38 ipad: check('ipad'), 39 ipod: check('ipod'), 40 android: check('android'), 41 blackberry: check('blackberry') || check('bb10') || check('rim') 42 }; 43 44 device.ios = device.iphone || device.ipod || device.ipad; 45 device.mobile = device.ios || device.android; 46 47 device.ios4 = function () { 48 if (device.ios) { 49 if (/OS [2-4]_\d(_\d)? like Mac OS X/i.test(userAgent)) { 50 $html.addClass('ipad-ios4'); 51 return true; 52 } else if (/CPU like Mac OS X/i.test(userAgent)) { 53 $html.addClass('ipad-ios4'); 54 return true; 55 } 56 } 57 return false; 58 }(); 59 60 if (device.mobile) { 61 $html.addClass('touch-device'); 62 } 63 64})(jQuery); 65 66 67/** 68 * jQuery plugins 69 */ 70;(function ($, window, $window, isUndefined) { 71 72 $.support.transform = (function() { 73 var elStyle = document.createElement('div').style; 74 75 return elStyle.transition !== isUndefined || 76 elStyle.WebkitTransition !== isUndefined || 77 elStyle.MozTransition !== isUndefined || 78 elStyle.MsTransition !== isUndefined || 79 elStyle.OTransition !== isUndefined; 80 81 })(); 82 83 84 /** 85 * -------------------------------------------------------------------- 86 * Positions element in the vertical middle. 87 * -------------------------------------------------------------------- 88 * 89 * Usage: $('.element').vcenter(); 90 */ 91 $.fn.vcenter = function (options) { 92 93 return this.each(function () { 94 95 var $el = $(this); 96 97 // Use CSS3 98 if ($.support.transform) { 99 100 $el.css('transform', 'translate(0, -50%)'); 101 102 // In case we are on IE8 103 } else { 104 105 var resizer = function () { 106 var $p = $el.parent(), 107 $offsetP = $el.offsetParent(), // Find a parent that has a position 108 middle = $el.height() / -2; 109 110 // If parent does not have position, then calculate the parent offset. 111 if ($offsetP.get(0) != $p.get(0)) { 112 middle += $p.position().top / 2; 113 } 114 115 $el.css('margin-top', middle); 116 }; 117 118 $window.on('resize.vcenter', _.debounce(resizer)); 119 resizer(); 120 121 } 122 123 }); 124 125 }; 126 127 128 // Legacy 129 $.fn.verticalCenter = function( options ) { 130 131 var $t = $( this ); 132 133 if ( $t.length > 1 ) { 134 135 $t.each( function () { 136 $( this ).verticalCenter( options ); 137 }); 138 139 } else { 140 141 var defaults = { 142 preloadSiblings: true 143 } 144 145 options = $.extend( {}, defaults, options ); 146 147 var $p = $t.parent(); 148 var height = $t.outerHeight(); 149 var parentHeight = $p.height(); 150 151 if ( options.preloadSiblings ) { 152 153 var $imageSiblings = $p.find( 'img' ); 154 155 if ( $imageSiblings.length && ( $t.data( 'child-images-loaded' ) == isUndefined ) ) { 156 157 $t.data( 'child-images-loaded', true ); 158 159 $t.css( 'visibility', 'hidden' ); 160 161 $imageSiblings.each( function () { 162 163 var img = new Image(); 164 165 $( img ).error( function () { 166 167 $t.hide().css( 'visibility', 'visible' ).fadeIn(); 168 $t.verticalCenter(); 169 170 } ).load( function () { 171 172 $t.hide().css( 'visibility', 'visible' ).fadeIn(); 173 $t.verticalCenter(); 174 175 } ); 176 177 img.src = $( this ).attr( 'src' ); 178 179 }); 180 181 } 182 183 } 184 185 if ( parentHeight <= height ) { 186 return; 187 } 188 189 var top = Math.floor( (parentHeight - height) / 2 ), 190 position = $t.css( 'position' ); 191 192 if ( ( position == 'absolute' ) || ( position == 'relative' ) ) {
193 $t.css( 'top', top ); 194 } else { 195 $t.css({ 196 top: top, 197 position: 'relative' 198 }); 199 } 200 201 } 202 203 return this; 204 205 }; 206 207 /** 208 * -------------------------------------------------------------------- 209 * Preloads images. 210 * Usage: $.preloadImage(src).then(function (img) { alert(img.width) }); 211 * -------------------------------------------------------------------- 212 */ 213 $.preloadImage = function (src) { 214 var img = new Image(), 215 dfd = new $.Deferred(); 216 217 $(img).load(function () { 218 dfd.resolveWith(this, [img]); 219 }).error(dfd.resolve); 220 221 img.src = src; 222 223 return dfd; 224 } 225 226 /** 227 * -------------------------------------------------------------------- 228 * Returns highest DOM element in the jQuery array. 229 * -------------------------------------------------------------------- 230 */ 231 $.fn.highestElement = function () { 232 233 var $el = $(this), 234 elementHeight = 0, 235 elementIndex = false; 236 237 $el.each(function (index) { 238 var height = $(this).outerHeight(); 239 240 if (height > elementHeight) { 241 elementHeight = height; 242 elementIndex = index; 243 } 244 }); 245 246 return elementIndex !== false ? $el.eq(elementIndex) : $(''); 247 248 }; 249 250 251 /** 252 * -------------------------------------------------------------------- 253 * Changes CSS while remembering old value, so it can be restored later. 254 * -------------------------------------------------------------------- 255 */ 256 $.fn.addTempCss = function(cssProp, cssValue) { 257 258 if (this.data('temp-css-' + cssProp) == isUndefined) { 259 this.data('temp-css-' + cssProp, this.css(cssProp)); 260 } 261 262 return this.css(cssProp, cssValue); 263 264 }; 265 266 $.fn.removeTempCss = function(cssProp) { 267 268 var originalValue = this.data('temp-css-' + cssProp); 269 270 if (originalValue) { 271 this.removeData('temp-css-' + cssProp); 272 this.css(cssProp, originalValue); 273 } 274 275 return this; 276 277 }; 278 279 280 // hoverIntent r6 // 2011.02.26 // jQuery 1.5.1+ 281 $.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev])}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev])};var handleHover=function(e){var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t)}if(e.type=="mouseenter"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob)},cfg.interval)}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob)},cfg.timeout)}}};return this.bind('mouseenter',handleHover).bind('mouseleave',handleHover)}; 282 283 284 // jquery-mousewheel Copyright (c) 2013 Brandon Aaron (http://brandonaaron.net) 285 (function(){var d=["wheel","mousewheel","DOMMouseScroll"];var f="onwheel" in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"];var e,a;if($.event.fixHooks){for(var b=d.length;b;){$.event.fixHooks[d[--b]]=$.event.mouseHooks}}$.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var g=f.length;g;){this.addEventListener(f[--g],c,false)}}else{this.onmousewheel=c}},teardown:function(){if(this.removeEventListener){for(var g=f.length;g;){this.removeEventListener(f[--g],c,false)}}else{this.onmousewheel=null}}};$.fn.extend({mousewheel:function(g){return g?this.bind("mousewheel",g):this.trigger("mousewheel")},unmousewheel:function(g){return this.unbind("mousewheel",g)}});function c(g){var h=g||window.event,m=[].slice.call(arguments,1),o=0,j=0,i=0,l=0,k=0,n;g=$.event.fix(h);g.type="mousewheel";if(h.wheelDelta){o=h.wheelDelta}if(h.detail){o=h.detail*-1}if(h.deltaY){i=h.deltaY*-1;o=i}if(h.deltaX){j=h.deltaX;o=j*-1}if(h.wheelDeltaY!==undefined){i=h.wheelDeltaY}if(h.wheelDeltaX!==undefined){j=h.wheelDeltaX*-1}l=Math.abs(o);if(!e||l<e){e=l}k=Math.max(Math.abs(i),Math.abs(j));if(!a||k<a){a=k}
285n=o>0?"floor":"ceil";o=Math[n](o/e);j=Math[n](j/a);i=Math[n](i/a);m.unshift(g,o,j,i);return($.event.dispatch||$.event.handle).apply(this,m)}})(); 286 287 288 // jquery-touchwipe Andreas Waltl, netCU Internetagentur (http://www.netcu.de) 289 (function(){$.fn.touchwipe=function(settings){var config={min_move_x:20,min_move_y:20,wipeLeft:function(){},wipeRight:function(){},wipeUp:function(){},wipeDown:function(){},preventDefaultEvents:true};if(settings)$.extend(config,settings);this.each(function(){var startX;var startY;var isMoving=false;function cancelTouch(){this.removeEventListener('touchmove',onTouchMove);startX=null;isMoving=false}function onTouchMove(e){if(config.preventDefaultEvents){e.preventDefault()}if(isMoving){var x=e.touches[0].pageX;var y=e.touches[0].pageY;var dx=startX-x;var dy=startY-y;if(Math.abs(dx)>=config.min_move_x){cancelTouch();if(dx>0){config.wipeLeft()}else{config.wipeRight()}}else if(Math.abs(dy)>=config.min_move_y){cancelTouch();if(dy>0){config.wipeDown()}else{config.wipeUp()}}}}function onTouchStart(e){if(e.touches.length==1){startX=e.touches[0].pageX;startY=e.touches[0].pageY;isMoving=true;this.addEventListener('touchmove',onTouchMove,false)}}if('ontouchstart'in document.documentElement){this.addEventListener('touchstart',onTouchStart,false)}});return this}})(); 290 291}(jQuery, window, jQuery(window))); 292 293 294/** 295 * Easing functions. 296 */ 297jQuery.extend(jQuery.easing, { 298 def: 'easeOutQuad', 299 easeOutQuad: function (x, t, b, c, d) { 300 return -c *(t/=d)*(t-2) + b; 301 } 302}); 303 304 305/** 306 * -------------------------------------------------------------------- 307 * Keyboard arrows & mousewheel navigation. 308 * -------------------------------------------------------------------- 309 */ 310(function ($, $window, $document, isUndefined) { 311 312 Navigation = function (options) { 313 314 this.options = $.extend({}, Navigation.settings, options); 315 this.$items = []; 316 this.$html = $('html,body'); 317 318 }; 319 320 Navigation.settings = { 321 322 onKeyboardNext: null, 323 onKeyboardPrevious: null, 324 nextItem: null, 325 onNextItem: null, 326 previoutItem: null, 327 onPreviousItem: null, 328 onSetItems: null 329 330 }; 331 332 Navigation.prototype = { 333 334 setItems: function ($items) { 335 336 this.$items = $items; 337 338 this.options.onSetItems && this.options.onSetItems.call(this); 339 340 if (this.$items && (this.$items.length > 1)) { 341 this.enableMousewheel(); 342 this.enableKeyboard(); 343 } 344 345 }, 346 347 getActive: function () { 348 349 var center = $window.scrollLeft() + ($window.width() / 2), 350 distances = [], 351 distancesAbs = [], 352 minDistance = 0, 353 index = 0; 354 355 this.$items.each(function () { 356 var $t = $(this), 357 left = parseInt($t.offset().left, 10), 358 right = left + parseInt($t.width(), 10), 359 distance = center - (right - $t.width() / 2); 360 361 distances.push(distance); 362 distancesAbs.push(Math.abs(distance)); 363 364 }); 365 366 minDistance = Math.min.apply(Math, distancesAbs); 367 index = distancesAbs.indexOf(minDistance); 368 369 return { 370 'item': this.$items.eq(index), 371 'distance': distances[index] 372 }; 373 374 }, 375 376 nextItem: function () { 377 378 if (this.options.nextItem) { 379 this.options.nextItem.call(this); 380 return false; 381 } 382 383 if (!this.$items.length) { 384 return false; 385 } 386 387 var active = this.getActive(); 388 389 if (active.distance < -30) { 390 391 this.scrollToItem(active.item); 392 393 } else { 394 395 var index = this.$items.index(active.item); 396 this.scrollToItem(this.$items.eq(index + 1)); 397 398 } 399 400 this.options.onNextItem && this.options.onNextItem.call(this); 401 402 }, 403 404 previousItem: function () { 405 406 if (this.options.previousItem) { 407 this.options.previousItem.call(this); 408 return false; 409 } 410 411 if (!this.$items.length) { 412 return false; 413 } 414 415 var active = this.getActive(); 416 417 if (active.distance > 30) { 418 419 this.scrollToItem(active.item); 420 421 } else { 422 423 var index = this.$items.index(active.item); 424 if (0 !== index) { 425 this.scrollToItem(this.$items.eq(index - 1)); 426 } else { 427 this.scrollTo(0); 428 } 429 430 } 431 432 this.options.onPreviousItem && this.options.onPreviousItem.call(this); 433 434 }, 435 436 mouseWheelScroll: function (deltaY) { 437 deltaY < 0 ? this.nextItem() : this.previousItem(); 438 }, 439 440 enableMousewheel: function() { 441 442 var that = this; 443 444 $window.on('mousewheel.fluxus', _.debounce(function (e, delta, deltaX, deltaY) { 445 if (0 === deltaX) {
446 var $scrollContainer = $(e.target).closest('.scroll-container'); 447 if ($scrollContainer.length) { 448 var $scrollbar = $scrollContainer.find('.scrollbar:first'); 449 if ($scrollbar.is('.disable')) { 450 that.mouseWheelScroll.call(that, deltaY); 451 return false; 452 } 453 } else { 454 that.mouseWheelScroll.call(that, deltaY); 455 return false; 456 } 457 } 458 })); 459 460 }, 461 462 scrollTo: function (x) { 463 464 if ($window.width() >= $document.width()) { 465 return; 466 } 467 468 this.$html.not(':animated').animate({ scrollLeft: x }, 300); 469 470 }, 471 472 scrollToItem: function ($item) { 473 474 if ($item && $item.length && ($window.width() < $document.width())) { 475 476 this.scrollTo($item.offset().left - ($window.width() - $item.width()) / 2); 477 478 } 479 480 }, 481 482 enableKeyboard: function () { 483 var that = this; 484 485 $window.on('keydown.navigation.fluxus', function (e) { 486 487 if (!that.$items.length) { 488 return true; 489 } 490 491 // on right arrow click 492 if (39 == e.which) { 493 494 if (that.options.onKeyboardNext) { 495 if (that.options.onKeyboardNext.apply(that, e)) { 496 that.nextItem(); 497 } 498 } else { 499 that.nextItem(); 500 } 501 502 return false; 503 } 504 505 // on left arrow click 506 if (37 == e.which) { 507 508 if (that.options.onKeyboardPrevious) { 509 if (that.options.onKeyboardPrevious.apply(that, e)) { 510 that.previousItem(); 511 } 512 } else { 513 that.previousItem(); 514 } 515 516 return false; 517 } 518 519 }); 520 521 }, 522 523 disableKeyboard: function () { 524 $window.off('keydown.navigation.fluxus'); 525 }, 526 527 disableMousewheel: function () { 528 $window.off('mousewheel.fluxus'); 529 } 530 531 }; 532 533})(jQuery, jQuery(window), jQuery(document)); 534 535 536(function ( $, window, undefined ) { 537 538 $.Appreciate = function( options, element, callback ) { 539 540 this.$element = $( element ); 541 this.callback = callback; 542 543 this.options = $.extend( {}, $.Appreciate.settings, options ); 544 545 this.ajaxurl = this.$element.data( 'ajaxurl' ); 546 this.id = this.$element.data( 'id' ); 547 this.title_after = this.$element.data( 'title-after' ); 548 549 this._init(); 550 551 }; 552 553 $.Appreciate.settings = { 554 555 template: '<span class="icon"></span><b class="numbers">{count}</b>' 556 557 }; 558 559 $.Appreciate.prototype = { 560 561 _init: function () { 562 563 var self = this; 564 565 this.count = this.$element.data( 'count' ); 566 if ( !this.count ) { 567 this.count = 0; 568 } 569 570 if ( this.$element.is( '.has-appreciated' ) ) { 571 this.$element.find( '.appreciate-title' ).html( this.title_after ); 572 } 573 574 this.$template = this.options.template.replace( '{count}', this.count ); 575 this.$template = $( this.$template ); 576 577 this.$element.append( 578 this.$template 579 ); 580 581 this.$element.click( function () { 582 583 var $t = $( this ); 584 if ( $t.is( '.has-appreciated' ) ) { 585 return false; 586 } 587 588 self.count++; 589 590 self.$element.find( '.numbers' ).html( self.count ); 591 self.$element.find( '.appreciate-title' ).html( this.title_after ); 592 593 if ( self.ajaxurl != undefined ) { 594 595 $.post( self.ajaxurl, { 596 action: 'appreciate', 597 post_id: self.id 598 }); 599 600 } 601 602 $t.addClass( 'has-appreciated' ); 603 604 return false; 605 606 }); 607 608 } 609 610 } 611 612 $.fn.appreciate = function( options, callback ) { 613 614 this.data( 'apprecaite', new $.Appreciate( options, this, callback ) ); 615 return this; 616 617 } 618 619})( jQuery, window ); 620 621 622(function ( $, window, undefined ) { 623 624 MobileNav = function( $items, options ) { 625 626 this.options = $.extend( MobileNav.settings, options ); 627 this.$items = $items; 628 629 this._create(); 630 631 } 632 633 MobileNav.settings = { 634 openButtonTitle: 'Menu', 635 minWindowWidth: 568 636 } 637 638 MobileNav.prototype = { 639 640 _create: function () { 641 642 var self = this; 643 644 /** 645 * Create mobile menu DOM element. 646 */ 647 var menuTemplate = '' + 648 '<div id="mobilenav" class="closed">' + 649 '<a href="#" class="btn-open">' + this.options.openButtonTitle + '</a>' + 650 '<nav></nav>' + 651 '</div>'; 652 653 var $menu = $( menuTemplate );
654 var $nav = $menu.find('nav'); 655 656 this.$items.each(function () { 657 var level = 1; 658 var $t = $(this); 659 if ( $t.data('level') != undefined ) { 660 level = $t.data('level'); 661 } 662 663 var $a = $('<a />').attr({ 664 href: $t.attr('href') 665 }).html($t.html()); 666 667 $a.addClass('level-' + level); 668 669 if ( self.options.active.get(0) == $t.get(0) ) { 670 $a.addClass('active'); 671 } 672 673 $nav.append( $a ); 674 }); 675 676 $( 'body' ).append( $menu ); 677 this.$menu = $menu; 678 679 $menu.css({ 680 left: $menu.outerWidth() * -1 681 }) 682 683 /** 684 * Open / Close button functionality. 685 */ 686 $menu.find( '.btn-open' ).click( function () { 687 if ( $menu.is( '.closed' ) ) { 688 self.open(); 689 } else { 690 self.close(); 691 } 692 return false; 693 }); 694 695 }, 696 697 698 open: function () { 699 700 var windowHeight = $(window).height(); 701 var docHeight = $(document).height(); 702 703 this.$menu.removeClass('closed').addClass('opened'); 704 705 this.$menu.css({ 706 height: windowHeight > docHeight ? windowHeight : docHeight 707 }).animate({ 708 left: 0 709 }, 300); 710 711 }, 712 713 714 close: function () { 715 716 this.$menu.removeClass('opened').addClass('closed'); 717 this.$menu.animate({ 718 left: this.$menu.outerWidth() * -1 719 }, 300); 720 721 } 722 723 724 } 725 726})( jQuery, window ); 727
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.