PageSourceSearch

https://transgenderlawcenter.org/wp-content/themes/bhm-tlc-pro/js/global.js?ver=1.2.0

js transgenderlawcenter.org collected 2026-10-01 09:07:21 UTC 16,416 bytes, 503 lines download raw bytes

1/**
2 * This script adds the jquery effects to the BHM Custom Theme Theme.
3 *
4 * @package BHM Custom Child\JS
5 * @author Bet Hannon Business Websites
6 * @license GPL-2.0-or-later
7 */
8( function( $ ) {
9
10	// Cache DOM selectors.
11	var $container    = $( '.site-container' ),
12		$header       = $( '.site-header' ),
13		$hsToggle     = $( '.toggle-header-search' ),
14		$hsWrap       = $( '#header-search-wrap' ),
15		$hsInput      = $hsWrap.find( 'input[type="search"]' );
16
17	// Make sure JS class is added.
18	$( document ).ready( function() {
19		let activeSubmenu = null; // Track the currently active submenu
20		
21		$( 'body' ).addClass( 'js' );
22
23        // Initialize all submenus as hidden
24        $('.sub-menu').each(function () {
25            $(this).hide().attr('aria-expanded', 'false');
26        });
27
28        // Hover Behavior for Mouse Users
29        $('.menu-item').on('mouseenter', function () {
30            const $this = $(this);
31            const $submenu = $this.find('.sub-menu:first');
32            const $button = $this.find('.sub-menu-toggle');
33
34            if ($submenu.length) {
35                // Close other submenus
36                closeAllSubmenus();
37
38                // Open this submenu
39                $submenu.stop(true, true).slideDown(200).attr('aria-expanded', 'true');
40                $button.attr('aria-expanded', 'true').attr('aria-pressed', 'true');
41                activeSubmenu = $submenu; // Set this submenu as active
42            }
43        });
44
45        $('.menu-item').on('mouseleave', function () {
46            // Do nothing here to let submenus remain open
47        });
48
49        // Dismiss submenus when clicking outside
50        $(document).on('click', function (e) {
51            if (!$(e.target).closest('.menu-item').length) {
52                closeAllSubmenus();
53            }
54        });
55
56        // Keyboard Accessibility: Toggle submenu with Enter or Space
57        $(document).on('keydown', '.sub-menu-toggle', function (e) {
58            if (e.key === 'Enter' || e.key === ' ') {
59                e.preventDefault();
60
61                const $button = $(this);
62                const $submenu = $button.siblings('.sub-menu');
63                const isExpanded = $button.attr('aria-expanded') === 'true';
64
65                if (isExpanded) {
66                    // Close submenu
67                    $submenu.slideUp(200).attr('aria-expanded', 'false');
68                    $button.attr('aria-expanded', 'false').attr('aria-pressed', 'false');
69                    activeSubmenu = null; // Clear active submenu
70                } else {
71                    // Close other submenus and open this one
72                    closeAllSubmenus();
73                    $submenu.stop(true, true).slideDown(200).attr('aria-expanded', 'true');
74                    $button.attr('aria-expanded', 'true').attr('aria-pressed', 'true');
75                    activeSubmenu = $submenu; // Set this submenu as active
76                }
77            }
78        });
79
80        // Keyboard Accessibility: Close submenu with Escape key
81        $(document).on('keydown', function (e) {
82            if (e.key === 'Escape') {
83                // Check if focus is inside an active submenu
84                if (activeSubmenu && activeSubmenu.find(':focus').length) {
85                    const $toggleButton = activeSubmenu.siblings('.sub-menu-toggle');
86                    activeSubmenu.slideUp(200).attr('aria-expanded', 'false');
87                    $toggleButton.attr('aria-expanded', 'false').attr('aria-pressed', 'false').focus();
88                    activeSubmenu = null; // Clear active submenu
89                } else {
90                    // Fallback to closing all submenus
91                    closeAllSubmenus();
92                }
93            }
94        });
95
96        // Helper function: Close all submenus
97        function closeAllSubmenus() {
98            $('.menu-item .sub-menu').slideUp(200).attr('aria-expanded', 'false');
99            $('.menu-item .sub-menu-toggle').attr('aria-expanded', 'false').attr('aria-pressed', 'false');
100            activeSubmenu = null; // Clear active submenu
101        }
102		
103		$('.kt-blocks-modal-link-inner').each(function () {
104			let html = $(this).html();
105
106			// Look for text like: Transcript* for video*
107			html = html.replace(/\*(.*?)\*/g, '<span class="sr-only">$1</span>');
108
109			$(this).html(html);
110		});	
111		
112		
113    });
114
115	// Run on page scroll.
116	$( window ).scroll( function() {
117
118		// Toggle header class after threshold point.
119		if ( 50 < $( document ).scrollTop() ) {
120			$( '.site-container' ).addClass( 'shadow' );
121		} else {
122			$( '.site-container' ).removeClass( 'shadow' );
123		}
124
125	});
126
127	// Handler for click a show/hide button.
128	$hsToggle.on( 'click', function( event ) {
129
130		event.preventDefault();
131
132		if ( $( this ).hasClass( 'close' ) ) {
133			hideSearch();
134		} else {
135			showSearch();
136		}
137
138	});
139
140	$( '.gb-block-post-grid-excerpt:empty' ).parent().parent().addClass( 'no-excerpt' );
141
142	// Handler for pressing show/hide button.
143	$hsToggle.on( 'keydown', function( event ) {
144
145		// If tabbing from toggle button, and search is hidden, exit early.
146		if ( 9 === event.keyCode && ! $header.hasClass( 'search-visible' ) ) {
147			return;
148		}
149
150		event.preventDefault();
151		handleKeyDown( event );
152
153	});
154
155	// Helper function to show the search form.
156	function showSearch() {
157
158		$header.addClass( 'search-visible' );
159		$hsWrap.fadeIn( 'fast' ).find( 'input[type="search"]' ).focus();
160		$hsToggle.attr( 'aria-expanded', true );
161
162	}
163
164	// Helper function to hide the search form.
165	function hideSearch() {
166
167		$hsWrap.fadeOut( 'fast' ).parents( '.site-header' ).removeClass( 'search-visible' );
168		$hsToggle.attr( 'aria-expanded', false );
169
170	}
171
172	// Keydown handler function for toggling search field visibility.
173	function handleKeyDown( event ) {
174
175		// Enter/Space, respectively.
176		if ( 13 === event.keyCode || 32 === event.keyCode ) {
177
178			event.preventDefault();
179
180			if ( $( event.target ).hasClass( 'close' ) ) {
181				hideSearch();
182			} else {
183				showSearch();
184			}
185
186		}
187
188	}
189	
190	// Adding parent prefix to submenu toggles for context
191	
192	setTimeout(function() {
193			
194		var submenuButtons = $('.sub-menu-toggle');
195		$.each(submenuButtons, function (buttonIdx, btn) {
196			var me = $(this);
197			var myText = me.find('span').text();
198			var myParent = me.parent();
199			var menuText = myParent.find(' > a').text();
200			var newText = menuText + ' ' + myText;
201			me.find('span').text(newText);
202		});
203	}, 250);
204	
205	
206	// Add additional wrappers to blockquote block
207	
208	$( ".wp-block-quote:not(.is-style-tlc-standard-blockquote)" ).wrap( "<div class='blockquote-wrapper'></div>" );
209	$( ".wp-block-quote:not(.is-style-tlc-standard-blockquote)" ).wrap( "<div class='blockquote-inner-wrapper'></div>" );
210	$( ".wp-block-quote:not(.is-style-tlc-standard-blockquote)" ).wrapInner( "<div class='blockquote-text-wrapper'></div>");
211
212    // Add additional wrapper to form field
213
214    $( ".comment-respond" ).wrapInner( "<div class='comment-respond-inner'></div>");
215	$( ".entry-comments" ).wrapInner( "<div class='comments-wrapper'></div>");
216
217
218	// Re-wrap the media-text link
219
220	$(document).ready(function() {
221		$('.thisisatest .wp-block-media-text__content').prev().wrap('<a href="#"></a>');
222		$('.thisisatest .wp-block-media-text__content').prev().appendTo($('.thisisatest .wp-block-media-text__content').prev().parent());
223		$('.thisisatest .wp-block-media-text__content').appendTo($('.thisisatest .wp-block-media-text__content').prev().parent());
224	});
225
226
227	/* Adds/edits Spanish attribute */
228
229	$(document).ready(function($) {
230		$('.lang-spanish').attr('lang', 'es');
231	});
232	
233	/* Change the buttons text for Spanish posts */
234	
235$(document).ready(function($) {
236    $('.category-espanol').each(function() {
237        var postTitle = $(this).find('.entry-title').text();
238        $(this).find('.more-link').html('Seguir Leyendo<span class="sr-only"> sobre ' + postTitle + '</span>');
239    });
240});
241
242	
243	
244	
245	/* Change Heroes Assemble heading levels
246	
247	******************************************/
248	/* Staff */
249	$('h4.lhea-member-name').replaceWith(function(){
250		return $('<h2>', {class: 'lhea-member-name', html: $(this).html()});
251	});	
252	
253	/* Modal */
254	$('h4.lhea-modal-position').replaceWith(function(){
255		return $('<div>', {class: 'lhea-modal-position', html: $(this).html()});
256	});
257	
258	/* Accessibility optimizations to the modal close button */
259	$('button.lhea-close-modal i').after(' Close<span class="sr-only"> profile modal</span>');
260
261	/* wrap the image */
262	$('div.lhea-member-picture img.wp-post-image').wrap('<div class="lhea-img-wrapper"></div>');
263
264	$(document).ready(function() {
265	  $('ul.lhea-heroes > li.lhea-hero').each(function() {
266		var $li = $(this);
267		$li.removeClass('lhea-hero').addClass('tlc-team-member-wrapper');
268	  });
269	});
270
271	/* Reduce the font size for long titles */
272
273	$(document).ready(function() {
274	  $('h1').each(function() {
275		if ($(this).text().length > 85) {
276		  $(this).addClass('small-h1');
277		}
278	  });
279	});
280
281
282$(document).ready(function() {
283    function applyCheckedClass() {
284        $('.case-archive-filter .checkbox input[type="checkbox"]').each(function() {
285            if ($(this).is(':checked')) {
286                $(this).parent().addClass('checked');
287            } else {
288                $(this).parent().removeClass('checked');
289            }
290        });
291    }
292
293    // Apply the checked class on initial load
294    applyCheckedClass();
295
296    // Listen for changes and apply the checked class
297    $('.case-archive-filter').on('change', '.checkbox input[type="checkbox"]', applyCheckedClass);
298
299    // Reapply the checked class after the AJAX refresh
300    $(document).on('js_event_wpv_pagination_completed', applyCheckedClass);
301});
302
303	/* Add #top to header */
304  jQuery(document).ready(function($) {
305    $('header').attr('id', 'top');
306  });
307
308}( jQuery ) );
309
310
311/* Smooth scroll with jQuery animate */
312jQuery(document).ready(function($) {
313  $('a[href^="#"]').on('click keydown', function(event) {
314    // Check for click or keydown (Enter or Space)
315    if (event.type === 'keydown' && (event.which !== 13 && event.which !== 32)) {
316      return;
317    }
318
319    event.preventDefault();
320
321    var targetId = $(this).attr('href');
322    var targetElement = $(targetId);
323
324    if (targetElement.length) {
325      $('html, body').animate({
326        scrollTop: targetElement.offset().top
327      }, 1000, function() {
328        // Callback after animation
329        window.location.hash = targetId;
330      });
331    }
332  });
333});
334
335
336// fast action 
337
338jQuery(document).ready(function($) {
339
340	function fixFastActionAccessibility() {
341
342		$('img.profile-link-fa-image:not([alt])').attr(
343			'alt',
344			'Fast Action log in'
345		);
346
347		$('a#fastaction-whatsthis:not([aria-label])').attr(
348			'aria-label',
349			'What is Fast Action (opens new window)'
350		);
351
352	}
353
354	// Run once in case FastAction already exists.
355	fixFastActionAccessibility();
356
357	// Watch for FastAction being injected later.
358	const observer = new MutationObserver(function() {
359		fixFastActionAccessibility();
360	});
361
362	observer.observe(document.body, {
363		childList: true,
364		subtree: true
365	});
366
367});
368
369// Cases accordion
370
371
372
373jQuery(document).ready(function($) {
374     // When an accordion button is clicked
375     $('.case-accordion-button').on('click', function() {
376        // Toggle the "active" class on the button
377        $(this).toggleClass('active');
378        // Change the "aria-expanded" attribute
379        var isExpanded = $(this).attr('aria-expanded') === 'true';
380        $(this).attr('aria-expanded', !isExpanded);
381        // Show/hide the associated accordion content
382        var $content = $(this).next('.case-accordion-content');
383        $content.slideToggle(200, function() {
384            // This callback function runs after the slideToggle animation is complete
385            if ($content.is(':visible')) {
386                adjustLineHeights($content);
387                appendPdfIconsAndSize($content);
388            } else {
389                // Remove the styles when the accordion is closed
390                $content.find('.cd-child-list').each(function() {
391                    var $list = $(this);
392                    var uniqueClass = $list.data('unique-class');
393                    if (uniqueClass) {
394                        $('head style[data-unique-class="' + uniqueClass + '"]').remove();
395                        $list.removeData('unique-class');
396                    }
397                });
398            }
399        });
400    });
401
402    function appendPdfIconsAndSize($context) {
403        console.log('Searching for PDFs in', $context);
404        $context.find('a[href$=".pdf"]').each(function() {
405            var $link = $(this);
406            if (!$link.data('pdf-icon-appended')) {  // Check if the icon and size have already been appended
407                var fileSize = $link.data('filesize'); // Assuming file size is in a data-filesize attribute
408    
409                if (fileSize) {
410                    appendIconAndSize($link, fileSize);
411                } else {
412                    // Try to fetch the file size via a HEAD request
413                    $.ajax({
414                        url: $link.attr('href'),
415                        type: 'HEAD',
416                        success: function(data, status, xhr) {
417                            var contentLength = xhr.getResponseHeader('Content-Length');
418                            if (contentLength) {
419                                var fileSize = formatFileSize(contentLength);
420                                appendIconAndSize($link, fileSize);
421                            }
422                        }
423                    });
424                }
425            }
426        });
427    }
428    
429    function appendIconAndSize($link, fileSize) {
430        // Create a visually hidden span for screen readers
431        var $screenReaderText = $('<span class="sr-only"> (PDF, ' + fileSize + ')</span>');
432        $link.append($screenReaderText);
433    
434        // Append the icon and visible text for sighted users
435        $link.append(' <i class="fas fa-file-pdf"></i> (' + fileSize + ')');
436    
437        $link.data('pdf-icon-appended', true);  // Set a flag to indicate that the icon and size have been appended
438    }
439    
440    function formatFileSize(bytes) {
441        var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
442        if (bytes === 0) return '0 Byte';
443        var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
444        return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
445    }
446    
447    
448
449    function adjustLineHeights($context) {
450        $context.find('.cd-child-list').each(function(index) {
451            var $list = jQuery(this);
452            var $items = $list.find('> li');
453            
454            if ($items.length > 0) {
455                var lastItemHeight = $items.last().outerHeight();
456                var listHeight = $list.outerHeight();
457
458                // Adding a unique class to each list
459                var uniqueClass = 'unique-list-' + index + '-' + new Date().getTime();
460                $list.data('unique-class', uniqueClass);
461
462                // Remove old style rule if it exists
463                $('head style[data-unique-class="' + uniqueClass + '"]').remove();
464
465                // Creating the dynamic style rule
466                var styleRule = '.' + uniqueClass + ':before { height: ' + (listHeight - (lastItemHeight / 2)) + 'px !important; }';
467                $('<style>' + styleRule + '</style>')
468                    .attr('data-unique-class', uniqueClass)
469                    .appendTo('head');
470
471                // Add the unique class to the list
472                $list.addClass(uniqueClass);
473            }
474        });
475    }
476	
477	// fixing the breadcrumbs
478    const $breadcrumbNav = $('.tlc-breadcrumbs > nav');
479    const $breadcrumbWrapper = $breadcrumbNav.children('span');
480
481    if ($breadcrumbWrapper.length) {
482        // create a new <ul>
483        const $ul = $('<ul class="kv-breadcrumb-list"></ul>');
484
485        // iterate through the children of the wrapper span
486        $breadcrumbWrapper.contents().each(function() {
487            if (this.nodeType === 1 && this.nodeName === 'SPAN') {
488                const $li = $('<li class="kv-breadcrumb-item"></li>').append($(this).contents());
489                if ($(this).hasClass('breadcrumb_last')) {
490                    $li.attr('aria-current', 'page').addClass('kv-breadcrumb-current');
491                }
492                $ul.append($li);
493            }
494        });
495
496
497        // replace the wrapper <span> with the new <ul>
498        $breadcrumbWrapper.replaceWith($ul);
499    }
500	
501
502
503});

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.