PageSourceSearch

https://sfgoodwill.org/wp-content/themes/goodwillsf/js/jquery.theme-main.min.js?ver=1.14.3

js sfgoodwill.org collected 2026-10-02 10:49:11 UTC 17,680 bytes, 576 lines download raw bytes

1/**
2 * Main theme Javascript - (c) SiteOrigin, freely distributable under the terms of the GPL 2.0 license.
3 */
4
5/* global jQuery */
6
7jQuery ( function( $ ) {
8	
9	$( 'body.no-js' ).removeClass( 'no-js' );
10
11	// Initialize FlexSlider.
12	$( '.entry-content .flexslider:not(.metaslider .flexslider), #metaslider-demo.flexslider, .gallery-format-slider' ).flexslider( { 
13		namespace: "flex-goodwill-",
14	} );
15
16	// Setup FitVids for entry content, video post format, Panels, WooCommerce pages, masthead widget area and the header sidebar.
17	if ( typeof $.fn.fitVids !== 'undefined' ) {
18		$( '.entry-content, .entry-content .panel, .entry-video, .woocommerce #main, #masthead-widgets, #header-sidebar' ).fitVids( { ignore: '.tableauViz' } );
19	}
20
21	var isMobileDevice = $( 'body' ).hasClass( 'so-goodwill-mobile-device' ),
22		isCustomizer = $( 'body' ).hasClass( 'so-goodwill-customizer-preview' ),
23		isMobileNav = $( 'nav.site-navigation.primary' ).hasClass('mobile-navigation' );
24	if ( ( ! isMobileDevice && $( '#scroll-to-top' ).hasClass( 'scroll-to-top' ) ) || ( ( isCustomizer || isMobileDevice ) ) ) {
25
26		// Everything we need for scrolling up and down.
27		$( window ).scroll( function() {
28			if ( $( window ).scrollTop() > 150 ) {
29				$( '#scroll-to-top' ).addClass( 'displayed' );
30			} else {
31				$( '#scroll-to-top' ).removeClass( 'displayed' );
32			}
33		} );
34
35		$( '#scroll-to-top' ).click( function() {
36			$( "html, body" ).animate( { scrollTop: "0px" } );
37			return false;
38		} );
39	}
40
41	// The carousel widget.
42	$( '.goodwill-carousel' ).each( function() {
43		var $$ = $( this );
44		var wrap = $$.closest( '.widget' );
45		var title = wrap.find( '.widget-title' );
46		var $items = $$.find( '.carousel-entry' );
47		var $firstItem = $items.eq(0);
48
49		var position = 0, page = 1, fetching = false, complete = false, numItems = $items.length, itemWidth = ( $firstItem.width() + parseInt( $firstItem.css( 'margin-right' ) ) );
50
51		var updatePosition = function() {
52			if ( position < 0 ) {
53				position = 0;
54			}
55			if ( position >= $$.find('.carousel-entry').length - 1 ) {
56				position = $$.find('.carousel-entry').length - 1;
57
58				// Fetch the next batch.
59				if ( ! fetching && ! complete ) {
60					fetching = true;
61					page++;
62					$$.append( '<li class="loading"></li>' );
63
64					$.get(
65						$$.data('ajax-url'),
66						{
67							query : $$.data( 'query' ),
68							action : 'goodwill_carousel_load',
69							paged : page
70						},
71						function( data, status ) {
72							var $items = $( data.html );
73							var count = $items.find( '.carousel-entry' ).appendTo( $$ ).hide().fadeIn().length;
74							numItems += count;
75							if ( count === 0 ) {
76								complete = true;
77								$$.find( '.loading' ).fadeOut( function() {
78									$( this ).remove();
79								} );
80							} else {
81								$$.find( '.loading' ).remove();
82							}
83							fetching = false;
84						}
85					);
86				}
87			}
88			$$.css( 'transition-duration', "0.45s" );
89			$$.css( 'margin-left', -( itemWidth * position) + 'px' );
90		};
91
92		title.find( 'a.previous' ).click( function(){
93			position -= 1;
94			updatePosition();
95			return false;
96		} );
97
98		title.find( 'a.next' ).click( function() {
99			position += 1;
100			updatePosition();
101			return false;
102		} );
103
104		// Setup swiping for mobile devices.
105		var validSwipe = false;
106		var prevDistance = 0;
107		var startPosition = 0;
108		var velocity = 0;
109		var prevTime = 0;
110		var posInterval;
111		$$.swipe( {
112			excludedElements: "",
113			triggerOnTouchEnd: true,
114			threshold: 75,
115			swipeStatus: function( event, phase, direction, distance, duration, fingerCount, fingerData ) {
116				if ( phase === "start" ) {
117					startPosition = -( itemWidth * position );
118					prevTime = new Date().getTime();
119					clearInterval( posInterval );
120				} else if ( phase === "move" ) {
121					if ( direction === "left" ) {
122						distance *= -1;
123					}
124					setNewPosition( startPosition + distance );
125					var newTime = new Date().getTime();
126					var timeDelta = (newTime - prevTime) / 1000;
127					velocity = (distance - prevDistance) / timeDelta;
128					prevTime = newTime;
129					prevDistance = distance;
130				} else if ( phase === "end" ) {
131					validSwipe = true;
132					if ( direction === "left" ) {
133						distance *= -1;
134					}
135					if ( Math.abs( velocity ) > 400 ) {
136						velocity *= 0.1;
137						var startTime = new Date().getTime();
138						var cumulativeDistance = 0;
139						posInterval = setInterval( function() {
140							var time = (new Date().getTime() - startTime) / 1000;
141							cumulativeDistance += velocity * time;
142							var newPos = startPosition + distance + cumulativeDistance;
143							var decel = 30;
144							var end = ( Math.abs( velocity ) - decel) < 0;
145							if ( direction === "left" ) {
146								velocity += decel;
147							} else {
148								velocity -= decel;
149							}
150							if ( end || !setNewPosition( newPos ) ) {
151								clearInterval(posInterval);
152								setFinalPosition();
153							}
154						}, 20 );
155					} else {
156						setFinalPosition();
157					}
158				} else if( phase === "cancel") {
159					updatePosition();
160				}
161			}
162		} );
163
164		var setNewPosition = function( newPosition ) {
165			if ( newPosition < 50 && newPosition >  -( itemWidth * numItems ) ) {
166				$$.css( 'transition-duration', "0s" );
167				$$.css( 'margin-left', newPosition + 'px' );
168				return true;
169			}
170			return false;
171		};
172		var setFinalPosition = function() {
173			var finalPosition = parseInt( $$.css( 'margin-left' ) );
174			position = Math.abs( Math.round( finalPosition / itemWidth ) );
175			updatePosition();
176		};
177
178		// Prevent clicks when we're swiping.
179		$$.on( 'click', 'li.carousel-entry .thumbnail a', function( event ) {
180			if ( validSwipe ) {
181				event.preventDefault();
182				validSwipe = false;
183			}
184		} );
185	} );
186
187	// Add keyboard access to the menu.
188	$( '.menu-item' ).children( 'a' ).focus( function() {
189		$( this ).parents( 'li' ).addClass( 'focus' );
190	} );
191	// Click event fires after focus event.
192	$( '.menu-item' ).children( 'a' ).click( function() {
193		$( this ).parents( 'li' ).removeClass( 'focus' );
194	} );
195	$( '.menu-item' ).children( 'a' ).focusout( function() {
196		$( this ).parents( 'li' ).removeClass( 'focus' );
197	} );
198
199	// Hover for the menu widget in the header
200	$( '#header-sidebar .widget_nav_menu', '#masthead-widgets .widget_nav_menu' )
201		.on('mouseenter', 'ul.menu li', function() {
202			var $$ = $( this );
203			var $ul = $$.find( '> ul' );
204			$ul.finish().css( 'opacity', 0 )
205				.hide().slideDown( 200 )
206				.animate( { opacity: 1 }, { queue: false, duration: 200 } );
207		} )
208		.on ('mouseleave', 'ul.menu li', function() {
209			var $$ = $( this );
210			var $ul = $$.find( '> ul' );
211			$ul.finish().fadeOut( 150 );
212		} );
213
214	// The search bar.
215	var isSearchHover = false;
216	$( document ).click( function() {
217		if ( ! isSearchHover ) {
218			$( '#search-icon form' ).fadeOut( 250 );
219		}
220	} );
221
222	// Check the device that is being used.
223	var deviceAgent = navigator.userAgent.toLowerCase();
224
225	// Open and focus the search form
226	$( document )
227		.on( 'click keydown', '#searchicon', function( e ) {
228			if ( e.type == 'keydown' ) {
229				if ( e.keyCode !== 13 ){
230					return;
231				}
232				e.preventDefault();
233			}
234			var $$ = $( this ).parent();
235			$$.find( 'form' ).fadeToggle( 250 );
236			if ( deviceAgent.match( /(iPad|iPhone|iPod)/i ) ) {
237				$$.find( 'input[type="search"]' ).focus();
238			} else {
239				setTimeout( function() {
240					$$.find( 'input[type="search"]' ).focus();
241				}, 300 );
242			}
243		} );
244
245	$( document )
246		.keyup( function( e ) {
247			if ( e.keyCode == 27 ) { // Escape key maps to keycode `27`.
248				$( '#search-icon form' ).fadeOut( 250 );
249			}
250		} );
251
252	$( document )
253	.on( 'mouseenter', '#search-icon', function() {
254		isSearchHover = true;
255	} )
256	.on( 'mouseleave', '#search-icon', function() {
257		isSearchHover = false;
258	} );
259
260	$( window ).resize( function() {
261		$( '#search-icon .searchform' ).each( function() {
262			$( this ).width( $( this ).closest( '.full-container' ).width() );
263		} );
264	} ).resize();
265
266	// The sticky menu.
267	if ( ( $( 'nav.site-navigation.primary' ).hasClass( 'use-sticky-menu' ) && !isMobileDevice ) ||
268		( ( isMobileDevice || isCustomizer ) && isMobileNav ) ) {
269
270		var $$ = $( 'nav.site-navigation.primary' );
271		var $initTop;
272		var isBoxedMega = $( 'body.mega-menu-primary.layout-boxed' ).length;
273		var boxedMegaWidth;
274		var resetStickyMenu = function() {
275			if ( ! $$.hasClass( 'sticky' ) ) {
276				$initTop = $$.offset().top;
277				boxedMegaWidth = $$.width();
278			}
279			var threshold = 0;
280			if ( $( 'body' ).hasClass( 'admin-bar' ) ) {
281				threshold = $( '#wpadminbar' ).css( 'position' ) == 'absolute' ? 0 : $( '#wpadminbar' ).outerHeight();
282			}
283			var navTop = parseInt( $initTop - $(window).scrollTop() ); //Force truncation of float value.
284			if ( navTop < threshold ) {
285				$$.addClass( 'sticky' );
286				$( 'body' ).addClass( 'sticky-menu' );
287				$( '#masthead' ).css( 'padding-bottom',  $$.innerHeight() );
288
289				if( isBoxedMega ) {
290					$$.width( boxedMegaWidth );
291				}
292			} else if( $$.hasClass( 'sticky' ) ) {
293				$( '#masthead' ).css( 'padding-bottom', 0 );
294				$$.removeClass( 'sticky' );
295				$('body').removeClass( 'sticky-menu' );
296
297				if( isBoxedMega ) {
298					$$.width( 'auto' );
299				}
300			}
301		};
302		$( window ).scroll( resetStickyMenu ).resize( resetStickyMenu );
303		resetStickyMenu();
304	}
305
306	// Lets make the slider stretch.
307	$( 'body.layout-full #main-slider[data-stretch="true"]' ).each( function() {
308		var $$ = $( this );
309		$$.find( '>div' ).css( 'max-width', '100%' );
310		$$.find( '.slides li' ).each( function() {
311			var $s = $( this );
312
313			// Move the image into the background.
314			var $img = $s.find( 'img.ms-default-image' ).eq( 0 );
315			if ( ! $img.length ) {
316				$img = $s.find( 'img' ).eq( 0 );
317			}
318
319			$s.css( 'background-image', 'url(' + $img.attr( 'src' ) + ')' );
320			$img.css( 'visibility', 'hidden' );
321			// Add a wrapper.
322			$s.wrapInner( '<div class="full-container"></div>' );
323			// This is because IE doesn't detect links correctly when we stretch slider images.
324			var link = $s.find( 'a' );
325			if ( link.length ) {
326				$s.mouseover( function() {
327					$s.css('cursor', 'hand');
328				} );
329				$s.mouseout( function() {
330					$s.css( 'cursor', 'pointer' );
331				} );
332				$s.click( function( event ) {
333					event.preventDefault();
334					var clickTarget = $(event.target);
335					var navTarget = clickTarget.is( 'a' ) ? clickTarget : link;
336					window.open( navTarget.attr( 'href' ), navTarget.attr( 'target' ) );
337				} );
338			}
339		} );
340	} );
341
342
343	$( '#colophon #footer-widgets .widget_nav_menu a' ).each( function() {
344		var $$ = $( this ),
345			itemDepth = $( this ).parents( '.sub-menu' ).length,
346			itemPadding = ( 10 * itemDepth ) + 'px';
347
348		$( this ).css( 'padding-left', itemPadding );
349	} );
350
351} );
352
353
354
355
356jQuery(document).ready(function($) {
357
358	// init Packery
359	var $grid = $('.masonry').packery({
360			columnWidth: '.spacer',
361			itemSelector: '.brick',
362			percentPosition: true,
363			gutter: 0,
364			isResizeBound: true
365	});
366	
367	// layout Packery after each image loads
368	$grid.imagesLoaded().progress( function() {
369	  $grid.packery();
370	});
371
372	
373	$(".socicon a").bind("click touchstart ", function(){
374		
375		window.location=jQuery(this).attr('href'); 
376		return false;
377	 
378	});
379
380    $(".brick").bind("click touchstart ", function(){
381		var newWidth = $('.masonry').width();
382
383		$(".brick").animate({"width": '25%'}, 0).removeClass('tileactive').attr('id', '');
384		
385		$(this).animate({"width": newWidth}, 0).addClass('tileactive').attr('id', 'tileactiveid');
386		
387		// init Masonry
388		$('.masonry').packery({
389			columnWidth: '.spacer',
390			itemSelector: '.brick',
391			percentPosition: true,
392			gutter: 0,
393			isResizeBound: true
394		})
395		
396		
397	//	var element = document.getElementById("tileactiveid");
398	//	element.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
399			
400		return false;
401	});
402	
403	$(".close").bind("click touchstart", function(){
404	
405		$(".brick").animate({"width": '25%'}, 0).removeClass('tileactive').attr('id', '');;
406				
407		// init Masonry
408		$('.masonry').packery({
409			columnWidth: '.spacer',
410			itemSelector: '.brick',
411			percentPosition: true,
412			gutter: 0,
413			isResizeBound: true
414		});
415		
416		return false;
417	
418	});
419	
420	$(window).resize(function () {
421	
422	if ($(window).width() > 480) {
423		
424		$(".brick").animate({"width": '25%'}, 0).removeClass('tileactive').attr('id', '');;
425				
426		// init Masonry
427		$('.masonry').packery({
428			columnWidth: '.spacer',
429			itemSelector: '.brick',
430			percentPosition: true,
431			gutter: 0,
432			isResizeBound: true
433		});
434		
435		return false;
436	
437	}
438	
439	});
440	
441	
442});
443
444
445jQuery(document).ready(function($) {
446	// homepage links
447
448	jQuery('#skillbuilding a').attr('data-track', 'true').attr('id', 'home_skillbuilding');
449	jQuery('#careerservices a').attr('data-track', 'true').attr('id', 'home_careerservices'); 
450	jQuery('#benefits a').attr('data-track', 'true').attr('id', 'home_benef
450its');
451
452	jQuery('#reentry a').attr('data-track', 'true').attr('id', 'home_reentry');
453	jQuery('#homeless a').attr('data-track', 'true').attr('id', 'home_homeless');
454	jQuery('#veterans a').attr('data-track', 'true').attr('id', 'home_veterans');
455	jQuery('#esl a').attr('data-track', 'true').attr('id', 'home_esl');
456
457	jQuery('#foundations a').attr('data-track', 'true').attr('id', 'home_foundations');
458	jQuery('#corporations a').attr('data-track', 'true').attr('id', 'home_corporations');
459	jQuery('#volunteergroups a').attr('data-track', 'true').attr('id', 'home_volunteergroups');
460	jQuery('#individuals a').attr('data-track', 'true').attr('id', 'home_individuals');
461
462	jQuery('#mc4wp-form-2 input:submit').attr('data-track', 'true').attr('id', 'footer_sign_up');
463	jQuery('#fmenu a').attr('data-track', 'true');
464
465	// Career services
466	jQuery('.page-id-5433 .centered input:submit').attr('data-track', 'true').attr('id', 'career_newsletter_submit');
467
468	// Jobs
469	jQuery('#jobsatgw a').attr('data-track', 'true').attr('id', 'jobs_jobsatgw');
470	
471	// Donate
472	jQuery('#findadonationlocation a').attr('data-track', 'true').attr('id', 'dg_findadonationlocation');
473	jQuery('#whatdonate a').attr('data-track', 'true').attr('id', 'dg_whatdonate');
474	jQuery('#cannotaccept a').attr('data-track', 'true').attr('id', 'dg_cannotaccept');
475	jQuery('#getreceipt a').attr('data-track', 'true').attr('id', 'dg_getreceipt');
476	jQuery('#estimatevalue a').attr('data-track', 'true').attr('id', 'dg_estimatevalue');
477	jQuery('#beloved a').attr('data-track', 'true').attr('id', 'dg_beloved');
478	jQuery('#schedulepickup a').attr('data-track', 'true').attr('id', 'dg_schedulepickup');
479	
480	jQuery('.page-id-6327 #gform_submit_button_2').attr('data-track', 'true');
481	jQuery('.page-id-5752 #gform_submit_button_3').attr('data-track', 'true');
482	jQuery('.page-id-6273 #gform_submit_button_5').attr('data-track', 'true');
483	
484	jQuery('#taskrabbit a').attr('data-track', 'true').attr('id', 'sd_taskrabbit');
485	jQuery('#pickupservice a').attr('data-track', 'true').attr('id', 'sd_pickupservice');
486
487	// Shop
488	jQuery('#womens a').attr('data-track', 'true').attr('id', 'shop_womens');
489	jQuery('#mens a').attr('data-track', 'true').attr('id', 'shop_mens');
490	jQuery('#shoes a').attr('data-track', 'true').attr('id', 'shop_shoes');
491	jQuery('#jewellery a').attr('data-track', 'true').attr('id', 'shop_jewellery');
492	jQuery('#bags a').attr('data-track', 'true').attr('id', 'shop_bags');
493	jQuery('#collectables a').attr('data-track', 'true').attr('id', 'shop_collectables');
494	jQuery('#art a').attr('data-track', 'true').attr('id', 'shop_art');
495	jQuery('#consumerelectronics a').attr('data-track', 'true').attr('id', 'shop_consumerelectronics');
496	jQuery('#allproducts a').attr('data-track', 'true').attr('id', 'shop_allproducts');
497
498	jQuery('#amazon a').attr('data-track', 'true').attr('id', 'shop_amazon');
499	jQuery('#shopgoodwill a').attr('data-track', 'true').attr('id', 'shop_shopgoodwill');
500
501});
502
503
504jQuery(document).ready(function($) {
505
506	// init Packery
507	var $bloggrid = $('#goodwill-grid-loop').packery({
508			columnWidth: '.spacer',
509			itemSelector: '.grid-post',
510			percentPosition: true,
511			gutter: 0,
512			isResizeBound: true
513	});
514	
515	// layout Packery after each image loads
516	$bloggrid.imagesLoaded().progress( function() {
517	  $bloggrid.packery();
518	});
519
520
521});
522
523
524
525jQuery(document).ready(function($) {
526	
527	// Open and focus the search form
528	$( document )
529		.on( 'click keydown', '#signtoggle', function( e ) {
530			if ( e.type == 'keydown' ) {
531				if ( e.keyCode !== 13 ){
532					return;
533				}
534				e.preventDefault();
535			}
536			
537			jQuery("#headersignup").slideToggle("500", "easeInOutCirc");
538			jQuery('#headersignup input[type="email"]').focus();
539			return false;
540		
541		} );
542	
543	var $el, $ps, $up, totalHeight;
544
545	$(".fullcontent .button").click(function() {
546		  
547	  totalHeight = 0
548
549	  $el = $(this);
550	  $p  = $el.parent();
551	  $up = $p.parent();
552	  $ps = $up.find("p:not('.read-more')");
553	  
554	  // measure how tall inside should be by adding together heights of all inside paragraphs (except read-more paragraph)
555	  $ps.each(function() {
556		totalHeight += $(this).outerHeight();
557	  });
558			
559	  $up
560		.css({
561		  // Set height to prevent instant jumpdown when max height is removed
562		  "height": $up.height(),
563		  "max-height": 9999
564		})
565		.animate({
566		  "height": totalHeight
567		});
568	  
569	  // fade out read-more
570	  $p.fadeOut();
571	  
572	  // prevent jump-down
573	  return false;
574 
575	});
576 });

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.