PageSourceSearch

https://petsonlypets.com/wp-content/themes/bam/assets/js/main.js?ver=1.3.4

js petsonlypets.com collected 2026-09-24 09:56:19 UTC 7,029 bytes, 277 lines download raw bytes

1var bam = bam || {};
2
3// polyfill forEach
4// https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Polyfill
5if ( window.NodeList && ! NodeList.prototype.forEach ) {
6	NodeList.prototype.forEach = function( callback, thisArg ) {
7		var i;
8		var len = this.length;
9
10		thisArg = thisArg || window;
11
12		for ( i = 0; i < len; i++ ) {
13			callback.call( thisArg, this[ i ], i, this );
14		}
15	};
16}
17
18/**
19 * Keyboard navigation support for menus
20 */
21 bam.keyboardNavigation = {
22
23	init: function() {
24		this.initMenus();
25	},
26
27	// The focusMenuItems() function implements Keyboard Navigation in the Bam Menus
28	// by adding the '.focus' class to all 'li' items when the focus is on the 'a' element.
29	focusMenuItems: function(navigationId) {
30		var navigation = document.getElementById(navigationId); 
31
32		// Return early if the navigation does not exist.
33		if ( ! navigation ) {
34			return;
35		}
36
37		const menu = navigation.getElementsByTagName( 'ul' )[ 0 ];
38
39		// If menu is empty return early.
40		if ( 'undefined' === typeof menu ) {
41			return;
42		}
43
44		if ( ! menu.classList.contains( 'nav-menu' ) ) {
45			menu.classList.add( 'nav-menu' );
46		}
47
48		// Get all the link elements within the menu.
49		var links = menu.getElementsByTagName( 'a' );
50
51		// Toggle focus each time a menu link is focused or blurred.
52		for ( var link of links ) {
53			link.addEventListener( 'focus', toggleFocus, true );
54			link.addEventListener( 'blur', toggleFocus, true );
55		}
56
57		/**
58		 * Sets or removes .foucs class on an element.
59		 */
60		function toggleFocus() {
61			var self = this;
62			// Move up through the ancestors of the current link until we hit .nav-menu
63			while ( ! self.classList.contains( 'nav-menu' ) ) {
64				// On li elements toggle the class .focus
65				if ( 'li' === self.tagName.toLowerCase() ) {
66					self.classList.toggle( 'focus' );
67				}
68				self = self.parentNode;
69			}
70		}
71	},
72
73	initMenus: function() {
74		var navigationIds = ['site-navigation', 'top-navigation'];
75		navigationIds.forEach(function(navigationId) {
76            this.focusMenuItems(navigationId);
77        }, this);
78	}
79};
80
81/**
82 * Mobile Menu.
83 */
84bam.mobileMenu = {
85
86    init: function() {
87        // Do the toggle.
88        this.toggle();
89    },
90
91    performToggle: function( element ) {
92
93        var target = element.dataset.toggleTarget,
94            activeClass = 'toggled-on';
95
96        // Get the target element.
97        targetElement = document.querySelector(target);
98
99        // Change the icon of the menu toggle button.
100        if ( element.classList.contains('menu-toggle') ) {
101            this.toggleIcon(element);
102        }
103
104        element.classList.toggle(activeClass);
105
106        bamToggleAttribute(element, 'aria-expanded', 'true', 'false');
107
108        targetElement.classList.toggle(activeClass);
109
110    },
111
112    toggle: function() {
113        var self = this;
114
115        document.querySelectorAll('*[data-toggle-target]').forEach( function( element ) {
116            element.addEventListener( 'click', function( event ) {
117                event.preventDefault();
118                self.performToggle( element );
119            } );
120        } );
121    },
122
123    toggleIcon: function(element) {
124        var icon = element.querySelector('i.fas');
125
126		if ( ! icon ) {
127			return false;
128		}
129
130        if( icon.classList.contains('fa-bars') ) {
131            icon.classList.remove('fa-bars');
132            icon.classList.add('fa-times');
133        } else if ( icon.classList.contains('fa-times') ) {
134            icon.classList.remove('fa-times');
135            icon.classList.add('fa-bars');
136        }
137    }
138};
139
140/**
141 * Search Toggle.
142 */
143 bam.searchToggle = {
144    init: function() {
145        this.addListener();
146    },
147
148    toggle: function( element ) {
149        
150		var navigationContainer = element.parentElement,
151            icon                = navigationContainer.querySelector('i.fas'),
152            searchBoxContainer  = navigationContainer.querySelector('.bam-search-box-container'),
153            inputField          = navigationContainer.querySelector('input.search-field');
154
155		// Toggle active class.
156		searchBoxContainer.classList.toggle('active');
157
158		// Toggle search icon.
159		this.toggleIcon(icon);
160
161		// Focus the input field if the search box is displayed.
162		if( searchBoxContainer.classList.contains('active') ) {
163			inputField.focus();
164		}
165
166    },
167
168	addListener: function() {
169		
170		var searchButton = document.querySelector('.bam-search-button-icon');
171
172		if ( ! searchButton ) {
173			return false;
174		}
175
176		var self = this;
177		
178		searchButton.addEventListener( 'click', function() {
179			self.toggle( this );
180		} );
181
182	},
183
184    toggleIcon: function( icon ) {
185        if ( icon.classList.contains('fa-search') ) {
186            icon.classList.remove('fa-search');
187            icon.classList.add('fa-times');
188        } else if ( icon.classList.contains('fa-times') ) {
189            icon.classList.remove('fa-times');
190            icon.classList.add('fa-search');
191        }
192    }
193};
194
195/**
196 * Intrinsic Ratio Embeds
197 * From TwentyTwenty WordPress theme. - Copyright (C) 2020 WordPress.org, GPLv2 or later
198 */
199bam.intrinsicRatioVideos = {
200
201	init: function() {
202		this.makeFit();
203
204		window.addEventListener( 'resize', function() {
205			this.makeFit();
206		}.bind( this ) );
207	},
208
209	makeFit: function() {
210		document.querySelectorAll( 'iframe, object, video' ).forEach( function( video ) {
211			var ratio, iTargetWidth,
212				container = video.parentNode;
213
214			// Skip videos we want to ignore.
215			if ( video.classList.contains( 'intrinsic-ignore' ) || video.parentNode.classList.contains( 'intrinsic-ignore' ) ) {
216				return true;
217			}
218
219			if ( ! video.dataset.origwidth ) {
220				// Get the video element proportions.
221				video.setAttribute( 'data-origwidth', video.width );
222				video.setAttribute( 'data-origheight', video.height );
223			}
224
225			iTargetWidth = container.offsetWidth;
226
227			// Get ratio from proportions.
228			ratio = iTargetWidth / video.dataset.origwidth;
229
230			// Scale based on ratio, thus retaining proportions.
231			video.style.width = iTargetWidth + 'px';
232			video.style.height = ( video.dataset.origheight * ratio ) + 'px';
233		} );
234	}
235
236};
237
238/* Toggle an attribute */
239function bamToggleAttribute( element, attribute, trueVal, falseVal ) {
240	if ( trueVal === undefined ) {
241		trueVal = true;
242	}
243	if ( falseVal === undefined ) {
244		falseVal = false;
245	}
246	if ( element.getAttribute( attribute ) !== trueVal ) {
247		element.setAttribute( attribute, trueVal );
248	} else {
249		element.setAttribute( attribute, falseVal );
250	}
251}
252
253/**
254 * Is the DOM ready?
255 *
256 * This implementation is coming from https://gomakethings.com/a-native-javascript-equivalent-of-jquerys-ready-method/
257 *
258 * @param {Function} fn Callback function to run.
259 */
260function bamDomReady( fn ) {
261	if ( typeof fn !== 'function' ) {
262		return;
263	}
264
265	if ( document.readyState === 'interactive' || document.readyState === 'complete' ) {
266		return fn();
267	}
268
269	document.addEventListener( 'DOMContentLoaded', fn, false );
270}
271
272bamDomReady( function() {
273	bam.mobileMenu.init();
274    bam.searchToggle.init();
275    bam.keyboardNavigation.init();
276    bam.intrinsicRatioVideos.init();
277} );

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.