PageSourceSearch

https://www.etoilewebdesign.com/wp-content/themes/activello/assets/js/functions.js?ver=1.6.1

js etoilewebdesign.com collected 2026-09-24 19:15:08 UTC 6,398 bytes, 265 lines download raw bytes

1/**
2 * Activello theme scripts.
3 *
4 * Plain DOM APIs -- no jQuery. The two globals (ActivelloIsMobile and
5 * generateMobileMenu) are kept on window because child themes may call them.
6 */
7( function () {
8	'use strict';
9
10	/**
11	 * Run a callback once the DOM is ready.
12	 *
13	 * @param {Function} fn Callback.
14	 */
15	function ready( fn ) {
16		if ( document.readyState !== 'loading' ) {
17			fn();
18		} else {
19			document.addEventListener( 'DOMContentLoaded', fn );
20		}
21	}
22
23	/**
24	 * Add class names to every element matching a selector.
25	 *
26	 * @param {string} selector CSS selector.
27	 * @param {Array}  classes  Class names to add.
28	 */
29	function addClasses( selector, classes ) {
30		document.querySelectorAll( selector ).forEach( function ( el ) {
31			el.classList.add.apply( el.classList, classes );
32		} );
33	}
34
35	/**
36	 * jQuery's "swing" easing, so the scroll-to-top motion is unchanged.
37	 *
38	 * @param {number} p Progress from 0 to 1.
39	 * @return {number} Eased progress.
40	 */
41	function swing( p ) {
42		return 0.5 - Math.cos( p * Math.PI ) / 2;
43	}
44
45	function prefersReducedMotion() {
46		return window.matchMedia && window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches;
47	}
48
49	/**
50	 * The display value jQuery's .show() would restore for an element.
51	 *
52	 * @param {Element} el Target element.
53	 * @return {string} CSS display value.
54	 */
55	function defaultDisplay( el ) {
56		if ( el.tagName === 'TABLE' ) {
57			return 'table';
58		}
59
60		if ( el.tagName === 'SELECT' ) {
61			return 'inline-block';
62		}
63
64		return 'block';
65	}
66
67	/**
68	 * Fade an element in or out, matching jQuery's fadeIn()/fadeOut().
69	 *
70	 * @param {Element} el       Target element.
71	 * @param {boolean} into     True to fade in, false to fade out.
72	 * @param {number}  duration Animation length in ms.
73	 */
74	function fade( el, into, duration ) {
75		if ( ! el || el.dataset.activelloFading === String( into ) ) {
76			return;
77		}
78
79		el.dataset.activelloFading = String( into );
80
81		if ( prefersReducedMotion() ) {
82			el.style.opacity = into ? '1' : '';
83			el.style.display = into ? defaultDisplay( el ) : 'none';
84			return;
85		}
86
87		var start = null;
88		var from  = parseFloat( window.getComputedStyle( el ).opacity );
89
90		if ( isNaN( from ) ) {
91			from = into ? 0 : 1;
92		}
93
94		if ( into ) {
95			el.style.display = defaultDisplay( el );
96		}
97
98		function step( ts ) {
99			if ( start === null ) {
100				start = ts;
101			}
102
103			var p = Math.min( ( ts - start ) / duration, 1 );
104			var v = from + ( ( into ? 1 : 0 ) - from ) * swing( p );
105
106			el.style.opacity = String( v );
107
108			if ( p < 1 ) {
109				window.requestAnimationFrame( step );
110			} else if ( ! into ) {
111				el.style.display = 'none';
112				el.style.opacity = '';
113			}
114		}
115
116		window.requestAnimationFrame( step );
117	}
118
119	/**
120	 * Detect a mobile user agent.
121	 *
122	 * Kept as-is (including the UA sniff) because the mobile menu styling below
123	 * depends on it and child themes may call it.
124	 *
125	 * @return {boolean} True on a mobile user agent.
126	 */
127	window.ActivelloIsMobile = function () {
128		return (
129			navigator.userAgent.match( /Android/i ) ||
130			navigator.userAgent.match( /webOS/i ) ||
131			navigator.userAgent.match( /iPhone/i ) ||
132			navigator.userAgent.match( /iPod/i ) ||
133			navigator.userAgent.match( /iPad/i ) ||
134			navigator.userAgent.match( /BlackBerry/ )
135		);
136	};
137
138	/**
139	 * Toggle the tap-friendly menu class on touch devices at tablet width and up.
140	 */
141	window.generateMobileMenu = function () {
142		var menu = document.querySelector( '#masthead .site-navigation-inner .navbar-collapse > ul.nav' );
143
144		if ( ! menu ) {
145			return;
146		}
147
148		if ( window.ActivelloIsMobile() && window.innerWidth > 768 ) {
149			menu.classList.add( 'activello-mobile-menu' );
150		} else {
151			menu.classList.remove( 'activello-mobile-menu' );
152		}
153	};
154
155	/**
156	 * Apply Bootstrap classes to markup WordPress generates, then reveal the
157	 * elements style.css keeps hidden until they have been dressed up.
158	 */
159	function styleCoreMarkup() {
160		addClasses( '.widget_rss ul', [ 'media-list' ] );
161		addClasses( '.postform', [ 'form-control' ] );
162		addClasses( 'table#wp-calendar', [ 'table', 'table-striped' ] );
163
164		document.querySelectorAll( '.widget_rss ul, .postform, table#wp-calendar' ).forEach( function ( el ) {
165			// 200ms matches the jQuery .show('fast') this replaced.
166			fade( el, true, 200 );
167		} );
168	}
169
170	/**
171	 * Scroll-to-top button: reveal past 100px, and smooth-scroll on click.
172	 */
173	function initScrollToTop() {
174		var button = document.querySelector( '.scroll-to-top' );
175
176		if ( ! button ) {
177			return;
178		}
179
180		function onScroll() {
181			fade( button, ( window.pageYOffset || document.documentElement.scrollTop ) > 100, 400 );
182		}
183
184		window.addEventListener( 'scroll', onScroll, { passive: true } );
185		onScroll();
186
187		button.addEventListener( 'click', function ( event ) {
188			event.preventDefault();
189
190			var from = window.pageYOffset || document.documentElement.scrollTop;
191
192			if ( ! from ) {
193				return;
194			}
195
196			if ( prefersReducedMotion() ) {
197				window.scrollTo( 0, 0 );
198				return;
199			}
200
201			var duration = 800;
202			var start    = null;
203
204			function step( ts ) {
205				if ( start === null ) {
206					start = ts;
207				}
208
209				var p = Math.min( ( ts - start ) / duration, 1 );
210
211				window.scrollTo( 0, from * ( 1 - swing( p ) ) );
212
213				if ( p < 1 ) {
214					window.requestAnimationFrame( step );
215				}
216			}
217
218			window.requestAnimationFrame( step );
219		} );
220	}
221
222	/**
223	 * "..." toggle for the extra-categories list, mobile user agents only.
224	 */
225	function initShowMoreCategories() {
226		document.querySelectorAll( '.show-more-categories' ).forEach( function ( el ) {
227			el.addEventListener( 'click', function () {
228				if ( window.ActivelloIsMobile() ) {
229					el.classList.toggle( 'active' );
230				}
231			} );
232		} );
233	}
234
235	/**
236	 * Sub-menu toggles the nav walker renders next to parent menu items.
237	 */
238	function initDropdowns() {
239		document.querySelectorAll( '.activello-dropdown' ).forEach( function ( el ) {
240			el.addEventListener( 'click', function () {
241				var parent = el.parentNode;
242
243				if ( ! parent ) {
244					return;
245				}
246
247				Array.prototype.forEach.call( parent.children, function ( child ) {
248					if ( child.tagName === 'UL' ) {
249						child.classList.toggle( 'active' );
250					}
251				} );
252			} );
253		} );
254	}
255
256	ready( function () {
257		styleCoreMarkup();
258		initScrollToTop();
259		initShowMoreCategories();
260		initDropdowns();
261		window.generateMobileMenu();
262
263		window.addEventListener( 'resize', window.generateMobileMenu );
264	} );
265}() );

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.