PageSourceSearch

https://wearegorilla.co/wp-content/themes/gorilla_theme/lib/js/application-min.js?ver=1.0

js wearegorilla.co collected 2026-10-04 08:27:21 UTC 15,322 bytes, 665 lines download raw bytes

1/* ---------------------------------- */
2
3/*
4 * WeAreGorilla.co
5 * 2018
6 *
7 * application.js
8 *
9 */
10
11/* JSHint */
12/* globals console, jQuery, Vimeo, YT, alert */
13/* jshint esversion: 6, loopfunc: true, curly: false, esnext: true */
14
15
16/* ---------------------------------- */
17
18/* Initialize */
19jQuery(function ($) {
20	$.HTML = $('html');
21	$.Body = $('body');
22	$.Window = $(window);
23	$.Document = $(document);
24
25	$('[data-controller]').Instantiate();
26
27
28
29	// Close menu on first visit (if no intentional hover)
30	if( Cookies.get('g409jg092j-iojboijvaln') === undefined ) {
31
32		// Setup hover listener
33		var nav_temp_to = 0,
34			has_visited_timeout = 0;
35		$('nav').one('mouseenter.cancel_close', function() {
36			nav_temp_to = setTimeout( function() {
37				clearTimeout( has_visited_timeout );
38			}, 1000 );
39		}).one('mouseleave.cancel_cancel_close', function() {
40			clearTimeout( nav_temp_to );
41		});
42
43		// Open nav
44		$.Body.addClass('nav-open');
45
46		// Setup close if no hover
47		has_visited_timeout = setTimeout( function() {
48			$.Body.removeClass('nav-open');
49
50			// If we are running "animate nav" don't save
51			Cookies.set('g409jg092j-iojboijvaln', true, { expires: 1 });
52
53		}, 3000 );
54
55	}
56
57	// Note: Hover is detected with @media (hover:hover) even though firefox doesn't support it
58	if( !(matchMedia('(hover: none)').matches) ) {
59		document.body.classList.add('can-hover');
60	}
61
62
63	if( window.location.hash === "#reset-nav-flash" ) {
64		Cookies.remove('g409jg092j-iojboijvaln');
65	}
66
67
68	// For testing
69	localStorage.removeItem( 'has_visited' );
70
71
72  // Video hover
73  let video, v_to;
74  $('.c-grid-post.video-on-hover').on('mouseenter', function() {
75    video = $(this).find('video')[0];
76    video.play();
77  }).on('mouseleave', function() {
78    video.pause();
79  });
80
81});
82
83
84
85// av2 functions necessary for lazyload controller
86const _ = {
87
88	on_window_load: callback => {
89
90		if (document.readyState === 'complete') {
91			callback();
92		} else {
93			window.addEventListener("load", callback);
94		}
95
96	},
97	
98  load_image: (img, callback) => {
99
100		// Make sure image isn't broken
101		if( ! img ) return;
102
103		// Only if it is setup to be lazy loaded or has not already been loaded
104		if( ! img.dataset.src ) {
105			if( ! _.is_loaded(img) ) {
106				img.addEventListener('load', () => callback( img ) );
107			} else {
108				callback( img )
109			}
110			return;
111		}
112
113		// If there is a callback, run it after image is loaded
114		if( callback ) img.addEventListener('load', () => callback( img ) );
115
116		img.src = img.dataset.src;
117		img.removeAttribute('data-src');
118		img.srcset = img.dataset.srcset;
119		img.removeAttribute('data-srcset');
120		img.classList.add('loaded');
121
122	},
123
124};
125
126
127
128/* ---------------------------------- */
129
130/* Auto Instantiate
131	NOTE: This function loads a 'plugin' for each data-controller */
132
133(function($) {
134	'use strict';
135	$.fn.Instantiate = function(settings) {
136		var config = {};
137		if (settings) {$.extend(config, settings);}
138		this.each(function() {
139			var $self = $(this),
140				$controller = $self.data('controller');
141
142			if ($self[$controller]){ $self[$controller](); }
143		});
144	};
145}(jQuery));
146
147
148
149
150
151
152
153/* ---------------------------------- */
154
155/* gravity_forms */
156
157(function($) {
158	'use strict';
159	$.fn.gravity_forms = function() {
160		this.each(function() {
161
162			const el = $(this).get(0);
163
164			// ******************************
165			// RECAPTCHA
166			// ******************************
167			grecaptcha.ready(function() {
168				grecaptcha.execute( RecaptchaKeys.site, {action: 'submit'}).then(function(token) {
169
170					let g_recaptcha_input = el.querySelector('.g-recaptcha-token input[type="hidden"]');
171					if( g_recaptcha_input === null ) {
172						console.error('Google reCAPTCHA field not found. Please ensure classes are setup.');
173						// const input = document.createElement('input');
174						// input.classList.add('g-recaptcha-token');
175						// input.type = 'hidden';
176						// input.name = 'g-recaptcha-token';
177						// input.value = token;
178						// el.querySelector('.gform_fields').appendChild(input);
179					} else {
180						g_recaptcha_input.value = token;
181					}
182
183				});
184			});
185
186		});
187	};
188}(jQuery));
189
190
191/* ---------------------------------- */
192
193/* LargeListHoverImage */
194
195(function($) {
196	'use strict';
197	$.fn.LargeListHoverImage = function() {
198		this.each(function() {
199			var $self = $(this),
200				$a = $self.find('li > a, li > span'),
201				doit = function() {
202					$self.toggleClass('over');
203				};
204
205			$a.on( 'mouseenter', doit ).on( 'mouseleave', doit );
206
207		});
208	};
209}(jQuery));
210
211
212
213/* ---------------------------------- */
214
215/* NavTrigger */
216
217(function($) {
218	'use strict';
219	$.fn.NavTrigger = function() {
220		this.each(function() {
221			var $self = $(this),
222				$nav = $('nav'),
223				t = 0,
224				nav_open = function(e){
225					e.preventDefault();
226
227					t = setTimeout( function(){
228						$.Body.toggleClass('nav-open');
229					}, 250 );
230				},
231				nav_cancel = function() {
232					clearTimeout( t );
233				},
234				nav_close = function(e) {
235					e.preventDefault();
236					t = setTimeout( function(){
237						$.Body.removeClass('nav-open');
238					}, 250 );
239				};
240
241
242			// Open close mini menu
243			$self.on( 'mouseenter touchstart', nav_open ).on( 'mouseleave', nav_cancel );
244			$nav.on( 'mouseleave', nav_close ).on( 'mouseenter', nav_cancel );
245		});
246	};
247}(jQuery));
248
249
250
251/* ---------------------------------- */
252
253/* HeroScrollingText */
254
255(function($) {
256	'use strict';
257	$.fn.HeroScrollingText = function() {
258		this.each(function() {
259
260			const scroller = document.getElementById('scroller');
261			document.getElementsByTagName('video')[0].addEventListener( 'loadeddata', function() {
262				scroller.classList.add('in');
263			});
264
265
266			// Fallback in case loaddata doesn't load
267			setTimeout( function() {
268				if( scroller.classList.length === 0 ) {
269					scroller.classList.add('in');
270				}
271			}, 3000 );
272
273		});
274	};
275}(jQuery));
276
277
278
279/* ---------------------------------- */
280
281/* HomepageVideoHeight */
282
283(function($) {
284	'use strict';
285	$.fn.HomepageVideoHeight = function() {
286		this.each(function() {
287
288			const $this = $(this);
289
290			$.Window.on( 'resize.videoHeight', function() {
291
292				$this.height( $.Window.height() - ( 88*2 ) );  // <= 88 is top and bottom margin
293
294			}).trigger( 'resize.videoHeight' );
295
296		});
297	};
298}(jQuery));
299
300
301
302/* ---------------------------------- */
303
304/* LazyLoad */
305
306(function($) {
307	'use strict';
308	$.fn.LazyLoad = function() {
309		this.each(function() {
310
311      const el = this;
312      const type = el.dataset.lazytype;
313
314      // Default is scroll to (default lazy load behavior)
315      if( type === 'custom' ) {
316
317        // Loaded on a custom event don't do anything
318        return;
319
320      } else if( type === 'deferred' ) {
321
322        // Deferred is used for non in view on load, but need to be quickly
323        _.on_window_load( () => _.load_image( el ) );
324
325      } else { // <= default... scroll in view
326
327        // Type = scroll to intersect
328        const img_observer = new IntersectionObserver((entries, img_observer) => {
329          entries.forEach(entry => {
330
331            if( entry.target.classList.contains('lazy-debug') ) console.log(entry.target, entry.isIntersecting);
332            
333            if ( ! entry.isIntersecting) return;
334
335            if( type === 'video_poster' ) {
336              el.poster = el.dataset.poster;
337              el.removeAttribute('data-poster');
338            } else {
339              _.load_image( entry.target );
340            }
341
342            img_observer.unobserve( entry.target );
343          });
344        }, { threshold: 0, rootMargin: "1000px 0px 1000px 0px" });
345
346        // Observe it
347        img_observer.observe(el);
348
349      }
350
351		});
352	};
353}(jQuery));
354
355
356
357
358/* ---------------------------------- */
359
360/* Video */
361
362(function($) {
363	'use strict';
364	$.fn.Video = function() {
365		this.each(function() {
366
367			const $self = $(this),
368        vids = {
369          local: $self.find('.local-video'),
370          vimeo: $self.find('.vimeo-video'),
371          youtube: $self.find('.youtube-video')
372        },
373        // $local_video = $self.find('.local-video'),
374				// $vimeo_video = $self.find('.vimeo-video'),
375				// $youtube_video = ,
376				service = vids.local.length > 0 ? 'local' : vids.vimeo.length > 0 ? 'vimeo' : 'youtube',
377        $video = vids[ service ],
378        location = $self.hasClass('modal') ? 'modal' : 'in-place';
379      
380			let player = 0;
381
382			// Click listener
383			$self.on('click.playvideo', function(e) {
384				e.preventDefault();
385        
386				if( 
387          ( location === 'modal' && ! $video.hasClass('video-ready') ) || // <= modal and video not ready
388          // ( location !== 'modal' && $self.hasClass('video-ready') ) || // <= not sure what this one does.  testing
389          e.target.nodeName === 'BUTTON' ) { // <= if close 
390          // Add reset video here if needed
391          return;
392        }
393        
394        if( location === 'modal' ) {
395
396          let closing = false;
397          const $modal = $self.find('.modal-content'),
398            $close_button = $modal.find('.close-modal'),
399            do_close = () => {
400              $modal.removeClass('in');
401              $video.removeClass('video-on').removeClass('playing');
402              $self.removeClass('video-on');
403              $.HTML.removeClass('modal-in');
404
405              // Pause video
406              if( service === 'local' ) {
407                player = $video.find('video')[0];
408                player.pause();
409              } else if( service === 'vimeo' ) {
410                player = $video.data('vimeo_player');
411                player.pause();
412              } else if( service === 'youtube' ) {
413                player = $video.data('yt_player');
414                player.pauseVideo();
415              }
416
417              $close_button.off('click.close-modal');
418              $modal.off('click.close-modal');
419            };
420
421
422          // #####################
423          // Close listener
424          $close_button.on('click.close-modal', function(t) { 
425            t.preventDefault();
426            do_close();
427          });
428
429
430          // #####################
431          // Activation classes
432          if( ! closing ) {
433            $.HTML.addClass('modal-in');
434            $self.addClass('video-on');
435            $video.addClass('video-on');
436
437            $modal.addClass('in');
438            $video.addClass('video-on');
439          }
440            
441        }
442
443        if( ! $video.hasClass('playing') ) {
444
445          // Play video
446          $self.addClass('video-on');
447          $video.addClass('video-on').addClass('playing');
448
449          if( service === 'local' ) {
450            player = $video.find('video')[0];
451            player.play();
452          } else if( service === 'vimeo' ) {
453            player = $video.data('vimeo_player');
454            player.play();
455          } else if( service === 'youtube' ) {
456            player = $video.data('yt_player');
457            player.playVideo();
458          }
459
460        } else {
461
462          // Play video
463          // $self.removeClass('video-on');
464          $video.removeClass('playing').removeClass('video-on');
465          // console.log('service', service);
466
467          if( service === 'local' ) {
468            player = $video.find('video')[0];
469            player.pause();
470          } else if( service === 'vimeo' ) {
471            player = $video.data('vimeo_player');
472            player.pause();
473          } else if( service === 'youtube' ) {
474            player = $video.data('yt_player');
475            player.pauseVideo();
476          }
477
478        }
479
480
481        // ##############################
482        // Close modal if click outside of video
483        if( location === 'modal' && e.target.classList.contains('modal-content') ) $self.find('.modal-content .close-modal').trigger('click.close-modal')
484
485			});
486
487		});
488	};
489}(jQuery));
490
491
492
493/* ---------------------------------- */
494
495/* Vimeo */
496
497(function($) {
498	'use strict';
499	$.fn.Vimeo = function() {
500		this.each(function() {
501
502			const $self = $(this),
503				$placeholder = $self.siblings('img, video').first(),
504				options = {
505					url: $self.data('url'),
506					height: $placeholder.height(),
507					width: $placeholder.width()
508				};
509
510			// Only run once
511			if( ! $.HTML.hasClass('vimeo-loaded') ) {
512
513				// Add notice
514				$.HTML.addClass('vimeo-loaded');
515
516				// Load YouTube Frame API
517				const tag = document.createElement('script');
518
519				tag.src = "https://player.vimeo.com/api/player.js";
520				const firstScriptTag = document.getElementsByTagName('script')[0];
521				firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
522
523			}
524
525
526			// Listen for vimeo being loaded
527			var c = 0;
528			var i = setInterval( function() {
529
530				// Vimeo is loaded
531				if( typeof( Vimeo ) !== 'undefined' ) {
532					clearInterval( i );
533
534					// Run it
535					onVimeoJSAPIReady();
536				}
537
538				// Bail if too long
539				if( c >= 20 ) {
540					clearInterval( i );
541				} else {
542					c++;
543				}
544
545			}, 100 );
546
547
548			function onVimeoJSAPIReady() {
549
550				// Vars
551				const player = new Vimeo.Player( $self.attr('id'), options);
552				let $iframe = {
553					length:0
554				};
555
556				// Resize
557				$.Window.on( 'resize.video-size', function() {
558					if( $iframe.length !== 0 ) {
559						$iframe
560							.height( $placeholder.height() )
561							.width( $placeholder.width() );
562					}
563				});
564
565				// On loaded, set the $iframe
566				player.on( 'loaded', function() {
567					$iframe = $self.find('iframe');
568
569					$.Window.trigger('resize.video-size');
570				});
571
572				// Set flags
573				$self.closest('.video').addClass('video-ready');
574				$self.data('vimeo_player', player );
575
576			};
577
578		});
579	};
580}(jQuery));
581
582
583
584/* ---------------------------------- */
585
586/* YouTube */
587
588(function($) {
589	'use strict';
590	$.fn.YouTube = function() {
591		this.each(function() {
592
593			var $self = $(this),
594				$video = $self.children('div').first(),
595				$placeholder = $self.siblings('img, video').first(),
596				$iframe = {},
597				options = {
598					videoId: $self.data('videoid'),
599					height: $placeholder.height(),
600					width: $placeholder.width(),
601					events: {
602						onReady: function() {
603
604							$iframe = $self.find('iframe');
605							$.Window.on( 'resize.youtube', function() {
606
607								$iframe
608									.height( $placeholder.height() )
609									.width( $placeholder.width() );
610
611							}).trigger( 'resize.youtube' );
612
613							// Allow click
614							$self.closest('.video').addClass('video-ready');
615
616						},
617						onStateChange: function( r ) {
618							if( r.data === 1 ) {
619								// playing, so pause all others
620								$('.youtube-video').not( $self ).each( function() {
621									var player = $(this).data( 'yt_player' );
622									player.pauseVideo();
623								});
624							}
625						}
626					}
627				};
628
629			// Only run once
630			if( ! $.HTML.hasClass('youtube-loaded') ) {
631
632				// Add notice
633				$.HTML.addClass('youtube-loaded');
634
635				// Load YouTube Frame API
636				var tag = document.createElement('script');
637
638				tag.src = "https://www.youtube.com/iframe_api";
639				var firstScriptTag = document.getElementsByTagName('script')[0];
640				firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
641
642				// Instantiate global
643				$.Youtube_Players = [];
644
645			}
646
647
648			// Save our callbacks for when YouTube API is ready
649			$.Youtube_Players.push( function() {
650				const player = new YT.Player( $video.attr('id'), options);
651
652				// Save for future use
653				$self.data( 'yt_player', player );
654
655			});
656
657		});
658	};
659}(jQuery));
660
661// Run callbacks when the api is ready
662function onYouTubeIframeAPIReady() { // jshint ignore:line
663	// Loop each of our youtube players
664	$.each( $.Youtube_Players, function( i, callback ) { callback(); });
665}

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.