PageSourceSearch

https://www.smbc.edu.au/wp-content/themes/smbc/assets/js/main.js?ver=1.2.0

js smbc.edu.au collected 2026-10-02 06:18:46 UTC 8,156 bytes, 305 lines download raw bytes

1/**
2 * File main.js.
3 *
4 * Handles toggling the navigation menu for small screens and enables TAB key
5 * navigation support for dropdown menus.
6 * 
7 * Also handles all the search forms and block animations.
8 */
9
10function getQueryParams() {
11  let params = {};
12  let queryString = window.location.search.substring(1);
13  let pairs = queryString.split("&");
14
15  for (let i = 0; i < pairs.length; i++) {
16    let pair = pairs[i].split("=");
17    let key = decodeURIComponent(pair[0].replace(/\[\]$/, "")); // Remove [] from the name
18    let value = decodeURIComponent(pair[1] || "");
19
20    if (!params[key]) {
21      params[key] = [];
22    }
23    params[key].push(value);
24  }
25  return params;
26}
27
28  // Function to expand an element
29  function expandElement(element) {
30      element.style.height = element.scrollHeight + 'px'; // Set height to scrollHeight
31      element.classList.add('active');
32      element.addEventListener('transitionend', function handler() {
33          element.style.height = 'auto'; // Reset to auto after transition
34          element.removeEventListener('transitionend', handler);
35      });
36  }
37
38  // Function to collapse an element
39  function collapseElement(element) {
40      element.style.height = element.scrollHeight + 'px'; // Set height to current scrollHeight
41      requestAnimationFrame(() => {
42          element.style.height = '0'; // Transition to 0
43      });
44      element.classList.remove('active');
45  }
46
47
48
49
50
51
52( function() {
53	// SOCIAL SHARING JS
54	document.addEventListener("DOMContentLoaded", function () {
55		const shareButtons = document.querySelectorAll(".social-sharing-buttons a");
56		const copyLinkButton = document.querySelector(".copy-link-button");
57		const copyToast = document.querySelector("#copy-toast");
58
59		shareButtons.forEach((button) => {
60			button.addEventListener("click", function (event) {
61			if (!this.classList.contains("copy-link-button")) {
62				event.preventDefault();
63				const width = 600,
64				height = 400;
65				const left = screen.width / 2 - width / 2;
66				const top = screen.height / 2 - height / 2;
67				const url = this.href;
68				window.open(
69				url,
70				"Share",
71				`width=${width},height=${height},top=${top},left=${left}`
72				);
73			}
74			});
75		});
76
77		if (copyLinkButton) {
78			copyLinkButton.addEventListener("click", function (event) {
79				event.preventDefault();
80				const url = this.getAttribute("data-url");
81
82				navigator.clipboard
83					.writeText(url)
84					.then(() => {
85					//alert('Link copied to clipboard!');
86					copyToast.classList.add("active");
87
88					setTimeout(() => {
89						copyToast.classList.remove("active");
90					}, 1500);
91					})
92					.catch((err) => {
93					console.error("Could not copy text: ", err);
94					});
95				});
96		}
97	});
98})();
99
100
101
102
103
104
105
106/** Testimonial Carousel */
107function getTallestElementInRem(parentElement) {
108  const children = parentElement.children;
109  let maxHeight = 0;
110
111  // Loop through all child elements to find the tallest one
112  for (let i = 0; i < children.length; i++) {
113    const childHeight = children[i].offsetHeight;
114    if (childHeight > maxHeight) {
115      maxHeight = childHeight;
116    }
117  }
118
119  // Get the root font-size to convert pixels to rem
120  const rootFontSize = parseFloat(
121    getComputedStyle(document.documentElement).fontSize
122  );
123
124  // Convert max height to rem (1rem = rootFontSize pixels)
125  const maxHeightInRem = maxHeight / rootFontSize;
126
127  parentElement.style = `--_carousel-min-height: ${maxHeightInRem}rem`;
128
129  return maxHeightInRem.toFixed(2); // Returning the value in rem, rounded to 2 decimal places
130}
131
132/**
133 * Testimonial Carousel Execution
134 */
135(function () {
136    document.addEventListener("DOMContentLoaded", function () {
137
138      const testimonialBlock = document.querySelectorAll(".testimonial-carousel");
139
140      if(!testimonialBlock) return;
141
142      testimonialBlock.forEach( block => {
143
144        const quotes = block.querySelectorAll(".carousel__body");
145        const people = block.querySelectorAll(".carousel__person");
146
147        const quotesWrap = block.querySelector(".carousel__testimonials");
148        const peopleWrap = block.querySelector(".carousel__people");
149
150        const nextButton = block.querySelector(".carousel__button--next");
151        const prevButton = block.querySelector(".carousel__button--prev");
152
153        const currentCount = block.querySelector(".count.current");
154
155        let currentIndex = 0;
156        const totalSlides = quotes.length;
157
158        // Set the default heights.
159        getTallestElementInRem(quotesWrap);
160        getTallestElementInRem(peopleWrap);
161
162        function toggleActiveTestimonial( items = [] ) {
163          items.forEach((item, i) => {
164            item.classList.remove("active");
165            if (i === currentIndex) {
166              item.classList.add("active");
167            }
168          });
169        }
170
171        function showTestimonial(index) {
172          toggleActiveTestimonial(quotes);
173          toggleActiveTestimonial(people);
174          currentCount.textContent = currentIndex+1;
175        }
176
177        function nextTestimonial() {
178          currentIndex = (currentIndex + 1) % totalSlides;
179          block.dataset.currentIndex = currentIndex;
180
181          showTestimonial(currentIndex);
182        }
183
184        function prevTestimonial() {
185          currentIndex =(currentIndex - 1 + totalSlides) % totalSlides;
186          block.dataset.currentIndex = currentIndex;
187
188          showTestimonial(currentIndex);
189        }
190
191        nextButton.addEventListener("click", nextTestimonial);
192        prevButton.addEventListener("click", prevTestimonial);
193      });
194    });
195})();
196
197
198
199/**
200 * Full Feature Block Lightbox
201 */
202(function () {
203    document.addEventListener("DOMContentLoaded", function () {
204      const fullFeatureBlocks = document.querySelectorAll(
205        ".block__full-feature.full-cover"
206      );
207
208      if (!fullFeatureBlocks) return;
209
210      fullFeatureBlocks.forEach((block) => {
211        const playButton = block.querySelector(".feature-play-button");
212        const lightbox = block.querySelector(".lightbox-wrap");
213        const close = block.querySelector(".lightbox-close");
214
215        if (playButton) {
216          playButton.addEventListener("click", function () {
217            lightbox.classList.add("open");
218          });
219        }
220
221        if (close) {
222          close.addEventListener("click", function () {
223            lightbox.classList.remove("open");
224          });
225        }
226      });
227
228      // Lazy load the lozads
229      if (typeof window.lozad === "function") {
230        const observer = lozad();
231        observer.observe();
232      }
233    });
234})();
235
236
237// SWUP
238/*
239const swup = new Swup({
240  containers: ["#primary"],
241  plugins: [
242    new SwupHeadPlugin(),
243    new SwupPreloadPlugin(),
244    new SwupFadeTheme(),
245    //new SwupScrollPlugin(),
246  ],
247});
248*/
249
250
251/** 
252 * Course Card Link Goodness
253 */
254(function () {
255  document.querySelectorAll(".card.card__study").forEach((card) => {
256    const link = card.querySelector("a[href]");
257    if (!link) return;
258
259    card.style.cursor = "pointer";
260
261    card.addEventListener("click", (e) => {
262      // Prevent navigating if a real link or button inside the card is clicked
263      const isInteractive = e.target.closest("a, button");
264      if (isInteractive) return;
265
266      window.location = link.href;
267    });
268  });
269})();
270
271
272(function () {
273  document.querySelectorAll(".testimonial__track").forEach((track) => {
274    let isDragging = false;
275    let startX = 0;
276    let scrollStart = 0;
277
278    const startDrag = (e) => {
279      isDragging = true;
280      startX = e.clientX;
281      scrollStart = track.scrollLeft;
282      track.setPointerCapture(e.pointerId);
283      track.classList.add("dragging");
284    };
285
286    const onDrag = (e) => {
287      if (!isDragging) return;
288      const dx = e.clientX - startX;
289      track.scrollLeft = scrollStart - dx * 3.5; // Tweak multiplier
290    };
291
292    const stopDrag = (e) => {
293      isDragging = false;
294      track.releasePointerCapture(e.pointerId);
295      track.classList.remove("dragging");
296    };
297
298    track.addEventListener("pointerdown", startDrag);
299    track.addEventListener("pointermove", onDrag);
300    track.addEventListener("pointerup", stopDrag);
301    track.addEventListener("pointercancel", stopDrag);
302  });
303})();
304
305

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.