@bostonuniversity/bulib-wc
Version:
collection of web components and styles used at Boston University Libraries
378 lines (330 loc) • 16.8 kB
JavaScript
/** - BROWSER COMPATIBILITY HELPER - */
const DEBUG_BROWSER = false;
function logBrowserMessage(msg){
if(DEBUG_BROWSER){ console.log("_browserCompatibility) " + msg); }
}
/** determine the browser the code is being run on */
function doesBrowserSupportWebComponents(notifyGA){
// note: thanks to [stackoverflow](https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser/9851769) for the implementation
let isIE = !!document.documentMode;
let isEdge = !!window.StyleMedia;
let isFirefox60 = navigator.userAgent.includes("Firefox/60.");
let user_agent_supports_web_components = !isIE && !isEdge && !isFirefox60;
let browserGuess = "supported";
if(!user_agent_supports_web_components){
browserGuess = isIE? "ie" : isEdge? "edge (old)" : "firefox (old)";
logBrowserMessage("user_agent doesn't support browser guess: " + browserGuess);
// log google analytics event (duplicates sendGAEvent, but saves having to load it)
if(notifyGA !== undefined && notifyGA === true){
let category = "browser-compatibility";
let path = window.location.pathname;
if(window.gtag){ window.gtag('event', browserGuess, {'event_category':category, 'event_label':path}); }
else if(window.ga){ window.ga('send', category, browserGuess, path); }
}
}
// log the result
var supportsMessage = user_agent_supports_web_components ? ": ]" : ":(";
logBrowserMessage("user_agent_supports_web_components: " + supportsMessage);
return user_agent_supports_web_components;
};
/** determine, based on user_agent, which elements to show/hide given web components support */
function loadWebComponentInto(tagname, replacedElements){
var user_agent_supports_web_components = doesBrowserSupportWebComponents(false);
// determine which elements to hide
var elementsToHide = user_agent_supports_web_components
? replacedElements // hide replaced elements if the web components worked,
: document.getElementsByTagName(tagname) // hide the contents of the custom tag if they don't (avoid showing 'slotted' coni)
;
// do the hiding
for(var i=0; i<elementsToHide.length; i++){ elementsToHide[i].hidden = true; }
};
/** - GOOGLE ANALYTICS HELPER - */
var DEBUG_ANALYTICS = false;
var PREVENT_GA_CALL = false;
function logGoogleAnalyticsMessage(message){
if(DEBUG_ANALYTICS){ console.log("google_analytics_helper) " + message); }
}
function sendGAEvent(eventName, action, label, value){
/** note: this assumes that a 'gtag' or a 'ga' has already been initialized/added to `window` */
let value_text = (value == null) || (value == undefined) ? "": `, value='${value}'`;
logGoogleAnalyticsMessage(`request made to sendGAEvent('${eventName}', '${action}', '${label}'${value_text})`);
try{
if(window.gtag && !PREVENT_GA_CALL){
window.gtag('event', action, {
'event_category': eventName, 'event_label': label, 'value': value
});
logGoogleAnalyticsMessage("window.gtag() found and called");
}else if(window.ga && !PREVENT_GA_CALL){
window.ga('send', eventName, action, label);
logGoogleAnalyticsMessage("window.ga() found and called");
}else{
logGoogleAnalyticsMessage(`event '${eventName}' was NOT SENT to either 'ga()' nor 'gtag()' [PREVENT_GA_CALL='${PREVENT_GA_CALL}']`);
}
}catch(err){
logGoogleAnalyticsMessage("ERROR! - unable to sendGAEvent with gtag, ga, or nothing.");
if(DEBUG_ANALYTICS){ console.log(err); }
}
}
function sendGAEventFromClickEvent(clickEvent, eventName, actionName){
let contentClicked = "[unknown]";
// obtain a label for the clicked link from its markup
try{
contentClicked = clickEvent.target.innerText
? clickEvent.target.innerText
: clickEvent.target.querySelector("span").innerText
|| "[unknown]";
contentClicked = contentClicked.replace(/[^a-zA-Z0-9 ]/g, ''); // remove special characters
contentClicked = contentClicked.toLowerCase().replace(/ +/g,"-"); // slugify (lowercase, dashes)
}catch(err){
logGoogleAnalyticsMessage("error getting contentClicked from clickEvent: ");
if(DEBUG_ANALYTICS){ console.log(err); }
}
// allow user to specify an actionName as well as the eventName, pushing contentClicked into the label
if(!actionName || actionName == ""){
logGoogleAnalyticsMessage(`actionName considered 'undefined' or empty. sending action:'${contentClicked}', label:'${window.location.pathname}'.`)
sendGAEvent(eventName, contentClicked, window.location.pathname);
}else{
logGoogleAnalyticsMessage(`actionName '${actionName}' registered as a real value, sending action with label as contentClicked: '${contentClicked}'`)
sendGAEvent(eventName, actionName, contentClicked);
}
}
function addSendGAEventOnAnchorClickToAnchorElements(anchorElements, eventName, actionName){
logGoogleAnalyticsMessage(`adding click listeners with eventName:'${eventName}', actionName:'${actionName}'`);
for(let i=0; i<anchorElements.length; i++){
anchorElements[i].addEventListener("click", (ev) => sendGAEventFromClickEvent(ev, eventName, actionName));
}
}
/** - LIBRARY INFO HELPER - */
const INFO_HELPER_DEBUG = false;
function logLibInfoToConsole(message, debug){
if(debug && debug === true){ console.log("lib_info_helper) " + message); }
};
// static data about each library, powering LoCoSo, LibHours
const libraries_data_backup = {
"mugar-memorial":{
"name":"Mugar Memorial Library",
"short":"Mugar Library",
"website":"https://www.bu.edu/library/mugar-memorial/",
"address":["771 Commonwealth Avenue","Boston, MA 02215"],
"contacts":{"phone":"617-353-2700","email":"ask@bu.edu"},
"social":{"facebook":"bostonulibraries","twitter":"bulibraries","instagram":"bulibraries"},
"hours_url": "https://www.bu.edu/library/mugar-memorial/about/hours/",
"libcal_lid": 1475
},"african-studies":{
"name":"African Studies Library",
"short":"African Studies",
"website":"https://www.bu.edu/library/african-studies/",
"address":["771 Commonwealth Ave, 6th Floor","Boston, MA, 02215"],
"contacts":{"phone":"617-353-3726"},
"social":{"facebook":"BuAfricanStudiesLibrary","flickr":"123460528@N03"},
"hours_url":"https://www.bu.edu/library/african-studies/about/hours/",
"libcal_lid":1809
},"medlib":{
"name":"Alumni Medical Library",
"short":"Medical Library",
"website":"https://medlib.bu.edu/",
"address":["72 E Concord, L-12","Boston, MA 02118"],
"contacts":{"phone":"617-358-2350","fax":"617-358-2347","email":"refquest@bu.edu"},
"hours_url": "https://www.bumc.bu.edu/medlib/about-us/hours/"
},"astronomy":{
"name":"Astronomy Library",
"short":"Astronomy Library",
"website":"https://www.bu.edu/library/astronomy/",
"address":["725 Commonwealth Avenue","Boston, MA 02445"],
"contacts":{"phone":"617-353-2625"},
"hours_url":"https://www.bu.edu/library/astronomy/about/hours/",
"libcal_lid":1784
},"lawlibrary":{
"name":"Fineman & Pappas Law Libraries",
"short":"Law Library",
"website":"https://www.bu.edu/lawlibrary/",
"address":["765 Commonwealth Ave, 2nd Floor","Boston, MA 02215"],
"contacts":{"phone":"617-353-8411","text":"1-617-997-4475"},
"hours_url":"https://www.bu.edu/lawlibrary/using-the-library/access-policy/"
},"hgar":{
"name":"Howard Gotlieb Archival Research Center",
"short":"BU Archive",
"website":"http://archives.bu.edu/",
"address":["771 Commonwealth Ave, 5th Floor","Boston, MA 02215"],
"contacts":{"phone":"617-353-3696","fax":"617-353-2838","email":"archives@bu.edu"},
"social":{"facebook":"hgarc","twitter":"BUHGARC"},
"hours_url":"http://archives.bu.edu/web/guest/about"
},"music":{
"name":"Music Library",
"short":"Music Library",
"website":"https://www.bu.edu/library/music/",
"address":["771 Commonwealth Ave, Floor 2","Boston, MA 02215"],
"contacts":{"phone":"617-353-3705","email":"musiclib@bu.edu"},
"social":{"twitter":"BUMusicLib","facebook":"bumusiclib"},
"hours_url":"https://www.bu.edu/library/music/about/hours/",
"libcal_lid":1810
},"pardee":{
"name":"Pardee Management Library",
"short":"Pardee Library",
"website":"https://www.bu.edu/library/management/",
"address":["595 Commonwealth Avenue","Boston, MA 02215"],
"contacts":{"phone":"617-353-4301","fax":"617-353-4307","email":"pardstf@bu.edu"},
"social":{"twitter":"BUpardeelibrary","facebook":"BUpardeelibrary"},
"hours_url":"https://www.bu.edu/library/management/about/hours/",
"libcal_lid":1476
},"pickering":{
"name":"Pickering Educational Resources Library",
"short":"Pickering Library",
"website":"https://www.bu.edu/library/pickering-educational/",
"address":["2 Silber Way","Boston, MA 02215"],
"contacts":{"phone":"617-353-3734"},
"social":{"twitter":"BUPickeringLib","facebook":"BUPickeringLibrary"},
"hours_url":"https://www.bu.edu/library/pickering-educational/about/hours",
"libcal_lid":1783
},"sel":{
"name":"Science & Engineering Library",
"short":"SciEng Library",
"website":"https://www.bu.edu/library/sel/",
"address":["38 Cummington Mall","Boston, MA 02215"],
"contacts":{"phone":"617-353-3733","fax":"617-353-3470"},
"social":{"twitter":"BUSciEngLib","tumblr":"buscienglib","instagram":"buscienglib"},
"hours_url":"https://www.bu.edu/library/sel/about/hours/",
"libcal_lid":1477
},"stone":{
"name":"Stone Science Library",
"short":"Stone Library",
"website":"https://www.bu.edu/library/stone-science/",
"address":["675 Commonwealth Ave, Room 440","Boston, MA 02445"],
"contacts":{"phone":"617-353-5679"},
"hours_url":"https://www.bu.edu/library/stone-science/about/hours/",
"libcal_lid":1785
},"theology":{
"name":"School of Theology Library",
"short":"Theology Library",
"website":"https://www.bu.edu/sthlibrary/",
"address":["745 Commonwealth Ave, Floor 2","Boston, MA 02215"],
"contacts":{"phone":"617-353-3034","fax":"617-358-0698","email":"sthlib@bu.edu"},
"social":{"twitter":"BUSTHLibrary","facebook":"busthlibrary","instagram":"butheologylibrary"},
"hours_url":"https://www.bu.edu/sthlibrary/for-visitors/directions/"
},"help":{
"name":"BU Libraries",
"short":"BU Libraries",
"website":"https://www.bu.edu/library",
"address":["771 Commonwealth Avenue","Boston, MA 02215"],
"contacts":{"phone":"617-353-2700","email":"ask@bu.edu","text":"617-431-2427"},
"social":{"facebook":"bostonulibraries","twitter":"bulibraries","instagram":"bulibraries"},
"hours_url": "https://www.bu.edu/library/mugar-memorial/about/hours/",
"libcal_lid": 1475
}
};
function getLibraryInfoFromCode(lib_code, debug, defLibCode){
if(debug === undefined){ debug = INFO_HELPER_DEBUG; }
if(defLibCode === undefined){ defLibCode = "help"; }
let libraries_data = /* TODO: _getDataFromFile("lib_info.json") || */ libraries_data_backup;
let library_data = libraries_data[lib_code] || libraries_data[defLibCode];
logLibInfoToConsole(`getting library_data for code: '${lib_code}' with default '${defLibCode}'.`, debug);
return library_data;
}
function getSiteCodeFromUrl(url, debug, defSiteCode){
if(debug === undefined){ debug = INFO_HELPER_DEBUG; }
if(defSiteCode === undefined){ defSiteCode="help"; }
let site_code = "about";
if(url.includes("askalibrarian")){ site_code = "help"; }
else if(url.includes("/disc/") || url.includes("/dioa")){ site_code ="services"; }
else if(url.includes("open.bu") || url.includes("archives")){ site_code = "collections"; }
else if(url.includes("guides") || url.includes("library.bu.edu")){ site_code = "guides" }
else if(url.includes("buprimo") || url.includes("exlibrisgroup") || url.includes("primo-explore")){ site_code = "search"; }
else if(url.includes(".bu.edu/library")){
if(url.includes("/research")){ site_code = "research"; }
else if(url.includes("/services")){ site_code = "services"; }
else{ site_code = "about"; }
}else{ site_code = "about"; }
logLibInfoToConsole(`site_code '${site_code}' extracted from url '${url}'.`, debug);
return site_code;
}
function getLibraryCodeFromUrl(lib_url, debug, defLibCode){
if(debug === undefined){ debug = INFO_HELPER_DEBUG; }
if(defLibCode === undefined){ defLibCode="help"; }
let lib_code = defLibCode;
if(lib_url.includes("archives.bu.edu")){ lib_code="hgar"; }
// main wordpress site
if(lib_url.includes("bu.edu/library/")){
// try to get {library_code} from url 'http://www.bu.edu/library/{stone-science}/research/guides/'
let lib_url_fragment = lib_url.split("bu.edu/library/")[1] || "";
lib_url_fragment = lib_url_fragment.split("/")[0];
// set library code based on url fragment
if(lib_url_fragment.includes("africa")){ lib_code = "african-studies"; }
else if(lib_url_fragment.includes("mugar")){ lib_code = "mugar-memorial"; }
else if(lib_url_fragment.includes("med")){ lib_code = "medlib"; }
else if(lib_url_fragment.includes("astronom")){ lib_code = "astronomy"; }
else if(lib_url_fragment.includes("law")){ lib_code = "lawlibrary"; }
else if(lib_url_fragment.includes("music")){ lib_code = "music"; }
else if(lib_url_fragment.includes("management")){ lib_code = "pardee"; }
else if(lib_url_fragment.includes("pickering")){ lib_code = "pickering"; }
else if(lib_url_fragment.includes("sel")){ lib_code = "sel"; }
else if(lib_url_fragment.includes("stone")){ lib_code = "stone"; }
else if(lib_url_fragment.includes("sth")){ lib_code = "stone"; }
else { lib_code = "help"; }
}
// reserve a room
if(lib_url.includes("booking/mugarstudy")){ lib_code = "mugar-memorial"; }
else if(lib_url.includes("booking/Pickering")){ lib_code = "pickering"; }
// floorplans
if(lib_url.includes("maps-floorplans/mugar")){
lib_code = "mugar-memorial";
if(lib_url.includes("mugar-2")){ lib_code = "music"; }
else if(lib_url.includes("mugar-6")){ lib_code = "african-studies"; }
}
// askalibrarian
if(lib_url.includes("askalibrarian") && lib_url.includes("business")){ lib_code = "pardee"; }
if(!Object.keys(libraries_data_backup).includes(lib_code)){ lib_code = "help"; }
// return resulting code
logLibInfoToConsole(`lib_code '${lib_code}' from lib_url '${lib_url}'`, debug);
return lib_code;
}
function getAllLibraryInfo(){ return libraries_data_backup; }
function makeLibraryUrlList(){
let ls_items = ""; let code;
for(code in libraries_data_backup){
let item = getLibraryInfoFromCode(code)
ls_items += `\t<li href="${item.website}">${item.name}"<li>\n`;
}
return `<ul>\n${ls_items}</ul>\n`;
};
/** - STORAGE UTILITY - */
const DEBUG_STORAGE_UTIL = false;
const DEFAULT_STORAGE_EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 3; // 3 days (for now)
function logStorageMessage(msg){ if(DEBUG_STORAGE_UTIL){ console.log("_storageUtility) " + msg); }}
/** try reading a value from local memory with a given fallback */
function readExpiringLocalValue(keyName, fallback){
var valueToReturn = fallback || false;
try{
// look in localStorage for our announcement-dismissed variables
var storedValue = localStorage.getItem(keyName);
var lastUpdated = localStorage.getItem(keyName+"-when");
// if both localStorage values are present...
if(!!storedValue && !!lastUpdated){
// if it hasn't 'expired', query the value :
if( (Date.now() - lastUpdated) < DEFAULT_STORAGE_EXPIRATION_TIME){
valueToReturn = localStorage.getItem(keyName) == "true";
logStorageMessage(`unexpired '${keyName}' value of '${storedValue}' read from localStorage`);
// if it has expired, reset/remove it
}else{
localStorage.removeItem(keyName);
localStorage.removeItem(keyName+"-when");
logStorageMessage(`expired '${keyName}*' values have been removed. will be sending fallback of '${fallback}'`);
}
}
}catch(exception){
logStorageMessage(`exception trying to get item '${keyName}' from localStorage: '${exception.message}'. returning fallback '${fallback}' instead`);
valueToReturn = fallback || false;
}finally{
return valueToReturn;
}
}
/** try setting a value from local memory with a timestamp of when it was set */
function setExpiringLocalValue(keyName, value){
try{ // note: safari breaks with a security error any time 'localStorage' is accessed
localStorage.setItem(keyName, value);
localStorage.setItem(keyName+"-when", Date.now());
logStorageMessage(`key '${keyName}' successfully set to value '${value}'.`)
}
catch(exception){
logStorageMessage("exception trying to setItem in localStorage: " + exception.message);
}
}