1class ClassBC 2{ 3 constructor() 4 { 5 let me = this; 6 this.root = document.currentScript.getAttribute("src"); 7 this.root = this.root.substring(0, this.root.lastIndexOf("/")+1); 8 this.version = BC.version; 9 this.modules = {}; 10 this.widgets = {}; 11 this.info = {}; 12 this.queryParameters = new URLSearchParams(location.search); 13 this.vimeoAPI = this.byId("vimeo-api"); 14 15 //touch 16 document.body.classList.add((("ontouchstart" in window ) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) ? "touch" : "no-touch"); 17 //keyboard navigation 18 document.body.addEventListener("keydown", (e)=> 19 { 20 if (e.key === "Tab") 21 { 22 document.body.classList.add("keyboard-navigation-engaged"); 23 } 24 }); 25 document.body.addEventListener("pointerdown", (e)=> 26 { 27 document.body.classList.remove("keyboard-navigation-engaged"); 28 }); 29 } 30 byId(q) {return document.getElementById(q);} 31 byClass(q, e = document) {return e.getElementsByClassName(q)[0];} 32 byTag(q, e = document) {return e.getElementsByTagName(q)[0];} 33 byQuery(q, e = document) {return e.querySelector(q);} 34 arrayByClass(q, e = document) {return Array.from(e.getElementsByClassName(q));} 35 arrayByTag(q, e = document) {return Array.from(e.getElementsByTagName(q));} 36 arrayByQuery(q, e = document) {return Array.from(e.querySelectorAll(q));} 37 go(fns) 38 { 39 fns.forEach(function(i){i();}); 40 this.ready = true; 41 this.scanWidgets(); 42 } 43 module(name, noScript) 44 { 45 let me = this; 46 let module = this.modules[name]; 47 if (!module) 48 { 49 module = {}; 50 module.ready = new Promise(function(resolve) 51 { 52 module.init = function(cl) 53 { 54 let object = new cl(); 55 me[name.toUpperCase()] = object; 56 if (object.widgetClass) 57 { 58 me.activateWidgets(name); 59 } 60 resolve(object); 61 }; 62 }); 63 this.modules[name] = module; 64 if (!noScript) 65 { 66 this.addModuleScript(name); 67 } 68 } 69 return module; 70 } 71 moduleReady(name) 72 { 73 return this.module(name).ready; 74 } 75 initModule(name, cl, noScript) 76 { 77 this.module(name, noScript).init(cl); 78 } 79 require(modules) 80 { 81 let me = this; 82 return new Promise(function(resolve, reject) 83 { 84 if ((typeof modules === "string") && (modules.length > 0)) 85 { 86 modules = modules.toLowerCase().split(" "); 87 modules = modules.map(function(i){return me.module(i).ready;}); 88 Promise.all(modules).then(function(){resolve();}); 89 } 90 else 91 { 92 reject("Dependencies as space-separated string required."); 93 } 94 }); 95 } 96 getModuleScript(name) 97 { 98 let src = this.root+"modules/"+name+".js"; 99 return this.byQuery("script[src='"+src+"']"); 100 } 101 addModuleScript(name) 102 { 103 name = name.toLowerCase(); 104 if (!this.getModuleScript(name)) 105 { 106 let script = document.createElement("script"); 107 script.src = this.root+"modules/"+name+".js?version="+this.version; 108 document.head.appendChild(script); 109 } 110 } 111 widget(base) 112 { 113 let me = this; 114 if (base) 115 { 116 let type = base.getAttribute("data-bc-widget"); 117 if (type) 118 { 119 let module = this.module(type); 120 let widget = null; 121 if (this.widgets[type]) 122 { 123 widget = this.widgets[type].find(function(i){return (i.base === base);}); 124 } 125 else 126 { 127 this.widgets[type] = []; 128 } 129 if (!widget) 130 { 131 widget = { 132 base:base, 133 type:type, 134 active:false 135 }; 136 widget.ready = new Promise(function(resolve, reject) 137 { 138 widget.init = function() 139 { 140 module.ready.then(function(object) 141 { 142 if (object.widgetClass) 143 { 144 resolve(new object.widgetClass(base)); 145 } 146 else 147 { 148 reject("No widget defined for module ("+type+")."); 149 } 150 }); 151 }; 152 }); 153 this.widgets[type].push(widget); 154 } 155 module.ready.then(function() 156 { 157 me.activateWidget(widget); 158 }); 159 return widget; 160 } 161 else 162 { 163 console.error({base:base,error:"No widget type found."}); 164 } 165 } 166 else 167 { 168 console.error("No widget base provided."); 169 } 170 } 171 widgetReady(base) 172 { 173 return this.widget(base).ready; 174 } 175 scanWidgets() 176 { 177 let me = this; 178 this.arrayByQuery("[data-bc-widget]").forEach(function(i){me.widget(i);}); 179 } 180 activateWidgets(type) 181 { 182 let me = this; 183 if (this.widgets[type]) 184 { 185 this.widgets[type].forEach(function(i){me.activateWidget(i);}); 186 } 187 } 188 activateWidget(widget) 189 { 190 if (!widget.active) 191 { 192 widget.active = true; 193 let init = widget.base.getAttribute("data-init"); 194 if (init && init.length > 0) 195 { 196 //init the widget based on the declared initiation process (time delay, scroll into view, defer to another widget, etc.) 197 init = init.toLowerCase().split(" "); 198 let method = init[0]; 199 if (method === "delay") 200 { 201 let ms = init[1] ? parseInt(init[1]) : 0; 202 setTimeout(function(){widget.init();}, ms); 203 } 204 } 205 else 206 { 207 widget.init(); 208 } 209 } 210 } 211} 212let bcInstance = new ClassBC(); 213 214bcInstance.initModule("util", class 215{ 216 constructor(){} 217 getQueryParameter(p) 218 { 219 return BC.queryParameters.get(p); 220 } 221 getQueryParameters(ps) 222 { 223 let me = this; 224 let values = {array:[]}; 225 for (const i of ps) 226 { 227 let v = me.getQueryParameter(i); 228 if (v) 229 { 230 values[i] = {name:i, value:v}; 231 values.array.push(values[i]); 232 } 233 } 234 return values; 235 } 236 getLinkQueryParameter(link, p) 237 { 238 return new URLSearchParams(link.search).get(p); 239 } 240 setLinkQueryParameter(link, value) 241 { 242 let params = new URLSearchParams(link.search); 243 params.set(value.name, value.value); 244 link.search = params.toString(); 245 } 246 forwardQueryParameters(values, links) 247 { 248 for (const i of links) 249 { 250 for (const j of values.array) 251 { 252 this.setLinkQueryParameter(i, j); 253 } 254 } 255 } 256 forwardQuery(ps, selector) 257 { 258 this.forwardQueryParameters(this.getQueryParameters(ps), BC.arrayByQuery(selector)); 259 } 260 forwardUTM(selector) 261 { 262 this.forwardQuery(["utm_source","utm_medium","utm_campaign","utm_term","utm_content"], selector); 263 } 264 forwardBCTM() 265 { 266 console.log("forward BCTM"); 267 } 268 bctm() 269 { 270 let source = this.getQueryParameter("bctm_source"); 271 if (source) 272 { 273 let links = this.getLinks(true, ["media.benedictine.edu","events.benedictine.edu","apply.benedictine.edu"]); 274 for (const i of links) 275 { 276 let linkSource = this.getLinkQueryParameter(i, "bctm_source"); 277 if (linkSource) 278 { 279 linkSource = linkSource + "---" + source; 280 } 281 else 282 { 283 linkSource = source; 284 } 285 this.setLinkQueryParameter(i, {name:"bctm_source", value:linkSource}); 286 } 287 } 288 289 /* 290 //external 291 if ((!values["bctm_referrer_external"]) && (document.referrer) && (!document.referrer.includes("www.benedictine.edu"))) 292 { 293 values["bctm_referrer_external"] = {name:"bctm_referrer_external", value:document.referrer}; 294 values.array.push(values["bctm_referrer_external"]); 295 } 296 297 //url of current page 298 values["bctm_referrer_url"] = {name:"bctm_referrer_url", value:host+path}; 299 values.array.push(values["bctm_referrer_url"]); 300 301 this.forwardQueryParameters(values, links); 302 */ 303 } 304 getInternalLinks() 305 { 306 return BC.arrayByTag("a").filter((i) => 307 { 308 if (i.getAttribute("href")?.charAt(0) !== "#") 309 { 310 try 311 { 312 let url = new URL(i.href); 313 return ((url.hostname === location.hostname) && (!url.pathname.includes("/wp-admin"))); 314 } 315 catch (error) {return false;} 316 } 317 }); 318 } 319 getLinks(internal, sites, selector) 320 { 321 let links = (internal) ? this.getInternalLinks() : []; 322 if (sites) 323 { 324 sites = "a[href*=\"//"+sites.join("\"], a[href*=\"//")+"\"]"; 325 links = links.concat(BC.arrayByQuery(sites)); 326 } 327 if (selector) 328 { 329 links = links.concat(BC.arrayByQuery(selector)); 330 } 331 if (links.length) 332 { 333 links = Array.from(new Set(links)); 334 return links; 335 } 336 } 337 getFocusableChildren(element) 338 { 339 return BC.arrayByQuery("a[href], button, input, textarea, select, details, [tabindex=\"0\"]", element); 340 } 341 setClick(element, fn) 342 { 343 element.addEventListener("click", function(e){fn(e);}); 344 } 345 setSpace(element, fn) 346 { 347 element.addEventListener("keydown", function(e) 348 { 349 if ((e.key === " ") || (e.key === "Space")) 350 { 351 fn(e); 352 } 353 }); 354 } 355 setTab(element, fn) 356 { 357 element.addEventListener("keydown", function(e) 358 { 359 if (e.key === "Tab") 360 { 361 fn(e); 362 } 363 }); 364 } 365 tabLoop(e, first, last) 366 { 367 if (first !== last) 368 { 369 let active = document.activeElement; 370 if (e.shiftKey) 371 { 372 if (active === first) 373 { 374 last.focus(); 375 e.preventDefault(); 376 } 377 } 378 else 379 { 380 if (active === last) 381 { 382 first.focus(); 383 e.preventDefault(); 384 } 385 } 386 } 387 else 388 { 389 e.preventDefault(); 390 } 391 } 392 shellActivate(shell) 393 { 394 //creates an element based on a placeholder element 395 let tag = shell.getAttribute("data-shell"); 396 if ((tag) && (!tag.includes("activated"))) 397 { 398 let attributes = shell.getAttribute("data-attributes"); 399 attributes = (attributes) ? attributes.split(" ") : []; 400 let element = document.createElement(tag);
401 attributes.forEach((i) => 402 { 403 let a = shell.getAttribute("data-"+i); 404 if (a) 405 { 406 element.setAttribute(i, a); 407 } 408 }); 409 shell.appendChild(element); 410 shell.setAttribute("data-shell", tag+" activated"); 411 } 412 } 413 wrapperSpin(wrapper, task, after, cancelOnFailure) 414 { 415 let me = this; 416 let enter = new Promise(function(resolve) 417 { 418 wrapper.classList.add("_spin"); 419 setTimeout(function(){resolve();}, 250); 420 }) 421 .then(function() 422 { 423 wrapper.classList.add("_hide"); 424 task() 425 .then(function() 426 { 427 let exit = new Promise(function(resolve) 428 { 429 wrapper.classList.remove("_hide"); 430 wrapper.classList.remove("_spin"); 431 setTimeout(function(){resolve();}, 250); 432 }).then(function(){return after();}); 433 }) 434 .catch(function() 435 { 436 //if the task fails, only exit spin state if specified 437 if (cancelOnFailure) 438 { 439 let exit = new Promise(function(resolve) 440 { 441 wrapper.classList.remove("_hide"); 442 wrapper.classList.remove("_spin"); 443 setTimeout(function(){resolve();}, 250); 444 }).then(function(){return after();}); 445 } 446 }); 447 }); 448 } 449 widgetPreparePostRequest(widget) 450 { 451 let r = {}; 452 let base = widget.base; 453 r["site"] = base.getAttribute("data-site"); 454 r["site"] = (r["site"]) ? "https://"+r["site"]+"/" : "/"; 455 r["per-page"] = base.getAttribute("data-per-page"); 456 r["page"] = base.getAttribute("data-page"); 457 r["types"] = base.getAttribute("data-types"); 458 r["excludes"] = base.getAttribute("data-excludes"); 459 r["categories"] = base.getAttribute("data-categories"); 460 r["x-categories"] = base.getAttribute("data-x-categories"); 461 r["videos"] = base.getAttribute("data-videos"); 462 r["x-videos"] = base.getAttribute("data-x-videos"); 463 r["podcasts"] = base.getAttribute("data-podcasts"); 464 r["x-podcasts"] = base.getAttribute("data-x-podcasts"); 465 r["lectures"] = base.getAttribute("data-lectures"); 466 r["x-lectures"] = base.getAttribute("data-x-lectures"); 467 r["associations"] = base.getAttribute("data-associations"); 468 r["x-associations"] = base.getAttribute("data-x-associations"); 469 r["lists"] = base.getAttribute("data-lists"); 470 r["x-lists"] = base.getAttribute("data-x-lists"); 471 r["contributors"] = base.getAttribute("data-contributors"); 472 r["x-contributors"] = base.getAttribute("data-x-contributors"); 473 r["unlisted"] = base.getAttribute("data-unlisted"); 474 r["item-template"] = base.getAttribute("data-item-template") || "entry"; 475 r["item-args"] = base.getAttribute("data-item-args"); 476 if (r["item-args"]) 477 { 478 let args = r["item-args"].split("|"); 479 r["item-args"] = {}; 480 for (let i=0; i<args.length-1; i+=2) 481 { 482 r["item-args"][args[i]] = args[i+1]; 483 } 484 } 485 r["item-image-args"] = base.getAttribute("data-item-image-args"); 486 if (r["item-image-args"]) 487 { 488 let args = r["item-image-args"].split("|"); 489 r["item-args"]["image-args"] = {}; 490 for (let i=0; i<args.length-1; i+=2) 491 { 492 r["item-args"]["image-args"][args[i]] = args[i+1]; 493 } 494 } 495 widget.postRequest = r; 496 console.log(r); 497 } 498 widgetMakePostRequest(widget) 499 { 500 let r = widget.postRequest; 501 let path = r["site"]+"wp-json/custom/v1/posts"; 502 let added = false; 503 let addField = function(v) 504 { 505 if (r[v]) 506 { 507 let d = (added) ? "&" : "?"; 508 path += d+v+"="+r[v]; 509 added = true; 510 } 511 }; 512 addField("per-page"); 513 addField("page"); 514 addField("types"); 515 addField("excludes"); 516 addField("categories"); 517 addField("x-categories"); 518 addField("videos"); 519 addField("x-videos"); 520 addField("podcasts"); 521 addField("x-podcasts"); 522 addField("lectures"); 523 addField("x-lectures"); 524 addField("associations"); 525 addField("x-associations"); 526 addField("lists"); 527 addField("x-lists"); 528 addField("contributors"); 529 addField("x-contributors"); 530 addField("unlisted"); 531 return new Promise(function(resolve, reject) 532 { 533 BC.GET.posts(path) 534 .then(function(response) 535 { 536 console.log(response); 537 response.elements = []; 538 response.data.objects.forEach(function(i) 539 { 540 i = Object.assign(i, r["item-args"]); 541 console.log(i); 542 response.elements.push(bcInstance.GENERATOR.generate(r["item-template"], i)); 543 }); 544 resolve(response); 545 }) 546 .catch(function(err) 547 { 548 reject(err); 549 }); 550 }); 551 } 552 vimeo() 553 { 554 return new Promise((resolve) => 555 { 556 if (window.Vimeo) 557 { 558 resolve(window.Vimeo); 559 } 560 else if (BC.vimeoAPI) 561 { 562 BC.vimeoAPI.onload = () => 563 { 564 resolve(window.Vimeo); 565 } 566 } 567 else 568 { 569 BC.vimeoAPI = document.createElement("script"); 570 BC.vimeoAPI.src = "https://player.vimeo.com/api/player.js"; 571 document.head.appendChild(BC.vimeoAPI);
572 BC.vimeoAPI.onload = () => 573 { 574 resolve(window.Vimeo); 575 } 576 } 577 }); 578 } 579}, true); 580 581bcInstance.initModule("get", class 582{ 583 constructor(){} 584 json(path) 585 { 586 return new Promise(function(resolve, reject) 587 { 588 fetch(path) 589 .then(function(response) 590 { 591 response.json() 592 .then(function(data) 593 { 594 resolve({path:path,data:data}); 595 }) 596 .catch(function() 597 { 598 reject("Could not process as JSON: "+path); 599 }); 600 }) 601 .catch(function() 602 { 603 reject("Could not fetch: "+path); 604 }); 605 }); 606 } 607 posts(path) 608 { 609 let me = this; 610 return new Promise(function(resolve, reject) 611 { 612 me.json(path) 613 .then(function(response) 614 { 615 response.data.objects.forEach(function(i) 616 { 617 i.link = (!i.link.includes("http")) ? response.data.base+i.link : i.link.replace(/\\/g, ""); 618 if (i.images) 619 { 620 Object.values(i.images).forEach(function(j) 621 { 622 if (j) 623 { 624 j.base = response.data.base; 625 j.uploads = response.data.uploads; 626 } 627 }); 628 } 629 }); 630 resolve(response); 631 }) 632 .catch(function(err) 633 { 634 reject(err); 635 }); 636 }); 637 } 638 all(paths, fn) 639 { 640 let me = this; 641 return Promise.all(paths.map(function(i) 642 { 643 return me[fn](i); 644 })); 645 } 646}, true); 647 648bcInstance.initModule("generator", class 649{ 650 constructor() 651 { 652 this.templates = {}; 653 }
654 generate(template, args) 655 { 656 if (typeof template === "string") //if using a built-in function 657 { 658 if (this.templates[template]) 659 { 660 return this.templates[template](args, this); 661 } 662 } 663 else if (typeof template === "function") //if using a provided function 664 { 665 return template(args, this); 666 } 667 } 668 make(item) 669 { 670 if ((item.iif) || (typeof item.iif === "undefined")) 671 { 672 if (item.tem) //if the item is a link to another template 673 { 674 return this.generate(item.tem, item.arg); 675 } 676 else 677 { 678 //create the HTML element based on the item's properties 679 let element = document.createElement(item.e[0]); 680 for (let i=1; i<item.e.length-1; i+=2) 681 { 682 let attribute = item.e[i]; 683 let value = item.e[i+1]; 684 if (attribute === "class") 685 { 686 element.className = value; 687 } 688 else if (attribute === "href") 689 { 690 element.href = value; 691 } 692 else if (attribute === "innerHTML") 693 { 694 element.innerHTML = value; 695 } 696 else 697 { 698 if (value !== "!null") //special value indicating that attribute should not be added (as opposed to adding an empty attribute) 699 { 700 element.setAttribute(attribute, value); 701 } 702 } 703 } 704 if (item.c) //if the item has children 705 { 706 let num = (item.loo) ? item.loo.length : 1; 707 for (let i=0; i<num; i++) 708 { 709 for (let j=0; j<item.c.length; j++) 710 { 711 if (item.loo) 712 { 713 item.c[j].arg = item.loo[i]; 714 } 715 let child = this.make(item.c[j]); 716 if (child) 717 { 718 element.appendChild(child); 719 } 720 } 721 } 722 } 723 return element; 724 } 725 } 726 } 727 addTemplate(name, template) 728 { 729 if (!this.templates[name]) 730 { 731 this.templates[name] = template; 732 } 733 else 734 { 735 console.error("Template with name '"+name+"' already exists.'"); 736 } 737 } 738}, true); 739 740bcInstance.GENERATOR.addTemplate("image", function(a, generator) 741{ 742 let image = a['image']; 743 if ((image) && (image.sizes)) 744 { 745 let base = image.base || "/"; 746 let uploads = image.uploads || "wp-content/uploads/"; 747 let branch = image.branch; 748 let name = image.name; 749 let ext = image.ext; 750 let alt = image.alt; 751 752 let sizes = a['sizes'] || "600px"; 753 let def = a['default'] || 1600; 754 let media = a['media']; 755 let classes = a['classes']; 756 757 let srcset = ""; 758 let src = null; 759 let last = null;
760 image.sizes.forEach(function(i, index) 761 { 762 let width = i[0]; 763 let height = i[1]; 764 let halfWidth = Math.floor(width / 2); 765 if (index > 0) 766 { 767 srcset += ", "; 768 } 769 srcset += base+uploads+branch+name+"-"+width+"x"+height+"."+ext+" "+halfWidth+"w"; 770 if ((!src) && (width >= def)) 771 { 772 src = [width, height]; 773 } 774 last = i; 775 }); 776 if ((!src) && (last)) 777 { 778 src = [last[0], last[1]]; 779 } 780 let width = src[0]; 781 let height = src[1]; 782 src = base+uploads+branch+name+"-"+width+"x"+height+"."+ext; 783 784 if (media) 785 { 786 return generator.make( 787 {e:["source","srcset",srcset,"src",src,"media",media]}); 788 } 789 else 790 { 791 return generator.make( 792 {e:["img","srcset",srcset,"sizes",sizes,"src",src,"alt",alt]}); 793 } 794 } 795}); 796 797bcInstance.GENERATOR.addTemplate("picture", function(a, generator) 798{ 799 let picture = Object.values(a['picture']); 800 if (picture) 801 { 802 Object.values(picture).forEach(function(i) 803 { 804 Object.assign(i, a); 805 }); 806 if (picture.length > 1) 807 { 808 return generator.make( 809 {loo:picture,e:["picture"],c:[ 810 {tem:"image"} 811 ]}); 812 } 813 else 814 { 815 return generator.make( 816 {tem:"image",arg:picture[0]}); 817 } 818 } 819}); 820 821bcInstance.GENERATOR.addTemplate("featured-image", function(a, generator) 822{ 823 let images = a["images"]; 824 let picture = a["picture"] || {standard:{}}; 825 if (images) 826 { 827 if (!a["no-fallback"]) 828 { 829 images["standard"] = images["standard"] || images["square"] || images["special"]; 830 images["square"] = images["square"] || images["standard"] || images["special"]; 831 images["special"] = images["special"] || images["standard"] || images["square"]; 832 } 833 Object.entries(picture).forEach(function(j) 834 { 835 picture[j[0]]["image"] = images[j[0]]; 836 }); 837 } 838 a["picture"] = picture; 839 return generator.make( 840 {tem:"picture",arg:a}); 841}); 842 843bcInstance.GENERATOR.addTemplate("entry", function(a, generator) 844{ 845 let title = a["title"]; 846 let link = a["link"]; 847 let excerpt = a["excerpt"]; 848 let type = a["type"]; 849 let date = a["date"]; 850 let timestamp = a["timestamp"]; 851 let images = a["images"]; 852 let imageArgs = a["image-args"] || {}; 853 imageArgs["images"] = images; 854 855 let ratio = a["ratio"] || "_2x1"; 856 let heading = a["heading"] || "p"; 857 let titleClasses = (a["title-classes"]) ? " "+a["title-classes"] : ""; 858 let linkClasses = (a["link-classes"]) ? " "+a["link-classes"] : ""; 859 let excerptClasses = (a["excerpt-classes"]) ? " "+a["excerpt-classes"] : ""; 860 let coverClasses = (a["cover-classes"]) ? " "+a["cover-classes"] : ""; 861 let extra = a["extra"] || {}; 862 let more = a["more"] || "Read More"; 863 let role = a["role"] || "!null"; 864 865 if (type === "item-basic") 866 { 867 let speaker = a["speaker"] || false; 868 return generator.make( 869 {e:["div","class","entry _item-basic card-link","role",role],c:[ 870 {e:["div","class","frame _zoom shadow "+ratio],c:[ 871 {e:["div","class","box"],c:[ 872 {iif:images,tem:"featured-image",arg:imageArgs}, 873 {iif:speaker,e:["div","class","cover"],c:[ 874 {e:["div","class","inner"],c:[ 875 {e:["p","class","meta text-medium","innerHTML",speaker]}, 876 {e:["p","class","meta"],c:[ 877 {e:["date","datetime",timestamp,"innerHTML",date]} 878 ]} 879 ]} 880 ]} 881 ]} 882 ]}, 883 {e:["div","class","body"],c:[ 884 {e:["div","class","header"],c:[ 885 {e:[heading,"class","title"+titleClasses],c:[ 886 {e:["a","class","link"+linkClasses,"href",link,"innerHTML",title]} 887 ]}, 888 ]}, 889 {e:["div","class","more"],c:[ 890 {e:["div","innerHTML",more]} 891 ]} 892 ]} 893 ]}); 894 } 895 else if (type === "item-post") 896 { 897 return generator.make( 898 {e:["div","class","entry _item-basic card-link","role",role],c:[ 899 {e:["div","class","frame _zoom shadow "+ratio],c:[ 900 {e:["div","class","box"],c:[ 901 {iif:images,tem:"featured-image",arg:imageArgs}, 902 {e:["div","class","cover _reverse"+coverClasses]} 903 ]} 904 ]}, 905 {e:["div","class","body"],c:[ 906 {e:["div","class","header"],c:[ 907 {e:[heading,"class","title text-xs line-limit-3"+titleClasses],c:[ 908 {e:["a","class","link"+linkClasses,"title",title,"href",link,"innerHTML",title]} 909 ]} 910 ]}, 911 {e:["div","class","excerpt"],c:[ 912 {e:["p","class","text-2xs line-limit-3"+excerptClasses,"innerHTML",excerpt+" <span class=\"text-gray-light\">…</span>"]} 913 ]}, 914 {e:["div","class","more"],c:[ 915 {e:["div","innerHTML",more]} 916 ]} 917 ]} 918 ]}); 919 } 920 else 921 { 922 return generator.make( 923 {e:["div","class","entry _basic card-link","role",role],c:[ 924 {e:["div","class","frame _zoom shadow "+ratio],c:[ 925 {e:["div","class","box"],c:[ 926 {iif:images,tem:"featured-image",arg:imageArgs}, 927 {e:["div","class","cover _reverse"+coverClasses]} 928 ]} 929 ]}, 930 {e:["div","class","body"],c:[ 931 {e:["div","class","header"],c:[ 932 {e:[heading,"class","title"+titleClasses],c:[ 933 {e:["a","class","link"+linkClasses,"href",link,"innerHTML",title]} 934 ]} 935 ]} 936 ]} 937 ]}); 938 } 939}); 940 941//"BC" is initialized in the HTML head with an array. Functions are added to this array using the _BC function
942//when this script file is loaded, save those pending functions and reinitialize the BC variable as the main class object 943const fns = BC.fns || BC; 944BC = bcInstance; 945 946//run code that is meant to be applied to all pages 947(()=> 948{ 949 //subscribe 950 let subscribeLinks = BC.arrayByQuery("a[href='#subscribe']"); 951 let subscribeField = BC.byId("footer-subscribe-email"); 952 if (subscribeField) 953 { 954 subscribeLinks.forEach(function(i) 955 { 956 i.addEventListener("click", function(e) 957 { 958 subscribeField.focus(); 959 e.preventDefault(); 960 }); 961 }); 962 }; 963 964 //ease-in frames 965 BC.arrayByQuery(".frame._ease-in").forEach(function(i) 966 { 967 i.classList.add("_final"); 968 }); 969 970 //scroll-triggers 971 let options = {rootMargin:"0px",threshold:0}; 972 let callback = function(triggers, observer) 973 { 974 triggers.forEach((i) => 975 { 976 if (i.isIntersecting) 977 { 978 i.target.classList.add("triggered"); 979 i.target.dispatchEvent(new Event("bc-scroll-trigger")); 980 observer.unobserve(i.target); 981 } 982 } 983 )}; 984 let observer = new IntersectionObserver(callback, options);
985 BC.arrayByClass("scroll-trigger").forEach((i) => {observer.observe(i);}); 986 987 //utm and tracking 988 let links = BC.UTIL.getLinks(true, ["media.benedictine.edu","events.benedictine.edu","my.benedictine.edu","apply.benedictine.edu","go.benedictine.edu"]); 989 let values = BC.UTIL.getQueryParameters(["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]); 990 BC.UTIL.forwardQueryParameters(values, links); 991 BC.UTIL.bctm(); 992})(); 993 994//run all functions that were waiting on this script file to load 995BC.go(fns);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.