1/** 2 * @file 3 * Behaviors for the theme. 4 */ 5(function ($, _, Drupal, drupalSettings) { 6 'use strict'; 7 Drupal.behaviors.partner = { 8 attach: function (context) { 9 10 // ===== Main menu - parent clickable ==== 11 if ($('header#navbar .menu--main', context).length > 0) { 12 $('.menu--main a.dropdown-toggle', context).click(function() { 13 if ($(window).width() >= 768) { 14 location.href = this.href; 15 return false; 16 } 17 }); 18 } 19 20 // ===== Search Page - focus on load ==== 21 if ($('header#navbar .search-box').length > 0) { 22 $('.search-box button').off('click').on('click', function(e) { 23 e.preventDefault(); 24 $( "header#navbar .search-popup-wrapper").slideToggle("fast", function() { 25 var keywords = $('header#navbar .search-popup-wrapper input').val(); 26 $('header#navbar .search-popup-wrapper input').select().val('').val(keywords); 27 }); 28 return false; 29 }); 30 } 31 if ($('body.path-search #edit-keys').length > 0) { 32 var keywords = $('.path-search #edit-keys').val(); $('.path-search #edit-keys').select().val('').val(keywords); 33 } 34 35 // External links 36 var anchors = $("nav .menu a, .testimonial .redirect-url", context); 37 for (var i=0; i<anchors.length; i++) { 38 if (anchors[i].hostname != window.location.hostname && anchors[i].hostname != "" && typeof anchors[i].getAttribute('target') == "object") { 39 anchors[i].setAttribute('target', '_blank'); 40 } 41 } 42 43 // ===== Contact ==== 44 if ($('.path-contact', context).length > 0) { 45 var urlParams = new URLSearchParams(window.location.search); 46 var selectedValue = urlParams.get("tid"); 47 if (selectedValue !== "" && !isNaN(selectedValue) && $.inArray(parseInt(selectedValue), [6, 7, 26, 27, 145, 146, 142, 143]) !== -1) { 48 $("#edit-field-department").val(selectedValue); 49 } 50 //remove advertisements for AJ360 51 $('#edit-field-department').on('change', function() { 52 const isRestricted = $(this).val() === '142' || $(this).val() === '146'; 53 const $feedbackItem = $('#edit-field-sub-category input[name="field_sub_category"][value="Advertisements Feedback"]').closest('.form-item'); 54 $feedbackItem.toggle(!isRestricted); 55 if (isRestricted) { 56 $feedbackItem.find('input[type="radio"]').prop('checked', false); 57 } 58 }); 59 $('#edit-field-department').trigger('change'); 60 $('.field--name-field-sub-category legend span, .field--name-field-sub-category1 legend span, .field--name-field-sub-category2 legend span', context).addClass('js-form-required form-required'); 61 62 $('#edit-field-sub-category input[name="field_sub_category"], #edit-field-sub-category1 input[name="field_sub_category1"]').on('change', function() { 63 $('#edit-field-contact-url-0-uri, #edit-field-contact-article-url-0-uri, #edit-field-contact-article-title-0-value').val(''); 64 }); 65 $('#edit-field-contact-url-0-uri, #edit-field-contact-article-url-0-uri').on('blur', function() { 66 var url = $.trim($(this).val()); 67 if (url && !/^https?:\/\//i.test(url) && /^[a-z0-9-]+(\.[a-z0-9-]+)+([\/?#].*)?$/i.test(url)) { 68 url = 'https://' + url; 69 } 70 $(this).val(url); 71 }); 72 } 73 74 // ===== Bureaus ==== 75 if ($('.path-frontpage .global-presence .bureau-region-group', context).length > 0) { 76 $('.bureau-region-group h3', context).off('click').on('click', function(e) { 77 e.preventDefault(); 78 var $this = $(this); 79 $this.toggleClass('is-active').next('.bureau-list').slideToggle(400); 80 $('.bureau-region-group h3', context).not($this).removeClass('is-active').css("color", "");; 81 $('.bureau-region-group .bureau-list', context).not($this.next('.bureau-list')).slideUp(); 82 }); 83 $('.bureau-region-group:first-child h3', context).css("color", "#02cbc9"); 84 } 85 86 // ===== Vision ==== 87 if ($('.view.vision-mission-page', context).length > 0) { 88 function visionBoxRow(){ 89 $(".visionbox-row", context).each(function() { 90 $(this).height($('.vision-box', $(this)).height() + 45); 91 }); 92 } 93 visionBoxRow(); 94 $(window).resize(function() { visionBoxRow(); }); 95 } 96 if ($('.view.vision-mission-page, body.path-our-values, body.path-more', context).length > 0) { 97 $("html").css({"scroll-behavior": "smooth"}); 98 } 99 // ===== Vision Parallax ==== 100 if ($('.view.vision-mission-page', context).length > 0) { 101 $("html").css({"font-size": 0}); 102 var viewport = $(window), 103 root = $('html'), 104 maxScroll; 105 106 viewport.on({ 107 scroll: function() { 108 var scrolled = viewport.scrollTop(); 109 root.css({ fontSize: (scrolled / maxScroll) * 100 }); 110 }, 111 resize: function() { 112 maxScroll = root.height() - viewport.height(); 113 } 114 }).trigger('resize'); 115 } 116 117 // ===== Leadership, Channels ==== 118 if ($('body.path-leadership, body.path-faces-aljazeera, body.path-channels', context).length > 0) { 119 $('.scrolling-wrapper > .carousel-control.right', context).click(function() { 120 $(this).siblings('.scrolling-wrapper-flexbox').animate({ scrollLeft: "+=400px" }, "slow"); 121 }); 122 $('.scrolling-wrapper > .carousel-control.left', context).click(function() { 123 $(this).siblings('.scrolling-wrapper-flexbox').animate({ scrollLeft: "-=400px" }, "slow"); 124 }); 125 } 126 if ($('body.path-faces-aljazeera .faces-group-channel .views-exposed-form').length > 0) { 127 var mycat = Drupal.t("All"); 128 $("[id^='edit-field-category-value'] option[value='All']").text(mycat); 129 $('html[dir="rtl"] .faces-group-channel:not(".view-display-id-page_1") .views-exposed-form input.form-text').attr("placeholder", "Ø§ÙØ¨ØØ« Ø¹Ù Ù Ø°ÙØ¹..."); 130 131 $('.faces-group-channel .views-exposed-form .form-select').bind('change', function(e) { 132 $("[id^='edit-actions'] > button", context).click(); 133 }); 134 135 var focusedField = $('.faces-group-channel .views-exposed-form input.form-text'); 136 if (focusedField.val()) { 137 var initialVal = focusedField.val(); 138 focusedField.focus().val('').val(initialVal); 139 } 140 141 var autoSubmitTimer = 0;
142 var autoSubmitDelay = 1000; 143 $('.faces-group-channel .views-exposed-form input.form-text').bind('keyup', function(e) { 144 e.preventDefault(); 145 if (autoSubmitTimer) { clearTimeout(autoSubmitTimer); } 146 autoSubmitTimer = setTimeout(function() { 147 $("[id^='edit-actions'] > button", context).click(); 148 }, autoSubmitDelay); 149 }); 150 151 } 152 153 // ===== Press or Awards filters ==== 154 if ($('body.path-awards .press-awards, body.path-press-releases .press-awards, body.path-events .events-filters').length > 0) { 155 var myvar = Drupal.t("Network"); 156 $("[id^='edit-term-node-tid-depth'] option:first").text(myvar); 157 158 $('.press-awards .views-exposed-form .form-select, .events-filters .views-exposed-form .form-select').bind('change', function(e) { 159 $("[id^='edit-actions'] > button", context).click(); 160 }); 161 } 162 // Hide duplicate years 163 if ($('.view-awards.view-display-id-page_1').length > 0) { 164 var prevGroupTitleText = ''; 165 $('h3.group-title', context).each(function() { 166 var currentText = $(this).find('span').text(); 167 prevGroupTitleText === currentText ? $(this).hide() : prevGroupTitleText = currentText; 168 }); 169 } 170 171 172 // ===== Live channels ==== 173 if ($('body.path-live').length > 0) { 174 var liveID = $('.live-channel').attr( "live-id" ); 175 $('.view-live .live-tabs li a.tab-' + liveID, context).addClass('active'); 176 } 177 178 // ===== Share on Social Media ==== 179 function openPopup(url) { 180 var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; 181 var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; 182 var desiredWidth = 550; 183 var desiredHeight = 350; 184 var left = (width - desiredWidth) / 2; 185 var top = (height - desiredHeight) / 2; 186 var windowFeatures = "width=" + desiredWidth + ",height=" + desiredHeight + ",resizable=yes,scrollbars=yes,status=yes,left=" + left + ",top=" + top; 187 var newWindow = window.open(url, "", windowFeatures); 188 if (window.focus) newWindow.focus(); 189 return false; 190 } 191 $(context).find('.open-popup').click(function (event) { 192 var url = $(this).attr('href'); 193 openPopup(url); 194 event.preventDefault(); 195 }); 196 197 // ===== FAQs section ==== 198 if ($('.view-faq', context).length > 0) { 199 var $questions = $('.question', context); 200 $questions.off('click').on('click', function(e) { 201 e.preventDefault(); 202 const $this = $(this); 203 const $answer = $this.next('.answer'); 204 $this.toggleClass('is-active'); 205 $answer.slideToggle(400); 206 $('.question').not($this).removeClass('is-active'); 207 $('.answer').not($answer).slideUp(); 208 }); 209 } 210 211 } 212 }; 213 214})(window.jQuery, window._, window.Drupal, window.drupalSettings); 215; 216/** 217 * @file 218 * Drupal Bootstrap object. 219 */ 220 221/** 222 * All Drupal Bootstrap JavaScript APIs are contained in this namespace. 223 * 224 * @param {underscore} _ 225 * @param {jQuery} $ 226 * @param {Drupal} Drupal 227 * @param {drupalSettings} drupalSettings 228 */ 229(function (_, $, Drupal, drupalSettings) { 230 'use strict'; 231 232 /** 233 * @typedef Drupal.bootstrap 234 */ 235 var Bootstrap = { 236 processedOnce: {}, 237 settings: drupalSettings.bootstrap || {} 238 }; 239 240 /** 241 * Wraps Drupal.checkPlain() to ensure value passed isn't empty. 242 * 243 * Encodes special characters in a plain-text string for display as HTML. 244 * 245 * @param {string} str 246 * The string to be encoded. 247 * 248 * @return {string} 249 * The encoded string. 250 * 251 * @ingroup sanitization 252 */ 253 Bootstrap.checkPlain = function (str) { 254 return str && Drupal.checkPlain(str) || ''; 255 }; 256 257 /** 258 * Creates a jQuery plugin. 259 * 260 * @param {String} id 261 * A jQuery plugin identifier located in $.fn. 262 * @param {Function} plugin 263 * A constructor function used to initialize the for the jQuery plugin. 264 * @param {Boolean} [noConflict]
265 * Flag indicating whether or not to create a ".noConflict()" helper method 266 * for the plugin. 267 */ 268 Bootstrap.createPlugin = function (id, plugin, noConflict) { 269 // Immediately return if plugin doesn't exist. 270 if ($.fn[id] !== void 0) { 271 return this.fatal('Specified jQuery plugin identifier already exists: @id. Use Drupal.bootstrap.replacePlugin() instead.', {'@id': id}); 272 } 273 274 // Immediately return if plugin isn't a function. 275 if (typeof plugin !== 'function') { 276 return this.fatal('You must provide a constructor function to create a jQuery plugin "@id": @plugin', {'@id': id, '@plugin': plugin}); 277 } 278 279 // Add a ".noConflict()" helper method. 280 this.pluginNoConflict(id, plugin, noConflict); 281 282 $.fn[id] = plugin; 283 }; 284 285 /** 286 * Diff object properties. 287 * 288 * @param {...Object} objects 289 * Two or more objects. The first object will be used to return properties 290 * values. 291 * 292 * @return {Object} 293 * Returns the properties of the first passed object that are not present 294 * in all other passed objects. 295 */ 296 Bootstrap.diffObjects = function (objects) { 297 var args = Array.prototype.slice.call(arguments); 298 return _.pick(args[0], _.difference.apply(_, _.map(args, function (obj) { 299 return Object.keys(obj); 300 }))); 301 }; 302 303 /** 304 * Map of supported events by regular expression. 305 * 306 * @type {Object<Event|MouseEvent|KeyboardEvent|TouchEvent,RegExp>} 307 */ 308 Bootstrap.eventMap = { 309 Event: /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/, 310 MouseEvent: /^(?:click|dblclick|mouse(?:down|enter|leave|up|over|move|out))$/, 311 KeyboardEvent: /^(?:key(?:down|press|up))$/, 312 TouchEvent: /^(?:touch(?:start|end|move|cancel))$/ 313 }; 314 315 /** 316 * Extends a jQuery Plugin. 317 * 318 * @param {String} id 319 * A jQuery plugin identifier located in $.fn. 320 * @param {Function} callback 321 * A constructor function used to initialize the for the jQuery plugin. 322 * 323 * @return {Function|Boolean} 324 * The jQuery plugin constructor or FALSE if the plugin does not exist. 325 */ 326 Bootstrap.extendPlugin = function (id, callback) { 327 // Immediately return if plugin doesn't exist. 328 if (typeof $.fn[id] !== 'function') { 329 return this.fatal('Specified jQuery plugin identifier does not exist: @id', {'@id': id}); 330 } 331 332 // Immediately return if callback isn't a function. 333 if (typeof callback !== 'function') { 334 return this.fatal('You must provide a callback function to extend the jQuery plugin "@id": @callback', {'@id': id, '@callback': callback}); 335 } 336 337 // Determine existing plugin constructor. 338 var constructor = $.fn[id] && $.fn[id].Constructor || $.fn[id]; 339 var plugin = callback.apply(constructor, [this.settings]); 340 if (!$.isPlainObject(plugin)) { 341 return this.fatal('Returned value from callback is not a plain object that can be used to extend the jQuery plugin "@id": @obj', {'@obj': plugin}); 342 } 343 344 this.wrapPluginConstructor(constructor, plugin, true); 345 346 return $.fn[id]; 347 }; 348 349 Bootstrap.superWrapper = function (parent, fn) { 350 return function () { 351 var previousSuper = this.super; 352 this.super = parent; 353 var ret = fn.apply(this, arguments); 354 if (previousSuper) { 355 this.super = previousSuper; 356 } 357 else { 358 delete this.super; 359 } 360 return ret; 361 }; 362 }; 363 364 /** 365 * Provide a helper method for displaying when something is went wrong. 366 * 367 * @param {String} message 368 * The message to display. 369 * @param {Object} [args] 370 * An arguments to use in message. 371 * 372 * @return {Boolean} 373 * Always returns FALSE. 374 */ 375 Bootstrap.fatal = function (message, args) { 376 if (this.settings.dev && console.warn) { 377 for (var name in args) { 378 if (args.hasOwnProperty(name) && typeof args[name] === 'object') { 379 args[name] = JSON.stringify(args[name]); 380 } 381 } 382 Drupal.throwError(new Error(Drupal.formatString(message, args))); 383 } 384 return false; 385 }; 386 387 /** 388 * Intersects object properties. 389 * 390 * @param {...Object} objects 391 * Two or more objects. The first object will be used to return properties 392 * values. 393 * 394 * @return {Object} 395 * Returns the properties of first passed object that intersects with all 396 * other passed objects. 397 */ 398 Bootstrap.intersectObjects = function (objects) { 399 var args = Array.prototype.slice.call(arguments); 400 return _.pick(args[0], _.intersection.apply(_, _.map(args, function (obj) { 401 return Object.keys(obj); 402 }
402))); 403 }; 404 405 /** 406 * Normalizes an object's values. 407 * 408 * @param {Object} obj 409 * The object to normalize. 410 * 411 * @return {Object} 412 * The normalized object. 413 */ 414 Bootstrap.normalizeObject = function (obj) { 415 if (!$.isPlainObject(obj)) { 416 return obj; 417 } 418 419 for (var k in obj) { 420 if (typeof obj[k] === 'string') { 421 if (obj[k] === 'true') { 422 obj[k] = true; 423 } 424 else if (obj[k] === 'false') { 425 obj[k] = false; 426 } 427 else if (obj[k].match(/^[\d-.]$/)) { 428 obj[k] = parseFloat(obj[k]); 429 } 430 } 431 else if ($.isPlainObject(obj[k])) { 432 obj[k] = Bootstrap.normalizeObject(obj[k]); 433 } 434 } 435 436 return obj; 437 }; 438 439 /** 440 * An object based once plugin (similar to jquery.once, but without the DOM). 441 * 442 * @param {String} id 443 * A unique identifier. 444 * @param {Function} callback 445 * The callback to invoke if the identifier has not yet been seen. 446 * 447 * @return {Bootstrap} 448 */ 449 Bootstrap.once = function (id, callback) { 450 // Immediately return if identifier has already been processed. 451 if (this.processedOnce[id]) { 452 return this; 453 } 454 callback.call(this, this.settings); 455 this.processedOnce[id] = true; 456 return this; 457 }; 458 459 /** 460 * Provide jQuery UI like ability to get/set options for Bootstrap plugins. 461 * 462 * @param {string|object} key 463 * A string value of the option to set, can be dot like to a nested key. 464 * An object of key/value pairs. 465 * @param {*} [value] 466 * (optional) A value to set for key. 467 * 468 * @returns {*} 469 * - Returns nothing if key is an object or both key and value parameters 470 * were provided to set an option. 471 * - Returns the a value for a specific setting if key was provided. 472 * - Returns an object of key/value pairs of all the options if no key or 473 * value parameter was provided. 474 * 475 * @see https://github.com/jquery/jquery-ui/blob/master/ui/widget.js 476 */ 477 Bootstrap.option = function (key, value) { 478 var options = $.isPlainObject(key) ? $.extend({}, key) : {}; 479 480 // Get all options (clone so it doesn't reference the internal object). 481 if (arguments.length === 0) { 482 return $.extend({}, this.options); 483 } 484 485 // Get/set single option. 486 if (typeof key === "string") { 487 // Handle nested keys in dot notation. 488 // e.g., "foo.bar" => { foo: { bar: true } } 489 var parts = key.split('.'); 490 key = parts.shift(); 491 var obj = options; 492 if (parts.length) { 493 for (var i = 0; i < parts.length - 1; i++) { 494 obj[parts[i]] = obj[parts[i]] || {}; 495 obj = obj[parts[i]]; 496 } 497 key = parts.pop(); 498 } 499 500 // Get. 501 if (arguments.length === 1) { 502 return obj[key] === void 0 ? null : obj[key]; 503 } 504 505 // Set. 506 obj[key] = value; 507 } 508 509 // Set multiple options. 510 $.extend(true, this.options, options); 511 }; 512 513 /** 514 * Adds a ".noConflict()" helper method if needed. 515 * 516 * @param {String} id 517 * A jQuery plugin identifier located in $.fn. 518 * @param {Function} plugin 519 * @param {Function} plugin 520 * A constructor function used to initialize the for the jQuery plugin. 521 * @param {Boolean} [noConflict] 522 * Flag indicating whether or not to create a ".noConflict()" helper method 523 * for the plugin. 524 */ 525 Bootstrap.pluginNoConflict = function (id, plugin, noConflict) { 526 if (plugin.noConflict === void 0 && (noConflict === void 0 || noConflict)) { 527 var old = $.fn[id]; 528 plugin.noConflict = function () { 529 $.fn[id] = old; 530 return this; 531 }; 532 } 533 }; 534 535 /** 536 * Creates a handler that relays to another event name. 537 * 538 * @param {HTMLElement|jQuery} target 539 * A target element. 540 * @param {String} name 541 * The name of the event to trigger. 542 * @param {Boolean} [stopPropagation=true] 543 * Flag indicating whether to stop the propagation of the event, defaults 544 * to true. 545 * 546 * @return {Function} 547 * An even handler callback function. 548 */ 549 Bootstrap.relayEvent = function (target, name, stopPropagation) { 550 return function (e) { 551 if (stopPropagation === void 0 || stopPropagation) { 552 e.stopPropagation(); 553 } 554 var $target = $(target);
555 var parts = name.split('.').filter(Boolean); 556 var type = parts.shift(); 557 e.target = $target[0]; 558 e.currentTarget = $target[0]; 559 e.namespace = parts.join('.'); 560 e.type = type; 561 $target.trigger(e); 562 }; 563 }; 564 565 /** 566 * Replaces a Bootstrap jQuery plugin definition. 567 * 568 * @param {String} id 569 * A jQuery plugin identifier located in $.fn. 570 * @param {Function} callback 571 * A callback function that is immediately invoked and must return a 572 * function that will be used as the plugin constructor. 573 * @param {Boolean} [noConflict] 574 * Flag indicating whether or not to create a ".noConflict()" helper method 575 * for the plugin. 576 */ 577 Bootstrap.replacePlugin = function (id, callback, noConflict) { 578 // Immediately return if plugin doesn't exist. 579 if (typeof $.fn[id] !== 'function') { 580 return this.fatal('Specified jQuery plugin identifier does not exist: @id', {'@id': id}); 581 } 582 583 // Immediately return if callback isn't a function. 584 if (typeof callback !== 'function') { 585 return this.fatal('You must provide a valid callback function to replace a jQuery plugin: @callback', {'@callback': callback}); 586 } 587 588 // Determine existing plugin constructor. 589 var constructor = $.fn[id] && $.fn[id].Constructor || $.fn[id]; 590 var plugin = callback.apply(constructor, [this.settings]); 591 592 // Immediately return if plugin isn't a function. 593 if (typeof plugin !== 'function') { 594 return this.fatal('Returned value from callback is not a usable function to replace a jQuery plugin "@id": @plugin', {'@id': id, '@plugin': plugin}); 595 } 596 597 this.wrapPluginConstructor(constructor, plugin); 598 599 // Add a ".noConflict()" helper method. 600 this.pluginNoConflict(id, plugin, noConflict); 601 602 $.fn[id] = plugin; 603 }; 604 605 /** 606 * Simulates a native event on an element in the browser. 607 * 608 * Note: This is a fairly complete modern implementation. If things aren't 609 * working quite the way you intend (in older browsers), you may wish to use 610 * the jQuery.simulate plugin. If it's available, this method will defer to 611 * that plugin. 612 * 613 * @see https://github.com/jquery/jquery-simulate 614 * 615 * @param {HTMLElement|jQuery} element 616 * A DOM element to dispatch event on. Note: this may be a jQuery object, 617 * however be aware that this will trigger the same event for each element 618 * inside the jQuery collection; use with caution. 619 * @param {String|String[]} type 620 * The type(s) of event to simulate. 621 * @param {Object} [options] 622 * An object of options to pass to the event constructor. Typically, if 623 * an event is being proxied, you should just pass the original event 624 * object here. This allows, if the browser supports it, to be a truly 625 * simulated event. 626 * 627 * @return {Boolean} 628 * The return value is false if event is cancelable and at least one of the 629 * event handlers which handled this event called Event.preventDefault(). 630 * Otherwise it returns true. 631 */ 632 Bootstrap.simulate = function (element, type, options) { 633 // Handle jQuery object wrappers so it triggers on each element. 634 var ret = true; 635 if (element instanceof $) { 636 element.each(function () { 637 if (!Bootstrap.simulate(this, type, options)) { 638 ret = false;
639 } 640 }); 641 return ret; 642 } 643 644 if (!(element instanceof HTMLElement)) { 645 this.fatal('Passed element must be an instance of HTMLElement, got "@type" instead.', { 646 '@type': typeof element, 647 }); 648 } 649 650 // Defer to the jQuery.simulate plugin, if it's available. 651 if (typeof $.simulate === 'function') { 652 new $.simulate(element, type, options); 653 return true; 654 } 655 656 var event; 657 var ctor; 658 var types = [].concat(type); 659 for (var i = 0, l = types.length; i < l; i++) { 660 type = types[i]; 661 for (var name in this.eventMap) { 662 if (this.eventMap[name].test(type)) { 663 ctor = name; 664 break; 665 } 666 } 667 if (!ctor) { 668 throw new SyntaxError('Only rudimentary HTMLEvents, KeyboardEvents and MouseEvents are supported: ' + type); 669 } 670 var opts = {bubbles: true, cancelable: true}; 671 if (ctor === 'KeyboardEvent' || ctor === 'MouseEvent') { 672 $.extend(opts, {ctrlKey: !1, altKey: !1, shiftKey: !1, metaKey: !1}); 673 } 674 if (ctor === 'MouseEvent') { 675 $.extend(opts, {button: 0, pointerX: 0, pointerY: 0, view: window}); 676 } 677 if (options) { 678 $.extend(opts, options); 679 } 680 if (typeof window[ctor] === 'function') { 681 event = new window[ctor](type, opts); 682 if (!element.dispatchEvent(event)) { 683 ret = false;
684 } 685 } 686 else if (document.createEvent) { 687 event = document.createEvent(ctor); 688 event.initEvent(type, opts.bubbles, opts.cancelable); 689 if (!element.dispatchEvent(event)) { 690 ret = false; 691 } 692 } 693 else if (typeof element.fireEvent === 'function') { 694 event = $.extend(document.createEventObject(), opts); 695 if (!element.fireEvent('on' + type, event)) { 696 ret = false; 697 } 698 } 699 else if (typeof element[type]) { 700 element[type](); 701 } 702 } 703 return ret; 704 }; 705 706 /** 707 * Strips HTML and returns just text. 708 * 709 * @param {String|Element|jQuery} html 710 * A string of HTML content, an Element DOM object or a jQuery object. 711 * 712 * @return {String} 713 * The text without HTML tags. 714 * 715 * @todo Replace with http://locutus.io/php/strings/strip_tags/ 716 */ 717 Bootstrap.stripHtml = function (html) { 718 if (html instanceof $) { 719 html = html.html(); 720 } 721 else if (html instanceof Element) { 722 html = html.innerHTML; 723 } 724 var tmp = document.createElement('DIV'); 725 tmp.innerHTML = html; 726 return (tmp.textContent || tmp.innerText || '').replace(/^[\s\n\t]*|[\s\n\t]*$/, ''); 727 }; 728 729 /** 730 * Provide a helper method for displaying when something is unsupported. 731 * 732 * @param {String} type 733 * The type of unsupported object, e.g. method or option. 734 * @param {String} name 735 * The name of the unsupported object. 736 * @param {*} [value] 737 * The value of the unsupported object. 738 */ 739 Bootstrap.unsupported = function (type, name, value) { 740 Bootstrap.warn('Unsupported by Drupal Bootstrap: (@type) @name -> @value', { 741 '@type': type, 742 '@name': name, 743 '@value': typeof value === 'object' ? JSON.stringify(value) : value 744 }); 745 }; 746 747 /** 748 * Provide a helper method to display a warning. 749 * 750 * @param {String} message 751 * The message to display. 752 * @param {Object} [args] 753 * Arguments to use as replacements in Drupal.formatString. 754 */ 755 Bootstrap.warn = function (message, args) { 756 if (this.settings.dev && console.warn) { 757 console.warn(Drupal.formatString(message, args)); 758 } 759 }; 760 761 /** 762 * Wraps a plugin with common functionality. 763 * 764 * @param {Function} constructor 765 * A plugin constructor being wrapped. 766 * @param {Object|Function} plugin 767 * The plugin being wrapped. 768 * @param {Boolean} [extend = false] 769 * Whether to add super extensibility. 770 */ 771 Bootstrap.wrapPluginConstructor = function (constructor, plugin, extend) { 772 var proto = constructor.prototype; 773 774 // Add a jQuery UI like option getter/setter method. 775 var option = this.option; 776 if (proto.option === void(0)) { 777 proto.option = function () { 778 return option.apply(this, arguments); 779 }; 780 } 781 782 if (extend) { 783 // Handle prototype properties separately. 784 if (plugin.prototype !== void 0) { 785 for (var key in plugin.prototype) { 786 if (!plugin.prototype.hasOwnProperty(key)) continue; 787 var value = plugin.prototype[key]; 788 if (typeof value === 'function') { 789 proto[key] = this.superWrapper(proto[key] || function () {}, value); 790 } 791 else { 792 proto[key] = $.isPlainObject(value) ? $.extend(true, {}, proto[key], value) : value; 793 } 794 } 795 } 796 delete plugin.prototype; 797 798 // Handle static properties. 799 for (key in plugin) { 800 if (!plugin.hasOwnProperty(key)) continue; 801 value = plugin[key]; 802 if (typeof value === 'function') { 803 constructor[key] = this.superWrapper(constructor[key] || function () {}, value); 804 } 805 else { 806 constructor[key] = $.isPlainObject(value) ? $.extend(true, {}, constructor[key], value) : value; 807 } 808 } 809 } 810 }; 811 812 // Add Bootstrap to the global Drupal object. 813 Drupal.bootstrap = Drupal.bootstrap || Bootstrap; 814 815})(window._, window.jQuery, window.Drupal, window.drupalSettings); 816; 817(function ($, _) { 818 819 /** 820 * @class Attributes 821 * 822 * Modifies attributes. 823 * 824 * @param {Object|Attributes} attributes 825 * An object to initialize attributes with. 826 */ 827 var Attributes = function (attributes) { 828 this.data = {}; 829 this.data['class'] = [];
830 this.merge(attributes); 831 }; 832 833 /** 834 * Renders the attributes object as a string to inject into an HTML element. 835 * 836 * @return {String} 837 * A rendered string suitable for inclusion in HTML markup. 838 */ 839 Attributes.prototype.toString = function () { 840 var output = ''; 841 var name, value; 842 var checkPlain = function (str) { 843 return str && str.toString().replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>') || ''; 844 }; 845 var data = this.getData(); 846 for (name in data) { 847 if (!data.hasOwnProperty(name)) continue; 848 value = data[name]; 849 if (_.isFunction(value)) value = value(); 850 if (_.isObject(value)) value = _.values(value); 851 if (_.isArray(value)) value = value.join(' '); 852 output += ' ' + checkPlain(name) + '="' + checkPlain(value) + '"'; 853 } 854 return output; 855 }; 856 857 /** 858 * Renders the Attributes object as a plain object. 859 * 860 * @return {Object} 861 * A plain object suitable for inclusion in DOM elements. 862 */ 863 Attributes.prototype.toPlainObject = function () { 864 var object = {}; 865 var name, value; 866 var data = this.getData(); 867 for (name in data) { 868 if (!data.hasOwnProperty(name)) continue; 869 value = data[name]; 870 if (_.isFunction(value)) value = value(); 871 if (_.isObject(value)) value = _.values(value); 872 if (_.isArray(value)) value = value.join(' '); 873 object[name] = value; 874 } 875 return object; 876 }; 877 878 /** 879 * Add class(es) to the array. 880 * 881 * @param {string|Array} value 882 * An individual class or an array of classes to add. 883 * 884 * @return {Attributes} 885 * 886 * @chainable 887 */ 888 Attributes.prototype.addClass = function (value) { 889 var args = Array.prototype.slice.call(arguments); 890 this.data['class'] = this.sanitizeClasses(this.data['class'].concat(args)); 891 return this; 892 }; 893 894 /** 895 * Returns whether the requested attribute exists. 896 * 897 * @param {string} name 898 * An attribute name to check. 899 * 900 * @return {boolean} 901 * TRUE or FALSE 902 */ 903 Attributes.prototype.exists = function (name) { 904 return this.data[name] !== void(0) && this.data[name] !== null; 905 }; 906 907 /** 908 * Retrieve a specific attribute from the array. 909 * 910 * @param {string} name 911 * The specific attribute to retrieve. 912 * @param {*} defaultValue 913 * (optional) The default value to set if the attribute does not exist. 914 * 915 * @return {*} 916 * A specific attribute value, passed by reference. 917 */ 918 Attributes.prototype.get = function (name, defaultValue) { 919 if (!this.exists(name)) this.data[name] = defaultValue; 920 return this.data[name]; 921 }; 922 923 /** 924 * Retrieves a cloned copy of the internal attributes data object. 925 * 926 * @return {Object} 927 */ 928 Attributes.prototype.getData = function () { 929 return _.extend({}, this.data); 930 }; 931 932 /** 933 * Retrieves classes from the array. 934 * 935 * @return {Array} 936 * The classes array. 937 */ 938 Attributes.prototype.getClasses = function () { 939 return this.get('class', []); 940 }; 941 942 /** 943 * Indicates whether a class is present in the array. 944 * 945 * @param {string|Array} className 946 * The class(es) to search for. 947 * 948 * @return {boolean} 949 * TRUE or FALSE 950 */ 951 Attributes.prototype.hasClass = function (className) { 952 className = this.sanitizeClasses(Array.prototype.slice.call(arguments)); 953 var classes = this.getClasses(); 954 for (var i = 0, l = className.length; i < l; i++) { 955 // If one of the classes fails, immediately return false. 956 if (_.indexOf(classes, className[i]) === -1) { 957 return false; 958 } 959 } 960 return true; 961 }; 962 963 /** 964 * Merges multiple values into the array. 965 * 966 * @param {Attributes|Node|jQuery|Object} object 967 * An Attributes object with existing data, a Node DOM element, a jQuery 968 * instance or a plain object where the key is the attribute name and the 969 * value is the attribute value. 970 * @param {boolean} [recursive] 971 * Flag determining whether or not to recursively merge key/value pairs. 972 * 973 * @return {Attributes} 974 * 975 * @chainable 976 */ 977 Attributes.prototype.merge = function (object, recursive) { 978 // Immediately return if there is nothing to merge. 979 if (!object) { 980 return this; 981 } 982 983 // Get attributes from a jQuery element. 984 if (object instanceof $) { 985 object = object[0]; 986 } 987 988 // Get attributes from a DOM element. 989 if (object instanceof Node) { 990 object = Array.prototype.slice.call(object.attributes).reduce(function (attributes, attribute) { 991 attributes[attribute.name] = attribute.value; 992 return attributes; 993 }, {}); 994 } 995 // Get attributes from an Attributes instance. 996 else if (object instanceof Attributes) { 997 object = object.getData(); 998 } 999 // Otherwise, clone the object. 1000 else { 1001 object = _.extend({}, object); 1002 } 1003 1004 // By this point, there should be a valid plain object. 1005 if (!$.isPlainObject(object)) { 1006 setTimeout(function () { 1007 throw new Error('Passed object is not supported: ' + object); 1008 }); 1009 return this; 1010 } 1011 1012 // Handle classes separately. 1013 if (object && object['class'] !== void 0) { 1014 this.addClass(object['class']); 1015 delete object['class']; 1016 } 1017 1018 if (recursive === void 0 || recursive) { 1019 this.data = $.extend(true, {}, this.data, object); 1020 } 1021 else { 1022 this.data = $.extend({}, this.data, object); 1023 } 1024 1025 return this; 1026 }; 1027 1028 /** 1029 * Removes an attribute from the array. 1030 * 1031 * @param {string} name 1032 * The name of the attribute to remove. 1033 * 1034 * @return {Attributes} 1035 * 1036 * @chainable 1037 */ 1038 Attributes.prototype.remove = function (name) { 1039 if (this.exists(name)) delete this.data[name]; 1040 return this; 1041 }; 1042 1043 /** 1044 * Removes a class from the attributes array. 1045 * 1046 * @param {...string|Array} className 1047 * An individual class or an array of classes to remove. 1048 * 1049 * @return {Attributes} 1050 * 1051 * @chainable 1052 */ 1053 Attributes.prototype.removeClass = function (className) { 1054 var remove = this.sanitizeClasses(Array.prototype.slice.apply(arguments)); 1055 this.data['class'] = _.without(this.getClasses(), remove); 1056 return this; 1057 }; 1058 1059 /** 1060 * Replaces a class in the attributes array. 1061 * 1062 * @param {string} oldValue 1063 * The old class to remove. 1064 * @param {string} newValue 1065 * The new class. It will not be added if the old class does not exist. 1066 * 1067 * @return {Attributes} 1068 * 1069 * @chainable 1070 */ 1071 Attributes.prototype.replaceClass = function (oldValue, newValue) { 1072 var classes = this.getClasses(); 1073 var i = _.indexOf(this.sanitizeClasses(oldValue), classes); 1074 if (i >= 0) { 1075 classes[i] = newValue; 1076 this.set('class', classes); 1077 } 1078 return this; 1079 }; 1080 1081 /** 1082 * Ensures classes are flattened into a single is an array and sanitized. 1083 * 1084 * @param {...String|Array} classes 1085 * The class or classes to sanitize. 1086 * 1087 * @return {Array} 1088 * A sanitized array of classes. 1089 */ 1090 Attributes.prototype.sanitizeClasses = function (classes) { 1091 return _.chain(Array.prototype.slice.call(arguments)) 1092 // Flatten in case there's a mix of strings and arrays. 1093 .flatten() 1094 1095 // Split classes that may have been added with a space as a separator. 1096 .map(function (string) { 1097 return string.split(' '); 1098 }) 1099 1100 // Flatten again since it was just split into arrays. 1101 .flatten() 1102 1103 // Filter out empty items. 1104 .filter() 1105
1106 // Clean the class to ensure it's a valid class name. 1107 .map(function (value) { 1108 return Attributes.cleanClass(value); 1109 }) 1110 1111 // Ensure classes are unique. 1112 .uniq() 1113 1114 // Retrieve the final value. 1115 .value(); 1116 }; 1117 1118 /** 1119 * Sets an attribute on the array. 1120 * 1121 * @param {string} name 1122 * The name of the attribute to set. 1123 * @param {*} value 1124 * The value of the attribute to set. 1125 * 1126 * @return {Attributes} 1127 * 1128 * @chainable 1129 */ 1130 Attributes.prototype.set = function (name, value) { 1131 var obj = $.isPlainObject(name) ? name : {}; 1132 if (typeof name === 'string') { 1133 obj[name] = value; 1134 } 1135 return this.merge(obj); 1136 }; 1137 1138 /** 1139 * Prepares a string for use as a CSS identifier (element, class, or ID name). 1140 * 1141 * Note: this is essentially a direct copy from 1142 * \Drupal\Component\Utility\Html::cleanCssIdentifier 1143 * 1144 * @param {string} identifier 1145 * The identifier to clean. 1146 * @param {Object} [filter] 1147 * An object of string replacements to use on the identifier. 1148 * 1149 * @return {string} 1150 * The cleaned identifier. 1151 */ 1152 Attributes.cleanClass = function (identifier, filter) { 1153 filter = filter || { 1154 ' ': '-', 1155 '_': '-', 1156 '/': '-', 1157 '[': '-', 1158 ']': '' 1159 }; 1160 1161 identifier = identifier.toLowerCase(); 1162 1163 if (filter['__'] === void 0) { 1164 identifier = identifier.replace('__', '#DOUBLE_UNDERSCORE#'); 1165 } 1166 1167 identifier = identifier.replace(Object.keys(filter), Object.keys(filter).map(function(key) { return filter[key]; })); 1168 1169 if (filter['__'] === void 0) { 1170 identifier = identifier.replace('#DOUBLE_UNDERSCORE#', '__'); 1171 } 1172
1173 identifier = identifier.replace(/[^\u002D\u0030-\u0039\u0041-\u005A\u005F\u0061-\u007A\u00A1-\uFFFF]/g, ''); 1174 identifier = identifier.replace(['/^[0-9]/', '/^(-[0-9])|^(--)/'], ['_', '__']); 1175 1176 return identifier; 1177 }; 1178 1179 /** 1180 * Creates an Attributes instance. 1181 * 1182 * @param {object|Attributes} [attributes] 1183 * An object to initialize attributes with. 1184 * 1185 * @return {Attributes} 1186 * An Attributes instance. 1187 * 1188 * @constructor 1189 */ 1190 Attributes.create = function (attributes) { 1191 return new Attributes(attributes); 1192 }; 1193 1194 window.Attributes = Attributes; 1195 1196})(window.jQuery, window._); 1197; 1198/** 1199 * @file 1200 * Theme hooks for the Drupal Bootstrap base theme. 1201 */ 1202(function ($, Drupal, Bootstrap, Attributes) { 1203 1204 /** 1205 * Fallback for theming an icon if the Icon API module is not installed. 1206 */ 1207 if (!Drupal.icon) Drupal.icon = { bundles: {} }; 1208 if (!Drupal.theme.icon || Drupal.theme.prototype.icon) { 1209 $.extend(Drupal.theme, /** @lends Drupal.theme */ { 1210 /** 1211 * Renders an icon. 1212 * 1213 * @param {string} bundle 1214 * The bundle which the icon belongs to. 1215 * @param {string} icon 1216 * The name of the icon to render. 1217 * @param {object|Attributes} [attributes] 1218 * An object of attributes to also apply to the icon. 1219 * 1220 * @returns {string} 1221 */ 1222 icon: function (bundle, icon, attributes) { 1223 if (!Drupal.icon.bundles[bundle]) return ''; 1224 attributes = Attributes.create(attributes).addClass('icon').set('aria-hidden', 'true'); 1225 icon = Drupal.icon.bundles[bundle](icon, attributes); 1226 return '<span' + attributes + '></span>'; 1227 } 1228 }); 1229 } 1230 1231 /** 1232 * Callback for modifying an icon in the "bootstrap" icon bundle. 1233 * 1234 * @param {string} icon 1235 * The icon being rendered. 1236 * @param {Attributes} attributes 1237 * Attributes object for the icon. 1238 */ 1239 Drupal.icon.bundles.bootstrap = function (icon, attributes) { 1240 attributes.addClass(['glyphicon', 'glyphicon-' + icon]); 1241 }; 1242 1243 /** 1244 * Add necessary theming hooks. 1245 */ 1246 $.extend(Drupal.theme, /** @lends Drupal.theme */ { 1247 1248 /** 1249 * Renders a Bootstrap AJAX glyphicon throbber. 1250 * 1251 * @returns {string} 1252 */ 1253 ajaxThrobber: function () { 1254 return Drupal.theme('bootstrapIcon', 'refresh', {'class': ['ajax-throbber', 'glyphicon-spin'] }); 1255 }, 1256 1257 /** 1258 * Renders a button element. 1259 * 1260 * @param {object|Attributes} attributes 1261 * An object of attributes to apply to the button. If it contains one of: 1262 * - value: The label of the button. 1263 * - context: The context type of Bootstrap button, can be one of: 1264 * - default 1265 * - primary 1266 * - success 1267 * - info 1268 * - warning 1269 * - danger 1270 * - link 1271 * 1272 * @returns {string} 1273 */ 1274 button: function (attributes) { 1275 attributes = Attributes.create(attributes).addClass('btn'); 1276 var context = attributes.get('context', 'default'); 1277 var label = attributes.get('value', ''); 1278 attributes.remove('context').remove('value'); 1279 if (!attributes.hasClass(['btn-default', 'btn-primary', 'btn-success', 'btn-info', 'btn-warning', 'btn-danger', 'btn-link'])) { 1280 attributes.addClass('btn-' + Bootstrap.checkPlain(context)); 1281 } 1282 1283 // Attempt to, intelligently, provide a default button "type". 1284 if (!attributes.exists('type')) { 1285 attributes.set('type', attributes.hasClass('form-submit') ? 'submit' : 'button'); 1286 } 1287 1288 return '<button' + attributes + '>' + label + '</button>'; 1289 }, 1290 1291 /** 1292 * Alias for "button" theme hook. 1293 * 1294 * @param {object|Attributes} attributes 1295 * An object of attributes to apply to the button. 1296 * 1297 * @see Drupal.theme.button() 1298 * 1299 * @returns {string} 1300 */ 1301 btn: function (attributes) { 1302 return Drupal.theme('button', attributes); 1303 }, 1304 1305 /** 1306 * Renders a button block element. 1307 * 1308 * @param {object|Attributes} attributes 1309 * An object of attributes to apply to the button. 1310 * 1311 * @see Drupal.theme.button() 1312 * 1313 * @returns {string} 1314 */ 1315 'btn-block': function (attributes) { 1316 return Drupal.theme('button', Attributes.create(attributes).addClass('btn-block')); 1317 }, 1318 1319 /**
1320 * Renders a large button element. 1321 * 1322 * @param {object|Attributes} attributes 1323 * An object of attributes to apply to the button. 1324 * 1325 * @see Drupal.theme.button() 1326 * 1327 * @returns {string} 1328 */ 1329 'btn-lg': function (attributes) { 1330 return Drupal.theme('button', Attributes.create(attributes).addClass('btn-lg')); 1331 }, 1332 1333 /** 1334 * Renders a small button element. 1335 * 1336 * @param {object|Attributes} attributes 1337 * An object of attributes to apply to the button. 1338 * 1339 * @see Drupal.theme.button() 1340 * 1341 * @returns {string} 1342 */ 1343 'btn-sm': function (attributes) { 1344 return Drupal.theme('button', Attributes.create(attributes).addClass('btn-sm')); 1345 }, 1346 1347 /** 1348 * Renders an extra small button element. 1349 * 1350 * @param {object|Attributes} attributes 1351 * An object of attributes to apply to the button. 1352 * 1353 * @see Drupal.theme.button() 1354 * 1355 * @returns {string} 1356 */ 1357 'btn-xs': function (attributes) { 1358 return Drupal.theme('button', Attributes.create(attributes).addClass('btn-xs')); 1359 }, 1360 1361 /** 1362 * Renders a glyphicon. 1363 * 1364 * @param {string} name 1365 * The name of the glyphicon. 1366 * @param {object|Attributes} [attributes] 1367 * An object of attributes to apply to the icon. 1368 * 1369 * @returns {string} 1370 */ 1371 bootstrapIcon: function (name, attributes) { 1372 return Drupal.theme('icon', 'bootstrap', name, attributes); 1373 } 1374 1375 }); 1376 1377})(window.jQuery, window.Drupal, window.Drupal.bootstrap, window.Attributes); 1378; 1379/** 1380* DO NOT EDIT THIS FILE. 1381* See the following change record for more information, 1382* https://www.drupal.org/node/2815083 1383* @preserve 1384**/ 1385 1386Drupal.debounce = function (func, wait, immediate) { 1387 var timeout; 1388 var result; 1389 return function () { 1390 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 1391 args[_key] = arguments[_key]; 1392 } 1393 1394 var context = this; 1395 1396 var later = function later() { 1397 timeout = null; 1398 1399 if (!immediate) { 1400 result = func.apply(context, args); 1401 } 1402 }; 1403 1404 var callNow = immediate && !timeout; 1405 clearTimeout(timeout); 1406 timeout = setTimeout(later, wait); 1407 1408 if (callNow) { 1409 result = func.apply(context, args); 1410 } 1411 1412 return result; 1413 }; 1414};; 1415/** 1416* DO NOT EDIT THIS FILE. 1417* See the following change record for more information, 1418* https://www.drupal.org/node/2815083 1419* @preserve 1420**/ 1421 1422(function ($, once) { 1423 var deprecatedMessageSuffix = "is deprecated in Drupal 9.3.0 and will be removed in Drupal 10.0.0. Use the core/once library instead. See https://www.drupal.org/node/3158256"; 1424 var originalJQOnce = $.fn.once; 1425 var originalJQRemoveOnce = $.fn.removeOnce; 1426 1427 $.fn.once = function jQueryOnce(id) { 1428 Drupal.deprecationError({ 1429 message: "jQuery.once() ".concat(deprecatedMessageSuffix) 1430 }); 1431 return originalJQOnce.apply(this, [id]); 1432 }; 1433 1434 $.fn.removeOnce = function jQueryRemoveOnce(id) { 1435 Drupal.deprecationError({ 1436 message: "jQuery.removeOnce() ".concat(deprecatedMessageSuffix) 1437 }); 1438 return originalJQRemoveOnce.apply(this, [id]); 1439 }; 1440 1441 var drupalOnce = once; 1442 1443 function augmentedOnce(id, selector, context) { 1444 originalJQOnce.apply($(selector, context), [id]); 1445 return drupalOnce(id, selector, context); 1446 } 1447 1448 function remove(id, selector, context) { 1449 originalJQRemoveOnce.apply($(selector, context), [id]); 1450 return drupalOnce.remove(id, selector, context); 1451 } 1452 1453 window.once = Object.assign(augmentedOnce, drupalOnce, { 1454 remove: remove 1455 }); 1456})(jQuery, once);; 1457/** 1458* DO NOT EDIT THIS FILE. 1459* See the following change record for more information, 1460* https://www.drupal.org/node/2815083 1461* @preserve 1462**/ 1463 1464(function ($, Drupal, debounce) { 1465 $.fn.drupalGetSummary = function () { 1466 var callback = this.data('summaryCallback'); 1467 return this[0] && callback ? callback(this[0]).trim() : ''; 1468 }; 1469 1470 $.fn.drupalSetSummary = function (callback) { 1471 var self = this; 1472 1473 if (typeof callback !== 'function') { 1474 var val = callback; 1475 1476 callback = function callback() { 1477 return val; 1478 }; 1479 } 1480 1481 return this.data('summaryCallback', callback).off('formUpdated.summary').on('formUpdated.summary', function () { 1482 self.trigger('summaryUpdated'); 1483 }).trigger('summaryUpdated'); 1484 }; 1485 1486 Drupal.behaviors.formSingleSubmit = { 1487 attach: function attach() { 1488 function onFormSubmit(e) { 1489 var $form = $(e.currentTarget); 1490 var formValues = $form.serialize(); 1491 var previousValues = $form.attr('data-drupal-form-submit-last'); 1492 1493 if (previousValues === formValues) { 1494 e.preventDefault(); 1495 } else { 1496 $form.attr('data-drupal-form-submit-last', formValues); 1497 } 1498 } 1499 1500 $(once('form-single-submit', 'body')).on('submit.singleSubmit', 'form:not([method~="GET"])', onFormSubmit); 1501 } 1502 }; 1503 1504 function triggerFormUpdated(element) { 1505 $(element).trigger('formUpdated'); 1506 } 1507 1508 function fieldsList(form) { 1509 return [].map.call(form.querySelectorAll('[name][id]'), function (el) { 1510 return el.id; 1511 }); 1512 } 1513 1514 Drupal.behaviors.formUpdated = { 1515 attach: function attach(context) { 1516 var $context = $(context);
1517 var contextIsForm = $context.is('form'); 1518 var $forms = $(once('form-updated', contextIsForm ? $context : $context.find('form'))); 1519 var formFields; 1520 1521 if ($forms.length) { 1522 $.makeArray($forms).forEach(function (form) { 1523 var events = 'change.formUpdated input.formUpdated '; 1524 var eventHandler = debounce(function (event) { 1525 triggerFormUpdated(event.target); 1526 }, 300); 1527 formFields = fieldsList(form).join(','); 1528 form.setAttribute('data-drupal-form-fields', formFields); 1529 $(form).on(events, eventHandler); 1530 }); 1531 } 1532 1533 if (contextIsForm) { 1534 formFields = fieldsList(context).join(','); 1535 var currentFields = $(context).attr('data-drupal-form-fields'); 1536 1537 if (formFields !== currentFields) { 1538 triggerFormUpdated(context); 1539 } 1540 } 1541 }, 1542 detach: function detach(context, settings, trigger) { 1543 var $context = $(context); 1544 var contextIsForm = $context.is('form'); 1545 1546 if (trigger === 'unload') { 1547 once.remove('form-updated', contextIsForm ? $context : $context.find('form')).forEac
1547h(function (form) { 1548 form.removeAttribute('data-drupal-form-fields'); 1549 $(form).off('.formUpdated'); 1550 }); 1551 } 1552 } 1553 }; 1554 Drupal.behaviors.fillUserInfoFromBrowser = { 1555 attach: function attach(context, settings) { 1556 var userInfo = ['name', 'mail', 'homepage']; 1557 var $forms = $(once('user-info-from-browser', '[data-user-info-from-browser]')); 1558 1559 if ($forms.length) { 1560 userInfo.forEach(function (info) { 1561 var $element = $forms.find("[name=".concat(info, "]")); 1562 var browserData = localStorage.getItem("Drupal.visitor.".concat(info)); 1563 1564 if (!$element.length) { 1565 return; 1566 } 1567 1568 var emptyValue = $element[0].value === ''; 1569 var defaultValue = $element.attr('data-drupal-default-value') === $element[0].value; 1570 1571 if (browserData && (emptyValue || defaultValue)) { 1572 $element.each(function (index, item) { 1573 item.value = browserData; 1574 }); 1575 } 1576 }); 1577 } 1578 1579 $forms.on('submit', function () { 1580 userInfo.forEach(function (info) { 1581 var $element = $forms.find("[name=".concat(info, "]")); 1582 1583 if ($element.length) { 1584 localStorage.setItem("Drupal.visitor.".concat(info), $element[0].value); 1585 } 1586 }); 1587 }); 1588 } 1589 }; 1590 1591 var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e) { 1592 var url; 1593 1594 if (e.type === 'click') { 1595 url = e.currentTarget.location ? e.currentTarget.location : e.currentTarget; 1596 } else { 1597 url = window.location; 1598 } 1599 1600 var hash = url.hash.substr(1); 1601 1602 if (hash) { 1603 var $target = $("#".concat(hash)); 1604 $('body').trigger('formFragmentLinkClickOrHashChange', [$target]); 1605 setTimeout(function () { 1606 return $target.trigger('focus'); 1607 }, 300); 1608 } 1609 }; 1610 1611 var debouncedHandleFragmentLinkClickOrHashChange = debounce(handleFragmentLinkClickOrHashChange, 300, true); 1612 $(window).on('hashchange.form-fragment', debouncedHandleFragmentLinkClickOrHashChange); 1613 $(document).on('click.form-fragment', 'a[href*="#"]', debouncedHandleFragmentLinkClickOrHashChange); 1614})(jQuery, Drupal, Drupal.debounce);; 1615/** 1616 * @file 1617 * Extends methods from core/misc/form.js. 1618 */ 1619 1620(function ($, window, Drupal, drupalSettings) { 1621 1622 /** 1623 * Behavior for "forms_has_error_value_toggle" theme setting. 1624 */ 1625 Drupal.behaviors.bootstrapForm = { 1626 attach: function (context) { 1627 if (drupalSettings.bootstrap && drupalSettings.bootstrap.forms_has_error_value_toggle) { 1628 var $context = $(context); 1629 $context.find('.form-item.has-error:not(.form-type-password.has-feedback)').once('error').each(function () { 1630 var $formItem = $(this); 1631 var $input = $formItem.find(':input'); 1632 $input.on('keyup focus blur', function () { 1633 if (this.defaultValue !== void 0) { 1634 $formItem[this.defaultValue !== this.value ? 'removeClass' : 'addClass']('has-error'); 1635 $input[this.defaultValue !== this.value ? 'removeClass' : 'addClass']('error'); 1636 } 1637 }); 1638 }); 1639 } 1640 } 1641 }; 1642 1643 1644})(jQuery, this, Drupal, drupalSettings); 1645; 1646/** 1647* DO NOT EDIT THIS FILE. 1648* See the following change record for more information, 1649* https://www.drupal.org/node/2815083 1650* @preserve 1651**/ 1652 1653(function ($, Drupal) { 1654 var states = { 1655 postponed: [] 1656 }; 1657 Drupal.states = states; 1658 1659 function invert(a, invertState) { 1660 return invertState && typeof a !== 'undefined' ? !a : a; 1661 } 1662 1663 function _compare2(a, b) { 1664 if (a === b) { 1665 return typeof a === 'undefined' ? a : true; 1666 } 1667 1668 return typeof a === 'undefined' || typeof b === 'undefined'; 1669 } 1670 1671 function ternary(a, b) { 1672 if (typeof a === 'undefined') { 1673 return b; 1674 } 1675 1676 if (typeof b === 'undefined') { 1677 return a; 1678 } 1679 1680 return a && b; 1681 } 1682 1683 Drupal.behaviors.states = { 1684 attach: function attach(context, settings) { 1685 var $states = $(context).find('[data-drupal-states]'); 1686 var il = $states.length; 1687 1688 var _loop = function _loop(i) { 1689 var config = JSON.parse($states[i].getAttribute('data-drupal-states')); 1690 Object.keys(config || {}
1690).forEach(function (state) { 1691 new states.Dependent({ 1692 element: $($states[i]), 1693 state: states.State.sanitize(state), 1694 constraints: config[state] 1695 }); 1696 }); 1697 }; 1698 1699 for (var i = 0; i < il; i++) { 1700 _loop(i); 1701 } 1702 1703 while (states.postponed.length) { 1704 states.postponed.shift()(); 1705 } 1706 } 1707 }; 1708 1709 states.Dependent = function (args) { 1710 var _this = this; 1711 1712 $.extend(this, { 1713 values: {}, 1714 oldValue: null 1715 }, args); 1716 this.dependees = this.getDependees(); 1717 Object.keys(this.dependees || {}).forEach(function (selector) { 1718 _this.initializeDependee(selector, _this.dependees[selector]); 1719 }); 1720 }; 1721 1722 states.Dependent.comparisons = { 1723 RegExp: function RegExp(reference, value) { 1724 return reference.test(value); 1725 }, 1726 Function: function Function(reference, value) { 1727 return reference(value); 1728 }, 1729 Number: function Number(reference, value) { 1730 return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value); 1731 } 1732 }; 1733 states.Dependent.prototype = { 1734 initializeDependee: function initializeDependee(selector, dependeeStates) { 1735 var _this2 = this; 1736 1737 this.values[selector] = {}; 1738 Object.keys(dependeeStates).forEach(function (i) { 1739 var state = dependeeStates[i]; 1740 1741 if ($.inArray(state, dependeeStates) === -1) { 1742 return; 1743 } 1744 1745 state = states.State.sanitize(state); 1746 _this2.values[selector][state.name] = null; 1747 $(selector).on("state:".concat(state), { 1748 selector: selector, 1749 state: state 1750 }, function (e) { 1751 _this2.update(e.data.selector, e.data.state, e.value); 1752 }); 1753 new states.Trigger({ 1754 selector: selector, 1755 state: state 1756 }); 1757 }); 1758 }, 1759 compare: function compare(reference, selector, state) { 1760 var value = this.values[selector][state.name]; 1761 1762 if (reference.constructor.name in states.Dependent.comparisons) { 1763 return states.Dependent.comparisons[reference.constructor.name](reference, value); 1764 } 1765 1766 return _compare2(reference, value); 1767 }, 1768 update: function update(selector, state, value) { 1769 if (value !== this.values[selector][state.name]) { 1770 this.values[selector][state.name] = value; 1771 this.reevaluate(); 1772 } 1773 }, 1774 reevaluate: function reevaluate() { 1775 var value = this.verifyConstraints(this.constraints); 1776 1777 if (value !== this.oldValue) { 1778 this.oldValue = value; 1779 value = invert(value, this.state.invert); 1780 this.element.trigger({ 1781 type: "state:".concat(this.state), 1782 value: value, 1783 trigger: true 1784 }); 1785 } 1786 }, 1787 verifyConstraints: function verifyConstraints(constraints, selector) { 1788 var result; 1789 1790 if ($.isArray(constraints)) { 1791 var hasXor = $.inArray('xor', constraints) === -1; 1792 var len = constraints.length; 1793 1794 for (var i = 0; i < len; i++) { 1795 if (constraints[i] !== 'xor') { 1796 var constraint = this.checkConstraints(constraints[i], selector, i); 1797 1798 if (constraint && (hasXor || result)) { 1799 return hasXor; 1800 } 1801 1802 result = result || constraint; 1803 } 1804 } 1805 } else if ($.isPlainObject(constraints)) { 1806 for (var n in constraints) { 1807 if (constraints.hasOwnProperty(n)) { 1808 result = ternary(result, this.checkConstraints(constraints[n], selector, n)); 1809 1810 if (result === false) { 1811 return false; 1812 } 1813 } 1814 } 1815 } 1816 1817 return result; 1818 }, 1819 checkConstraints: function checkConstraints(value, selector, state) { 1820 if (typeof state !== 'string' || /[0-9]/.test(state[0])) { 1821 state = null; 1822 } else if (typeof selector === 'undefined') { 1823 selector = state; 1824 state = null; 1825 } 1826 1827 if (state !== null) { 1828 state = states.State.sanitize(state); 1829 return invert(this.compare(value, selector, state), state.invert); 1830 } 1831 1832 return this.verifyConstraints(value, selector); 1833 }, 1834 getDependees: function getDependees() { 1835 var cache = {}; 1836 var _compare = this.compare; 1837 1838 this.compare = function (reference, selector, state) { 1839 (cache[selector] || (cache[selector] = [])).push(state.name); 1840 }; 1841 1842 this.verifyConstraints(this.constraints); 1843 this.compare = _compare; 1844 return cache; 1845 } 1846 }; 1847 1848 states.Trigger = function (args) { 1849 $.extend(this, args); 1850 1851 if (this.state in states.Trigger.states) { 1852 this.element = $(this.selector); 1853 1854 if (!this.element.data("trigger:".concat(this.state))) { 1855 this.initialize(); 1856 } 1857 } 1858 }; 1859 1860 states.Trigger.prototype = { 1861 initialize: function initialize() { 1862 var _this3 = this; 1863 1864 var trigger = states.Trigger.states[this.state]; 1865 1866 if (typeof trigger === 'function') { 1867 trigger.call(window, this.element); 1868 } else { 1869 Object.keys(trigger || {}
1869).forEach(function (event) { 1870 _this3.defaultTrigger(event, trigger[event]); 1871 }); 1872 } 1873 1874 this.element.data("trigger:".concat(this.state), true); 1875 }, 1876 defaultTrigger: function defaultTrigger(event, valueFn) { 1877 var oldValue = valueFn.call(this.element); 1878 this.element.on(event, $.proxy(function (e) { 1879 var value = valueFn.call(this.element, e); 1880 1881 if (oldValue !== value) { 1882 this.element.trigger({ 1883 type: "state:".concat(this.state), 1884 value: value, 1885 oldValue: oldValue 1886 }); 1887 oldValue = value; 1888 } 1889 }, this)); 1890 states.postponed.push($.proxy(function () { 1891 this.element.trigger({ 1892 type: "state:".concat(this.state), 1893 value: oldValue, 1894 oldValue: null 1895 }); 1896 }, this)); 1897 } 1898 }; 1899 states.Trigger.states = { 1900 empty: { 1901 keyup: function keyup() { 1902 return this.val() === ''; 1903 } 1904 }, 1905 checked: { 1906 change: function change() { 1907 var checked = false; 1908 this.each(function () { 1909 checked = $(this).prop('checked'); 1910 return !checked; 1911 }); 1912 return checked; 1913 } 1914 }, 1915 value: { 1916 keyup: function keyup() { 1917 if (this.length > 1) { 1918 return this.filter(':checked').val() || false; 1919 } 1920 1921 return this.val(); 1922 }, 1923 change: function change() { 1924 if (this.length > 1) { 1925 return this.filter(':checked').val() || false; 1926 } 1927 1928 return this.val(); 1929 } 1930 }, 1931 collapsed: { 1932 collapsed: function collapsed(e) { 1933 return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]'); 1934 } 1935 } 1936 }; 1937 1938 states.State = function (state) { 1939 this.pristine = state; 1940 this.name = state; 1941 var process = true; 1942 1943 do { 1944 while (this.name.charAt(0) === '!') { 1945 this.name = this.name.substring(1); 1946 this.invert = !this.invert; 1947 } 1948 1949 if (this.name in states.State.aliases) { 1950 this.name = states.State.aliases[this.name]; 1951 } else { 1952 process = false; 1953 } 1954 } while (process); 1955 }; 1956 1957 states.State.sanitize = function (state) { 1958 if (state instanceof states.State) { 1959 return state; 1960 } 1961 1962 return new states.State(state); 1963 }; 1964 1965 states.State.aliases = { 1966 enabled: '!disabled', 1967 invisible: '!visible', 1968 invalid: '!valid', 1969 untouched: '!touched', 1970 optional: '!required', 1971 filled: '!empty', 1972 unchecked: '!checked', 1973 irrelevant: '!relevant', 1974 expanded: '!collapsed', 1975 open: '!collapsed', 1976 closed: 'collapsed', 1977 readwrite: '!readonly' 1978 }; 1979 states.State.prototype = { 1980 invert: false, 1981 toString: function toString() { 1982 return this.name; 1983 } 1984 }; 1985 var $document = $(document); 1986 $document.on('state:disabled', function (e) { 1987 if (e.trigger) { 1988 $(e.target).prop('disabled', e.value).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value).find('select, input, textarea').prop('disabled', e.value); 1989 } 1990 }); 1991 $document.on('state:required', function (e) { 1992 if (e.trigger) { 1993 if (e.value) { 1994 var label = "label".concat(e.target.id ? "[for=".concat(e.target.id, "]") : ''); 1995 var $label = $(e.target).attr({ 1996 required: 'required', 1997 'aria-required': 'true' 1998 }).closest('.js-form-item, .js-form-wrapper').find(label); 1999 2000 if (!$label.hasClass('js-form-required').length) { 2001 $label.addClass('js-form-required form-required'); 2002 } 2003 } else { 2004 $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required'); 2005 } 2006 } 2007 }); 2008 $document.on('state:visible', function (e) { 2009 if (e.trigger) { 2010 $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value); 2011 } 2012 }); 2013 $document.on('state:checked', function (e) { 2014 if (e.trigger) { 2015 $(e.target).prop('checked', e.value); 2016 } 2017 }); 2018 $document.on('state:collapsed', function (e) { 2019 if (e.trigger) { 2020 if ($(e.target).is('[open]') === e.value) { 2021 $(e.target).find('> summary').trigger('click'); 2022 } 2023 } 2024 }); 2025})(jQuery, Drupal);; 2026/** 2027 * @file 2028 * Extends core/misc/states.js. 2029 */ 2030(function($) { 2031 2032 // Unbind core state.js from document first so we can then override below. 2033 $(document).unbind('state:disabled'); 2034 2035 /** 2036 * Global state change handlers. These are bound to "document" to cover all 2037 * elements whose state changes. Events sent to elements within the page 2038 * bubble up to these handlers. We use this system so that themes and modules 2039 * can override these state change handlers for particular parts of a page. 2040 */ 2041 $(document).bind('state:disabled', function(e) { 2042 // Only act when this change was triggered by a dependency and not by the 2043 // element monitoring itself. 2044 if (e.trigger) { 2045 $(e.target) 2046 .attr('disabled', e.value) 2047 .closest('.form-item, .form-submit, .form-wrapper').toggleClass('form-disabled', e.value) 2048 .find(':input').attr('disabled', e.value); 2049 2050 // Note: WebKit nightlies don't reflect that change correctly. 2051 // See https://bugs.webkit.org/show_bug.cgi?id=23789 2052 } 2053 }); 2054 2055})(jQuery); 2056;
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.