PageSourceSearch

https://www.rossfordart.com/wp-content/themes/fluxus/js/utils.js?ver=7.1.3

js rossfordart.com collected 2026-10-06 18:21:44 UTC 19,110 bytes, 727 lines download raw bytes

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.