PageSourceSearch

https://otakunoculture.com/_static/??wp-content/themes/twentysixte…/twentysixteen/js/functions.js?m=1686746140

js otakunoculture.com collected 2026-10-02 13:01:58 UTC 10,826 bytes, 335 lines download raw bytes

1/**
2 * Makes "skip to content" link work correctly in IE9, Chrome, and Opera
3 * for better accessibility.
4 *
5 * @link http://www.nczonline.net/blog/2013/01/15/fixing-skip-to-content-links/
6 */
7
8 ( function() {
9	var isWebkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1,
10		isOpera  = navigator.userAgent.toLowerCase().indexOf( 'opera' )  > -1,
11		isIE     = navigator.userAgent.toLowerCase().indexOf( 'msie' )   > -1;
12
13	if ( ( isWebkit || isOpera || isIE ) && document.getElementById && window.addEventListener ) {
14		window.addEventListener( 'hashchange', function() {
15			var id = location.hash.substring( 1 ),
16				element;
17
18			if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) {
19				return;
20			}
21
22			element = document.getElementById( id );
23
24			if ( element ) {
25				if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) {
26					element.tabIndex = -1;
27				}
28
29				element.focus();
30
31				// Repositions the window on jump-to-anchor to account for admin bar and border height.
32				window.scrollBy( 0, -53 );
33			}
34		}, false );
35	}
36} )();
37;
38/* global screenReaderText */
39/**
40 * Theme functions file.
41 *
42 * Contains handlers for navigation and widget area.
43 */
44( function () {
45	'use strict';
46
47	var mainNav, masthead, menuToggle, siteNavigation, socialNavigation, siteHeaderMenu, resizeTimer;
48
49	function matches( el, sel ) {
50		if ( Element.prototype.matches ) {
51			return el.matches( sel );
52		}
53
54		if ( Element.prototype.msMatchesSelector ) {
55			return el.msMatchesSelector( sel );
56		}
57	}
58
59	// Based on https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
60	function closest( el, sel ) {
61		if ( el.closest ) {
62			return el.closest( sel );
63		}
64
65		var current = el;
66
67		do {
68			if ( matches( el, sel ) ) {
69				return current;
70			}
71			current = current.parentElement || current.parentNode;
72		} while ( current !== null && current.nodeType === 1 );
73
74		return null;
75	}
76
77	function forEachNode( parent, selector, fn ) {
78		var nodes = parent.querySelectorAll( selector );
79		for ( var i = 0; i < nodes.length; i++ ) {
80			fn( nodes[ i ] );
81		}
82	}
83
84	function initMainNavigation( container ) {
85		forEachNode( container, '.menu-item-has-children > a', function ( el ) {
86			// Add dropdown toggle that displays child menu items.
87			var dropdownToggle = document.createElement( 'button' );
88			dropdownToggle.className = 'dropdown-toggle';
89			dropdownToggle.setAttribute( 'aria-expanded', 'false' );
90
91			var span = document.createElement( 'span' );
92			span.className = 'screen-reader-text';
93			span.textContent = screenReaderText.expand;
94
95			dropdownToggle.appendChild( span );
96
97			el.parentNode.insertBefore( dropdownToggle, el.nextSibling );
98		} );
99
100		// Toggle buttons and submenu items with active children menu items.
101		forEachNode( container, '.current-menu-ancestor > button', function ( el ) {
102			el.classList.add( 'toggled-on' );
103		} );
104		forEachNode( container, '.current-menu-ancestor > .sub-menu', function ( el ) {
105			el.classList.add( 'toggled-on' );
106		} );
107
108		// Add menu items with submenus to aria-haspopup="true".
109		forEachNode( container, '.menu-item-has-children', function ( el ) {
110			el.setAttribute( 'aria-haspopup', 'true' );
111		} );
112
113		forEachNode( container, '.dropdown-toggle', function ( el ) {
114			el.addEventListener( 'click', function ( e ) {
115				var screenReaderSpan = el.querySelector( '.screen-reader-text' );
116
117				e.preventDefault();
118				el.classList.toggle( 'toggled-on' );
119				var next = el.nextElementSibling;
120				if ( next && matches( next, '.children, .sub-menu' ) ) {
121					next.classList.toggle( 'toggled-on' );
122				}
123
124				el.setAttribute(
125					'aria-expanded',
126					el.getAttribute( 'aria-expanded' ) === 'false' ? 'true' : 'false'
127				);
128				screenReaderSpan.textContent =
129					screenReaderSpan.textContent === screenReaderText.expand ? screenReaderText.collapse: screenReaderText.expand;
130			} );
131		} );
132	}
133
134	mainNav = document.querySelector( '.main-navigation' );
135	if ( mainNav ) {
136		initMainNavigation( mainNav );
137	}
138
139	masthead = document.querySelector( '#masthead' );
140	menuToggle = masthead && masthead.querySelector( '#menu-toggle' );
141	siteHeaderMenu = masthead && masthead.querySelector( '#site-header-menu' );
142	siteNavigation = masthead && masthead.querySelector( '#site-navigation' );
143	socialNavigation = masthead && masthead.querySelector( '#social-navigation' );
144
145	// Enable menuToggle.
146	( function () {
147		// Return early if menuToggle is missing.
148		if ( ! menuToggle ) {
149			return;
150		}
151
152		var controls = [ menuToggle, siteNavigation, socialNavigation ].filter( Boolean );
153
154		// Add an initial values for the attribute.
155		controls.forEach( function ( el ) {
156			el.setAttribute( 'aria-expanded', 'false' );
157		} );
158
159		menuToggle.addEventListener( 'click', function () {
160			menuToggle.classList.toggle( 'toggled-on' );
161			siteHeaderMenu.classList.toggle( 'toggled-on' );
162
163			var newVal = menuToggle.getAttribute( 'aria-expanded' ) === 'false' ? 'true' : 'false';
164			controls.forEach( function ( el ) {
165				el.setAttribute( 'aria-expanded', newVal );
166			} );
167		} );
168	} )();
169
170	// Fix sub-menus for touch devices and better focus for hidden submenu items for accessibility.
171	( function () {
172		if ( ! siteNavigation || ! siteNavigation.children.length ) {
173			return;
174		}
175
176		// Init `focus` class to allow submenu access on tablets.
177		function initFocusClassTouchScreen() {
178			document.body.addEventListener( 'touchstart', function ( e ) {
179				if ( ! closest( e.target, '.main-navigation li' ) ) {
180					forEachNode( document, '.main-navigation li', function ( el ) {
181						el.classList.remove( 'focus' );
182					} );
183				}
184			} );
185			forEachNode( siteNavigation, '.menu-item-has-children > a', function ( link ) {
186				link.addEventListener( 'touchstart', function ( e ) {
187					if ( window.innerWidth >= 910 ) {
188						var el = link.parentElement;
189
190						if ( matches( el, 'li' ) && ! el.classList.contains( 'focus' ) ) {
191							e.preventDefault();
192							el.classList.toggle( 'focus' );
193							var children = el.parentElement.children;
194							for ( var i = 0; i < children.length; i++ ) {
195								if ( children[ i ] !== el ) {
196									children[ i ].classList.remove( 'focus' );
197								}
198							}
199						}
200					}
201				} );
202			} );
203		}
204
205		function toggleFocus( el ) {
206			var item = closest( el, '.menu-item' );
207			if ( item ) {
208				item.classList.toggle( 'focus' );
209			}
210		}
211
212		if ( 'ontouchstart' in window ) {
213			initFocusClassTouchScreen();
214		}
215
216		forEachNode( siteNavigation, 'a', function ( link ) {
217			link.addEventListener( 'focus', toggleFocus( link ) );
218			link.addEventListener( 'blur', toggleFocus( link ) );
219		} );
220	} )();
221
222	// Add the default ARIA attributes for the menu toggle and the navigations.
223	function onResizeARIA() {
224		if ( window.innerWidth < 910 ) {
225			if ( menuToggle && menuToggle.classList.contains( 'toggled-on' ) ) {
226				menuToggle.setAttribute( 'aria-expanded', 'true' );
227			} else {
228				menuToggle.setAttribute( 'aria-expanded', 'false' );
229			}
230
231			if ( siteHeaderMenu && siteHeaderMenu.classList.contains( 'toggled-on' ) ) {
232				siteNavigation && siteNavigation.setAttribute( 'aria-expanded', 'true' );
233				socialNavigation && socialNavigation.setAttribute( 'aria-expanded', 'true' );
234			} else {
235				siteNavigation && siteNavigation.setAttribute( 'aria-expanded', 'false' );
236				socialNavigation && socialNavigation.setAttribute( 'aria-expanded', 'false' );
237			}
238
239			menuToggle && menuToggle.setAttribute( 'aria-controls', 'site-navigation social-navigation' );
240		} else {
241			menuToggle && menuToggle.removeAttribute( 'aria-expanded' );
242			siteNavigation && siteNavigation.removeAttribute( 'aria-expanded' );
243			socialNavigation && socialNavigation.removeAttribute( 'aria-expanded' );
244			menuToggle && menuToggle.removeAttribute( 'aria-controls' );
245		}
246	}
247
248	// Add 'below-entry-meta' class to elements.
249	function belowEntryMetaClass( selector ) {
250		if (
251			document.body.classList.contains( 'page' ) ||
252			document.body.classList.contains( 'search' ) ||
253			document.body.classList.contains( 'single-attachment' ) ||
254			document.body.classList.contains( 'error404' )
255		) {
256			return;
257		}
258
259		forEachNode( document, '.entry-content', function ( content ) {
260			forEachNode( content, selector, function ( element ) {
261				var elementPosTop = element.getBoundingClientRect().top;
262				var article = closest( element, 'article' );
263				var entryFooter = article && article.querySelector( '.entry-footer' );
264				var entryFooterPosBottom =
265					entryFooter ? entryFooter.getBoundingClientRect().top + entryFooter.offsetHeight + 28	: null;
266				var caption = closest( element, 'figure' );
267				var next = element.nextSibling;
268				var figcaption = next && matches( next, 'figcaption' ) ? next : null;
269				var newImg;
270
271				// Add 'below-entry-meta' to elements below the entry meta.
272				if ( entryFooterPosBottom !== null && elementPosTop > entryFooterPosBottom ) {
273					// Check if full-size images and captions are larger than or equal to 840px.
274					if ( selector === 'img.size-full' || selector === '.wp-block-image img' ) {
275						// Create an image to find native image width of resized images (i.e. max-width: 100%).
276						newImg = new Image();
277						newImg.src = element.getAttribute( 'src' );
278						newImg.onload = function () {
279							if ( newImg.width >= 840 ) {
280								// Check if an image in an image block has a width attribute; if its value is less than 840, return.
281								if (
282									selector === '.wp-block-image img' &&
283									element.hasAttribute( 'width' ) &&
284									element.getAttribute( 'width' ) < 840
285								) {
286									return;
287								}
288
289								element.classList.add( 'below-entry-meta' );
290
291								if ( caption && caption.classList.contains( 'wp-caption' ) ) {
292									caption.classList.add( 'below-entry-meta' );
293									caption.removeAttribute( 'style' );
294								}
295
296								if ( figcaption ) {
297									figcaption.classList.add( 'below-entry-meta' );
298								}
299							}
300						};
301					} else {
302						element.classList.add( 'below-entry-meta' );
303					}
304				} else {
305					element.classList.remove( 'below-entry-meta' );
306					caption && caption.classList.remove( 'below-entry-meta' );
307				}
308			} );
309		} );
310	}
311
312	function init() {
313		window.addEventListener( 'load', onResizeARIA );
314		window.addEventListener( 'resize', function () {
315			clearTimeout( resizeTimer );
316			resizeTimer = setTimeout( function () {
317				belowEntryMetaClass( 'img.size-full' );
318				belowEntryMetaClass( 'blockquote.alignleft, blockquote.alignright' );
319				belowEntryMetaClass( '.wp-block-image img' );
320			}, 300 );
321			onResizeARIA();
322		} );
323
324		belowEntryMetaClass( 'img.size-full' );
325		belowEntryMetaClass( 'blockquote.alignleft, blockquote.alignright' );
326		belowEntryMetaClass( '.wp-block-image img' );
327	}
328
329	if ( document.readyState === 'loading' ) {
330		document.addEventListener( 'DOMContentLoaded', init );
331	} else {
332		init();
333	}
334} )();
335;

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.