1/** 2 * @file 3 * Colorbox module init js. 4 */ 5 6(function ($) { 7 8Backdrop.behaviors.initColorbox = { 9 attach: function (context, settings) { 10 if (typeof $.colorbox !== 'function' || typeof settings.colorbox === 'undefined') { 11 return; 12 } 13 14 if (settings.colorbox.mobiledetect && window.matchMedia) { 15 // Disable Colorbox for small screens. 16 var mq = window.matchMedia("(max-device-width: " + settings.colorbox.mobiledevicewidth + ")"); 17 if (mq.matches) { 18 return; 19 } 20 } 21 22 // Use "data-colorbox-gallery" if set otherwise use "rel". 23 settings.colorbox.rel = function () { 24 if ($(this).data('colorbox-gallery')) { 25 return $(this).data('colorbox-gallery'); 26 } 27 else { 28 return $(this).attr('rel'); 29 } 30 }; 31 32 $('.colorbox', context) 33 .once('init-colorbox').each(function() { 34 // Only images are supported for the "colorbox" class. 35 // The "photo" setting forces the href attribute to be treated as an image. 36 var extendParams = { 37 photo: true 38 }; 39 // If a title attribute is supplied, sanitize it. 40 var title = $(this).attr('title'); 41 if (typeof title === 'undefined') { 42 title = this.dataset.cboxTitle; 43 } 44 if (title) { 45 extendParams.title = Backdrop.colorbox.sanitizeMarkup(title); 46 } 47 $(this).colorbox($.extend({}, settings.colorbox, extendParams)); 48 49 // Only allow http or https protocol in hrefs. 50 var href = $(this).attr('href'); 51 var protocolRegex = /^(https?)/; 52 if (href && href.substring(0, 1) !== '/') { 53 var protocol = href.split(':')[0]; 54 // Use a regex to match http or https protocol. 55 if (!protocolRegex.test(protocol)) { 56 $(this).removeAttr('href'); 57 } 58 } 59 var dataHref = this.dataset.cboxHref; 60 if (dataHref && dataHref.substring(0, 1) !== '/') { 61 var dataProtocol = dataHref.split(':')[0]; 62 if (!protocolRegex.test(dataProtocol)) { 63 delete this.dataset.cboxHref; 64 } 65 } 66 // Since the sanitized title has been passed to colorbox settings, 67 // delete the unsanitized data-cbox-title attribute. 68 delete this.dataset.cboxTitle; 69 // Disallow dangerous data attributes. 70 delete this.dataset.cboxIframeAttrs; 71 // Sanitize other data attributes. 72 var sanitizeDataList = ['cboxNext', 'cboxPrevious', 'cboxCurrent', 73 'cboxClose', 'cboxSlideshowstop', 'cboxSlideshowstart', 74 'cboxXhrError', 'cboxImgerror', 'cboxHtml' 75 ]; 76 for (var a of sanitizeDataList) { 77 if (this.dataset.hasOwnProperty(a)) { 78 this.dataset[a] = Backdrop.colorbox.sanitizeMarkup(this.dataset[a]); 79 } 80 } 81 }); 82 83 $(context).on('cbox_complete', function () { 84 Backdrop.attachBehaviors('#cboxLoadedContent'); 85 }); 86 } 87}; 88 89// Create colorbox namespace if it doesn't exist. 90if (!Backdrop.hasOwnProperty('colorbox')) { 91 Backdrop.colorbox = {}; 92} 93 94/** 95 * Global function to allow sanitizing captions and control strings. 96 * 97 * @param markup 98 * String containing potential markup. 99 * @return @string 100 * Sanitized string with potentially dangerous markup removed. 101 */ 102Backdrop.colorbox.sanitizeMarkup = function(markup) { 103 // If DOMPurify installed, allow some HTML. Otherwise, treat as plain text. 104 if (typeof DOMPurify !== 'undefined') { 105 var purifyConfig = { 106 ALLOWED_TAGS: [ 107 'a', 108 'b', 109 'strong', 110 'i', 111 'em', 112 'u', 113 'cite', 114 'code', 115 'br' 116 ], 117 ALLOWED_ATTR: [ 118 'href', 119 'hreflang', 120 'title', 121 'target' 122 ] 123 } 124 if (Backdrop.settings.hasOwnProperty('dompurify_custom_config')) { 125 purifyConfig = Backdrop.settings.dompurify_custom_config; 126 } 127 return DOMPurify.sanitize(markup, purifyConfig); 128 } 129 else { 130 return Backdrop.checkPlain(markup); 131 } 132} 133 134})(jQuery); 135; 136/** 137 * @file 138 * Colorbox module style js. 139 */ 140 141(function ($) { 142 143Backdrop.behaviors.initColorboxDefaultStyle = { 144 attach: function (context, settings) { 145 $(context).on('cbox_complete', function () { 146 // Only run if there is a title. 147 if ($('#cboxTitle:empty', context).length == false) { 148 $('#cboxLoadedContent img', context).on('mouseover', function () { 149 $('#cboxTitle', context).slideDown(); 150 }); 151 $('#cboxOverlay', context).on('mouseover', function () {
152 $('#cboxTitle', context).slideUp(); 153 }); 154 } 155 else { 156 $('#cboxTitle', context).hide(); 157 } 158 }); 159 } 160}; 161 162})(jQuery); 163; 164/** 165 * @file 166 * Colorbox module inline js. 167 */ 168 169(function ($) { 170 171Backdrop.behaviors.initColorboxInline = { 172 attach: function (context, settings) { 173 if (typeof $.colorbox !== 'function' || typeof settings.colorbox === 'undefined') { 174 return; 175 } 176 177 if (settings.colorbox.mobiledetect && window.matchMedia) { 178 // Disable Colorbox for small screens. 179 var mq = window.matchMedia("(max-device-width: " + settings.colorbox.mobiledevicewidth + ")"); 180 if (mq.matches) { 181 return; 182 } 183 } 184 185 $.urlParam = function(name, url){ 186 if (name == 'fragment') { 187 var results = new RegExp('(#[^&#]*)').exec(url); 188 } 189 else { 190 var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(url); 191 } 192 if (!results) { return ''; } 193 return results[1] || ''; 194 }; 195 $('.colorbox-inline', context).once('init-colorbox-inline').colorbox({ 196 transition:settings.colorbox.transition, 197 speed:settings.colorbox.speed, 198 opacity:settings.colorbox.opacity, 199 slideshow:settings.colorbox.slideshow, 200 slideshowAuto:settings.colorbox.slideshowAuto, 201 slideshowSpeed:settings.colorbox.slideshowSpeed, 202 slideshowStart:settings.colorbox.slideshowStart, 203 slideshowStop:settings.colorbox.slideshowStop, 204 current:settings.colorbox.current, 205 previous:settings.colorbox.previous, 206 next:settings.colorbox.next, 207 close:settings.colorbox.close, 208 overlayClose:settings.colorbox.overlayClose, 209 maxWidth:settings.colorbox.maxWidth, 210 maxHeight:settings.colorbox.maxHeight, 211 innerWidth:function(){ 212 return $.urlParam('width', $(this).attr('href')); 213 }, 214 innerHeight:function(){ 215 return $.urlParam('height', $(this).attr('href')); 216 }, 217 title:function(){ 218 return Backdrop.colorbox.sanitizeMarkup( 219 decodeURIComponent($.urlParam('title', $(this).attr('href')))); 220 }, 221 iframe:function(){ 222 return $.urlParam('iframe', $(this).attr('href')); 223 }, 224 inline:function(){ 225 return $.urlParam('inline', $(this).attr('href')); 226 }, 227 href:function(){ 228 return $.urlParam('fragment', $(this).attr('href')); 229 } 230 }); 231 } 232}; 233 234})(jQuery); 235; 236 237/** 238 * @file 239 * Attaches the behaviors for the Scroll to Destination Anchors module. 240 */ 241 242// Prevent script conflicts and attach the behavior. 243(function($) { 244 Backdrop.behaviors.smooth_scroll = { 245 attach: function(context, settings) { 246 247 // Wait until after the window has loaded. 248 $(window).on('load', function(){ 249 250 // Select all links with hashes 251 $('a[href*="#"]') 252 // Remove links that don't actually link to anything 253 .not('[href="#"]') 254 .not('[href="#0"]') 255 .click(function(event) { 256 // On-page links 257 if ( 258 location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') 259 && 260 location.hostname == this.hostname 261 ) { 262 // Figure out element to scroll to 263 var target = $(this.hash); 264 target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); 265 // Does a scroll target exist? 266 if (target.length) { 267 //Get settings from Backdrop 268 var scrollSpeed = Backdrop.settings.scrollSpeed; 269 270 // Only prevent default if animation is actually gonna happen 271 event.preventDefault(); 272 $('html, body').animate({ 273 scrollTop: target.offset().top 274 }, scrollSpeed, function() { 275 // Callback after animation 276 // Must change focus! 277 var $target = $(target); 278 $target.focus(); 279 if ($target.is(":focus")) { // Checking if the target was focused 280 return false; 281 } else { 282 $target.attr('tabindex','-1'); // Adding tabindex for elements not focusable
283 $target.focus(); // Set focus again 284 }; 285 }); 286 } 287 } 288 }); 289 290 }); 291 292 } 293 }; 294}(jQuery)); 295; 296(function($) { 297 Backdrop.behaviors.stickynav = { 298 breakpoint: 0, 299 compensation: 0, 300 originalPadding: 0, 301 attach : function(context) { 302 var selector = Backdrop.settings.stickynav.selector; 303 //only getting the first elmenet in the dom 304 var $menu = $(selector).eq(0); 305 var offset = 0; 306 if ($menu.length) { 307 $menu.once('stickynav', function() { 308 // Save original padding on top. 0 timeout to get correct padding. 309 setTimeout(function() { 310 Backdrop.behaviors.stickynav.originalPadding = $('body').css('paddingTop'); 311 }, 0); 312 offset += parseInt(Backdrop.settings.stickynav.offsets.custom_offset); 313 offset = offset || 0; 314 $(Backdrop.settings.stickynav.offsets.selector).each(function() { 315 offset += $(this).outerHeight(); 316 }); 317 Backdrop.behaviors.stickynav.breakpoint = $menu.offset().top - offset; 318 //we need to compensate the element so that the content does not jump up. 319 Backdrop.behaviors.stickynav.compensation = $menu.outerHeight(); 320 $(window).scroll(function () { 321 if ($(window).scrollTop() > Backdrop.behaviors.stickynav.breakpoint) { 322 $menu.addClass('stickynav-active'); 323 if (offset) { 324 $menu.css({'top': offset + 'px'}); 325 } 326 $('body').css('padding-top', Backdrop.behaviors.stickynav.compensation); 327 } 328 else { 329 $menu.removeClass('stickynav-active'); 330 $menu.css({'top': ''}); 331 $('body').css('padding-top', Backdrop.behaviors.stickynav.originalPadding); 332 } 333 }); 334 }); 335 } 336 } 337 } 338})(jQuery); 339; 340/** 341 * @file 342 * Javascript processing to create tokens to render a date and/or time in the 343 * user's time zone. 344 */ 345 346(function ($) { 347 $(document).ready(function() { 348 349 /** 350 * Returns a formatted string from a Luxon DateTime object mimicking PHP's 351 * DateTime::format() functionality. 352 * 353 * date object Luxon DateTime object 354 * format string "Y-m-d H:i:s" or similar PHP-style format string 355 */ 356 function formatPHP(date, format) { 357 let string = ''; 358 for (let i of format.match(/(\\)*./g)) 359 switch (i) { 360 361 // Day 362 363 case 'd': // Day of the month, 2 digits with leading zeros (01 to 31) 364 string += date.toFormat('dd'); 365 break; 366 367 case 'D': // A textual representation of a day, three letters 368 string += date.toFormat('ccc'); 369 break; 370 371 case 'j': // Day of the month without leading zeros (1 to 31) 372 string += date.toFormat('d'); 373 break; 374 375 case 'l': // (lowercase 'L') A full textual representation of the day of the week 376 string += date.toFormat('cccc'); 377 break; 378 379 case 'N': // ISO-8601 representation of the day of the week (1=Monday,...7=Sunday) 380 string += date.toFormat('c'); 381 break; 382 383 case 'S': // English ordinal suffix for the day of the month, 2 characters 384 var day = date.toFormat('d'); 385 if (day == 1) { 386 string += 'st'; 387 } else if (day == 2) { 388 string += 'nd'; 389 } else if (day == 3) { 390 string += 'rd'; 391 } else { 392 string += 'th'; 393 } 394 break; 395 396 case 'w': // Numeric representation of the day of the week (1=Monday,...6=Saturday) 397 string += (date.toFormat('c')) % 7; 398 break; 399 400 case 'z': // Numeric representation of the day of the year, starting from 0 401 string += date.toFormat('o') - 1; 402 break; 403 404 // Week 405 406 case 'W': // ISO-860 week number of year, weeks starting on monday 407 string += date.toFormat('W'); 408 break; 409 410 // Month 411 412 case 'F': // A full textual representation of a month, such as January or March
413 string += date.toFormat('LLLL'); 414 break; 415 416 case 'm': // Numeric representation of a month, with leading zeros (01 to 12) 417 string += date.toFormat('LL'); 418 break; 419 420 case 'M': // A short textual representation of a month, three letters (Jan - Dec) 421 string += date.toFormat('LLL'); 422 break; 423 424 case 'n': // Numeric representation of a month, without leading zeros (1 to 12) 425 string += date.toFormat('L'); 426 break; 427 428 case 't': // Number of days in the given month 429 string += date.daysInMonth; 430 break; 431 432 // Year 433 434 case 'L': // Whether it's a leap year, 1 or 0 435 string += +(date.isInLeapYear); 436 break; 437 438 case 'o': // ISO-8601 week-numbering year, 4 digits 439 string += date.toFormat('kkkk'); 440 break; 441 442 case 'Y': // A full numeric representation of a year, 4 digits (1999 OR 2003) 443 string += date.toFormat('yyyy'); 444 break; 445 446 case 'y': // A two digit representation of a year (99 OR 03) 447 string += date.toFormat('yy'); 448 break; 449 450 // Time 451 452 case 'a': // Lowercase Ante meridiem and Post meridiem (am or pm) 453 string += (date.hour < 12) ? "am" : "pm"; 454 break; 455 456 case 'A': // Lowercase Ante meridiem and Post meridiem (AM or PM) 457 string += (date.hour < 12) ? "AM" : "PM"; 458 break; 459 460 case 'B': // Swatch internet time 461 // Left to be implemented in the future. Does anyone actually use this? 462 string += '**TBD**'; 463 break; 464 465 // Time - Hours 466 467 case 'g': // 12-hour format of an hour without leading zeros (1 to 12) 468 string += (date.hour + 11) % 12 + 1; 469 break; 470 471 case 'H': // 24-hour format of an hour with leading zeros (00 to 23) 472 string += date.hour; 473 break; 474 475 case 'h': // 12-hour format of an hour with leading zeros (01 to 12) 476 var hour = (date.hour + 11) % 12 + 1; 477 if (hour < 10) { 478 string += '0'; 479 } 480 string += hour; 481 break; 482 483 // Time - Minutes 484 485 case 'i': // Minutes with leading zeros (00 to 59) 486 var mi = date.minute; 487 string += (mi < 10) ? "0" + mi : mi; 488 break; 489 490 // Time - Seconds and fractions thereof 491 492 case 's': // Seconds, with leading zeros (00 to 59) 493 var s = date.second; 494 string += (s < 10) ? "0" + s : s; 495 break; 496 497 case 'u': // Microseconds 498 var ms = date.millisecond * 1000; 499 ms = ms.toString(); 500 while (ms.length < 6) { 501 ms = '0' + ms; 502 } 503 string += ms; 504 break; 505 506 case 'v': // Milliseconds 507 var ms = date.millisecond; 508 ms = ms.toString(); 509 while (ms.length < 3) { 510 ms = '0' + ms; 511 } 512 string += ms; 513 break; 514 515 // Timezone 516 517 case 'e': // Timezone identifier 518 string += date.toFormat('z'); 519 break; 520 521 case 'I': // Whether or not the date is in daylight saving time, 1 or 0 522 string += +date.isInDST; 523 break; 524 525 case 'O': // Different to Greenwich time (GMT) without colon e.g. +0200 526 string += date.toFormat('ZZZ'); 527 break; 528 529 case 'P': // Different to Greenwich time (GMT) with colon e.g. +02:00 530 string += date.toFormat('ZZ'); 531 break; 532 533 // This is a bit weird. PHP 7.3 doesn't seem to recognize 'p' as an 534 // option even though it's in the online PHP manual. So we won't either 535 // until we figure out what's going on. 536 537 // case 'p': // Same as P but returns Z instead of +00:00 538 // diff = date.toFormat('ZZ'); 539 // if (diff == '+00:00') { 540 // string += 'Z'; 541 // } else {
542 // string += diff; 543 // } 544 // break; 545 546 case 'T': // Timezone abbreviation, e.g., EST, MDT, etc. 547 string += date.toFormat('ZZZZ'); 548 break; 549 550 case 'Z': // Timezone offset in seconds. 551 string += date.offset * 60; 552 break; 553 554 // Full Date/Time 555 556 case 'c': // ISO 8601 date (eg: 2012-11-20T18:05:54.944Z) 557 // Note that Luxon's implementation of ISO 8601 is not identical to PHP's. 558 string += date.toISO(); 559 break; 560 561 case 'r': // RFC 2822 formatted date 562 string += date.toRFC2822(); 563 break; 564 565 case 'U': // Seconds since Unix epoch (Jan 1 1970 00:00:00). 566 string += date.toSeconds(); 567 break; 568 569 // Ignore everything else 570 571 default: 572 if (i.startsWith("\\")) i = i.substr(1); 573 string += i; 574 } 575 return string; 576 }; 577 578 // If using browser timezone detection, find any utz-datetime items, then 579 // format the string using the PHP format converter. 580 var detection = Backdrop.settings.utz_tokens.timezone_detection; 581 if (detection == 1 || detection == 2) { 582 var selector = 'span.utz-datetime'; 583 if (detection == 1) { 584 selector += '[data-anonymous="1"]'; 585 } 586 jQuery(selector).each(function() { 587 var timestamp = +($(this).attr('data-timestamp')); 588 var format = $(this).attr('data-format'); 589 var date = luxon.DateTime.fromSeconds(timestamp); 590 var dateStr = formatPHP(date, format); 591 $(this).text(dateStr); 592 $(this).attr('utz-datetime-processed', '1'); 593 }); 594 } 595 }); 596})(jQuery); 597;
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.