PageSourceSearch

https://herniau.com/wp-content/themes/herniau/assets/js/global.js?ver=1784565822

js herniau.com collected 2026-10-07 20:00:39 UTC 7,859 bytes, 262 lines download raw bytes

1(function($) { "use strict";
2
3document.addEventListener('DOMContentLoaded', function () {
4    var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
5    var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
6        return new bootstrap.Tooltip(tooltipTriggerEl)
7    })
8});
9
10jQuery(document).ready(function($) {
11
12$('body').addClass('loaded');
13
14flyoutMenuToggle();
15flyoutMenuSubMenus();
16externalLinks();
17contentAjax();
18loadHeroBackground();
19accountMenu();
20addNavPills();
21
22
23});
24
25function flyoutMenuToggle() {
26    const $navToggle = $(".nav-toggle");
27    const $flyoutMenu = $("nav.flyout-menu");
28
29    // Toggle menu on button click
30    $(".nav-toggle, .flyout-menu .close-btn").on("click", function (e) {
31        e.stopPropagation(); // Prevent the click from bubbling up
32        $navToggle.toggleClass("active");
33        $flyoutMenu.toggleClass("active");
34    });
35
36    // Close menu if clicking outside
37    $(document).on("click", function (e) {
38        if (!$flyoutMenu.is(e.target) && $flyoutMenu.has(e.target).length === 0 &&
39            !$navToggle.is(e.target) && $navToggle.has(e.target).length === 0) {
40            // Remove active classes
41            $navToggle.removeClass("active");
42            $flyoutMenu.removeClass("active");
43        }
44    });
45}
46
47function flyoutMenuSubMenus() {
48
49
50  const menuItems = document.querySelectorAll(".flyout-menu .menu > li");
51
52  menuItems.forEach((item) => {
53    const subMenu = item.querySelector(".sub-menu");
54
55    if (subMenu) {
56      // Create toggle button
57      const toggleBtn = document.createElement("button");
58      toggleBtn.classList.add("submenu-toggle");
59      toggleBtn.setAttribute("aria-label", "Toggle submenu");
60      toggleBtn.innerHTML = `
61        <svg class="caret-icon" width="16" height="16" viewBox="0 0 24 24">
62          <path d="M6 9l6 6 6-6" fill="none" stroke="currentColor" stroke-width="2"/>
63        </svg>
64      `;
65
66      // Append toggle button after the anchor link
67      const link = item.querySelector("a");
68      link.after(toggleBtn);
69
70      // Toggle logic
71      toggleBtn.addEventListener("click", function () {
72        subMenu.classList.toggle("active");
73        this.classList.toggle("open");
74        // Swap the icon direction
75        this.querySelector("path").setAttribute(
76          "d",
77          subMenu.classList.contains("active")
78            ? "M6 15l6-6 6 6"  // up
79            : "M6 9l6 6 6-6"  // down
80        );
81      });
82    }
83  });
84
85
86}
87
88
89function externalLinks() {
90
91  const links = document.querySelectorAll('a[href^="http"]');
92  links.forEach(function (link) {
93    // Only apply to external links
94    if (link.hostname !== window.location.hostname) {
95      link.setAttribute('target', '_blank');
96      link.setAttribute('rel', 'noopener noreferrer');
97    }
98  });
99
100}
101
102function loadHeroBackground() {
103
104    const imageUrl = document.getElementById('background-image')?.value;
105
106    if (imageUrl) {
107      const bg = document.createElement('div');
108      bg.className = 'background-image';
109      bg.style.backgroundImage = `url('${imageUrl}')`;
110
111      const heroContainer = document.querySelector('.page-hero');
112
113      if (heroContainer) {
114        // Calculate total height including padding
115        const computedStyle = window.getComputedStyle(heroContainer);
116        const height = heroContainer.offsetHeight;
117        const paddingTop = parseFloat(computedStyle.paddingTop);
118        const paddingBottom = parseFloat(computedStyle.paddingBottom);
119        const totalHeight = height + paddingTop + paddingBottom;
120
121        bg.style.height = `${totalHeight}px`;
122
123        // Insert background before other content
124        heroContainer.insertBefore(bg, heroContainer.firstChild);
125
126        // Trigger fade-in after a tiny delay to allow initial render
127        requestAnimationFrame(() => {
128          bg.classList.add('visible');
129        });
130      }
131    }
132
133}
134
135
136
137function accountMenu() {
138    $(".account-menu .trigger").on("click", function(e) {
139        e.stopPropagation();
140        $(this).toggleClass("active");
141        $(".account-menu nav").toggleClass("active");
142    });
143
144    $(document).on("click", function(e) {
145        if (!$(e.target).closest(".account-menu").length) {
146            $(".account-menu .trigger").removeClass("active");
147            $(".account-menu nav").removeClass("active");
148        }
149    });
150}
151
152
153
154function addNavPills() {
155  // Check if WordPress output the logged-in body class
156  const isLoggedIn = document.body.classList.contains('logged-in');
157
158  // Define the menu items
159  const items = [
160    { text: 'Home', href: '/', activeOn: ['page-id-1663'] },
161    { 
162      text: 'Courses', 
163      href: isLoggedIn ? '/my-courses' : '/hernia-a-to-z-fundamentals/', // <-- Swaps based on body class
164      activeOn: ['page-id-43868'] 
165    },
166    { text: 'Upcoming Events', href: '/events', activeOn: ['page-id-994'] },
167    { text: 'Videos', href: '/videos', activeOn: ['page-id-43873'] },
168    { text: 'Lectures', href: '/lectures', activeOn: ['page-id-12106'] },  
169    { text: 'IHS', href: '/ihs', activeOn: ['page-id-44114'] },
170    { text: 'Podcasts', href: '/podcast', activeOn: ['page-id-44428'] }
171  ];
172
173  // Create the main nav container
174  const navDiv = document.createElement('div');
175  navDiv.className = 'nav-pills alt';
176
177  const ul = document.createElement('ul');
178
179  // Loop through items and build each <li>
180  items.forEach(item => {
181    const li = document.createElement('li');
182
183    // Check if any of the "activeOn" classes are present on <body>
184    const isActive = item.activeOn.some(cls => document.body.classList.contains(cls));
185    if (isActive) {
186      li.classList.add('active');
187    }
188
189    const a = document.createElement('a');
190    a.href = item.href;
191    a.textContent = item.text;
192
193    li.appendChild(a);
194    ul.appendChild(li);
195  });
196
197  navDiv.appendChild(ul);
198
199  const wrapperDiv = document.createElement('div');
200  wrapperDiv.className = 'sub-nav-menu';
201
202  wrapperDiv.appendChild(navDiv);
203
204  // Prepend to .entry-content .wp-block-group.container
205  const entryContent = document.querySelector('.entry-content .wp-block-group.container');
206  if (entryContent) {
207    entryContent.prepend(wrapperDiv);
208  }
209}
210
211
212function contentAjax() {
213
214    jQuery(document).on('click', '.load-more', function() {
215        var button = jQuery(this);
216
217        var page   = parseInt(button.attr('data-current-page')) + 1;
218        var max    = parseInt(button.attr('data-max-pages'));
219        var type   = button.data('post-type');
220        var per    = button.data('posts-per-page');
221        var tax    = button.data('taxonomy');
222        var term   = button.data('term');
223        var sortby = button.data('sort'); 
224
225        jQuery.ajax({
226            url: ajax_loadmore_params.ajaxurl,
227            type: 'POST',
228            data: {
229                action: 'loadmore_posts',
230                page: page,
231                post_type: type,
232                posts_per_page: per,
233                taxonomy: tax,
234                term: term,
235                sort_by: sortby 
236            },
237            beforeSend: function() {
238                button.text('Loading...');
239            },
240            success: function(data) {
241                if (data) {
242                    button.text('Load More');
243                    button.attr('data-current-page', page);
244                    jQuery('.grid-posts').append(data);
245
246                    if (page >= max) {
247                        button.remove();
248                    }
249                } else {
250                    button.remove();
251                }
252            }
253        });
254    });
255
256}
257
258
259
260})(jQuery);
261
262

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.