1// Place your application-specific JavaScript functions and classes here 2// This file is automatically included by javascript_include_tag :defaults 3; 4/** 5 * listen for afterMenu right away and set a cookie when its ready 6 */ 7$(document).one("epub.afterMenu", function () { 8 $.cookie("epubAfterMenu", true, { path: "/" }); 9}); 10 11$(function () { 12 if ($("#related-categories").length > 0) { 13 require(["components/expandable-nav"], function (ExpandableNav) { 14 new ExpandableNav("#related-categories", { 15 defaultVisibleItems: 4, 16 }); 17 }); 18 } 19}); 20 21if ($(".page-search-index").length > 0) { 22 require([ 23 "pickerdate", 24 "css!/javascripts/vendor/pickadatejs/themes/classic", 25 "css!/javascripts/vendor/pickadatejs/themes/classic.date", 26 ], function (pickadate) { 27 $(function () { 28 $("#filter_start_date, #filter_end_date").pickadate({ 29 max: new Date(), 30 formatSubmit: "mm/dd/yyyy", 31 hiddenName: true, 32 selectYears: true, 33 onStart: function () { 34 this.set("select", null); 35 }, 36 }); 37 }); 38 }); 39} 40 41require(["jquery", "components/add-this-toolbox"], function ( 42 $, 43 AddThisToolbox 44) { 45 $(function () { 46 var services = [ 47 { name: "print" }, 48 { name: "email" }, 49 { name: "facebook", type: "counter" }, 50 { name: "twitter" }, 51 { name: "linkedin", type: "counter" }, 52 { name: "more" }, 53 ]; 54 55 $(".addthis-toolbox").each(function () { 56 new AddThisToolbox(this, { 57 services: services, 58 }); 59 }); 60 }); 61}); 62 63$(function() { 64 const mainHeader = document.querySelector(".main-header"); 65 66 if (mainHeader && !mainHeader.classList.contains("event-microsite")) { 67 require([ 68 "jquery", 69 "mobile-nav", 70 "nav-quick-return", 71 "quick-search", 72 "user-actions", 73 ], function ($, MobileNav, NavQuickReturn, QuickSearch) { 74 let config = {}; 75 76 // Diff order and config of Mobile Menu for v2 redesign 77 // TODO: Refactor once all sites are on v2 78 if (window.homeVersionV2Enabled) { 79 config = { 80 triggerID: "#hamburger-nav-link,#search-nav-link", 81 addBeforeMenu: [ 82 ".main-nav--horizontal:not(.main-nav--horizontal--quick-return) #user-actions", 83 "#user-actions", 84 "#quick-search", 85 "#subscribe-mobile-nav-link", 86 ], 87 addAfterMenu: ["#directory-nav", "#cart-social-wrapper"], 88 mmenuConfigAddon: { 89 classNames: { 90 fixedElements: { 91 fixedTop: "main-header--quick-return", 92 }, 93 }, 94 }, 95 mmenu: { 96 offCanvas: { 97 position: "right", 98 }, 99 }, 100 }; 101 } else { 102 config = { 103 addBeforeMenu: [ 104 "#quick-search", 105 "#user-actions", 106 "#subscribe-mobile-nav-link", 107 ],
108 addAfterMenu: ["#directory-nav", "#cart-link", "#social-links"], 109 mmenuConfigAddon: { 110 classNames: { 111 fixedElements: { 112 fixedTop: "main-header--quick-return", 113 }, 114 }, 115 }, 116 }; 117 } 118 119 new MobileNav(".main-nav--horizontal", config); 120 121 new NavQuickReturn(".main-header", { 122 mediaQuery: "screen and (max-width: 1200px)", 123 appendCloneTo: ".mmenu-placeholder", 124 }); 125 126 new NavQuickReturn(".main-nav--horizontal"); 127 128 new QuickSearch("#quick-search"); 129 }); 130 } 131}); 132 133require([ 134 "jquery", 135 "follow-scroll", 136 "sponsored-content-help", 137 "selectize", 138 "bundle/scrolldepth.bundle", 139], function ( 140 $, 141 FollowScroll, 142 SponsoredContentHelp, 143 selectize, 144 ScrollDepthWrapper 145) { 146 $(function () { 147 new ScrollDepthWrapper.default(); 148 149 if (!window.homeVersionV2Enabled) { 150 new FollowScroll("#homepage-left-column", { 151 bottomPosition: function () { 152 return $("#main-footer").offset().top; 153 }, 154 mediaQuery: "screen and (min-width: 950px)", 155 }); 156 157 new FollowScroll("#main-sidebar", { 158 bottomPosition: function () { 159 return $("#main-footer").offset().top; 160 }, 161 }); 162 163 new FollowScroll("#featured-home-contents", { 164 bottomPosition: function () { 165 return $("#main-footer").offset().top; 166 }, 167 }); 168 } 169 170 if (!Modernizr.csstransitions) { 171 $(".main-nav--horizontal").on( 172 { 173 mouseenter: function mainNavMouseEnter() { 174 $(this).find(".level2").show(); 175 }, 176 mouseleave: function mainNavMouseLeave() { 177 $(this).find(".level2").hide(); 178 }, 179 }, 180 ".level1-li" 181 ); 182 } 183 184 $("#subscribe-now").on( 185 "click.subscribe-now", 186 ".subscribe-now__subscribe-link", 187 function openSubscribeNowDropdown(e) { 188 e.preventDefault(); 189 var $nav = $(this).next(".subscribe-now__nav"); 190 // Animation Fallback if No CSS3 Transition Support 191 if (!Modernizr.csstransitions) { 192 $nav.slideToggle(); 193 } else { 194 $nav.toggleClass("js-animate--flip-open"); 195 } 196 } 197 ); 198 199 $("#home-subscribe-cta").on( 200 "click.home-subscribe-cta", 201 ".home-subscribe-cta__subscribe-link", 202 function openSubscribeNowDropdown(e) { 203 e.preventDefault(); 204 var $nav = $(this).next(".home-subscribe-cta__nav"); 205 // Animation Fallback if No CSS3 Transition Support 206 if (!Modernizr.csstransitions) { 207 $nav.slideToggle(); 208 } else { 209 $nav.toggleClass("js-animate--flip-open"); 210 } 211 } 212 ); 213 214 // Hide Apprenticeship Reviews Directories breadcrumbs 215 if ($(".breadcrumbs").length) { 216 const breadcrumb = $(".breadcrumbs").text(); 217 if (breadcrumb.indexOf("Apprenticeship") > 0) { 218 $(".breadcrumbs").hide(); 219 } 220 } 221 222 if ($("#sponsored-content").length) { 223 new SponsoredContentHelp("#sponsored-content"); 224 } 225 if ($("#home-sponsored-content").length) { 226 new SponsoredContentHelp("#home-sponsored-content", { 227 component: ".sponsored-content-list", 228 }); 229 } 230 if ($("#sponsored-content-widget").length) { 231 new SponsoredContentHelp("#sponsored-content-widget", { 232 component: ".sponsored-content-widget", 233 }); 234 } 235 if ($("#topic-sponsored-article").length) { 236 new SponsoredContentHelp("#topic-sponsored-article", { 237 component: ".sponsored-content-widget", 238 }); 239 } 240 241 // Replace select fields with improved UI 242 // Cache to var to use API 243 // Implemented using workaround https://github.com/brianreavis/selectize.js/issues/744 244 $("select").each(function () { 245 // The 'if' makes sure that selectize does not get added to the drop downs 246 // in the calendar search for select year. 247 if (!$(this).hasClass("picker__select--year")) { 248 $(this).selectize(); 249 } 250 }); 251 $(window).on("pageshow", function () { 252 var $location = $("#location"); 253 if ($location.length) { 254 var $select = $location.selectize(); 255 var selectize = $select[0].selectize; 256 if (selectize) { 257 selectize.clear(); // Clears the selected value on page load 258 } 259 } 260 }); 261 262 // Checkout Page: Update the country and state custom select fields, 263 // on the change event of the native select fields. This is 264 // for when the shipping address is the same as billing. 265 266 $("#bill_country_id").on("change", function () { 267 var value = $(this).val(); 268 var selectize = $("#ship_country_id")[0].selectize; 269 selectize.setValue(value); 270 }); 271 272 $("#bill_state_id").on("change", function () { 273 var value = $(this).val(); 274 var selectize = $("#ship_state_id")[0].selectize; 275 selectize.setValue(value); 276 }); 277 278 // jQuery validation will ignore hidden elements, 279 // since we are using Selectize to replace select fields, 280 // we must set validation to ignore hidden fields with the exception 281 // of selectize controlled hidden fields 282 $.validator.setDefaults({ 283 ignore: 284 ":hidden:not([class~=selectized]),:hidden > .selectized, .selectize-control .selectize-input input", 285 }); 286 287 /* 288 This corrects a bug on the navigation for tablet devices where a click on the 289 parent link was going directly to the link and not expanding the level2 nav 290 items. This prevents default in cases where the level2 nav is not currently 291 visible. 292 */
293 $(".main-nav--horizontal").on("click", ".link2", function (evt) { 294 if ($(this).siblings(".level2").height() == 0) { 295 evt.preventDefault(); 296 } 297 }); 298 299 // Detect RFP form changes and show red dot on submit 300 const RFPChange = localStorage.getItem("rfpchange"); 301 if (RFPChange === "true") { 302 $(".badge-dot-edit").show(); 303 } 304 $(".rfp-form input, .rfp-form select, .rfp-form textarea").on( 305 "input", 306 function () { 307 $(".badge-dot-edit").show(); 308 } 309 ); 310 $(".rfp-add-supplier-button").click(function () { 311 localStorage.setItem("rfpchange", "true"); 312 $(".badge-dot-edit").show(); 313 }); 314 $(".rfp-form__button-container input").click(function () { 315 localStorage.removeItem("rfpchange"); 316 }); 317 }); 318}); 319 320// Initialize all the brightcove video lists we find that have the following markup 321// 322// <div 323// data-playlist-id="" 324// data-player-url="" 325// data-open-in-new-window="" 326// data-width="" 327// data-height="" 328// data-video-logo="" 329// data-video-play-arrow="" 330// data-randomize-videos="" 331// data-show-long-descriptions="" 332// data-max-videos-visible=""> 333// </div> 334// 335// 336require(["jquery"], function ($) { 337 $(function () { 338 $("div[data-playlist-id]").each(function () { 339 var videoDiv = $(this); 340 // If we don't find any, this won't ever be pulled in 341 require([ 342 "bundle/brightcove-video-list.bundle", 343 ], function (videoBrightCoveGallery) { 344 var playlist_id = videoDiv.data("playlist-id"); 345 var player_url = videoDiv.data("player-url"); 346 var width = videoDiv.data("width"); 347 var height = videoDiv.data("height"); 348 var openInNewWindow = videoDiv.data("open-in-new-window"); 349 var randomizeVideos = videoDiv.data("randomize-videos"); 350 var showLongDescriptions = videoDiv.data("show-long-descriptions"); 351 var video_logo = videoDiv.data("video-logo"); 352 var video_play_arrow = videoDiv.data("video-play-arrow"); 353 var max_videos_visible = videoDiv.data("max-videos-visible"); 354 var max_thumbnails_visible = videoDiv.data("max-thumbnails-visible"); 355 var autoplay = videoDiv.data("autoplay"); 356 var carousel = videoDiv.data("carousel"); 357 var token = 358 videoDiv.data("token") || 359 "BCpkADawqM1CSLkNMXl4noZnUFKfkqq30qsaWUzd5MZ8UFUmwKL7KzrYLM-Z9C_5OJG351h5c1ZBtJFULAf6Jp_hmftcuqTx93AFdiL1lNh6YaeVgKAS5unUTZ0"; 360 361 var videoList = new videoBrightCoveGallery.default( 362 videoDiv, 363 playlist_id, 364 token, 365 player_url, 366 { 367 width: width, 368 height: height, 369 openInNewWindow: openInNewWindow, 370 randomizeVideos: randomizeVideos, 371 showLongDescriptions: showLongDescriptions, 372 video_logo: video_logo, 373 max_videos_visible: max_videos_visible, 374 max_thumbnails_visible: max_thumbnails_visible, 375 carousel: carousel, 376 }, 377 { 378 autoplay: autoplay, 379 } 380 ); 381 }); 382 }); 383 }); 384}); 385 386window.addEventListener("load", function (event) { 387 require([ 388 "jquery", 389 "bundle/olytics-dfp.bundle", 390 "bundle/dfp-ads.bundle", 391 "bundle/modify-dfp-targeting.bundle", 392 "bundle/geolocation.bundle", 393 ], function ($, olyticsDFPInit, GoogleTagSetup, ModifyDfpTargeting, Geolocation) { 394 // wrapper function for ad initialization 395 const init_ads = () => { 396 /** 397 * A better way of ensuring that window.olytics is completely 398 * ready. Relying on the load of olyticsImport script revealed an 399 * async issue. 400 */ 401 const checkForOlyticsHandler = setInterval(function () { 402 if ( 403 typeof window.olytics !== "undefined" && 404 "ready" in window.olytics 405 ) { 406 window.olytics.ready(olyticsInit); 407 } 408 }, 200); 409 410 const olyticsGiveupHandler = setTimeout(function () { 411 if ( 412 typeof window.olytics !== "undefined" && 413 "ready" in window.olytics 414 ) { 415 clearTimeout(olyticsGiveupHandler); 416 return; 417 } 418 clearInterval(checkForOlyticsHandler); 419 dfpInit(); 420 }, 1500); 421 422 function dfpInit() { 423 var href = window.location.href; 424 var shouldCollapse = !( 425 href.includes(".stage.epublishing.com") || href.includes(":3000") 426 ); 427 428 window.dfpAds = new GoogleTagSetup.default(targeting, { 429 refreshChangeCorrelator: true, 430 collapse: shouldCollapse, 431 slotRenderEnded: function (evt, slot) { 432 if (typeof slot === "undefined") return; 433 434 var $slot = $("#" + slot.id); 435 var $frame = $($slot.find("iframe").prop("contentDocument")); 436 437 if (!$frame.length && shouldCollapse) return $slot.remove(); 438 439 $frame.on("load", function () { 440 if ($frame.find("canvas,img").length) return; 441 442 shouldCollapse && $slot.remove(); 443 }); 444 }, 445 }); 446 } 447 448 function olyticsInit() { 449 /** 450 * kick off olytics DFP 451 */ 452 clearInterval(checkForOlyticsHandler); 453 clearTimeout(olyticsGiveupHandler); 454 window.olytics.loadDfpSegments(); 455 456 window.olyticsDfpSegments = function (segments) { 457 /** 458 * olytics is looking for this global function as its callback 459 * segments from `loadDfpSegments` are sent to this function 460 */ 461 new olyticsDFPInit.default(segments, { 462 awaitMobileNav: true, 463 initDFP: function (mergedTargeting) { 464 targeting = ModifyDfpTargeting.modifyDfpTargeting( 465 mergedTargeting, 466 { 467 reg_user: "email", 468 } 469 ); 470 471 dfpInit(); 472 }, 473 }); 474 }; 475 } 476 }; 477 478 if (typeof window.OneTrust == 'undefined') return init_ads(); 479 480 // run ads for everyone outside eu, otherwise wait for consent, checking every second 481 Geolocation.default( 482 () => { 483 // check for affirmative consent every second 484 const check_interval = setInterval(() => { 485 if (!document.cookie.includes("C0004%3A1")) return; 486 487 clearInterval(check_interval); 488 init_ads(); 489 }, 1000); 490 }, 491 () => { 492 // run ads until they opt out everywhere else 493 if (document.cookie.includes("C0004%3A0")) return; 494 495 init_ads(); 496 } 497 ); 498 }); 499}); 500 501require(["jquery"], function ($) { 502 $(document).ready(function () { 503 if (
504 $("body").data("controller") == "events" && 505 $("body").data("action") == "category" 506 ) { 507 $(".live-and-upcoming__see-full-description").on("click", function () { 508 $button = $(this); 509 const eventID = $button.data("eventId"); 510 511 $("#classification-title__description--truncated-" + eventID).toggle(); 512 $("#classification-title__description--full-" + eventID).toggle(); 513 514 const SEE_FULL = "See Full Description"; 515 const COLLAPSE = "Collapse Full Description"; 516 if ($button.text() === SEE_FULL) { 517 $button.text(COLLAPSE); 518 } else { 519 $button.text(SEE_FULL); 520 } 521 }); 522 } 523 }); 524});
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.