PageSourceSearch

https://manheimbic.org/wp-content/themes/maranatha/js/main.js?ver=2.6

js manheimbic.org collected 2026-10-06 18:57:01 UTC 36,992 bytes, 1,296 lines download raw bytes

1/**
2 * Main JavaScript
3 */
4
5// Max width for mobile
6var maranatha_mobile_width = 700; // match value in _media-queries.scss
7
8// Stop Edge browser from linking phone numbers.
9// Later, when possible, style the links instead of removing.
10if (/Edge/.test(navigator.userAgent)) {
11	jQuery('head').append('<meta name="format-detection" content="telephone=no">');
12}
13
14// DOM is fully loaded
15jQuery(document).ready(function ($) {
16
17	/**********************************************
18	 * LAYOUT
19	 **********************************************/
20
21	/*---------------------------------------------
22	 * Viewport Units
23	 *--------------------------------------------*/
24
25	// Buggyfill to help correct vh units on old iOS Safari, Android and IE
26	window.viewportUnitsBuggyfill.init({
27		refreshDebounceWait: 50,
28		hacks: window.viewportUnitsBuggyfillHacks
29	});
30
31	/*---------------------------------------------
32	 * Header Top
33	 *--------------------------------------------*/
34
35	// Show narrow header top bar when scroll down
36	$(window).on('scroll', function () {
37
38		// Not on mobile devices
39		if ($(window).width() <= maranatha_mobile_width) {
40			return;
41		}
42
43		// Scroll down, show narrow top bar
44		if ($(document).scrollTop() > 0) {
45			$('.maranatha-not-scrolled #maranatha-header-top').show();
46		}
47
48		// Scroll up, show full top bar
49		else {
50			$('.maranatha-scrolled #maranatha-header-top').show();
51		}
52
53	});
54
55	/*---------------------------------------------
56	 * Header Menu
57	 *--------------------------------------------*/
58
59	setTimeout(function () { // helps with mobile menu icon position old iOS
60		maranatha_activate_menu();
61	}, 50);
62
63	/*---------------------------------------------
64	 * Header Search
65	 *--------------------------------------------*/
66
67	// Open Search
68	$('#maranatha-header-search-open').on('click', function (e) {
69
70		// Stop regular click action
71		e.preventDefault();
72
73		// Lock logo width/height to keep it from sizing up when search is opened and hidden menu gives it more space
74		// The restraint should be removed on closing search
75		maranatha_search_lock_logo();
76
77		// Add body class for "search is open"
78		// See media queries for hiding logo on mobile
79		jQuery('body').addClass('maranatha-search-is-open');
80
81		// Focus on search input
82		$('#maranatha-header-search input').focus();
83
84	});
85
86	// Close Search
87	$('#maranatha-header-search-close').on('click', function (e) {
88
89		// Stop regular click action
90		e.preventDefault();
91
92		// Unlock logo width/height
93		maranatha_search_lock_logo('unlock');
94
95		// Remove body class for "search is open"
96		jQuery('body').removeClass('maranatha-search-is-open');
97
98		// Snap mobile menu icon into proper position
99		$(window).trigger('resize');
100
101	});
102
103	/*---------------------------------------------
104	 * Header Archives (Dropdowns)
105	 *--------------------------------------------*/
106
107	if ($('#maranatha-header-archives').length) {
108
109		// Loop top-level links
110		$('a.maranatha-header-archive-top-name').each(function () {
111
112			var $link, $dropdown, dropdown_id;
113
114			$link = $(this);
115			$dropdown = $link.next('.maranatha-header-archive-dropdown');
116			dropdown_id = $dropdown.attr('id');
117
118			// Move it to before </body> where jQuery Dropdown works best
119			$dropdown.appendTo('body');
120
121			// Attach dropdown to control
122			$link.dropdown('attach', '#' + dropdown_id);
123
124		});
125
126	}
127
128	/*---------------------------------------------
129	 * Footer Stickies
130	 *--------------------------------------------*/
131
132	// Show latest events, comments, etc.
133	// Hide stickies when scroll to/from footer to prevent covering copyright, etc.
134	// Also hide on homepage when not scrolled beneath the first section
135	maranatha_show_footer_stickies();
136	$(window).on('scroll', maranatha_show_footer_stickies);
137
138	/*---------------------------------------------
139	 * Search Forms (Header, Widget, etc.)
140	 *--------------------------------------------*/
141
142	// Trim search query and stop if empty
143	// Note: This presently has no effect on mobile menu (see notes above; same cause)
144	$('.maranatha-search-form form').on('submit', function (event) {
145
146		var s;
147
148		s = $('input[name=s]', this).val().trim();
149
150		if (s.length) { // submit trimmed value
151			$('input[name=s]', this).val(s);
152		} else { // empty, stop
153			event.preventDefault();
154		}
155
156	});
157
158	/*---------------------------------------------
159	 * Scrolling
160	 *--------------------------------------------*/
161
162	// Scroll to comments or any other anchor
163	var hash = window.location.hash;
164	if (hash) {
165
166		// Scroll down
167		$.smoothScroll({
168			scrollTarget: hash,
169			offset: -120, // consider sticky bar
170			easing: 'swing',
171			speed: 1200,
172		});
173
174	}
175
176	/*---------------------------------------------
177	 * Homepage
178	 *--------------------------------------------*/
179
180	if ($('.page-template-homepage').length) {
181
182		// Fade in first section
183		if (!maranatha_is_mobile()) { // not on mobile (better performance)
184			$('#maranatha-home-section-1').hide().css('visibility', 'visible').fadeIn(600);
185		} else {
186			$('#maranatha-home-section-1').hide().css('visibility', 'visible').show();
187		}
188
189		// Show video background on non-mobile and image on mobile
190		// iOS and most Android don't support video so don't cause MP4 to download
191		// Also keeps Vide poster image from flickering in before video plays
192		// Note: 1024 is iPad landscape; virtually all laptops are larger: http://ux.stackexchange.com/a/41474
193		var show_video = true;
194		if (maranatha_is_mobile() || (typeof window.matchMedia !== 'undefined' && window.matchMedia('only screen and (max-device-width: 1024px)').matches)) { // by resolution just in case (IE9 doesn't support matchMedia)
195			show_video = false;
196		}
197
198		// Get video file
199		var video_url = $('#maranatha-home-section-video-vide').data('video-url');
200
201		// Regular Display
202		if (show_video && video_url) {
203
204			// Image background is already hidden since video is in use
205
206			// Show Vide video background
207			$('#maranatha-home-section-video-vide').vide({
208				mp4: video_url
209			}, {
210				posterType: 'none',
211				position: 'center center'
212			});
213
214			// Fade video in
215			$('#maranatha-home-section-video-vide').data('vide').getVideoObject().onloadeddata = function () {
216
217				// Make auto-play work in Safari 11
218				// https://github.com/vodkabears/Vide/issues/206#issuecomment-332625880
219				$('#maranatha-home-section-video-vide').data('vide').getVideoObject().play();
220
221				// Fade in
222				$(this).parent().hide().fadeIn(600);
223
224			}
225
226		}
227
228		// Mobile Device (or no video file)
229		// No video, iOS and most Android don't support in background
230		// Show image in background as usual
231		else {
232
233			// Hide video color overlay
234			$('#maranatha-home-section-video-color').hide();
235
236			// Show regular bg img element
237			// By default it's hidden when video exists and not on mobile
238			$('#maranatha-home-section-video-vide').parent().siblings('.maranatha-home-section-image').show();
239
240		}
241
242
243	}
244
245	/*---------------------------------------------
246	 * Post Navigation
247	 *--------------------------------------------*/
248
249	// Make nav blocks on single posts click anywhere
250	$('.maranatha-nav-block').on('click', function () {
251
252		var url;
253
254		url = $('.maranatha-nav-block-title', this).prop('href');
255
256		if (url) {
257			window.location = url;
258		}
259
260	});
261
262	// Brighten on hover
263	$('.maranatha-nav-block').hover(function (e) {
264
265		var $image, new_opacity;
266
267		$image = $('.maranatha-nav-block-image', this);
268
269		if ($image.length) {
270
271			// Get original opacity on first hover
272			if ('mouseenter' == e.type) {
273
274				opacity = $image.css('opacity'); // global
275				new_opacity = opacity * 1.75; // increase by 75%
276
277				$image.fadeTo(0, new_opacity);
278
279			}
280
281			else {
282				$image.fadeTo(0, opacity);
283			}
284
285		}
286
287	});
288
289	/*---------------------------------------------
290	 * Entries
291	 *--------------------------------------------*/
292
293	// Regular narrow template only.
294	if ($('.maranatha-content-width-700').length) {
295
296		// Add class to images in full content big enough to make exceed content width.
297		$('img.alignnone, img.aligncenter', $('.maranatha-entry-full-content > p')).each(function () {
298
299			var img_width;
300
301			img_width = parseFloat($(this).attr('width'));
302
303			if (img_width >= 980) {
304				$(this).parents('p').addClass('maranatha-image-exceed-700-980');
305			}
306
307		});
308
309
310		// Add class to wide Gutenberg elements that are NOT a container (and put them in container).
311		$('.wp-block-cover.alignwide, .wp-block-cover.alignfull, .wp-block-columns.alignwide, .wp-block-columns.alignfull, .wp-block-table.alignwide, .wp-block-table.alignfull, .wp-block-tag-cloud.alignwide, .wp-block-tag-cloud.alignfull', $('.maranatha-entry-full-content')).each(function () {
312
313			// Add container before element.
314			var $container = $('<div class="maranatha-image-exceed-700-980 maranatha-block-wide-container"></div>');
315			$(this).after($container);
316
317			// Move element into container.
318			$(this).appendTo($container);
319
320		});
321
322		// Add class to wide Gutenberg elements that ARE in a container.
323		$('.wp-block-image.alignwide, .wp-block-image.alignfull, .wp-block-gallery.alignwide, .wp-block-gallery.alignfull, .wp-block-embed.alignwide, .wp-block-embed.alignfull, .wp-block-video.alignwide, .wp-block-video.alignfull, .wp-block-audio.alignwide, .wp-block-audio.alignfull, .wp-block-pullquote.alignwide, .wp-block-pullquote.alignfull, .wp-block-media-text.alignwide, .wp-block-media-text.alignfull', $('.maranatha-entry-full-content')).each(function () {
324			$(this).addClass('maranatha-image-exceed-700-980');
325		});
326
327	}
328
329	// Hide empty footer element (ie. no button)
330
331	$('.maranatha-entry-short-footer').each(function () {
332		if (0 == $(this).children().length) {
333			$(this).hide();
334		}
335	});
336
337	/*---------------------------------------------
338	 * Sermons
339	 *--------------------------------------------*/
340
341	if ($('.single-ctc_sermon').length) {
342
343		// Scroll down to article when "Read" is clicked
344		$('#maranatha-sermon-read-button a').on('click', function (e) {
345
346			var buttons_bottom;
347
348			e.preventDefault();
349
350			buttons_bottom = $('#maranatha-sermon-buttons').position().top + $('#maranatha-sermon-buttons').outerHeight();
351
352			$.smoothScroll({
353				offset: buttons_bottom - 10,
354				easing: 'swing',
355				speed: 1200,
356			});
357
358		});
359
360		// Dropdown for download links on Save button
361		$('#maranatha-sermon-download-button a')
362			.dropdown('attach', '#maranatha-sermon-download-dropdown');
363
364	}
365
366	/*---------------------------------------------
367	 * Single Event
368	 *--------------------------------------------*/
369
370	// Single event only
371	if ($('.maranatha-event-full').length) {
372
373		// Recurrence tooltip
374		$('#maranatha-event-recurrence a, #maranatha-event-excluded-dates a').tooltipster({
375			theme: 'maranatha-tooltipster',
376			arrow: false,
377			animation: 'fade',
378			speed: 0, // fade speed
379		}).on('click', function (e) {
380			e.preventDefault(); // stop clicks
381		});
382
383	}
384
385	/*---------------------------------------------
386	 * Events Calendar
387	 *--------------------------------------------*/
388
389	// Calendar template only
390	if ($('#maranatha-calendar').length) {
391
392		// Attach dropdowns to controls
393		maranatha_attach_calendar_dropdowns();
394
395		// AJAX-load event calendar when use controls
396		// This keeps page from reloading and scrolling to top
397		// PJAX updates URL, <title> and browser/back history
398		$(document).pjax('.maranatha-calendar-control, .maranatha-calendar-dropdown a', '#maranatha-calendar', {
399			fragment: '#maranatha-calendar', // replace only the calendar
400			scrollTo: false, // don't scroll to top after loading
401			timeout: 5000, // page reloads after timeout (default 650)
402		});
403
404		// Loading indicator
405		$(document).on('pjax:send', function () {
406			$('.maranatha-calendar-dropdown-control').dropdown('hide'); // hide controls
407			$('#maranatha-calendar-loading').show();
408		})
409		$(document).on('pjax:complete', function () {
410			$('#maranatha-calendar-loading').hide();
411		})
412
413		// After contents replaced
414		$(document).on('pjax:success', function () {
415
416			// Re-attach dropdowns to controls
417			maranatha_attach_calendar_dropdowns();
418
419			// Re-activate tooltip hovering
420			maranatha_activate_calendar_hover();
421
422		});
423
424		// Hide dropdowns on back/forward
425		$(document).on('pjax:popstate', function (e) {
426			if (e.direction) {
427				$('.maranatha-calendar-dropdown-control').dropdown('hide');
428			}
429		});
430
431		// Use Tooltipster to show event hover for each link
432		maranatha_activate_calendar_hover();
433
434		// Handle mobile clicks on linked days
435		$(document).on('click', 'a.maranatha-calendar-table-day-number', function (e) {
436
437			var $day, $events, date_formatted, scroll_offset;
438
439			e.preventDefault();
440
441			// Get day cell
442			$day = $(this).parents('td');
443
444			// Show heading for date
445			date_formatted = $day.attr('data-date-formatted');
446			$('#maranatha-calendar-list h3:first-of-type').remove();
447			$('#maranatha-calendar-list').prepend('<h3 id="maranatha-calendar-list-heading">' + date_formatted + '</h3>');
448			$('#maranatha-calendar-list-heading').show();
449
450			// Hide all events in list and show list container
451			$('#maranatha-calendar-list .maranatha-event-short').hide();
452			$('#maranatha-calendar-list').show();
453
454			// Show all events for this day
455			$events = $('.maranatha-calendar-table-day-events li', $day);
456			$events.each(function () {
457
458				var event_id;
459
460				// Get event ID
461				event_id = $(this).attr('data-event-id');
462
463				// Show that event in list
464				$('#maranatha-calendar-list .maranatha-event-short[data-event-id="' + event_id + '"]').show();
465
466			});
467
468			// Scroll down if events are out of view
469			// Otherwise user sees no change
470			if (!$('#maranatha-calendar-list-heading').visible()) {
471
472				// Scroll events into bottom of screen
473				scroll_offset = 0 - $(window).height() + 150; // negative
474
475				$.smoothScroll({
476					scrollTarget: '#maranatha-calendar-list-heading',
477					offset: scroll_offset,
478					easing: 'swing',
479					speed: 800
480				});
481
482			}
483
484		});
485
486	}
487
488	/*---------------------------------------------
489	 * People
490	 *--------------------------------------------*/
491
492	// People archive or page template
493	// This keeps it from being applied on search results or elsehwere
494	if ($('.maranatha-person-short').length && ($('.page-template-people').length || $('.tax-ctc_person_group').length || $('.post-type-archive-ctc_person').length)) {
495		$('.maranatha-person-short').matchHeight();
496	};
497
498	/*---------------------------------------------
499	 * Galleries
500	 *--------------------------------------------*/
501
502	// Give each gallery item same height to avoid gaps / awkward wrapping
503	if ($('.gallery-icon img').length) {
504		$('.gallery-icon img').matchHeight();
505	}
506
507	// Same for gallery index (caption images)
508	if ($('.maranatha-galleries-list .maranatha-caption-image').length) {
509		$('.maranatha-galleries-list .maranatha-caption-image').matchHeight();
510	}
511
512	// Make clicks on caption also go to URL
513	$('.gallery-caption').on('click', function () {
514
515		var $parent, url;
516
517		$parent = $(this).parent();
518		url = $('a', $parent).prop('href');
519
520		// Go to URL if no data- attributes, which indicate Jetpack Carousel or possbily other lightbox
521		if (url && $.isEmptyObject($('.gallery-icon img', $parent).data())) {
522			window.location = url;
523		}
524
525	});
526
527	/*---------------------------------------------
528	 * Buttons
529	 *--------------------------------------------*/
530
531	// Use theme styles for Gutenberg buttons.
532	$('.wp-block-button').each(function () {
533
534		var align_class = '';
535		if ($(this).hasClass('alignleft')) {
536			align_class = 'alignleft';
537		} else if ($(this).hasClass('alignright')) {
538			align_class = 'alignright';
539		} else if ($(this).hasClass('aligncenter')) {
540			align_class = 'aligncenter';
541		}
542
543		// Get button link.
544		if ($('a', this).length) {
545			var $button_link = $('a', this);
546		} else if ($('button', this).length) {
547			var $button_link = $('button', this);
548		}
549
550		// Remove class and style from button.
551		$button_link
552			.removeClass()
553			.removeAttr('style', '') // color.
554			.addClass('maranatha-button')
555			.addClass('maranatha-button-block')
556			.addClass(align_class);
557
558		// Move button outside of container then remove container.
559		$(this)
560			.after($button_link)
561			.remove();
562
563		// Show button (hidden in style.css).
564		$button_link.css('visibility', 'visible')
565
566	});
567
568	// Use theme styled button for search.
569	$('.wp-block-search__button').each(function () {
570		$(this)
571			.addClass('maranatha-button')
572			.removeClass('wp-block-search__button');
573	});
574
575	/*---------------------------------------------
576	 * Comments
577	 *--------------------------------------------*/
578
579	// Scroll to comments on click Comments sticky or comment permalink
580	if ($('a.maranatha-scroll-to-comments').length) {
581		$('a.maranatha-scroll-to-comments, a[href*=comment]').smoothScroll({
582			offset: -120, // consider sticky bar
583			easing: 'swing',
584			speed: 1200,
585		});
586	}
587
588	// Comment Validation using jQuery Validation Plugin by Jörn Zaefferer
589	// http://bassistance.de/jquery-plugins/jquery-plugin-validation/
590	if (jQuery().validate) { // if plugin loaded
591
592		var $validate_params, $validate_comment_field;
593
594		// Parameters
595		$validate_params = {
596			rules: {
597				author: {
598					required: maranatha_main.comment_name_required !== '' ? true : false // if WP configured to require
599				},
600				email: {
601					required: maranatha_main.comment_email_required !== '' ? true : false, // if WP configured to require
602					email: true // check validity
603				},
604				url: 'url' // optional but check validity
605			},
606			messages: { // localized error strings
607				author: maranatha_main.comment_name_error_required,
608				email: {
609					required: maranatha_main.comment_email_error_required,
610					email: maranatha_main.comment_email_error_invalid
611				},
612				url: maranatha_main.comment_url_error_invalid
613			}
614		};
615
616		// Comment textarea
617		// Use ID instead of name to work with Antispam Bee plugin which duplicates/hides original textarea
618		$validate_comment_field = $('#comment').attr('name');
619		$validate_params['rules'][$validate_comment_field] = 'required';
620		$validate_params['messages'][$validate_comment_field] = maranatha_main.comment_message_error_required;
621
622		// Validate the form
623		$('#commentform').validate($validate_params);
624
625	}
626
627	/*---------------------------------------------
628	 * Widgets
629	 *--------------------------------------------*/
630
631	// Categories dropdown redirect
632	$('.maranatha-dropdown-taxonomy-redirect').on('change', function () {
633
634		var taxonomy, term_id;
635
636		taxonomy = $(this).prev('input[name=taxonomy]').val();
637		term_id = $('option:selected', this).val();
638
639		if (taxonomy && term_id && -1 != term_id) {
640			location.href = maranatha_main.home_url + '/?redirect_taxonomy=' 
640+ taxonomy + '&redirect_term_id=' + term_id;
641		}
642
643	});
644
645	/*---------------------------------------------
646	 * List Item Counts
647	 *--------------------------------------------*/
648
649	// Modify list item counts
650	// This includes widgets and sermon topics, etc. indexes using wp_list_categories()
651	// Change (#) into <span class="maranatha-list-item-count">#</span> so it can be styled
652	var $list_items = $('.maranatha-list li, .maranatha-sermon-index-list li, .widget_categories li, .widget_ctfw-categories li, .widget_ctfw-archives li, .widget_ctfw-galleries li, .widget_recent_comments li, .widget_archive li, .widget_pages li, .widget_links li, .widget_nav_menu li, .widget_meta li');
653	for (var i = 0; i < $list_items.length; i++) {
654
655		$list_items.each(function () {
656
657			var modified_count;
658
659			// Manipulate it
660			modified_count = $(this).html().replace(/(<\/a>.*)\(([0-9]+)\)/, '$1 <span class="maranatha-list-item-count">$2</span>');
661
662			// Replace it
663			$(this).html(modified_count);
664
665		});
666
667	}
668	$list_items.parent('ul').css('visibility', 'visible');
669
670	/*---------------------------------------------
671	 * CSS Classes
672	 *--------------------------------------------*/
673
674	// <body> classes for client detection (mobile, browser, etc.) should be done here with JS
675	// instead of in body.php so that they work when caching plugins are used.
676
677	// Scrolled down or not
678
679	// On load
680	if ($(document).scrollTop() > 0) {
681
682		$('body')
683			.removeClass('maranatha-not-scrolled')
684			.addClass('maranatha-scrolled')
685			.addClass('maranatha-loaded-scrolled');
686
687	} else {
688
689		$('body')
690			.addClass('maranatha-not-scrolled');
691
692	}
693
694	// User scrolled
695	$(window).on('scroll', function () {
696
697		if ($(document).scrollTop() > 0) {
698
699			$('body')
700				.removeClass('maranatha-loaded-scrolled')
701				.removeClass('maranatha-not-scrolled')
702				.addClass('maranatha-scrolled');
703
704		} else {
705
706			$('body')
707				.removeClass('maranatha-scrolled')
708				.addClass('maranatha-not-scrolled');
709
710		}
711
712	});
713
714	// Mobile Detection
715	// Useful for :hover issue with slider video play icon (some browsers handle it better than others)
716	if (maranatha_is_mobile()) {
717		$('body').addClass('maranatha-is-mobile');
718	} else {
719		$('body').addClass('maranatha-not-mobile');
720	}
721
722	// iOS Detection
723	// Especially useful for re-styling form submit buttons, which iOS takes too much liberty with
724	if (navigator.userAgent.match(/iPad|iPod|iPhone|iWatch/)) {
725		$('body').addClass('maranatha-is-ios');
726	} else {
727		$('body').addClass('maranatha-not-ios');
728	}
729
730	// Showing singe post nav
731	if ($('.maranatha-nav-blocks').length) {
732		$('body').addClass('maranatha-has-nav-blocks');
733	} else {
734		$('body').addClass('maranatha-no-nav-blocks');
735	}
736
737	// Showing comments section
738	if ($('#comments').length) {
739		$('body').addClass('maranatha-has-comments-section');
740	} else {
741		$('body').addClass('maranatha-no-comments-section');
742	}
743
744	// Showing full entry map
745	if ($('.maranatha-entry-full-map').length) {
746		$('body').addClass('maranatha-has-entry-map');
747	} else {
748		$('body').addClass('maranatha-no-entry-map');
749	}
750
751	// Section map has info box
752	if ($('#maranatha-map-section-info').length) {
753		$('body').addClass('maranatha-has-map-info');
754	} else {
755		$('body').addClass('maranatha-no-map-info');
756	}
757
758	// Has header bottom bar (breadcrumbs / archive dropdowns)
759	if ($('#maranatha-header-bottom').length) {
760		$('body').addClass('maranatha-has-header-bottom');
761	} else {
762		$('body').addClass('maranatha-no-header-bottom');
763	}
764
765});
766
767/**********************************************
768 * FUNCTIONS
769 **********************************************/
770
771/*---------------------------------------------
772 * Menu Functions
773 *--------------------------------------------*/
774
775var $maranatha_header_menu_raw; // make accessible to maranatha_activate_menu() later
776
777// Activate Menu Function
778// Also used in Customizer admin preview JS
779function maranatha_activate_menu() {
780
781	var $header_menu_raw_list, $header_menu_raw_items;
782
783	// Continue if menu not empty
784	if (!jQuery('#maranatha-header-menu-content').children().length) {
785		return;
786	}
787
788	// Make copy of menu contents before Superfish modified
789	// Original markup works better with MeanMenu (less Supersubs and styling issues)
790	if (!jQuery($maranatha_header_menu_raw).length) { // not done already
791		$maranatha_header_menu_raw = jQuery('<div></div>'); // Create empty div
792		$header_menu_raw_list = jQuery('<ul></ul>'); // Create empty list
793		$header_menu_raw_items = jQuery('#maranatha-header-menu-content').html(); // Get menu items
794		$header_menu_raw_list = $header_menu_raw_list.html($header_menu_raw_items); // Copy items to empty list
795		$maranatha_header_menu_raw = $maranatha_header_menu_raw.html($header_menu_raw_list); // Copy list to div
796	}
797
798	// Regular Menu (Superfish)
799	jQuery('#maranatha-header-menu-content').supersubs({ // Superfish dropdowns
800		minWidth: 14.5,	// minimum width of sub-menus in em units
801		maxWidth: 14.5,	// maximum width of sub-menus in em units
802		extraWidth: 1	// extra width can ensure lines don't sometimes turn over due to slight rounding differences and font-family
803	}).superfish({
804		delay: 150,
805		disableHI: false,
806		animation: {
807			opacity: 'show',
808			//height:'show'
809		},
810		speed: 0, // animation
811		onInit: function () {
812
813			// Responsive Menu (MeanMenu) for small screens
814			// Replaces regular menu with responsive controls
815			// Init after Superfish done because Supersubs needs menu visible for calculations
816			jQuery($maranatha_header_menu_raw).meanmenu({
817				meanMenuContainer: '#maranatha-header-mobile-menu',
818				meanScreenWidth: maranatha_mobile_width, // use CSS media query to hide #maranatha-header-menu-content at same size
819				meanRevealPosition: 'right',
820				meanRemoveAttrs: true, // remove any Superfish classes, duplicate item ID's, etc.
821				meanMenuClose: '<i class="' + maranatha_main.mobile_menu_close + '"></i>',
822				meanExpand: '+',
823				meanContract: '-',
824				//removeElements: '#maranatha-header-menu-inner' // toggle visibility of regular
825			});
826
827			// Set open/close height same as logo and position top same as logo, so vertically centered
828			// Also insert search into mobile menu
829			// And again on resize in case logo changes height of bar
830			maranatha_activate_mobile_menu();
831			jQuery(window).on('resize', function () {
832				maranatha_activate_mobile_menu();
833			});
834
835		},
836		onBeforeShow: function () {
837
838			// Make dropdowns on right open to the left if will go off screen
839			// This considers that the links may have wrapped and dropdowns may be mobile-size
840
841			var $link, $dropdown, $dropdown_width, $offset;
842
843			// Detect if is first-level dropdown and if not return
844			if (jQuery(this, '#maranatha-header-menu-content').parents('li.menu-item').length != 1) {
845				return;
846			}
847
848			// Top-level link hovered on
849			$link = jQuery(this).parents('#maranatha-header-menu-content > li.menu-item');
850
851			// First-level dropdown
852			$dropdown = jQuery('> ul', $link);
853
854			// First-level dropdown width
855			$dropdown_width = $dropdown.outerWidth();
856			$dropdown_width_adjusted = $dropdown_width - 20; // compensate for left alignment
857
858			// Remove classes first in case don't need anymore
859			$link.removeClass('maranatha-dropdown-align-right maranatha-dropdown-open-left');
860
861			// Get offset between left side of link and right side of window
862			$offset = jQuery(window).width() - $link.offset().left;
863
864			// Is it within one dropdown length of window's right edge?
865			// Add .maranatha-dropdown-align-right to make first-level dropdown not go off screen
866			if ($offset < $dropdown_width_adjusted) {
867				$link.addClass('maranatha-dropdown-align-right');
868			}
869
870			// Is it within two dropdown lengths of window's right edge?
871			// Add .maranatha-dropdown-open-left to open second-level dropdowns left: https://github.com/joeldbirch/superfish/issues/98
872			if ($offset < ($dropdown_width_adjusted * 2)) {
873				$link.addClass('maranatha-dropdown-open-left');
874			}
875
876		},
877
878	});
879
880}
881
882// Set open/close height same as logo and position top same as logo, so vertically centered
883// Also insert search into mobile menu
884function maranatha_activate_mobile_menu() {
885
886	var $logo, move_up;
887
888	if (jQuery('.mean-container .mean-bar').length) {
889
890		// Move mobile search container into bottom of mobile menu
891		if (jQuery('#maranatha-header-search').length && !jQuery('#maranatha-header-search-mobile').length) {
892			jQuery('.mean-nav > ul').append('<li id="maranatha-header-search-mobile" role="search">' + jQuery('#maranatha-header-search .maranatha-search-form').html() + '</li>');
893		}
894
895		// Get logo
896		$logo = jQuery('#maranatha-logo');
897
898		// Move up to half of logo height
899		move_up = $logo.offset().top - jQuery('.mean-container .mean-bar').offset().top + ($logo.outerHeight() / 2);
900
901		// Do not move again if already in place
902		if (move_up != 0) {
903
904			jQuery('.mean-container .mean-bar')
905				.height($logo.outerHeight())
906				.css('top', move_up + 'px');
907
908		}
909
910	}
911
912}
913
914// Lock logo width/height to keep it from sizing up when search is opened and hidden menu gives it more space
915// The restraint should be removed on closing search
916function maranatha_search_lock_logo(action) {
917
918	var action;
919
920	if (!action) {
921		action = 'lock';
922	}
923
924	// Lock
925	if ('lock' == action) {
926
927		jQuery('#maranatha-logo')
928			.width(jQuery('#maranatha-logo').width() + 'px')
929			.height(jQuery('#maranatha-logo').height() + 'px');
930
931	}
932
933	// Unlock
934	else if ('unlock' == action) {
935
936		jQuery('#maranatha-logo')
937			.width('auto')
938			.height('auto');
939
940	}
941
942}
943
944/*---------------------------------------------
945 * Footer Stickies
946 *--------------------------------------------*/
947
948// Show latest events, comments, etc.
949// Hide stickies when scroll to/from footer to prevent covering copyright, etc.
950// Also hide on homepage when not scrolled beneath the first section
951function maranatha_show_footer_stickies() {
952
953	var scroll_bottom, bottom_of_first, top_of_footer, show;
954
955	show = true;
956	scroll_bottom = jQuery(window).scrollTop() + jQuery(window).height();
957
958	// Hide on homepage when not scrolled beneath the first section
959	if (jQuery('#maranatha-home-section-1').length) {
960
961		bottom_of_first = jQuery('#maranatha-home-section-1').outerHeight();
962
963		// Show when below first section
964		if (scroll_bottom <= bottom_of_first) {
965			show = false;
966		}
967
968	}
969
970	// Hide when below top of last footer element (widgets, map or bottom bar)
971	top_of_footer = jQuery(document).height() - jQuery('#maranatha-footer > *:last-child').height();
972	if (scroll_bottom > top_of_footer) {
973		show = false;
974	}
975
976	// Do show/hide
977	if (show) {
978		jQuery('#maranatha-stickies').show();
979	} else {
980		jQuery('#maranatha-stickies').hide();
981	}
982
983}
984
985/*---------------------------------------------
986 * Fonts
987 *--------------------------------------------*/
988
989// Change <body> helper font/setting class
990// Used by Theme Customizer (and front-end demo customizer)
991function maranatha_update_body_font_class(setting, font) {
992
993	var setting_slug, font_slug, body_class;
994
995	// Prepare strings
996	setting_slug = setting.replace(/_/g, '-');
997	font_slug = font.toLowerCase().replace(/\s/g, '-'); // spaces to -
998	body_class = 'maranatha-' + setting_slug + '-' + font_slug;
999
1000	// Remove old class
1001	jQuery('body').removeClass(function (i, css_class) { // helpful information: http://bit.ly/1f7KH3f
1002		return (css_class.match(new RegExp('\\b\\S+-' + setting_slug + '-\\S+', 'g')) || []).join(' ');
1003	})
1004
1005	// Add new class
1006	jQuery('body').addClass(body_class);
1007
1008}
1009
1010/*---------------------------------------------
1011 * Map Section
1012 *--------------------------------------------*/
1013
1014// Position Google Map on homepage and footer
1015// Also run on resize to keep things in proper place
1016function maranatha_position_map_section() {
1017
1018	// Delay improves resize accuracy
1019	setTimeout(function () {
1020
1021		var map, latlng, map_width, map_center, offset_left, marker_width, pan_x, pan_y;
1022
1023		map = jQuery('#maranatha-map-section-canvas').data('ctfw-map');
1024		latlng = jQuery('#maranatha-map-section-canvas').data('ctfw-map-latlng');
1025
1026		// Reset location to center
1027		map.setCenter(latlng);
1028
1029		// Move center left to be directly under marker icon
1030		if (jQuery('#maranatha-map-section-info').length) {
1031
1032			map_width = jQuery('.maranatha-map-section').width();
1033			map_center = map_width / 2;
1034			offset_left = jQuery('#maranatha-map-section-marker').offset().left;
1035			marker_width = jQuery('#maranatha-map-section-marker').width();
1036			pan_x = map_center - (offset_left + (marker_width / 2)); // half of marker width is its center
1037
1038			// Pan map down when have breadcrumb/archive nav bar and showing map on event/location
1039			// This offsets the marker position after moving marker / info box down to make room for breadcrumb bar
1040			pan_y = 0;
1041			if (jQuery('.maranatha-entry-full-map').length && jQuery('#maranatha-header-bottom').length) {
1042
1043				// Important: Also change value in .maranatha-has-header-bottom & #maranatha-map-section-content > *
1044				pan_y = -25;
1044 // half of .maranatha-has-header-bottom & #maranatha-map-section-content > *
1045
1046			}
1047
1048			map.panBy(pan_x, pan_y);
1049
1050		}
1051
1052	}, 10);
1053
1054}
1055
1056/*---------------------------------------------
1057 * Event Calendar
1058 *--------------------------------------------*/
1059
1060// Attach calendar dropdowns to controls
1061// Used on load and after PJAX replaces content
1062function maranatha_attach_calendar_dropdowns() {
1063
1064	// Remove it from before </body> if already exists (old before PJAX)
1065	jQuery('body > #maranatha-calendar-month-dropdown').remove();
1066	jQuery('body > #maranatha-calendar-category-dropdown').remove();
1067
1068	// Move it from calendar container to before </body>
1069	// jQuery Dropdown works best with it there
1070	// But need it in main calendar container for PJAX to get new contents of dropdowns
1071	jQuery('#maranatha-calendar-month-dropdown').appendTo('body');
1072	jQuery('#maranatha-calendar-category-dropdown').appendTo('body');
1073
1074	// Re-attach dropdown to control
1075	jQuery('#maranatha-calendar-month-control').dropdown('attach', '#maranatha-calendar-month-dropdown');
1076	jQuery('#maranatha-calendar-category-control').dropdown('attach', '#maranatha-calendar-category-dropdown');
1077
1078}
1079
1080// Use Tipster to show calendar's event hover for each link
1081function maranatha_activate_calendar_hover() {
1082
1083	// Use Tipster to show event hover for each link
1084	jQuery('#maranatha-calendar .maranatha-event-short').each(function () {
1085
1086		var event_id;
1087
1088		// Get ID
1089		event_id = jQuery(this).attr('data-event-id');
1090
1091		// Activate tooltips on links having that ID
1092		if (event_id) {
1093
1094			jQuery('.maranatha-calendar-table-day-events a[data-event-id="' + event_id + '"]').tooltipster({
1095				theme: 'maranatha-tooltipster-calendar',
1096				content: jQuery(this),
1097				contentCloning: true,
1098				functionInit: function (origin, content) {
1099
1100					var date_formatted;
1101
1102					// Get localized date from calendar
1103					date_formatted = jQuery(origin).parents('td').attr('data-date-formatted');
1104
1105					// Add date to the tooltip
1106					jQuery('.maranatha-event-short-date-range', content).html(date_formatted);
1107
1108					return content;
1109
1110				},
1111				minWidth: 300,
1112				maxWidth: 600,
1113				touchDevices: false, // no hovers on touch (including w/mouse; otherwise pure touch opens + goes)
1114				interactive: true, // let them click on tooltip
1115				arrow: false,
1116				delay: 50,
1117				animation: 'fade',
1118				speed: 0, // fade speed
1119				onlyOne: true, // immediately close other tooltips when opening
1120			});
1121
1122		}
1123
1124	});
1125
1126}
1127
1128/*---------------------------------------------
1129 * Detection
1130 *--------------------------------------------*/
1131
1132// Is device mobile?
1133// The regex below is based on wp_is_mobile() -- good enough for most
1134// "Mobile" will handle iOS devices and many others
1135function maranatha_is_mobile() {
1136	return navigator.userAgent.match(/Mobile|Android|Silk\/|Kindle|BlackBerry|Opera Mini|Opera Mobi/)
1137}
1138
1139/*---------------------------------------------
1140 * Google Maps
1141 *--------------------------------------------*/
1142
1143// Global marker image
1144var ctfw_map_marker_image = maranatha_main.theme_url + '/images/map-marker.png';
1145var ctfw_map_marker_image_hidpi = maranatha_main.theme_url + '/images/[email protected]';
1146var ctfw_map_marker_image_width = 69; // only necessary when providing HiDPI image
1147var ctfw_map_marker_image_height = 69;
1148
1149// Custom map styles that are more minimal and flat than default ROADMAP
1150// This is applied globally to all maps using framework integration
1151var ctfw_map_styles = [
1152
1153	// Lighten BG
1154	{
1155		"featureType": "landscape",
1156		"elementType": "geometry",
1157		"stylers": [
1158			{ "saturation": -100 },
1159			{ "lightness": 100 }
1160		]
1161	},
1162
1163	// No stroke on labels
1164	{
1165		"elementType": "labels",
1166		"stylers": [
1167			{ "visibility": "simplified" }
1168		]
1169	},
1170
1171	// No color on labels
1172	{
1173		"elementType": "labels.text",
1174		"stylers": [
1175			{ "saturation": -100 }
1176		]
1177	},
1178
1179	// Darken city, neighborhood names
1180	{
1181		"featureType": "administrative",
1182		"elementType": "labels.text.fill",
1183		"stylers": [
1184			{ "saturation": -100 },
1185			{ "lightness": -70 }
1186		]
1187	},
1188
1189	// Lighten water
1190	{
1191		"featureType": "water",
1192		"elementType": "geometry",
1193		"stylers": [
1194			{ "lightness": 40 }
1195		]
1196	},
1197
1198	// Lighten places of interests
1199	{
1200		"featureType": "poi",
1201		"elementType": "geometry",
1202		"stylers": [
1203			{ "lightness": 30 }
1204		]
1205	},
1206
1207	// Hide churches
1208	{
1209		"featureType": "poi.place_of_worship",
1210		"stylers": [
1211			{ "visibility": "off" }
1212		]
1213	},
1214
1215	// Hide businesses
1216	{
1217		"featureType": "poi.business",
1218		"stylers": [
1219			{ "visibility": "off" }
1220		]
1221	},
1222
1223	// Hide labels for business, parks, schools, etc.
1224	{
1225		"featureType": "poi",
1226		"elementType": "labels",
1227		"stylers": [
1228			{ "visibility": "off" }
1229		]
1230	},
1231
1232	// Hide labels for airport, bus, ferries, etc.
1233	{
1234		"featureType": "transit",
1235		"elementType": "labels",
1236		"stylers": [
1237			{ "visibility": "off" }
1238		]
1239	},
1240
1241	// Simplify highways
1242	{
1243		"featureType": "road.highway",
1244		"stylers": [
1245			{ "visibility": "simplified" }
1246		]
1247	},
1248
1249	// Darken highways
1250	{
1251		"featureType": "road.highway",
1252		"elementType": "geometry",
1253		"stylers": [
1254			{ "lightness": -10 },
1255			{ "saturation": -10 }
1256		]
1257	},
1258
1259	// Make major roads thinner, uncolored
1260	{
1261		"featureType": "road.arterial",
1262		"stylers": [
1263			{ "saturation": -100 },
1264			{ "weight": 0.3 },
1265		]
1266	},
1267
1268	// Lessen minor streets
1269	{
1270		"featureType": "road.local",
1271		"stylers": [
1272			{ "visibility": "simplified" },
1273			{ "saturation": -100 },
1274			{ "weight": 0.8 },
1275			{ "lightness": -5 }
1276		]
1277	},
1278
1279	// Lighten minor road labels
1280	{
1281		"featureType": "road.local",
1282		"elementType": "labels",
1283		"stylers": [
1284			{ "lightness": 17 }
1285		]
1286	},
1287
1288	// Don't show property lines
1289	{
1290		"featureType": "administrative.land_parcel",
1291		"stylers": [
1292			{ "visibility": "off" }
1293		]
1294	}
1295
1296];

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.