3-js edit

wm-main-js  edit

Copy
Edit
<!-- components/3-js/wm-main-js.php -->
Copy
Copy
Edit
/* scss/3-js/_wm-main-js.scss */
Copy
Edit
// synced with Test 12-5-2022 NE // IE 11 Polyfill if (!Element.prototype.matches) { Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; } if (!Element.prototype.closest) { Element.prototype.closest = function (s) { var el = this; do { if (Element.prototype.matches.call(el, s)) return el; el = el.parentElement || el.parentNode; } while (el !== null && el.nodeType === 1); return null; }; } var winWidth = window.innerWidth; // --------------------- BREADCRUMBS ---------------------------- // document.addEventListener("DOMContentLoaded", function () { // BREADCRUMB POPPER if ( document.querySelector(".m-breadcrumbs") && document.querySelector(".m-breadcrumbs").length != 0 ) { // Make sure Popper is loaded if (typeof Popper != "undefined") { var mySelector = "main .m-breadcrumbs"; var breadLists = document.querySelectorAll(mySelector); var breadlistNum = 0; for (b = 0; b < breadLists.length; b++) { var thisBreadList = breadLists[b]; var breadListItems = thisBreadList.getElementsByTagName("li"); var numBreadListItems = breadListItems.length; if (numBreadListItems > 3) { var newCollapsedLinks = document.createElement("div"); newCollapsedLinks.setAttribute("id", "collapsedlinks" + breadlistNum); for (i = 1; i < numBreadListItems - 2; ++i) { newCollapsedLinks.appendChild(breadListItems[1]); // as items are taken away, the "next" item remains index 1 } newArrow = document.createElement("div"); newArrow.setAttribute("id", "bc_arrow" + breadlistNum); newArrow.setAttribute("data-popper-arrow", "true"); newCollapsedLinks.appendChild(newArrow); // ELLIPSE var newListItem = document.createElement("li"); newListItem.setAttribute("class", "m-breadcrumbs__link"); newButton = document.createElement("button"); newButton.innerHTML = "&hellip;"; newButton.setAttribute("aria-expanded", "false"); newButton.setAttribute( "aria-controls", "collapsedlinks" + breadlistNum ); newListItem.appendChild(newButton); thisBreadList.insertBefore(newListItem, thisBreadList.children[1]); thisBreadList.insertBefore( document.createTextNode("\n"), thisBreadList.children[2] ); newListItem.appendChild(newCollapsedLinks); //newListItem.appendChild(document.createTextNode('\n')); // create the Popper const button = thisBreadList.querySelector( ".m-breadcrumbs__link button" ); const tooltip = thisBreadList.querySelector( "#collapsedlinks" + breadlistNum ); let popperInstance = null; function create() { popperInstance = Popper.createPopper(button, tooltip, { placement: "bottom-start", modifiers: [ { name: "offset", options: { offset: [-5, 20] } }, { name: "flip", options: { behavior: ["top-start", "bottom-start"] }, }, ], }); } function destroy() { if (popperInstance) { popperInstance.destroy(); popperInstance = null; } } function toggleLinks() { if (tooltip.hasAttribute("data-show")) { tooltip.removeAttribute("data-show"); button.setAttribute("aria-expanded", "false"); destroy(); } else { tooltip.setAttribute("data-show", ""); button.setAttribute("aria-expanded", "true"); create(); } } button.addEventListener("click", toggleLinks); document.addEventListener( "click", function (event) { if (event.target.closest(".m-breadcrumbs__link button")) return; if (tooltip.hasAttribute("data-show")) { tooltip.removeAttribute("data-show"); button.setAttribute("aria-expanded", "false"); destroy(); } }, true ); } else if (numBreadListItems == 1) { thisBreadList.style.display = "none"; } breadlistNum++; } // end loop multiple breadcrumb lists } } }); // ----------------------- WM.EDU MENUS -------------------------------- // // no need to comment out for grad schools document.addEventListener("DOMContentLoaded", function () { // =================== "SITE MENU" AND "INFO FOR" MENU BUTTONS // INFO TAB COOKIE function setInfoTabCookie(cname, val) { var expire = new Date(); expire.setTime(expire.getTime() + 365 * 24 * 60 * 60 * 1000); document.cookie = cname + "=" + val + ";domain=.wm.edu;path=/;expires=" + expire.toUTCString(); } function getInfoTabCookie(cname) { var name = cname + "="; var decodedCookie = decodeURIComponent(document.cookie); var ca = decodedCookie.split(";"); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == " ") { c = c.substring(1); } if (c.indexOf(name) == 0) { return c.substring(name.length, c.length); } } return ""; } // HIDE INFO FOR BUTTON ON SCROLL var $window = $(window); $window.on("scroll", hideOnScroll); function hideOnScroll() { // if (!$("body").hasClass("menu-open") && !$("body").hasClass("info-open")) { if (!$("body").hasClass("info-open")) { var scrolled = $window.scrollTop(); if (scrolled > 150) { $(".wm-topbar__buttons .wm-js-info-menu-button").addClass("is-hidden"); } else { $(".wm-topbar__buttons .wm-js-info-menu-button").removeClass( "is-hidden" ); } } } // check if there's a topbar // if so, do all the menu thangs if (document.querySelector(".wm-topbar")) { // -- TOPBAR VARIABLES var topBar = document.querySelector(".wm-topbar"); // button - site menu //var menuBtn = document.querySelectorAll(".wm-topbar__menu-button"); var menuBtn = document.querySelector(".wm-topbar .wm-js-site-menu-button"); // button - info for var infoBtn = document.querySelector(".wm-topbar__info-for-button"); // background var menuBackdrop = document.querySelector(".menubackdrop-dark"); // -- SITE MENU VARIABLES var siteMenu = document.querySelector(".wm-site-menu"); // button - close site menu var closeSiteMenuBtn = document.querySelector( ".wm-site-menu .wm-js-site-menu-button-close-x" ); // button - switch to info for menu var infoBtnOnMenu = document.querySelector( ".wm-site-menu .wm-js-info-menu-button" ); // primary wrapper of site menu content var siteMenuPrimaryWrapper = document.querySelector( ".wm-site-menu__primary-wrapper" )[0]; // -- INFO FOR MENU VARIABLES // button - switch to site menu var infoForMenu = document.querySelector(".wm-info-for-menu"); var menuBtnOnInfo = document.querySelector( ".wm-info-for-menu .wm-js-site-menu-button" ); // button - close info for menu var closeInfoForBtn = document.querySelector( ".wm-info-for-menu .wm-js-info-menu-button.-close-x" ); // tab wrapper var infoForTabs = document.querySelectorAll( '.wm-info-for-menu [role="tablist"]' )[0]; // keep page scroll location for when menu opens // window.addEventListener("scroll", () => { // document.documentElement.style.setProperty( // "--scroll-y", // window.scrollY + "px" // ); // }); //hide wm logo on white menu backdrop on scroll var backdrop_wmlogo = document.querySelectorAll( ".menubackdrop-white .wm_logo_banner" )[0]; siteMenu.addEventListener("scroll", function () { if (siteMenu.scrollTop > 0) { backdrop_wmlogo.style.display = "none"; } else { backdrop_wmlogo.style.display = "block"; } }); infoForMenu.addEventListener("scroll", function () { if (infoForMenu.scrollTop > 0) { backdrop_wmlogo.style.display = "none"; } else { backdrop_wmlogo.style.display = "block"; } }); // SITE MENU TAB TRAPPING var firsttab_sitemenu = document.querySelector( ".wm-js-site-menu-button-close-x" ); var lasttab_sitemenu = document.querySelector( ".sec-wrapper__item:last-of-type" ); if (firsttab_sitemenu) { firsttab_sitemenu.addEventListener("keydown", function (e) { if (e.which == 9) { if (e.shiftKey) { lasttab_sitemenu.focus(); e.preventDefault(); } } }); } if (lasttab_sitemenu) { lasttab_sitemenu.addEventListener("keydown", function (e) { if (e.which == 9) { if (!e.shiftKey) { firsttab_sitemenu.focus(); e.preventDefault(); } } }); } // INFO FOR MENU TAB TRAPPING var firsttab_infofor = document.querySelector( ".wm-info-for-menu .wm-js-site-menu-button" ); var lasttab_prospective = document.querySelector( "#infofor_prospective .infofor-features a:last-of-type" ); var lasttab_current = document.querySelector( "#infofor_current .infofor-features a:last-of-type" ); var lasttab_facstaff = document.querySelector( "#infofor_facstaff .infofor-features a:last-of-type" ); var lasttab_parentsfamilies = document.querySelector( "#infofor_parentsfamilies .infofor-features a:last-of-type" ); var lasttab_alumni = document.querySelector( "#infofor_alumni .infofor-features a:last-of-type" ); if (firsttab_infofor) { firsttab_infofor.addEventListener("keydown", function (e) { if (e.which == 9) { if (e.shiftKey) { // figure out the open tab, then set to last of it var activeButton = document.querySelector( '#wm-js-tablist button[aria-selected="true"]' ); var currOpenTabId = activeButton.getAttribute("aria-controls"); var currOpenTab = document.getElementById(currOpenTabId); var lastTabItem = currOpenTab.querySelector( ".infofor-features a:last-of-type" ); if (lastTabItem) { lastTabItem.focus(); e.preventDefault(); } } } }); } if (lasttab_prospective) { lasttab_prospective.addEventListener("keydown", function (e) { if (e.which == 9) { if (!e.shiftKey) { if (firsttab_infofor) { firsttab_infofor.focus(); e.preventDefault(); } } } }); } if (lasttab_current) { lasttab_current.addEventListener("keydown", function (e) { if (e.which == 9) { if (!e.shiftKey) { if (firsttab_infofor) { firsttab_infofor.focus(); e.preventDefault(); } } } }); } if (lasttab_facstaff) { lasttab_facstaff.addEventListener("keydown", function (e) { if (e.which == 9) { if (!e.shiftKey) { if (firsttab_infofor) { firsttab_infofor.focus(); e.preventDefault(); } } } }); } if (lasttab_parentsfamilies) { lasttab_parentsfamilies.addEventListener("keydown", function (e) { if (e.which == 9) { if (!e.shiftKey) { if (firsttab_infofor) { firsttab_infofor.focus(); e.preventDefault(); } } } }); } if (lasttab_alumni) { lasttab_alumni.addEventListener("keydown", function (e) { if (e.which == 9) { if (!e.shiftKey) { if (firsttab_infofor) { firsttab_infofor.focus(); e.preventDefault(); } } } }); } // OPEN TAKEOVER MENUS // add perfect scrollbar to menus // this fixes issue where menu contents jump left on scrolling var ps_sitemenu, ps_infoformenu; function initMenuScrollbar() { ps_sitemenu = new PerfectScrollbar(siteMenu); ps_infoformenu = new PerfectScrollbar(infoForMenu); } // 1024 == $menu-mobile-to-desktop-breakpoint if (winWidth > 1024) { initMenuScrollbar(); } function updateMenuScrollVisibility() { winWidth = window.innerWidth; if (winWidth > 1024) { if (!ps_sitemenu) { initMenuScrollbar(); } ps_sitemenu.update(); ps_infoformenu.update(); } else { if (ps_sitemenu) { ps_sitemenu.destroy(); ps_infoformenu.destroy(); ps_sitemenu = null; ps_infoformenu = null; } } } // set up site menu targets for animation var siteMenuPrimaryNavChildren = document.querySelectorAll( ".primary-nav__mainmenu > li" ); var siteMenuTacNavChildren = document.querySelectorAll( ".tactical-nav__list > li" ); var siteMenuSearch = document.querySelectorAll(".wm-search")[0]; var siteMenuLogoBanners = document.querySelectorAll(".wm_logo_banner"); // var siteMenuSecondaryLinks = document.querySelectorAll(".sec-wrapper")[0]; function setSiteMenuToAnimationStartState() { for (let i = 0; i < siteMenuPrimaryNavChildren.length; i++) { const child = siteMenuPrimaryNavChildren[i]; child.style.opacity = "0"; child.style.transform = "translateY(7px)"; } for (let i = 0; i < siteMenuTacNavChildren.length; i++) { const child = siteMenuTacNavChildren[i]; child.style.opacity = "0"; child.style.transform = "translateY(7px)"; } siteMenuSearch.style.opacity = "0"; for (let i = 0; i < siteMenuLogoBanners.length; i++) { const child = siteMenuLogoBanners[i]; //child.style.opacity = "0"; child.style.transform = "translateY(-150px)"; } // siteMenuSecondaryLinks.style.opacity = "0"; } setSiteMenuToAnimationStartState(); // function - openMenus function openMenus(which, callback) { // Images in the Info for menu are empty on page load to prevent them from getting pulled by Google // The images are stored in data attribute: "data-src" // atms var atmImg = document.querySelectorAll(".infofor-atm img"); for (let i = 0; i < atmImg.length; i++) { if (atmImg[i].style.display = "none") { atmImg[i].style.display = "block"; } else { atmImg[i].style.display = "none"; } } // features var featureImg = document.querySelectorAll(".infofor-features img"); for (let i = 0; i < featureImg.length; i++) { if (featureImg[i].style.display = "none") { featureImg[i].style.display = "block"; } else { featureImg[i].style.display = "none"; } } // Figcaptions in the Info For menu are empty on page load to prevent them from getting pulled for share links by Facebook, Twitter etc. // The title and text used in the figcaption are stored in data-attributes: "data-ftitle" and "data-ftext" // features var empty_captions = document.querySelectorAll('.infofor-features figcaption[data-ftext]'); for (let f = 0; f < empty_captions.length; f++) { var this_figcaption = empty_captions[f]; var this_title = this_figcaption.getAttribute('data-ftitle'); var this_text = this_figcaption.getAttribute('data-ftext'); var full_caption = ""; if (this_title && this_title != '') { full_caption = full_caption + '<span class="title">' + this_title + '</span>'; } if (this_text && this_text != '') { full_caption = full_caption + this_text; } // wrap in a p tag if not empty if (full_caption != "") { full_caption = "<p>" + full_caption + "</p>"; } this_figcaption.innerHTML = full_caption; this_figcaption.removeAttribute('data-ftext'); this_figcaption.removeAttribute('data-ftitle'); } // atms var empty_captions = document.querySelectorAll('.infofor-atm figcaption[data-ftext]'); for (let f = 0; f < empty_captions.length; f++) { var this_figcaption = empty_captions[f]; var this_title = this_figcaption.getAttribute('data-ftitle'); var this_text = this_figcaption.getAttribute('data-ftext'); var full_caption = ""; if (this_title && this_title != '') { full_caption = full_caption + '<span class="title">' + this_title + '</span>'; } if (this_text && this_text != '') { full_caption = full_caption + '<p>' + this_text + '</p>'; } // in case of button var curr_html = this_figcaption.innerHTML; this_figcaption.innerHTML = full_caption + curr_html; this_figcaption.removeAttribute('data-ftext'); this_figcaption.removeAttribute('data-ftitle'); } if (which == "site") { document.body.classList.add("toggle-menus"); document.body.classList.add("menu-open"); document.body.classList.remove("info-open"); window.addEventListener("resize", updateMenuScrollVisibility); // animation timeline var sitemenu_timeline = anime.timeline({ easing: "cubicBezier(.645,.045,.355,1)", }); sitemenu_timeline .add({ targets: siteMenuPrimaryNavChildren, opacity: 1, translateY: 0, delay: anime.stagger(100), duration: 600, }) .add( { targets: siteMenuTacNavChildren, opacity: 1, translateY: 0, delay: anime.stagger(100), duration: 600, }, 0 ) .add( { targets: siteMenuLogoBanners, translateY: 0, //opacity: 1, duration: 600, }, "-=1000" ) .add( { targets: siteMenuSearch, opacity: 1, duration: 400, }, 0 ); } else if (which == "info") { var bodyTag = document.getElementsByTagName("body"); if (bodyTag[0].classList.contains("menu-open")) { document.body.classList.remove("menu-open"); } else { // animate banner anime({ targets: siteMenuLogoBanners, translateY: 0, duration: 600, }); } document.body.classList.add("toggle-menus"); document.body.classList.add("info-open"); } // set body to not scroll when menus are open const body = document.body; if (!$("html").hasClass("modal-open")) { freezeBackground(true); } // callback function used for setting focus for keyboard tabbing callback(); } // Callback function to set focus on search input that should be visble now.... (sometimes it isn't so using an interval to poll it) function focusSearchBox() { var winWidth = window.innerWidth; if (winWidth > 1023) { // put cursor in search box on desktop var input = document.getElementById("q"); var counter = 20; var checkExist = setInterval(function () { counter--; if (input || counter === 0) { input.focus(); input.style.outline = "none"; clearInterval(checkExist); } }, 100); } else { var thisClose = document.querySelector( ".wm-site-menu .wm-js-site-menu-button-close-x" ); if (thisClose) { var counter = 20; var checkExist = setInterval(function () { counter--; if (thisClose || counter === 0) { thisClose.focus(); clearInterval(checkExist); } }, 100); } } } // Callback function to set focus on the active tab that should be visble now.... (sometimes it isn't so using an interval to poll it) function focusActiveTab() { var activeTab = document.querySelector( '.wm-info-for-menu button[aria-selected="true"]' ); var counter = 20; var checkExist = setInterval(function () { counter--; if (activeTab || counter === 0) { activeTab.focus(); clearInterval(checkExist); } }, 100); } // open site menu - topbar button click menuBtn.onclick = function (e) { e.preventDefault(); this.setAttribute("aria-expanded", "true"); openMenus("site", focusSearchBox); return false; }; // open info for menu - topbar button click infoBtn.onclick = function (e) { e.preventDefault(); this.setAttribute("aria-expanded", "true"); openMenus("info", focusActiveTab); return false; }; // open info for from site menu - click infoBtnOnMenu.onclick = function (e) { e.preventDefault(); menuBtn.setAttribute("aria-expanded", "false"); infoBtn.setAttribute("aria-expanded", "true"); openMenus("info", focusActiveTab); return false; }; // open site menu from info for - click menuBtnOnInfo.onclick = function (e) { e.preventDefault(); infoBtn.setAttribute("aria-expanded", "false"); menuBtn.setAttribute("aria-expanded", "true"); openMenus("site", focusSearchBox); return false; }; // CLOSE TAKEOVER MENUS // function - closeMenus function closeMenus(which) { document.body.classList.remove("toggle-menus"); if (which == "all") { // close any expanded menu item, otherwise it is sticking around in keyboard tabbing even though the menus are visibility:hidden :( var expandedMenuButton = document.querySelector( '.primary-nav__togglesubmenu[aria-expanded="true"]' ); if (expandedMenuButton) { expandedMenuButton.click(); } // set focus to the topbar toggle menu button menuBtn.focus(); document.body.classList.remove("menu-open"); document.body.classList.remove("info-open"); } else if (which == "site") { document.body.classList.remove("menu-open"); } else if (which == "info") { document.body.classList.remove("info-open"); } window.removeEventListener("resize", updateMenuScrollVisibility); // reset menu scroll to top siteMenu.scrollTop = 0; infoForMenu.scrollTop = 0; // set scroll position of page to what it was before menu open const body = document.body; freezeBackground(false); // update position of homepage logo var logo = document.querySelector(".m-desktoplogo"); if (logo) { logo.style.left = "50%"; } // close open accordian const buttons = document.querySelectorAll( ".primary-nav .wm-js-togglesubmenu" ); for (var b = 0; b < buttons.length; b++) { buttons[b].setAttribute("aria-expanded", "false"); buttons[b].nextElementSibling.setAttribute("aria-hidden", "true"); } // reset animation setSiteMenuToAnimationStartState(); } // close menus - 'Esc' key close global and info for menus document.onkeydown = function (evt) { evt = evt || window.event; if (evt.keyCode == 27) { infoBtn.setAttribute("aria-expanded", "false"); menuBtn.setAttribute("aria-expanded", "false"); closeMenus('all'); } }; // close menus - menubackdrop-dark click menuBackdrop.onclick = function (event) { infoBtn.setAttribute("aria-expanded", "false"); menuBtn.setAttribute("aria-expanded", "false"); closeMenus('all'); }; // close menus - close site menu button click closeSiteMenuBtn.onclick = function (e) { e.preventDefault(); menuBtn.setAttribute("aria-expanded", "false"); closeMenus("site"); return false; }; // close menus - close info for menu button click closeInfoForBtn.onclick = function (e) { e.preventDefault(); infoBtn.setAttribute("aria-expanded", "false"); closeMenus("info"); return false; }; // function to make background not scroll when menus are open let previousScrollY = 0; function freezeBackground(freeze) { if (freeze) { previousScrollY = window.scrollY; var broadcastBarHeight; $("broadcastBarTop") ? (broadcastBarHeight = $("broadcastBarTop").outerHeight()) : (broadcastBarHeight = 0); var topbarHeight = $(".wm-topbar").outerHeight(); var topbarY = $(".wm-topbar").offset(); topbarY = topbarY.top; if (previousScrollY == 0) { contentOffset = topbarHeight + broadcastBarHeight; } else { contentOffset = topbarHeight; } var scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; var homelogo = document.querySelector(".m-desktoplogo"); $("html").addClass("modal-open").css({ marginTop: -previousScrollY, overflow: "hidden", left: 0, right: 0, top: 0, bottom: 0, position: "fixed", }); $(".wm-topbar").css({ position: "absolute", top: topbarY, paddingRight: scrollbarWidth, }); $("body").css({ paddingRight: scrollbarWidth, }); $("#main-header").css({ marginTop: contentOffset, }); // HOMEPAGE if (scrollbarWidth !== 0) { // update position of homepage logo if (homelogo) { var adjustment = scrollbarWidth / 2; homelogo.style.left = "calc(50% - " + adjustment + "px)"; } } } else { $("html").removeClass("modal-open").css({ marginTop: 0, overflow: "visible", left: "auto", right: "auto", top: "auto", bottom: "auto", position: "static", }); $(".wm-topbar").css({ position: "", top: 0, paddingRight: 0, }); $("body").css({ paddingRight: 0, }); $("#main-header").css({ marginTop: 0, }); //window.scrollTo(0, previousScrollY); window.scrollTo({ top: previousScrollY, behavior: 'instant' }); // HOMEPAGE if (homelogo) { homelogo.style.left = ""; } } } // PRIMARY NAV ACCORDION SUBMENU var accordion = $("body").find('[data-behavior="accordion"]'); var expandedClass = "is-expanded"; $.each(accordion, function () { // loop through all accordions on the page var accordionItems = $(this).find('[data-binding="expand-accordion-item"]'); $.each(accordionItems, function () { // loop through all accordion items of each accordion var $this = $(this); var triggerBtn = $this.find('[data-binding="expand-accordion-trigger"]'); var setHeight = function (nV) { // set height of inner content for smooth animation var innerContent = nV.find(".accordion__content-inner")[0], maxHeight = $(innerContent).outerHeight(), content = nV.find(".accordion__content")[0]; if (!content.style.height || content.style.height === "0px") { $(content).css("height", maxHeight); } else { $(content).css("height", "0px"); } }; var toggleClasses = function (event) { var clickedItem = event.currentTarget; var currentItem = $(clickedItem).parent(); var clickedContent = $(currentItem).find(".accordion__content"); var currentItemIsExpanded = currentItem.hasClass("is-expanded"); $(".accordion__item").removeClass(expandedClass); $(".accordion__title").attr("aria-selected", "false"); $(".accordion__title").attr("aria-expanded", "false"); $(".accordion__content").attr("aria-hidden", "true"); $(".accordion__content").css("height", "0px"); if (!currentItemIsExpanded) { $(currentItem).toggleClass(expandedClass); setHeight(currentItem); $(clickedItem).attr("aria-selected", "true"); $(clickedItem).attr("aria-expanded", "true"); $(clickedContent).attr("aria-hidden", "false"); } else { $(clickedItem).attr("aria-selected", "false"); $(clickedItem).attr("aria-expanded", "false"); $(clickedContent).attr("aria-hidden", "true"); } }; triggerBtn.on("click", event, function (e) { e.preventDefault(); toggleClasses(event); }); // open tabs if the spacebar or enter button is clicked whilst they are in focus $(triggerBtn).on("keydown", event, function (e) { if (e.keyCode === 13 || e.keyCode === 32) { e.preventDefault(); toggleClasses(event); } }); }); }); // SEARCH FUNCTIONS var search_box = document.querySelector("input#q"); var common_area = document.querySelector(".wm-search__common-searches"); var common_items = document.querySelector( ".wm-search__common-searches .items" ); var suggestion_area = document.querySelector(".wm-search__suggested-results"); var suggested_items = document.querySelector( ".wm-search__suggested-results .items" ); var search_caption = document.querySelectorAll(".wm-search__caption"); showCommonSearches(); hideSuggestionArea(); search_box.addEventListener("input", showSuggestions); function hideSuggestionArea() { suggestion_area.classList.add("hidden"); } function showSuggestionArea() { search_box.classList.add("active"); suggestion_area.classList.remove("hidden"); } function hideCommonArea() { common_area.classList.add("hidden"); } function showCommonArea() { common_area.classList.remove("hidden"); search_caption[0].classList.remove("highlight"); } function showCommonSearches() { // only try ajax if on www, test-www or dev-www if (window.location.href.indexOf("www.wm.edu") > -1) { xhr = new XMLHttpRequest(); // the function that runs on return... xhr.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { var myArr = JSON.parse(this.responseText); formatCommonSearches(myArr); } }; var common_address = "/atoz/common_searches_json.php"; xhr.open("GET", common_address, true); xhr.send(); } } function formatCommonSearches(arr) { var out = ""; // loop data items for (i = 0; i < arr.length; i++) { // fix the internal links... reone = /^(http|\/\/)/i; retwo = /(\.[a-zA-Z]+|\/)$/i; var comp = arr[i].url; if (!comp.match(reone) && !comp.match(retwo)) { arr[i].url = comp + ".php"; } out += '<li><a href="' + arr[i].url + '">' + arr[i].display + "</a></li>"; } common_items.innerHTML = out; } function showSuggestions(e) { var value = e.target.value; if (value.length < 3) { suggested_items.innerHTML = ""; hideSuggestionArea(); showCommonArea(); search_box.classList.remove("active"); search_caption[0].classList.remove("active"); return false; } else { hideCommonArea(); search_box.classList.add("active"); search_caption[0].classList.add("active"); // only try ajax if on www, test-www or dev-www if (window.location.href.indexOf("www.wm.edu") > -1) { xhr = new XMLHttpRequest(); // the function that runs on return... xhr.onreadystatechange = function () { if (this.readyState == 4 && this.status == 200) { var myArr = JSON.parse(this.responseText); formatSuggestions(myArr, value); } }; var suggestions_address = "/atoz/suggestions_json.php"; xhr.open("GET", suggestions_address, true); xhr.send(); } } } function formatSuggestions(arr, str) { showSuggestionArea(); // alpha sort the arr arr.sort(function (a, b) { return a.display < b.display ? -1 : a.display > b.display ? 1 : 0; }); var out = ""; // convert str to array (search terms) var terms = str.split(" "); // loop data items for (i = 0; i < arr.length; i++) { var matches_all_terms = 0; // loop search terms for (t = 0; t < terms.length; t++) { if (terms[t].length > 2) { // if display contains the term add to output var re = new RegExp(terms[t], "gi"); var disp = arr[i].display; if (disp.match(re)) { matches_all_terms = 1; } else { matches_all_terms = 0; break; } } } if (matches_all_terms == 1) { // fix the internal links... reone = /^(http|\/\/)/i; retwo = /(\.[a-zA-Z]+|\/)$/i; var comp = arr[i].url; if (!comp.match(reone) && !comp.match(retwo)) { arr[i].url = comp + ".php"; } out += '<li><a href="' + arr[i].url + '">' + arr[i].display + "</a></li>"; } } if (out == "") { search_caption[0].classList.add("highlight"); hideSuggestionArea(); //out = "Hit enter to search all of wm.edu"; } suggested_items.innerHTML = out; } // INFO FOR TAB DROPDOWN var tabList = document.getElementById("wm-js-tablist"); function tabDropdown() { tabList.classList.toggle("show"); } // Close the dropdown menu if the user clicks outside of it if (tabList) { bodyWidth = viewport().width; window.onclick = function (event) { if ( !event.target.matches(".wm-js-tab-button") && !event.target.matches(".wm-js-tab-button span") ) { tabList.classList.remove("show"); } else { if (bodyWidth < 1024) { tabDropdown(); } } }; } /* * This content is licensed according to the W3C Software License at * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document */ (function () { var tablist = document.querySelectorAll( '.wm-info-for-menu [role="tablist"]' )[0]; var tabs; var panels; generateArrays(); function generateArrays() { tabs = document.querySelectorAll('.wm-info-for-menu [role="tab"]'); panels = document.querySelectorAll('.wm-info-for-menu [role="tabpanel"]'); } // For easy reference var keys = { end: 35, home: 36, left: 37, up: 38, right: 39, down: 40, delete: 46, enter: 13, space: 32, }; // Add or subtract depending on key pressed var direction = { 37: -1, 38: -1, 39: 1, 40: 1, }; // Bind listeners for (i = 0; i < tabs.length; ++i) { addListeners(i); } function addListeners(index) { tabs[index].addEventListener("click", clickEventListener); tabs[index].addEventListener("keydown", keydownEventListener); tabs[index].addEventListener("keyup", keyupEventListener); // Build an array with all tabs (<button>s) in it tabs[index].index = index; } // When a tab is clicked, activateTab is fired to activate it function clickEventListener(event) { var tab = event.target; if (event.target.tagName == "SPAN") { tab = event.target.parentNode; } activateTab(tab, false); } // Handle keydown on tabs function keydownEventListener(event) { var key = event.keyCode; switch (key) { case keys.end: event.preventDefault(); // Activate last tab focusLastTab(); break; case keys.home: event.preventDefault(); // Activate first tab focusFirstTab(); break; // Up and down are in keydown // because we need to prevent page scroll >:) case keys.up: case keys.down: determineOrientation(event); break; } } // Handle keyup on tabs function keyupEventListener(event) { var key = event.keyCode; switch (key) { case keys.left: case keys.right: determineOrientation(event); break; case keys.delete: determineDeletable(event); break; case keys.enter: case keys.space: activateTab(event.target); break; } } // When a tablist's aria-orientation is set to vertical, // only up and down arrow should function. // In all other cases only left and right arrow function. function determineOrientation(event) { var key = event.keyCode; var vertical = tablist.getAttribute("aria-orientation") == "vertical"; var proceed = false; if (vertical) { if (key === keys.up || key === keys.down) { event.preventDefault(); proceed = true; } } else { if (key === keys.left || key === keys.right) { proceed = true; } } if (proceed) { switchTabOnArrowPress(event); } } // Either focus the next, previous, first, or last tab // depending on key pressed function switchTabOnArrowPress(event) { var pressed = event.keyCode; if (direction[pressed]) { var target = event.target; if (target.index !== undefined) { if (tabs[target.index + direction[pressed]]) { tabs[target.index + direction[pressed]].focus(); } else if (pressed === keys.left || pressed === keys.up) { focusLastTab(); } else if (pressed === keys.right || pressed == keys.down) { focusFirstTab(); } } } } // set up start state of info for tab animation states for (p = 0; p < panels.length; p++) { panels[p].style.position = "absolute"; panels[p].style.opacity = 0; } var currentActiveTab = document.querySelector( '.wm-info-for-menu .wm-js-tab-button[aria-selected="true"]' ); var currentActivePanel = document.getElementById( currentActiveTab.getAttribute("aria-controls") ); currentActivePanel.style.position = "static"; currentActivePanel.style.opacity = 1; // Activates any given tab panel function activateTab(tab, setFocus) { setFocus = setFocus || true; var oldActiveTab = document.querySelector( '.wm-info-for-menu .wm-js-tab-button[aria-selected="true"]' ); var oldActivePanel = document.getElementById( oldActiveTab.getAttribute("aria-controls") ); // Get the value of aria-controls (which is an ID) var controls = tab.getAttribute("aria-controls"); var newActivePanel = document.getElementById(controls); // fade out old; hidden // remove hidden; fade in new anime.set(oldActivePanel, { position: "absolute", hidden: "hidden", }); anime.set(newActivePanel, { position: "static", }); newActivePanel.removeAttribute("hidden"); var switchPanelTimeline = anime.timeline({ easing: "easeOutExpo", duration: 1500, }); switchPanelTimeline .add({ targets: oldActivePanel, opacity: 0, begin: function (anim) { // for some reason this wasn't being called on prod // replaced with anime.set functions above // oldActivePanel.style.position = "absolute"; // oldActivePanel.setAttribute("hidden", "hidden"); }, complete: function (anim) { // Remove hidden attribute from tab panel to make it visible }, }) .add( { targets: newActivePanel, opacity: 1, begin: function (anim) { // Remove hidden attribute from tab panel to make it visible // newActivePanel.removeAttribute("hidden"); // newActivePanel.style.position = "static"; }, }, 50 ); // Deactivate all other tabs //deactivateTabs(activePanel); for (t = 0; t < tabs.length; t++) { tabs[t].setAttribute("tabindex", "-1"); tabs[t].setAttribute("aria-selected", "false"); } // Remove tabindex attribute tab.removeAttribute("tabindex"); // Set the tab as selected tab.setAttribute("aria-selected", "true"); // Set focus when required if (setFocus) { tab.focus(); } // *** SET A "LAST TAB" COOKIE *** setInfoTabCookie("www_wm_tab", tab.getAttribute("id")); // update scroll bar visibility if (winWidth > 1024) { ps_infoformenu.update(); } } // Make a guess function focusFirstTab() { tabs[0].focus(); } // Make a guess function focusLastTab() { tabs[tabs.length - 1].focus(); } // Detect if a tab is deletable function determineDeletable(event) { target = event.target; if (target.getAttribute("data-deletable") !== null) { // Delete target tab deleteTab(event, target); // Update arrays related to tabs widget generateArrays(); // Activate the closest tab to the one that was just deleted if (target.index - 1 < 0) { activateTab(tabs[0]); } else { activateTab(tabs[target.index - 1]); } } } // Deletes a tab and its panel function deleteTab(event) { var target = event.target; var panel = document.getElementById(target.getAttribute("aria-controls")); target.parentElement.removeChild(target); panel.parentElement.removeChild(panel); } // Determine whether there should be a delay // when user navigates with the arrow keys function determineDelay() { var hasDelay = tablist.hasAttribute("data-delay"); var delay = 0; if (hasDelay) { var delayValue = tablist.getAttribute("data-delay"); if (delayValue) { delay = delayValue; } else { // If no value is specified, default to 300ms delay = 300; } } return delay; } // check cookie value and activate the initial tab var last_tab_id = getInfoTabCookie("www_wm_tab"); if (last_tab_id != "") { var last_tab = document.getElementById(last_tab_id); if (last_tab) { activateTab(last_tab, false); } } // Add Listeners to Footer info for links var footerinfos = document.querySelectorAll("[data-infofor]"); for (var i = 0; i < footerinfos.length; i++) { footerinfos[i].addEventListener( "click", function (event) { event.preventDefault(); var my_tab = document.getElementById( this.getAttribute("data-infofor") ); if (my_tab) { activateTab(my_tab, false); } openMenus("info", focusActiveTab); }, false ); } })(); } }); // pre-redesign code $(document).ready(function () { /*** setcopyright year in footer ***/ $("#footercopyyear").text(new Date().getFullYear()); // Hide focus outlines if this is a mouse or touch user window.addEventListener("touchstart", function () { $("body").addClass("mouseuser"); }); $("body, .bx-pager-link").mousedown(function () { $("body").addClass("mouseuser"); }); $("body").keyup(function (e) { var code = e.keyCode || e.which; if (code == "9") { $("body").removeClass("mouseuser"); } }); // Mobile slide-in Side Menu - still in use by grad schools 12-5-2022 $("#side_q").click(function () { $(this).focus(); }); $("#menu_btn").click(function (e) { e.stopPropagation(); if ($("#page-wrapper-inner").hasClass("page-push-right")) { $("#page-wrapper-inner").removeClass("page-push-right"); $("#page-wrapper-inner").one( "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function () { $("#side_menu").attr("aria-hidden", "true"); $("#page-wrapper-outer").removeClass("locked"); $(this).focus(); } ); return; } else { $("#side_menu").attr("aria-hidden", "false"); $("#page-wrapper-inner").addClass("page-push-right"); $("#page-wrapper-inner").one( "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function () { $("#page-wrapper-outer").addClass("locked"); $("#side_menu").focus(); } ); return; } }); $("#search_btn").click(function (e) { e.stopPropagation(); if ($("#page-wrapper-inner").hasClass("page-push-right")) { $("#page-wrapper-inner").removeClass("page-push-right"); $("#page-wrapper-inner").one( "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function () { $("#side_menu").attr("aria-hidden", "true"); $("#page-wrapper-outer").removeClass("locked"); $(this).focus(); } ); } else { $("#side_menu").attr("aria-hidden", "false"); $("#page-wrapper-inner").addClass("page-push-right"); $("#page-wrapper-inner").one( "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function () { $("#page-wrapper-outer").addClass("locked"); $("#side_search_site #side_q").focus(); } ); } }); // close menu with left swipe // $(".side-menu, .side-menu ul").swipe({ // swipeLeft: function (e, direction, distance, duration, fingerCount) { // e.stopPropagation(); // $("#page-wrapper-inner").removeClass("page-push-right"); // $("#page-wrapper-inner").one( // "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", // function () { // $("#side_menu").attr("aria-hidden", "true"); // $("#page-wrapper-outer").removeClass("locked"); // } // ); // return false; // }, // }); // close menu with esc key $(document).keyup(function (e) { if (e.keyCode == 27) { if ($("#page-wrapper-inner").hasClass("page-push-right")) { $("#page-wrapper-inner").removeClass("page-push-right"); $("#page-wrapper-inner").one( "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function () { $("#side_menu").attr("aria-hidden", "true"); $("#page-wrapper-outer").removeClass("locked"); } ); } } }); // close menu by touching the off-menu content $("#page-wrapper-inner").click(function (e) { if ( $("#page-wrapper-inner").hasClass("page-push-right") && $(e.target).parents(".side-menu").length == 0 ) { e.preventDefault(); e.stopPropagation(); $("#page-wrapper-inner").removeClass("page-push-right"); $("#page-wrapper-inner").one( "transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function () { $("#side_menu").attr("aria-hidden", "true"); $("#page-wrapper-outer").removeClass("locked"); } ); } }); // close menu (if open) when switching from mobile to desktop width $(window).resize(function () { bodyWidth = viewport().width; //$("body").width(); if (bodyWidth >= 990) { if ($("#page-wrapper-inner").hasClass("page-push-right")) { $("#page-wrapper-inner").removeClass("page-push-right"); $("#side_menu").attr("aria-hidden", "true"); $("#page-wrapper-outer").removeClass("locked"); $("#menu_btn").focus(); } } }); // curator.io feeds $("[data-curatorio-feed-id]").each(function () { var feedId = $(this).data("curatorio-feed-id"); $.getScript( "https://cdn.curator.io/published/" + feedId + ".js", function () { } ); }); }); function viewport() { var e = window, a = "inner"; if (!("innerWidth" in window)) { a = "client"; e = document.documentElement || document.body; } return { width: e[a + "Width"], height: e[a + "Height"] }; }