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 = "…";
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"] };
}