1/** 2* DO NOT EDIT THIS FILE. 3* See the following change record for more information, 4* https://www.drupal.org/node/2815083 5* @preserve 6**/ 7 8Drupal.debounce = function (func, wait, immediate) { 9 var timeout = void 0; 10 var result = void 0; 11 return function () { 12 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 13 args[_key] = arguments[_key]; 14 } 15 16 var context = this; 17 var later = function later() { 18 timeout = null; 19 if (!immediate) { 20 result = func.apply(context, args); 21 } 22 }; 23 var callNow = immediate && !timeout; 24 clearTimeout(timeout); 25 timeout = setTimeout(later, wait); 26 if (callNow) { 27 result = func.apply(context, args); 28 } 29 return result; 30 }; 31};; 32/** 33* DO NOT EDIT THIS FILE. 34* See the following change record for more information, 35* https://www.drupal.org/node/2815083 36* @preserve 37**/ 38 39(function ($, Drupal, debounce) { 40 $.fn.drupalGetSummary = function () { 41 var callback = this.data('summaryCallback'); 42 return this[0] && callback ? $.trim(callback(this[0])) : ''; 43 }; 44 45 $.fn.drupalSetSummary = function (callback) { 46 var self = this; 47 48 if (typeof callback !== 'function') { 49 var val = callback; 50 callback = function callback() { 51 return val; 52 }; 53 } 54 55 return this.data('summaryCallback', callback).off('formUpdated.summary').on('formUpdated.summary', function () { 56 self.trigger('summaryUpdated'); 57 }).trigger('summaryUpdated'); 58 }; 59 60 Drupal.behaviors.formSingleSubmit = { 61 attach: function attach() { 62 function onFormSubmit(e) { 63 var $form = $(e.currentTarget); 64 var formValues = $form.serialize(); 65 var previousValues = $form.attr('data-drupal-form-submit-last'); 66 if (previousValues === formValues) { 67 e.preventDefault(); 68 } else { 69 $form.attr('data-drupal-form-submit-last', formValues); 70 } 71 } 72 73 $('body').once('form-single-submit').on('submit.singleSubmit', 'form:not([method~="GET"])', onFormSubmit); 74 } 75 }; 76 77 function triggerFormUpdated(element) { 78 $(element).trigger('formUpdated'); 79 } 80 81 function fieldsList(form) { 82 var $fieldList = $(form).find('[name]').map(function (index, element) { 83 return element.getAttribute('id'); 84 }); 85 86 return $.makeArray($fieldList); 87 } 88 89 Drupal.behaviors.formUpdated = { 90 attach: function attach(context) { 91 var $context = $(context); 92 var contextIsForm = $context.is('form'); 93 var $forms = (contextIsForm ? $context : $context.find('form')).once('form-updated'); 94 var formFields = void 0; 95 96 if ($forms.length) { 97 $.makeArray($forms).forEach(function (form) { 98 var events = 'change.formUpdated input.formUpdated '; 99 var eventHandler = debounce(function (event) { 100 triggerFormUpdated(event.target); 101 }, 300); 102 formFields = fieldsList(form).join(','); 103 104 form.setAttribute('data-drupal-form-fields', formFields); 105 $(form).on(events, eventHandler); 106 }); 107 } 108 109 if (contextIsForm) { 110 formFields = fieldsList(context).join(','); 111 112 var currentFields = $(context).attr('data-drupal-form-fields'); 113 114 if (formFields !== currentFields) { 115 triggerFormUpdated(context); 116 } 117 } 118 }, 119 detach: function detach(context, settings, trigger) { 120 var $context = $(context); 121 var contextIsForm = $context.is('form'); 122 if (trigger === 'unload') { 123 var $forms = (contextIsForm ? $context : $context.find('form')).removeOnce('form-updated'); 124 if ($forms.length) { 125 $.makeArray($forms).forEach(function (form) { 126 form.removeAttribute('data-drupal-form-fields'); 127 $(form).off('.formUpdated'); 128 }); 129 } 130 } 131 } 132 }; 133 134 Drupal.behaviors.fillUserInfoFromBrowser = { 135 attach: function attach(context, settings) { 136 var userInfo = ['name', 'mail', 'homepage']; 137 var $forms = $('[data-user-info-from-browser]').once('user-info-from-browser'); 138 if ($forms.length) { 139 userInfo.forEach(function (info) { 140 var $element = $forms.find('[name=' + info + ']'); 141 var browserData = localStorage.getItem('Drupal.visitor.' + info); 142 var emptyOrDefault = $element.val() === '' || $element.attr('data-drupal-default-value') === $element.val(); 143 if ($element.length && emptyOrDefault && browserData) { 144 $element.val(browserData); 145 } 146 }); 147 } 148 $forms.on('submit', function () { 149 userInfo.forEach(function (info) { 150 var $element = $forms.find('[name=' + info + ']'); 151 if ($element.length) { 152 localStorage.setItem('Drupal.visitor.' + info, $element.val()); 153 } 154 }); 155 }); 156 } 157 }; 158 159 var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e) { 160 var url = void 0; 161 if (e.type === 'click') { 162 url = e.currentTarget.location ? e.currentTarget.location : e.currentTarget; 163 } else { 164 url = window.location; 165 } 166 var hash = url.hash.substr(1); 167 if (hash) { 168 var $target = $('#' + hash); 169 $('body').trigger('formFragmentLinkClickOrHashChange', [$target]); 170 171 setTimeout(function () { 172 return $target.trigger('focus'); 173 }, 300); 174 } 175 }; 176 177 var debouncedHandleFragmentLinkClickOrHashChange = debounce(handleFragmentLinkClickOrHashChange, 300, true); 178 179 $(window).on('hashchange.form-fragment', debouncedHandleFragmentLinkClickOrHashChange); 180 181 $(document).on('click.form-fragment', 'a[href*="#"]', debouncedHandleFragmentLinkClickOrHashChange); 182})(jQuery, Drupal, Drupal.debounce);; 183/** 184 * @file 185 * Extends methods from core/misc/form.js. 186 */ 187 188(function ($, window, Drupal, drupalSettings) { 189 190 /** 191 * Behavior for "forms_has_error_value_toggle" theme setting. 192 */ 193 Drupal.behaviors.bootstrapForm = { 194 attach: function (context) { 195 if (drupalSettings.bootstrap && drupalSettings.bootstrap.forms_has_error_value_toggle) { 196 var $context = $(context); 197 $context.find('.form-item.has-error:not(.form-type-password.has-feedback)').once('error').each(function () { 198 var $formItem = $(this); 199 var $input = $formItem.find(':input'); 200 $input.on('keyup focus blur', function () { 201 if (this.defaultValue !== void 0) { 202 $formItem[this.defaultValue !== this.value ? 'removeClass' : 'addClass']('has-error'); 203 $input[this.defaultValue !== this.value ? 'removeClass' : 'addClass']('error'); 204 } 205 }); 206 }); 207 } 208 } 209 }; 210 211 212})(jQuery, this, Drupal, drupalSettings); 213; 214/** 215 * @file 216 * Webform behaviors. 217 */ 218 219(function ($, Drupal) { 220 221 'use strict'; 222 223 // Trigger Drupal's attaching of behaviors after the page is 224 // completely loaded. 225 // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button 226 // @see https://stackoverflow.com/questions/20899274/how-to-refresh-page-on-back-button-click/20899422#20899422 227 var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase())); 228 if (isChrome) { 229 // Track back button in navigation. 230 // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button 231 var backButton = false;
232 if (window.performance) { 233 var navEntries = window.performance.getEntriesByType('navigation'); 234 if (navEntries.length > 0 && navEntries[0].type === 'back_forward') { 235 backButton = true; 236 } 237 else if (window.performance.navigation 238 && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) { 239 backButton = true; 240 } 241 } 242 243 // If the back button is pressed, delay Drupal's attaching of behaviors. 244 if (backButton) { 245 var attachBehaviors = Drupal.attachBehaviors; 246 Drupal.attachBehaviors = function (context, settings) { 247 setTimeout(function (context, settings) { 248 attachBehaviors(context, settings); 249 }, 300); 250 }; 251 } 252 } 253 254})(jQuery, Drupal); 255; 256/** 257* DO NOT EDIT THIS FILE. 258* See the following change record for more information, 259* https://www.drupal.org/node/2815083 260* @preserve 261**/ 262 263(function ($, Drupal) { 264 var states = { 265 postponed: [] 266 }; 267 268 Drupal.states = states; 269 270 function invert(a, invertState) { 271 return invertState && typeof a !== 'undefined' ? !a : a; 272 } 273 274 function _compare2(a, b) { 275 if (a === b) { 276 return typeof a === 'undefined' ? a : true; 277 } 278 279 return typeof a === 'undefined' || typeof b === 'undefined'; 280 } 281 282 function ternary(a, b) { 283 if (typeof a === 'undefined') { 284 return b; 285 } 286 if (typeof b === 'undefined') { 287 return a; 288 } 289 290 return a && b; 291 } 292 293 Drupal.behaviors.states = { 294 attach: function attach(context, settings) { 295 var $states = $(context).find('[data-drupal-states]'); 296 var il = $states.length; 297 298 var _loop = function _loop(i) { 299 var config = JSON.parse($states[i].getAttribute('data-drupal-states')); 300 Object.keys(config || {}).forEach(function (state) { 301 new states.Dependent({ 302 element: $($states[i]), 303 state: states.State.sanitize(state), 304 constraints: config[state] 305 }); 306 }); 307 }; 308 309 for (var i = 0; i < il; i++) { 310 _loop(i); 311 } 312 313 while (states.postponed.length) { 314 states.postponed.shift()(); 315 } 316 } 317 }; 318 319 states.Dependent = function (args) { 320 var _this = this; 321 322 $.extend(this, { values: {}, oldValue: null }, args); 323 324 this.dependees = this.getDependees(); 325 Object.keys(this.dependees || {}).forEach(function (selector) { 326 _this.initializeDependee(selector, _this.dependees[selector]); 327 }); 328 }; 329 330 states.Dependent.comparisons = { 331 RegExp: function RegExp(reference, value) { 332 return reference.test(value); 333 }, 334 Function: function Function(reference, value) { 335 return reference(value); 336 }, 337 Number: function Number(reference, value) { 338 return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value); 339 } 340 }; 341 342 states.Dependent.prototype = { 343 initializeDependee: function initializeDependee(selector, dependeeStates) { 344 var _this2 = this; 345 346 this.values[selector] = {}; 347 348 Object.keys(dependeeStates).forEach(function (i) { 349 var state = dependeeStates[i]; 350 351 if ($.inArray(state, dependeeStates) === -1) { 352 return; 353 } 354 355 state = states.State.sanitize(state); 356 357 _this2.values[selector][state.name] = null; 358 359 $(selector).on('state:' + state, { selector: selector, state: state }, function (e) { 360 _this2.update(e.data.selector, e.data.state, e.value); 361 }); 362 363 new states.Trigger({ selector: selector, state: state }); 364 }); 365 }, 366 compare: function compare(reference, selector, state) { 367 var value = this.values[selector][state.name]; 368 if (reference.constructor.name in states.Dependent.comparisons) { 369 return states.Dependent.comparisons[reference.constructor.name](reference, value); 370 } 371 372 return _compare2(reference, value); 373 }, 374 update: function update(selector, state, value) { 375 if (value !== this.values[selector][state.name]) { 376 this.values[selector][state.name] = value; 377 this.reevaluate(); 378 } 379 }, 380 reevaluate: function reevaluate() { 381 var value = this.verifyConstraints(this.constraints); 382 383 if (value !== this.oldValue) { 384 this.oldValue = value; 385 386 value = invert(value, this.state.invert); 387 388 this.element.trigger({ 389 type: 'state:' + this.state, 390 value: value, 391 trigger: true 392 }); 393 } 394 }, 395 verifyConstraints: function verifyConstraints(constraints, selector) { 396 var result = void 0; 397 if ($.isArray(constraints)) { 398 var hasXor = $.inArray('xor', constraints) === -1; 399 var len = constraints.length; 400 for (var i = 0; i < len; i++) { 401 if (constraints[i] !== 'xor') { 402 var constraint = this.checkConstraints(constraints[i], selector, i); 403 404 if (constraint && (hasXor || result)) { 405 return hasXor; 406 } 407 result = result || constraint; 408 } 409 } 410 } else if ($.isPlainObject(constraints)) { 411 for (var n in constraints) { 412 if (constraints.hasOwnProperty(n)) { 413 result = ternary(result, this.checkConstraints(constraints[n], selector, n)); 414 415 if (result === false) { 416 return false;
417 } 418 } 419 } 420 } 421 return result; 422 }, 423 checkConstraints: function checkConstraints(value, selector, state) { 424 if (typeof state !== 'string' || /[0-9]/.test(state[0])) { 425 state = null; 426 } else if (typeof selector === 'undefined') { 427 selector = state; 428 state = null; 429 } 430 431 if (state !== null) { 432 state = states.State.sanitize(state); 433 return invert(this.compare(value, selector, state), state.invert); 434 } 435 436 return this.verifyConstraints(value, selector); 437 }, 438 getDependees: function getDependees() { 439 var cache = {}; 440 441 var _compare = this.compare; 442 this.compare = function (reference, selector, state) { 443 (cache[selector] || (cache[selector] = [])).push(state.name); 444 }; 445 446 this.verifyConstraints(this.constraints); 447 448 this.compare = _compare; 449 450 return cache; 451 } 452 }; 453 454 states.Trigger = function (args) { 455 $.extend(this, args); 456 457 if (this.state in states.Trigger.states) { 458 this.element = $(this.selector); 459 460 if (!this.element.data('trigger:' + this.state)) { 461 this.initialize(); 462 } 463 } 464 }; 465 466 states.Trigger.prototype = { 467 initialize: function initialize() { 468 var _this3 = this; 469 470 var trigger = states.Trigger.states[this.state]; 471 472 if (typeof trigger === 'function') { 473 trigger.call(window, this.element); 474 } else { 475 Object.keys(trigger || {}).forEach(function (event) { 476 _this3.defaultTrigger(event, trigger[event]); 477 }); 478 } 479 480 this.element.data('trigger:' + this.state, true); 481 }, 482 defaultTrigger: function defaultTrigger(event, valueFn) { 483 var oldValue = valueFn.call(this.element); 484 485 this.element.on(event, $.proxy(function (e) { 486 var value = valueFn.call(this.element, e); 487 488 if (oldValue !== value) { 489 this.element.trigger({ 490 type: 'state:' + this.state, 491 value: value, 492 oldValue: oldValue 493 }); 494 oldValue = value; 495 } 496 }, this)); 497 498 states.postponed.push($.proxy(function () { 499 this.element.trigger({ 500 type: 'state:' + this.state, 501 value: oldValue, 502 oldValue: null 503 }); 504 }, this)); 505 } 506 }; 507 508 states.Trigger.states = { 509 empty: { 510 keyup: function keyup() { 511 return this.val() === ''; 512 } 513 }, 514 515 checked: { 516 change: function change() { 517 var checked = false; 518 this.each(function () { 519 checked = $(this).prop('checked'); 520 521 return !checked; 522 }); 523 return checked; 524 } 525 }, 526 527 value: { 528 keyup: function keyup() { 529 if (this.length > 1) { 530 return this.filter(':checked').val() || false; 531 } 532 return this.val(); 533 }, 534 change: function change() { 535 if (this.length > 1) { 536 return this.filter(':checked').val() || false; 537 } 538 return this.val(); 539 } 540 }, 541 542 collapsed: { 543 collapsed: function collapsed(e) { 544 return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]'); 545 } 546 } 547 }; 548 549 states.State = function (state) { 550 this.pristine = state; 551 this.name = state; 552 553 var process = true; 554 do { 555 while (this.name.charAt(0) === '!') { 556 this.name = this.name.substring(1); 557 this.invert = !this.invert; 558 } 559 560 if (this.name in states.State.aliases) { 561 this.name = states.State.aliases[this.name]; 562 } else { 563 process = false; 564 } 565 } while (process); 566 }; 567 568 states.State.sanitize = function (state) { 569 if (state instanceof states.State) { 570 return state; 571 } 572 573 return new states.State(state); 574 }; 575 576 states.State.aliases = { 577 enabled: '!disabled', 578 invisible: '!visible', 579 invalid: '!valid', 580 untouched: '!touched', 581 optional: '!required', 582 filled: '!empty', 583 unchecked: '!checked', 584 irrelevant: '!relevant', 585 expanded: '!collapsed', 586 open: '!collapsed', 587 closed: 'collapsed', 588 readwrite: '!readonly' 589 }; 590 591 states.State.prototype = { 592 invert: false, 593 594 toString: function toString() { 595 return this.name; 596 } 597 }; 598 599 var $document = $(document); 600 $document.on('state:disabled', function (e) { 601 if (e.trigger) { 602 $(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); 603 } 604 }); 605 606 $document.on('state:required', function (e) { 607 if (e.trigger) { 608 if (e.value) { 609 var label = 'label' + (e.target.id ? '[for=' + e.target.id + ']' : ''); 610 var $label = $(e.target).attr({ required: 'required', 'aria-required': 'true' }).closest('.js-form-item, .js-form-wrapper').find(label); 611 612 if (!$label.hasClass('js-form-required').length) { 613 $label.addClass('js-form-required form-required'); 614 } 615 } else { 616 $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required'); 617 } 618 } 619 }); 620 621 $document.on('state:visible', function (e) { 622 if (e.trigger) { 623 $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value); 624 } 625 }); 626 627 $document.on('state:checked', function (e) { 628 if (e.trigger) { 629 $(e.target).prop('checked', e.value); 630 } 631 }); 632 633 $document.on('state:collapsed', function (e) { 634 if (e.trigger) { 635 if ($(e.target).is('[open]') === e.value) { 636 $(e.target).find('> summary').trigger('click'); 637 } 638 } 639 }); 640})(jQuery, Drupal);; 641/** 642 * @file 643 * Extends core/misc/states.js. 644 */ 645(function($) { 646 647 // Unbind core state.js from document first so we can then override below. 648 $(document).unbind('state:disabled'); 649 650 /** 651 * Global state change handlers. These are bound to "document" to cover all 652 * elements whose state changes. Events sent to elements within the page 653 * bubble up to these handlers. We use this system so that themes and modules 654 * can override these state change handlers for particular parts of a page. 655 */ 656 $(document).bind('state:disabled', function(e) { 657 // Only act when this change was triggered by a dependency and not by the 658 // element monitoring itself. 659 if (e.trigger) { 660 $(e.target) 661 .attr('disabled', e.value) 662 .closest('.form-item, .form-submit, .form-wrapper').toggleClass('form-disabled', e.value) 663 .find(':input').attr('disabled', e.value); 664 665 // Note: WebKit nightlies don't reflect that change correctly. 666 // See https://bugs.webkit.org/show_bug.cgi?id=23789 667 } 668 }); 669 670})(jQuery); 671; 672/** 673 * @file 674 * JavaScript behaviors for custom webform #states. 675 */ 676 677(function ($, Drupal) { 678 679 'use strict'; 680 681 Drupal.webform = Drupal.webform || {}; 682 Drupal.webform.states = Drupal.webform.states || {}; 683 Drupal.webform.states.slideDown = Drupal.webform.states.slideDown || {}; 684 Drupal.webform.states.slideDown.duration = 'slow'; 685 Drupal.webform.states.slideUp = Drupal.webform.states.slideUp || {}; 686 Drupal.webform.states.slideUp.duration = 'fast'; 687 688 /* ************************************************************************ */ 689 // jQuery functions. 690 /* ************************************************************************ */ 691 692 /** 693 * Check if an element has a specified data attribute. 694 * 695 * @param {string} data 696 * The data attribute name. 697 * 698 * @return {boolean} 699 * TRUE if an element has a specified data attribute. 700 */ 701 $.fn.hasData = function (data) { 702 return (typeof this.data(data) !== 'undefined'); 703 }; 704 705 /**
706 * Check if element is within the webform or not. 707 * 708 * @return {boolean} 709 * TRUE if element is within the webform. 710 */ 711 $.fn.isWebform = function () { 712 return $(this).closest('form[id^="webform"], form[data-is-webform]').length ? true : false; 713 }; 714 715 /** 716 * Check if element is to be treated as a webform element. 717 * 718 * @return {boolean} 719 * TRUE if element is to be treated as a webform element. 720 */ 721 $.fn.isWebformElement = function () { 722 return ($(this).isWebform() || $(this).closest('[data-is-webform-element]').length) ? true : false; 723 }; 724 725 /* ************************************************************************ */ 726 // Trigger. 727 /* ************************************************************************ */ 728 729 // The change event is triggered by cut-n-paste and select menus. 730 // Issue #2445271: #states element empty check not triggered on mouse 731 // based paste. 732 // @see https://www.drupal.org/node/2445271 733 Drupal.states.Trigger.states.empty.change = function change() { 734 return this.val() === ''; 735 }; 736 737 /* ************************************************************************ */ 738 // Dependents. 739 /* ************************************************************************ */ 740 741 742 // Apply solution included in #1962800 patch. 743 // Issue #1962800: Form #states not working with literal integers as 744 // values in IE11. 745 // @see https://www.drupal.org/project/drupal/issues/1962800 746 // @see https://www.drupal.org/files/issues/core-states-not-working-with-integers-ie11_1962800_46.patch 747 // 748 // This issue causes pattern, less than, and greater than support to break. 749 // @see https://www.drupal.org/project/webform/issues/2981724 750 var states = Drupal.states; 751 Drupal.states.Dependent.prototype.compare = function compare(reference, selector, state) { 752 var value = this.values[selector][state.name]; 753 754 var name = reference.constructor.name; 755 if (!name) { 756 name = $.type(reference); 757 758 name = name.charAt(0).toUpperCase() + name.slice(1); 759 } 760 if (name in states.Dependent.comparisons) { 761 return states.Dependent.comparisons[name](reference, value); 762 } 763 764 if (reference.constructor.name in states.Dependent.comparisons) { 765 return states.Dependent.comparisons[reference.constructor.name](reference, value); 766 } 767 768 return _compare2(reference, value); 769 }; 770 function _compare2(a, b) { 771 if (a === b) { 772 return typeof a === 'undefined' ? a : true; 773 } 774 775 return typeof a === 'undefined' || typeof b === 'undefined'; 776 } 777 778 // Adds pattern, less than, and greater than support to #state API. 779 // @see http://drupalsun.com/julia-evans/2012/03/09/extending-form-api-states-regular-expressions 780 Drupal.states.Dependent.comparisons.Object = function (reference, value) { 781 if ('pattern' in reference) { 782 return (new RegExp(reference['pattern'])).test(value); 783 } 784 else if ('!pattern' in reference) { 785 return !((new RegExp(reference['!pattern'])).test(value)); 786 } 787 else if ('less' in reference) { 788 return (value !== '' && parseFloat(reference['less']) > parseFloat(value)); 789 } 790 else if ('less_equal' in reference) { 791 return (value !== '' && parseFloat(reference['less_equal']) >= parseFloat(value)); 792 } 793 else if ('greater' in reference) { 794 return (value !== '' && parseFloat(reference['greater']) < parseFloat(value)); 795 } 796 else if ('greater_equal' in reference) { 797 return (value !== '' && parseFloat(reference['greater_equal']) <= parseFloat(value)); 798 } 799 else if ('between' in reference || '!between' in reference) { 800 if (value === '') { 801 return false; 802 } 803 804 var between = reference['between'] || reference['!between']; 805 var betweenParts = between.split(':'); 806 var greater = betweenParts[0]; 807 var less = (typeof betweenParts[1] !== 'undefined') ? betweenParts[1] : null; 808 var isGreaterThan = (greater === null || greater === '' || parseFloat(value) >= parseFloat(greater)); 809 var isLessThan = (less === null || less === '' || parseFloat(value) <= parseFloat(less)); 810 var result = (isGreaterThan && isLessThan); 811 return (reference['!between']) ? !result : result; 812 } 813 else { 814 return reference.indexOf(value) !== false; 815 } 816 }; 817 818 /* ************************************************************************ */ 819 // States events. 820 /* ************************************************************************ */ 821 822 var $document = $(document); 823 824 $document.on('state:required', function (e) { 825 if (e.trigger && $(e.target).isWebformElement()) { 826 var $target = $(e.target); 827 // Fix #required file upload. 828 // @see Issue #2860529: Conditional required File upload field don't work. 829 toggleRequired($target.find('input[type="file"]'), e.value); 830 831 // Fix #required for radios. 832 // @see Issue #2856795: If radio buttons are required but not filled form is nevertheless submitted. 833 if ($target.is('.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other')) { 834 toggleRequired($target.find('input[type="radio"]'), e.value); 835 } 836 837 // Fix #required for checkboxes. 838 // @see Issue #2938414: Checkboxes don't support #states required. 839 // @see checkboxRequiredhandler 840 if ($target.is('.js-form-type-checkboxes, .js-form-type-webform-checkboxes-other, .js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other')) { 841 var $checkboxes = $target.find('input[type="checkbox"]'); 842 if (e.value) { 843 // Add event handler. 844 $checkboxes.on('click', statesCheckboxesRequiredEventHandler); 845 // Initialize and add required attribute. 846 checkboxesRequired($target); 847 } 848 else { 849 // Remove event handler. 850 $checkboxes.off('click', statesCheckboxesRequiredEventHandler); 851 // Remove required attribute. 852 toggleRequired($checkboxes, false); 853 } 854 } 855 856 // Fix required label for elements without the for attribute. 857 // @see Issue #3145300: Conditional Visible Select Other not working. 858 if ($target.is('.js-form-type-webform-select-other, .js-webform-type-webform-select-other')) { 859 var $select = $target.find('select'); 860 toggleRequired($select, e.value); 861 copyRequireMessage($target, $select); 862 } 863 if ($target.find('> label:not([for])').length) { 864 $target.find('> label').toggleClass('js-form-required form-required', e.value); 865 } 866 867 // Fix required label for checkboxes and radios. 868 // @see Issue #2938414: Checkboxes don't support #states required 869 // @see Issue #2731991: Setting required on radios marks all options required. 870 // @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset. 871 // Fix #required for fieldsets. 872 // @see Issue #2977569: Hidden fieldsets that become visible with conditional logic cannot be made required. 873 if ($target.is('.js-webform-type-radios, .js-webform-type-checkboxes, fieldset')) { 874 $target.find('legend span.fieldset-legend:not(.visually-hidden)').toggleClass('js-form-required form-required', e.value); 875 } 876 877 // Issue #2986017: Fieldsets shouldn't have required attribute. 878 if ($target.is('fieldset')) { 879 $target.removeAttr('required aria-required'); 880 } 881 } 882 }); 883 884 $document.on('state:checked', function (e) { 885 if (e.trigger) { 886 $(e.target).trigger('change'); 887 } 888 }); 889 890 $document.on('state:readonly', function (e) { 891 if (e.trigger && $(e.target).isWebformElement()) { 892 $(e.target).prop('readonly', e.value).closest('.js-form-item, .js-form-wrapper').toggleClass('webform-readonly', e.value).find('input, textarea').prop('readonly', e.value); 893 894 // Trigger webform:readonly. 895 $(e.target).trigger('webform:readonly') 896 .find('select, input, textarea, button').trigger('webform:readonly'); 897 } 898 }); 899 900 $document.on('state:visible state:visible-slide', function (e) { 901 if (e.trigger && $(e.target).isWebformElement()) { 902 if (e.value) { 903 $(':input', e.target).addBack().each(function () { 904 restoreValueAndRequired(this); 905 triggerEventHandlers(this); 906 }); 907 } 908 else { 909 // @see https://www.sitepoint.com/jquery-function-clear-form-data/ 910 $(':input', e.target).addBack().each(function () { 911 backupValueAndRequired(this); 912 clearValueAndRequired(this); 913 triggerEventHandlers(this); 914 }); 915 } 916 } 917 }); 918 919 $document.on('state:visible-slide', function (e) { 920 if (e.trigger && $(e.target).isWebformElement()) { 921 var effect = e.value ? 'slideDown' : 'slideUp'; 922 var duration = Drupal.webform.states[effect].duration; 923 $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper')[effect](duration); 924 } 925 }); 926 Drupal.states.State.aliases['invisible-slide'] = '!visible-slide'; 927 928 $document.on('state:disabled', function (e) { 929 if (e.trigger && $(e.target).isWebformElement()) { 930 // Make sure disabled property is set before triggering webform:disabled. 931 // Copied from: core/misc/states.js 932 $(e.target) 933 .prop('disabled', e.value) 934 .closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value) 935 .find('select, input, textarea, button').prop('disabled', e.value); 936 937 // Never disable hidden file[fids] because the existing values will 938 // be completely lost when the webform is submitted. 939 var fileElements = $(e.target) 940 .find(':input[type="hidden"][name$="[fids]"]'); 941 if (fileElements.length) { 942 // Remove 'disabled' attribute from fieldset which will block 943 // all disabled elements from being submitted. 944 if ($(e.target).is('fieldset')) { 945 $(e.target).prop('disabled', false); 946 } 947 fileElements.removeAttr('disabled'); 948 } 949 950 // Trigger webform:disabled. 951 $(e.target).trigger('webform:disabled') 952 .find('select, input, textarea, button').trigger('webform:disabled'); 953 } 954 }); 955 956 /* ************************************************************************ */ 957 // Behaviors. 958 /* ************************************************************************ */ 959 960 /** 961 * Adds HTML5 validation to required checkboxes. 962 * 963 * @type {Drupal~behavior} 964 * 965 * @see https://www.drupal.org/project/webform/issues/3068998 966 */ 967 Drupal.behaviors.webformCheckboxesRequired = { 968 attach: function (context) { 969 $('.js-form-type-checkboxes.required, .js-form-type-webform-checkboxes-other.required, .js-webform-type-checkboxes.required, .js-webform-type-webform-checkboxes-other.required, .js-webform-type-webform-radios-other.checkboxes', context) 970 .once('webform-checkboxes-required') 971 .each(function () { 972 var $element = $(this); 973 $element.find('input[type="checkbox"]').on('click', statesCheckboxesRequiredEventHandler); 974 setTimeout(function () {checkboxesRequired($element);}); 975 }); 976 } 977 }; 978 979 /** 980 * Adds HTML5 validation to required radios. 981 * 982 * @type {Drupal~behavior} 983 * 984 * @see https://www.drupal.org/project/webform/issues/2856795 985 */ 986 Drupal.behaviors.webformRadiosRequired = { 987 attach: function (context) { 988 $('.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other', context) 989 .once('webform-radios-required') 990 .each(function () { 991 var $element = $(this); 992 setTimeout(function () {radiosRequired($element);}); 993 }); 994 } 995 }; 996 997 /** 998 * Add HTML5 multiple checkboxes required validation. 999 * 1000 * @param {jQuery} $element
1001 * An jQuery object containing HTML5 radios. 1002 * 1003 * @see https://stackoverflow.com/a/37825072/145846 1004 */ 1005 function checkboxesRequired($element) { 1006 var $firstCheckbox = $element.find('input[type="checkbox"]').first(); 1007 var isChecked = $element.find('input[type="checkbox"]').is(':checked'); 1008 toggleRequired($firstCheckbox, !isChecked); 1009 copyRequireMessage($element, $firstCheckbox); 1010 } 1011 1012 /** 1013 * Add HTML5 radios required validation. 1014 * 1015 * @param {jQuery} $element 1016 * An jQuery object containing HTML5 radios. 1017 * 1018 * @see https://www.drupal.org/project/webform/issues/2856795 1019 */ 1020 function radiosRequired($element) { 1021 var $radios = $element.find('input[type="radio"]'); 1022 var isRequired = $element.hasClass('required'); 1023 toggleRequired($radios, isRequired); 1024 copyRequireMessage($element, $radios); 1025 } 1026 1027 /* ************************************************************************ */ 1028 // Event handlers. 1029 /* ************************************************************************ */ 1030 1031 /** 1032 * Trigger #states API HTML5 multiple checkboxes required validation. 1033 * 1034 * @see https://stackoverflow.com/a/37825072/145846 1035 */ 1036 function statesCheckboxesRequiredEventHandler() { 1037 var $element = $(this).closest('.js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other'); 1038 checkboxesRequired($element); 1039 } 1040 1041 /** 1042 * Trigger an input's event handlers. 1043 * 1044 * @param {element} input 1045 * An input. 1046 */ 1047 function triggerEventHandlers(input) { 1048 var $input = $(input); 1049 var type = input.type; 1050 var tag = input.tagName.toLowerCase(); 1051 // Add 'webform.states' as extra parameter to event handlers. 1052 // @see Drupal.behaviors.webformUnsaved 1053 var extraParameters = ['webform.states']; 1054 if (type === 'checkbox' || type === 'radio') { 1055 $input 1056 .trigger('change', extraParameters) 1057 .trigger('blur', extraParameters); 1058 } 1059 else if (tag === 'select') { 1060 $input 1061 .trigger('change', extraParameters) 1062 .trigger('blur', extraParameters); 1063 } 1064 else if (type !== 'submit' && type !== 'button' && type !== 'file') { 1065 $input 1066 .trigger('input', extraParameters) 1067 .trigger('change', extraParameters) 1068 .trigger('keydown', extraParameters) 1069 .trigger('keyup', extraParameters) 1070 .trigger('blur', extraParameters); 1071 1072 // Make sure input mask is reset when value is restored. 1073 // @see https://www.drupal.org/project/webform/issues/3124155 1074 if ($input.attr('data-inputmask-mask')) { 1075 setTimeout(function () {$input.inputmask('remove').inputmask();}); 1076 } 1077 } 1078 } 1079 1080 /* ************************************************************************ */ 1081 // Backup and restore value functions. 1082 /* ************************************************************************ */ 1083 1084 /** 1085 * Backup an input's current value and required attribute 1086 * 1087 * @param {element} input 1088 * An input. 1089 */ 1090 function backupValueAndRequired(input) { 1091 var $input = $(input); 1092 var type = input.type; 1093 var tag = input.tagName.toLowerCase(); // Normalize case. 1094 1095 // Backup required. 1096 if ($input.prop('required') && !$input.hasData('webform-required')) { 1097 $input.data('webform-required', true); 1098 } 1099 1100 // Backup value. 1101 if (!$input.hasData('webform-value')) { 1102 if (type === 'checkbox' || type === 'radio') { 1103 $input.data('webform-value', $input.prop('checked')); 1104 } 1105 else if (tag === 'select') { 1106 var values = []; 1107 $input.find('option:selected').each(function (i, option) { 1108 values[i] = option.value; 1109 }); 1110 $input.data('webform-value', values); 1111 } 1112 else if (type !== 'submit' && type !== 'button') { 1113 $input.data('webform-value', input.value); 1114 } 1115 } 1116 } 1117 1118 /** 1119 * Restore an input's value and required attribute. 1120 * 1121 * @param {element} input 1122 * An input. 1123 */ 1124 function restoreValueAndRequired(input) { 1125 var $input = $(input); 1126 1127 // Restore value. 1128 var value = $input.data('webform-value'); 1129 if (typeof value !== 'undefined') { 1130 var type = input.type; 1131 var tag = input.tagName.toLowerCase(); // Normalize case. 1132 1133 if (type === 'checkbox' || type === 'radio') { 1134 $input.prop('checked', value); 1135 } 1136 else if (tag === 'select') { 1137 $.each(value, function (i, option_value) { 1138 $input.find("option[value='" + option_value + "']").prop('selected', true); 1139 }); 1140 } 1141 else if (type !== 'submit' && type !== 'button') { 1142 input.value = value; 1143 } 1144 $input.removeData('webform-value'); 1145 } 1146 1147 // Restore required. 1148 var required = $input.data('webform-required'); 1149 if (typeof required !== 'undefined') { 1150 if (required) { 1151 $input.prop('required', true); 1152 } 1153 $input.removeData('webform-required'); 1154 } 1155 } 1156 1157 /** 1158 * Clear an input's value and required attributes. 1159 * 1160 * @param {element} input 1161 * An input. 1162 */ 1163 function clearValueAndRequired(input) { 1164 var $input = $(input); 1165 1166 // Check for #states no clear attribute.
1167 // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/ 1168 if ($input.closest('[data-webform-states-no-clear]').length) { 1169 return; 1170 } 1171 1172 // Clear value. 1173 var type = input.type; 1174 var tag = input.tagName.toLowerCase(); // Normalize case. 1175 if (type === 'checkbox' || type === 'radio') { 1176 $input.prop('checked', false); 1177 } 1178 else if (tag === 'select') { 1179 if ($input.find('option[value=""]').length) { 1180 $input.val(''); 1181 } 1182 else { 1183 input.selectedIndex = -1; 1184 } 1185 } 1186 else if (type !== 'submit' && type !== 'button') { 1187 input.value = (type === 'color') ? '#000000' : ''; 1188 } 1189 1190 // Clear required. 1191 $input.prop('required', false); 1192 } 1193 1194 /* ************************************************************************ */ 1195 // Helper functions. 1196 /* ************************************************************************ */ 1197 1198 /** 1199 * Toggle an input's required attributes. 1200 * 1201 * @param {element} $input 1202 * An input. 1203 * @param {boolean} required 1204 * Is input required. 1205 */ 1206 function toggleRequired($input, required) { 1207 if (required) { 1208 $input.attr({'required': 'required', 'aria-required': 'true'}); 1209 } 1210 else { 1211 $input.removeAttr('required aria-required'); 1212 } 1213 } 1214 1215 /** 1216 * Copy the clientside_validation.module's message. 1217 * 1218 * @param {jQuery} $source 1219 * The source element. 1220 * @param {jQuery} $destination 1221 * The destination element. 1222 */ 1223 function copyRequireMessage($source, $destination) { 1224 if ($source.attr('data-msg-required')) { 1225 $destination.attr('data-msg-required', $source.attr('data-msg-required')); 1226 } 1227 } 1228 1229})(jQuery, Drupal); 1230; 1231/** 1232 * @file 1233 * JavaScript behaviors for webforms. 1234 */ 1235 1236(function ($, Drupal) { 1237 1238 'use strict'; 1239 1240 /** 1241 * Remove single submit event listener. 1242 * 1243 * @type {Drupal~behavior} 1244 * 1245 * @prop {Drupal~behaviorAttach} attach 1246 * Attaches the behavior for removing single submit event listener. 1247 * 1248 * @see Drupal.behaviors.formSingleSubmit 1249 */ 1250 Drupal.behaviors.webformRemoveFormSingleSubmit = { 1251 attach: function attach() { 1252 function onFormSubmit(e) { 1253 var $form = $(e.currentTarget); 1254 $form.removeAttr('data-drupal-form-submit-last'); 1255 } 1256 $('body') 1257 .once('webform-single-submit') 1258 .on('submit.singleSubmit', 'form.webform-remove-single-submit', onFormSubmit); 1259 } 1260 }; 1261 1262 /** 1263 * Prevent webform autosubmit on wizard pages. 1264 * 1265 * @type {Drupal~behavior} 1266 * 1267 * @prop {Drupal~behaviorAttach} attach 1268 * Attaches the behavior for disabling webform autosubmit. 1269 * Wizard pages need to be progressed with the Previous or Next buttons, 1270 * not by pressing Enter. 1271 */ 1272 Drupal.behaviors.webformDisableAutoSubmit = { 1273 attach: function (context) { 1274 // Not using context so that inputs loaded via Ajax will have autosubmit 1275 // disabled. 1276 // @see http://stackoverflow.com/questions/11235622/jquery-disable-form-submit-on-enter 1277 $('.js-webform-disable-autosubmit input') 1278 .not(':button, :submit, :reset, :image, :file') 1279 .once('webform-disable-autosubmit') 1280 .on('keyup keypress', function (e) { 1281 if (e.which === 13) { 1282 e.preventDefault(); 1283 return false; 1284 } 1285 }); 1286 } 1287 }; 1288 1289 /** 1290 * Skip client-side validation when submit button is pressed. 1291 * 1292 * @type {Drupal~behavior} 1293 * 1294 * @prop {Drupal~behaviorAttach} attach 1295 * Attaches the behavior for the skipping client-side validation. 1296 * 1297 * @deprecated in Webform 8.x-5.x and will be removed in Webform 8.x-6.x. 1298 * Use 'formnovalidate' attribute instead. 1299 */ 1300 Drupal.behaviors.webformSubmitNoValidate = { 1301 attach: function (context) { 1302 $(context).find(':submit.js-webform-novalidate') 1303 .once('webform-novalidate') 1304 .attr('formnovalidate', 'formnovalidate'); 1305 } 1306 }; 1307 1308 /** 1309 * Custom required and pattern validation error messages. 1310 * 1311 * @type {Drupal~behavior} 1312 * 1313 * @prop {Drupal~behaviorAttach} attach 1314 * Attaches the behavior for the webform custom required and pattern 1315 * validation error messages. 1316 * 1317 * @see http://stackoverflow.com/questions/5272433/html5-form-required-attribute-set-custom-validation-message 1318 **/ 1319 Drupal.behaviors.webformRequiredError = { 1320 attach: function (context) { 1321 $(context).find(':input[data-webform-required-error], :input[data-webform-pattern-error]').once('webform-required-error') 1322 .on('invalid', function () { 1323 this.setCustomValidity(''); 1324 if (this.valid) { 1325 return; 1326 } 1327 1328 if (this.validity.patternMismatch && $(this).attr('data-webform-pattern-error')) { 1329 this.setCustomValidity($(this).attr('data-webform-pattern-error')); 1330 } 1331 else if (this.validity.valueMissing && $(this).attr('data-webform-required-error')) { 1332 this.setCustomValidity($(this).attr('data-webform-required-error')); 1333 } 1334 }) 1335 .on('input change', function () { 1336 // Find all related elements by name and reset custom validity. 1337 // This specifically applies to required radios and checkboxes. 1338 var name = $(this).attr('name'); 1339 $(this.form).find(':input[name="' + name + '"]').each(function () { 1340 this.setCustomValidity(''); 1341 }); 1342 }); 1343 } 1344 }; 1345 1346 // When #state:required is triggered we need to reset the target elements 1347 // custom validity. 1348 $(document).on('state:required', function (e) { 1349 $(e.target).filter('[data-webform-required-error]') 1350 .each(function () {this.setCustomValidity('');}); 1351 }); 1352 1353})(jQuery, Drupal); 1354; 1355/** 1356 * @file 1357 * JavaScript behaviors for details element. 1358 */ 1359 1360(function ($, Drupal) { 1361 1362 'use strict'; 1363 1364 // Determine if local storage exists and is enabled. 1365 // This approach is copied from Modernizr. 1366 // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 1367 var hasLocalStorage = (function () { 1368 try { 1369 localStorage.setItem('webform', 'webform'); 1370 localStorage.removeItem('webform'); 1371 return true; 1372 } 1373 catch (e) { 1374 return false;
1375 } 1376 }()); 1377 1378 /** 1379 * Attach handler to save details open/close state. 1380 * 1381 * @type {Drupal~behavior} 1382 */ 1383 Drupal.behaviors.webformDetailsSave = { 1384 attach: function (context) { 1385 if (!hasLocalStorage) { 1386 return; 1387 } 1388 1389 // Summary click event handler. 1390 $('details > summary', context).once('webform-details-summary-save').on('click', function () { 1391 var $details = $(this).parent(); 1392 1393 // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/ 1394 if ($details[0].hasAttribute('data-webform-details-nosave')) { 1395 return; 1396 } 1397 1398 var name = Drupal.webformDetailsSaveGetName($details); 1399 if (!name) { 1400 return; 1401 } 1402 1403 var open = ($details.attr('open') !== 'open') ? '1' : '0'; 1404 localStorage.setItem(name, open); 1405 }); 1406 1407 // Initialize details open state via local storage. 1408 $('details', context).once('webform-details-save').each(function () { 1409 var $details = $(this); 1410 1411 var name = Drupal.webformDetailsSaveGetName($details); 1412 if (!name) { 1413 return; 1414 } 1415 1416 var open = localStorage.getItem(name); 1417 if (open === null) { 1418 return; 1419 } 1420 1421 if (open === '1') { 1422 $details.attr('open', 'open'); 1423 } 1424 else { 1425 $details.removeAttr('open'); 1426 } 1427 }); 1428 } 1429 1430 }; 1431 1432 /** 1433 * Get the name used to store the state of details element. 1434 * 1435 * @param {jQuery} $details 1436 * A details element. 1437 * 1438 * @return {string} 1439 * The name used to store the state of details element. 1440 */ 1441 Drupal.webformDetailsSaveGetName = function ($details) { 1442 if (!hasLocalStorage) { 1443 return ''; 1444 } 1445 1446 // Ignore details that are vertical tabs pane. 1447 if ($details.hasClass('vertical-tabs__pane')) { 1448 return ''; 1449 } 1450 1451 // Any details element not included a webform must have define its own id. 1452 var webformId = $details.attr('data-webform-element-id'); 1453 if (webformId) { 1454 return 'Drupal.webform.' + webformId.replace('--', '.'); 1455 } 1456 1457 var detailsId = $details.attr('id'); 1458 if (!detailsId) { 1459 return ''; 1460 } 1461 1462 var $form = $details.parents('form'); 1463 if (!$form.length || !$form.attr('id')) { 1464 return ''; 1465 } 1466 1467 var formId = $form.attr('id'); 1468 if (!formId) { 1469 return ''; 1470 } 1471 1472 // ISSUE: When Drupal renders a webform in a modal dialog it appends a unique 1473 // identifier to webform ids and details ids. (i.e. my-form--FeSFISegTUI) 1474 // WORKAROUND: Remove the unique id that delimited using double dashes. 1475 formId = formId.replace(/--.+?$/, '').replace(/-/g, '_'); 1476 detailsId = detailsId.replace(/--.+?$/, '').replace(/-/g, '_'); 1477 return 'Drupal.webform.' + formId + '.' + detailsId; 1478 }; 1479 1480})(jQuery, Drupal); 1481; 1482/** 1483* DO NOT EDIT THIS FILE. 1484* See the following change record for more information, 1485* https://www.drupal.org/node/2815083 1486* @preserve 1487**/ 1488 1489(function (Drupal, debounce) { 1490 var liveElement = void 0; 1491 var announcements = []; 1492 1493 Drupal.behaviors.drupalAnnounce = { 1494 attach: function attach(context) { 1495 if (!liveElement) { 1496 liveElement = document.createElement('div'); 1497 liveElement.id = 'drupal-live-announce'; 1498 liveElement.className = 'visually-hidden'; 1499 liveElement.setAttribute('aria-live', 'polite'); 1500 liveElement.setAttribute('aria-busy', 'false'); 1501 document.body.appendChild(liveElement); 1502 } 1503 } 1504 }; 1505 1506 function announce() { 1507 var text = []; 1508 var priority = 'polite'; 1509 var announcement = void 0; 1510 1511 var il = announcements.length; 1512 for (var i = 0; i < il; i++) { 1513 announcement = announcements.pop(); 1514 text.unshift(announcement.text); 1515 1516 if (announcement.priority === 'assertive') { 1517 priority = 'assertive'; 1518 } 1519 } 1520 1521 if (text.length) { 1522 liveElement.innerHTML = ''; 1523 1524 liveElement.setAttribute('aria-busy', 'true'); 1525 1526 liveElement.setAttribute('aria-live', priority); 1527 1528 liveElement.innerHTML = text.join('\n'); 1529 1530 liveElement.setAttribute('aria-busy', 'false'); 1531 } 1532 } 1533 1534 Drupal.announce = function (text, priority) { 1535 announcements.push({ 1536 text: text, 1537 priority: priority 1538 }); 1539 1540 return debounce(announce, 200)(); 1541 }; 1542})(Drupal, Drupal.debounce);; 1543/** 1544 * @file 1545 * JavaScript behaviors for details element. 1546 */ 1547 1548(function ($, Drupal) { 1549 1550 'use strict'; 1551 1552 Drupal.webform = Drupal.webform || {}; 1553 Drupal.webform.detailsToggle = Drupal.webform.detailsToggle || {}; 1554 Drupal.webform.detailsToggle.options = Drupal.webform.detailsToggle.options || {}; 1555 1556 /** 1557 * Attach handler to toggle details open/close state. 1558 * 1559 * @type {Drupal~behavior} 1560 */ 1561 Drupal.behaviors.webformDetailsToggle = { 1562 attach: function (context) { 1563 $('.js-webform-details-toggle', context).once('webform-details-toggle').each(function () { 1564 var $form = $(this); 1565 var $tabs = $form.find('.webform-tabs'); 1566 1567 // Get only the main details elements and ignore all nested details. 1568 var selector = ($tabs.length) ? '.webform-tab' : '.js-webform-details-toggle, .webform-elements'; 1569 var $details = $form.find('details').filter(function () { 1570 var $parents = $(this).parentsUntil(selector); 1571 return ($parents.find('details').length === 0); 1572 }); 1573 1574 // Toggle is only useful when there are two or more details elements. 1575 if ($details.length < 2) { 1576 return; 1577 } 1578 1579 var options = $.extend({ 1580 button: '<button type="button" class="webform-details-toggle-state"></button>' 1581 }, Drupal.webform.detailsToggle.options); 1582 1583 // Create toggle buttons. 1584 var $toggle = $(options.button) 1585 .attr('title', Drupal.t('Toggle details widget state.')) 1586 .on('click', function (e) { 1587 // Get details that are not vertical tabs pane. 1588 var $details = $form.find('details:not(.vertical-tabs__pane)'); 1589 var open; 1590 if (Drupal.webform.detailsToggle.isFormDetailsOpen($form)) { 1591 $details.removeAttr('open'); 1592 open = 0; 1593 } 1594 else { 1595 $details.attr('open', 'open'); 1596 open = 1; 1597 } 1598 Drupal.webform.detailsToggle.setDetailsToggleLabel($form); 1599 1600 // Set the saved states for all the details elements. 1601 // @see webform.element.details.save.js 1602 if (Drupal.webformDetailsSaveGetName) { 1603 $details.each(function () { 1604 // Note: Drupal.webformDetailsSaveGetName checks if localStorage 1605 // exists and is enabled. 1606 // @see webform.element.details.save.js 1607 var name = Drupal.webformDetailsSaveGetName($(this)); 1608 if (name) {
1609 localStorage.setItem(name, open); 1610 } 1611 }); 1612 } 1613 }) 1614 .wrap('<div class="webform-details-toggle-state-wrapper"></div>') 1615 .parent(); 1616 1617 if ($tabs.length) { 1618 // Add toggle state before the tabs. 1619 $tabs.find('.item-list:first-child').eq(0).before($toggle); 1620 } 1621 else { 1622 // Add toggle state link to first details element. 1623 $details.eq(0).before($toggle); 1624 } 1625 1626 Drupal.webform.detailsToggle.setDetailsToggleLabel($form); 1627 }); 1628 } 1629 }; 1630 1631 /** 1632 * Determine if a webform's details are all opened. 1633 * 1634 * @param {jQuery} $form 1635 * A webform. 1636 * 1637 * @return {boolean} 1638 * TRUE if a webform's details are all opened. 1639 */ 1640 Drupal.webform.detailsToggle.isFormDetailsOpen = function ($form) { 1641 return ($form.find('details[open]').length === $form.find('details').length); 1642 }; 1643 1644 /** 1645 * Set a webform's details toggle state widget label. 1646 * 1647 * @param {jQuery} $form 1648 * A webform. 1649 */ 1650 Drupal.webform.detailsToggle.setDetailsToggleLabel = function ($form) { 1651 var isOpen = Drupal.webform.detailsToggle.isFormDetailsOpen($form); 1652 1653 var label = (isOpen) ? Drupal.t('Collapse all') : Drupal.t('Expand all'); 1654 $form.find('.webform-details-toggle-state').html(label); 1655 1656 var text = (isOpen) ? Drupal.t('All details have been expanded.') : Drupal.t('All details have been collapsed.'); 1657 Drupal.announce(text); 1658 }; 1659 1660})(jQuery, Drupal); 1661; 1662/** 1663* DO NOT EDIT THIS FILE. 1664* See the following change record for more information, 1665* https://www.drupal.org/node/2815083 1666* @preserve 1667**/ 1668 1669(function ($, Drupal) { 1670 Drupal.theme.progressBar = function (id) { 1671 return '<div id="' + id + '" class="progress" aria-live="polite">' + '<div class="progress__label"> </div>' + '<div class="progress__track"><div class="progress__bar"></div></div>' + '<div class="progress__percentage"></div>' + '<div class="progress__description"> </div>' + '</div>'; 1672 }; 1673 1674 Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) { 1675 this.id = id; 1676 this.method = method || 'GET'; 1677 this.updateCallback = updateCallback; 1678 this.errorCallback = errorCallback; 1679 1680 this.element = $(Drupal.theme('progressBar', id)); 1681 }; 1682 1683 $.extend(Drupal.ProgressBar.prototype, { 1684 setProgress: function setProgress(percentage, message, label) { 1685 if (percentage >= 0 && percentage <= 100) { 1686 $(this.element).find('div.progress__bar').css('width', percentage + '%'); 1687 $(this.element).find('div.progress__percentage').html(percentage + '%'); 1688 } 1689 $('div.progress__description', this.element).html(message); 1690 $('div.progress__label', this.element).html(label); 1691 if (this.updateCallback) { 1692 this.updateCallback(percentage, message, this); 1693 } 1694 }, 1695 startMonitoring: function startMonitoring(uri, delay) { 1696 this.delay = delay; 1697 this.uri = uri; 1698 this.sendPing(); 1699 }, 1700 stopMonitoring: function stopMonitoring() { 1701 clearTimeout(this.timer); 1702 1703 this.uri = null; 1704 }, 1705 sendPing: function sendPing() { 1706 if (this.timer) { 1707 clearTimeout(this.timer); 1708 } 1709 if (this.uri) { 1710 var pb = this; 1711 1712 var uri = this.uri; 1713 if (uri.indexOf('?') === -1) { 1714 uri += '?'; 1715 } else { 1716 uri += '&'; 1717 } 1718 uri += '_format=json'; 1719 $.ajax({ 1720 type: this.method, 1721 url: uri, 1722 data: '', 1723 dataType: 'json', 1724 success: function success(progress) { 1725 if (progress.status === 0) { 1726 pb.displayError(progress.data); 1727 return; 1728 } 1729 1730 pb.setProgress(progress.percentage, progress.message, progress.label); 1731 1732 pb.timer = setTimeout(function () { 1733 pb.sendPing(); 1734 }, pb.delay); 1735 }, 1736 error: function error(xmlhttp) { 1737 var e = new Drupal.AjaxError(xmlhttp, pb.uri); 1738 pb.displayError('<pre>' + e.message + '</pre>'); 1739 } 1740 }); 1741 } 1742 }, 1743 displayError: function displayError(string) { 1744 var error = $('<div class="messages messages--error"></div>').html(string); 1745 $(this.element).before(error).hide(); 1746 1747 if (this.errorCallback) { 1748 this.errorCallback(this); 1749 } 1750 } 1751 }); 1752})(jQuery, Drupal);; 1753/** 1754 * @file 1755 * Extends methods from core/misc/progress.js. 1756 */ 1757 1758(function ($, Drupal) { 1759 1760 'use strict'; 1761 1762 /** 1763 * Theme function for the progress bar. 1764 * 1765 * @param {string} id 1766 * 1767 * @return {string} 1768 * The HTML for the progress bar. 1769 */ 1770 Drupal.theme.progressBar = function (id) { 1771 return '<div class="progress-wrapper" aria-live="polite">' + 1772 '<div class="message"></div>'+ 1773 '<div id ="' + id + '" class="progress progress-striped active">' + 1774 '<div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">' + 1775 '<span class="percentage"></span>' + 1776 '</div>' + 1777 '</div>' + 1778 '<div class="progress-label"></div>' + 1779 '</div>'; 1780 }; 1781 1782 $.extend(Drupal.ProgressBar.prototype, /** @lends Drupal.ProgressBar */{ 1783 1784 /** 1785 * Set the percentage and status message for the progressbar. 1786 * 1787 * @param {number} percentage 1788 * @param {string} message 1789 * @param {string} label 1790 */ 1791 setProgress: function (percentage, message, label) { 1792 if (percentage >= 0 && percentage <= 100) {
1793 $(this.element).find('.progress-bar').css('width', percentage + '%').attr('aria-valuenow', percentage); 1794 $(this.element).find('.percentage').html(percentage + '%'); 1795 } 1796 if (message) { 1797 // Remove the unnecessary whitespace at the end of the message. 1798 message = message.replace(/<br\/> |\s*$/, ''); 1799 1800 $('.message', this.element).html(message); 1801 } 1802 if (label) { 1803 $('.progress-label', this.element).html(label); 1804 } 1805 if (this.updateCallback) { 1806 this.updateCallback(percentage, message, this); 1807 } 1808 }, 1809 1810 /** 1811 * Display errors on the page. 1812 * 1813 * @param {string} string 1814 */ 1815 displayError: function (string) { 1816 var error = $('<div class="alert alert-block alert-error"><button class="close" data-dismiss="alert">×</button><h4>' + Drupal.t('Error message') + '</h4></div>').append(string); 1817 $(this.element).before(error).hide(); 1818 1819 if (this.errorCallback) { 1820 this.errorCallback(this); 1821 } 1822 } 1823 }); 1824 1825})(jQuery, Drupal); 1826; 1827/** 1828* DO NOT EDIT THIS FILE. 1829* See the following change record for more information, 1830* https://www.drupal.org/node/2815083 1831* @preserve 1832**/ 1833function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } 1834 1835(function ($, window, Drupal, drupalSettings) { 1836 Drupal.behaviors.AJAX = { 1837 attach: function attach(context, settings) { 1838 function loadAjaxBehavior(base) { 1839 var elementSettings = settings.ajax[base]; 1840 if (typeof elementSettings.selector === 'undefined') { 1841 elementSettings.selector = '#' + base; 1842 } 1843 $(elementSettings.selector).once('drupal-ajax').each(function () { 1844 elementSettings.element = this; 1845 elementSettings.base = base; 1846 Drupal.ajax(elementSettings); 1847 }); 1848 } 1849 1850 Object.keys(settings.ajax || {}).forEach(function (base) { 1851 return loadAjaxBehavior(base); 1852 }); 1853 1854 Drupal.ajax.bindAjaxLinks(document.body); 1855 1856 $('.use-ajax-submit').once('ajax').each(function () { 1857 var elementSettings = {}; 1858 1859 elementSettings.url = $(this.form).attr('action'); 1860 1861 elementSettings.setClick = true; 1862 1863 elementSettings.event = 'click'; 1864 1865 elementSettings.progress = { type: 'throbber' }; 1866 elementSettings.base = $(this).attr('id'); 1867 elementSettings.element = this; 1868 1869 Drupal.ajax(elementSettings); 1870 }); 1871 }, 1872 detach: function detach(context, settings, trigger) { 1873 if (trigger === 'unload') { 1874 Drupal.ajax.expired().forEach(function (instance) { 1875 Drupal.ajax.instances[instance.instanceIndex] = null; 1876 }); 1877 } 1878 } 1879 }; 1880 1881 Drupal.AjaxError = function (xmlhttp, uri, customMessage) { 1882 var statusCode = void 0; 1883 var statusText = void 0; 1884 var responseText = void 0; 1885 if (xmlhttp.status) { 1886 statusCode = '\n' + Drupal.t('An AJAX HTTP error occurred.') + '\n' + Drupal.t('HTTP Result Code: !status', { 1887 '!status': xmlhttp.status 1888 }); 1889 } else { 1890 statusCode = '\n' + Drupal.t('An AJAX HTTP request terminated abnormally.'); 1891 } 1892 statusCode += '\n' + Drupal.t('Debugging information follows.'); 1893 var pathText = '\n' + Drupal.t('Path: !uri', { '!uri': uri }); 1894 statusText = ''; 1895 1896 try { 1897 statusText = '\n' + Drupal.t('StatusText: !statusText', { 1898 '!statusText': $.trim(xmlhttp.statusText) 1899 }); 1900 } catch (e) {} 1901 1902 responseText = ''; 1903 1904 try { 1905 responseText = '\n' + Drupal.t('ResponseText: !responseText', { 1906 '!responseText': $.trim(xmlhttp.responseText) 1907 }); 1908 } catch (e) {} 1909 1910 responseText = responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi, ''); 1911 responseText = responseText.replace(/[\n]+\s+/g, '\n'); 1912 1913 var readyStateText = xmlhttp.status === 0 ? '\n' + Drupal.t('ReadyState: !readyState', { 1914 '!readyState': xmlhttp.readyState 1915 }) : ''; 1916 1917 customMessage = customMessage ? '\n' + Drupal.t('CustomMessage: !customMessage', { 1918 '!customMessage': customMessage 1919 }) : ''; 1920 1921 this.message = statusCode + pathText + statusText + customMessage + responseText + readyStateText; 1922 1923 this.name = 'AjaxError'; 1924 }; 1925 1926 Drupal.AjaxError.prototype = new Error(); 1927 Drupal.AjaxError.prototype.constructor = Drupal.AjaxError; 1928 1929 Drupal.ajax = function (settings) { 1930 if (arguments.length !== 1) { 1931 throw new Error('Drupal.ajax() function must be called with one configuration object only'); 1932 } 1933 1934 var base = settings.base || false; 1935 var element = settings.element || false; 1936 delete settings.base; 1937 delete settings.element; 1938 1939 if (!settings.progress && !element) { 1940 settings.progress = false;
1941 } 1942 1943 var ajax = new Drupal.Ajax(base, element, settings); 1944 ajax.instanceIndex = Drupal.ajax.instances.length; 1945 Drupal.ajax.instances.push(ajax); 1946 1947 return ajax; 1948 }; 1949 1950 Drupal.ajax.instances = []; 1951 1952 Drupal.ajax.expired = function () { 1953 return Drupal.ajax.instances.filter(function (instance) { 1954 return instance && instance.element !== false && !document.body.contains(instance.element); 1955 }); 1956 }; 1957 1958 Drupal.ajax.bindAjaxLinks = function (element) { 1959 $(element).find('.use-ajax').once('ajax').each(function (i, ajaxLink) { 1960 var $linkElement = $(ajaxLink); 1961 1962 var elementSettings = { 1963 progress: { type: 'throbber' }, 1964 dialogType: $linkElement.data('dialog-type'), 1965 dialog: $linkElement.data('dialog-options'), 1966 dialogRenderer: $linkElement.data('dialog-renderer'), 1967 base: $linkElement.attr('id'), 1968 element: ajaxLink 1969 }; 1970 var href = $linkElement.attr('href'); 1971 1972 if (href) { 1973 elementSettings.url = href; 1974 elementSettings.event = 'click'; 1975 } 1976 Drupal.ajax(elementSettings); 1977 }); 1978 }; 1979 1980 Drupal.Ajax = function (base, element, elementSettings) { 1981 var defaults = { 1982 event: element ? 'mousedown' : null, 1983 keypress: true, 1984 selector: base ? '#' + base : null, 1985 effect: 'none', 1986 speed: 'none', 1987 method: 'replaceWith', 1988 progress: { 1989 type: 'throbber', 1990 message: Drupal.t('Please wait...') 1991 }, 1992 submit: { 1993 js: true 1994 } 1995 }; 1996 1997 $.extend(this, defaults, elementSettings); 1998 1999 this.commands = new Drupal.AjaxCommands(); 2000 2001 this.instanceIndex = false; 2002 2003 if (this.wrapper) { 2004 this.wrapper = '#' + this.wrapper; 2005 } 2006 2007 this.element = element; 2008 2009 this.element_settings = elementSettings; 2010 2011 this.elementSettings = elementSettings; 2012 2013 if (this.element && this.element.form) { 2014 this.$form = $(this.element.form); 2015 } 2016 2017 if (!this.url) { 2018 var $element = $(this.element); 2019 if ($element.is('a')) { 2020 this.url = $element.attr('href'); 2021 } else if (this.element && element.form) { 2022 this.url = this.$form.attr('action'); 2023 } 2024 } 2025 2026 var originalUrl = this.url; 2027 2028 this.url = this.url.replace(/\/nojs(\/|$|\?|#)/, '/ajax$1'); 2029 2030 if (drupalSettings.ajaxTrustedUrl[originalUrl]) { 2031 drupalSettings.ajaxTrustedUrl[this.url] = true; 2032 } 2033 2034 var ajax = this; 2035 2036 ajax.options = { 2037 url: ajax.url, 2038 data: ajax.submit, 2039 beforeSerialize: function beforeSerialize(elementSettings, options) { 2040 return ajax.beforeSerialize(elementSettings, options); 2041 }, 2042 beforeSubmit: function beforeSubmit(formValues, elementSettings, options) { 2043 ajax.ajaxing = true; 2044 return ajax.beforeSubmit(formValues, elementSettings, options); 2045 }, 2046 beforeSend: function beforeSend(xmlhttprequest, options) { 2047 ajax.ajaxing = true; 2048 return ajax.beforeSend(xmlhttprequest, options); 2049 }, 2050 success: function success(response, status, xmlhttprequest) { 2051 if (typeof response === 'string') { 2052 response = $.parseJSON(response); 2053 } 2054 2055 if (response !== null && !drupalSettings.ajaxTrustedUrl[ajax.url]) { 2056 if (xmlhttprequest.getResponseHeader('X-Drupal-Ajax-Token') !== '1') { 2057 var customMessage = Drupal.t('The response failed verification so will not be processed.'); 2058 return ajax.error(xmlhttprequest, ajax.url, customMessage); 2059 } 2060 } 2061 2062 return ajax.success(response, status); 2063 }, 2064 complete: function complete(xmlhttprequest, status) { 2065 ajax.ajaxing = false; 2066 if (status === 'error' || status === 'parsererror') { 2067 return ajax.error(xmlhttprequest, ajax.url); 2068 } 2069 }, 2070 2071 dataType: 'json', 2072 jsonp: false, 2073 type: 'POST' 2074 }; 2075 2076 if (elementSettings.dialog) { 2077 ajax.options.data.dialogOptions = elementSettings.dialog; 2078 } 2079 2080 if (ajax.options.url.indexOf('?') === -1) { 2081 ajax.options.url += '?'; 2082 } else { 2083 ajax.options.url += '&'; 2084 } 2085 2086 var wrapper = 'drupal_' + (elementSettings.dialogType || 'ajax'); 2087 if (elementSettings.dialogRenderer) { 2088 wrapper += '.' + elementSettings.dialogRenderer; 2089 } 2090 ajax.options.url += Drupal.ajax.WRAPPER_FORMAT + '=' + wrapper; 2091 2092 $(ajax.element).on(elementSettings.event, function (event) { 2093 if (!drupalSettings.ajaxTrustedUrl[ajax.url] && !Drupal.url.isLocal(ajax.url)) { 2094 throw new Error(Drupal.t('The callback URL is not local and n
2094ot trusted: !url', { 2095 '!url': ajax.url 2096 })); 2097 } 2098 return ajax.eventResponse(this, event); 2099 }); 2100 2101 if (elementSettings.keypress) { 2102 $(ajax.element).on('keypress', function (event) { 2103 return ajax.keypressResponse(this, event); 2104 }); 2105 } 2106 2107 if (elementSettings.prevent) { 2108 $(ajax.element).on(elementSettings.prevent, false); 2109 } 2110 }; 2111 2112 Drupal.ajax.WRAPPER_FORMAT = '_wrapper_format'; 2113 2114 Drupal.Ajax.AJAX_REQUEST_PARAMETER = '_drupal_ajax'; 2115 2116 Drupal.Ajax.prototype.execute = function () { 2117 if (this.ajaxing) { 2118 return; 2119 } 2120 2121 try { 2122 this.beforeSerialize(this.element, this.options); 2123 2124 return $.ajax(this.options); 2125 } catch (e) { 2126 this.ajaxing = false; 2127 window.alert('An error occurred while attempting to process ' + this.options.url + ': ' + e.message); 2128 2129 return $.Deferred().reject(); 2130 } 2131 }; 2132 2133 Drupal.Ajax.prototype.keypressResponse = function (element, event) { 2134 var ajax = this; 2135 2136 if (event.which === 13 || event.which === 32 && element.type !== 'text' && element.type !== 'textarea' && element.type !== 'tel' && element.type !== 'number') { 2137 event.preventDefault(); 2138 event.stopPropagation(); 2139 $(element).trigger(ajax.elementSettings.event); 2140 } 2141 }; 2142 2143 Drupal.Ajax.prototype.eventResponse = function (element, event) { 2144 event.preventDefault(); 2145 event.stopPropagation(); 2146 2147 var ajax = this; 2148 2149 if (ajax.ajaxing) { 2150 return; 2151 } 2152 2153 try { 2154 if (ajax.$form) { 2155 if (ajax.setClick) { 2156 element.form.clk = element; 2157 } 2158 2159 ajax.$form.ajaxSubmit(ajax.options); 2160 } else { 2161 ajax.beforeSerialize(ajax.element, ajax.options); 2162 $.ajax(ajax.options); 2163 } 2164 } catch (e) { 2165 ajax.ajaxing = false; 2166 window.alert('An error occurred while attempting to process ' + ajax.options.url + ': ' + e.message); 2167 } 2168 }; 2169 2170 Drupal.Ajax.prototype.beforeSerialize = function (element, options) { 2171 if (this.$form && document.body.contains(this.$form.get(0))) { 2172 var settings = this.settings || drupalSettings; 2173 Drupal.detachBehaviors(this.$form.get(0), settings, 'serialize'); 2174 } 2175 2176 options.data[Drupal.Ajax.AJAX_REQUEST_PARAMETER] = 1; 2177 2178 var pageState = drupalSettings.ajaxPageState; 2179 options.data['ajax_page_state[theme]'] = pageState.theme; 2180 options.data['ajax_page_state[theme_token]'] = pageState.theme_token; 2181 options.data['ajax_page_state[libraries]'] = pageState.libraries; 2182 }; 2183 2184 Drupal.Ajax.prototype.beforeSubmit = function (formValues, element, options) {}; 2185 2186 Drupal.Ajax.prototype.beforeSend = function (xmlhttprequest, options) { 2187 if (this.$form) { 2188 options.extraData = options.extraData || {}; 2189 2190 options.extraData.ajax_iframe_upload = '1'; 2191 2192 var v = $.fieldValue(this.element); 2193 if (v !== null) { 2194 options.extraData[this.element.name] = v; 2195 } 2196 } 2197 2198 $(this.element).prop('disabled', true); 2199 2200 if (!this.progress || !this.progress.type) { 2201 return; 2202 } 2203 2204 var progressIndicatorMethod = 'setProgressIndicator' + this.progress.type.slice(0, 1).toUpperCase() + this.progress.type.slice(1).toLowerCase(); 2205 if (progressIndicatorMethod in this && typeof this[progressIndicatorMethod] === 'function') { 2206 this[progressIndicatorMethod].call(this); 2207 } 2208 }; 2209 2210 Drupal.theme.ajaxProgressThrobber = function (message) { 2211 var messageMarkup = typeof message === 'string' ? Drupal.theme('ajaxProgressMessage', message) : ''; 2212 var throbber = '<div class="throbber"> </div>'; 2213 2214 return '<div class="ajax-progress ajax-progress-throbber">' + throbber + messageMarkup + '</div>'; 2215 }; 2216 2217 Drupal.theme.ajaxProgressIndicatorFullscreen = function () { 2218 return '<div class="ajax-progress ajax-progress-fullscreen"> </div>'; 2219 }; 2220 2221 Drupal.theme.ajaxProgressMessage = function (message) { 2222 return '<div class="message">' + message + '</div>'; 2223 }; 2224 2225 Drupal.theme.ajaxProgressBar = function ($element) { 2226 return $('<div class="ajax-progress ajax-progress-bar"></div>').append($element); 2227 }; 2228 2229 Drupal.Ajax.prototype.setProgressIndicatorBar = function () { 2230 var progressBar = new Drupal.ProgressBar('ajax-progress-' + this.element.i
2230d, $.noop, this.progress.method, $.noop); 2231 if (this.progress.message) { 2232 progressBar.setProgress(-1, this.progress.message); 2233 } 2234 if (this.progress.url) { 2235 progressBar.startMonitoring(this.progress.url, this.progress.interval || 1500); 2236 } 2237 this.progress.element = $(Drupal.theme('ajaxProgressBar', progressBar.element)); 2238 this.progress.object = progressBar; 2239 $(this.element).after(this.progress.element); 2240 }; 2241 2242 Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () { 2243 this.progress.element = $(Drupal.theme('ajaxProgressThrobber', this.progress.message)); 2244 $(this.element).after(this.progress.element); 2245 }; 2246 2247 Drupal.Ajax.prototype.setProgressIndicatorFullscreen = function () { 2248 this.progress.element = $(Drupal.theme('ajaxProgressIndicatorFullscreen')); 2249 $('body').append(this.progress.element); 2250 }; 2251 2252 Drupal.Ajax.prototype.success = function (response, status) { 2253 var _this = this; 2254 2255 if (this.progress.element) { 2256 $(this.progress.element).remove(); 2257 } 2258 if (this.progress.object) { 2259 this.progress.object.stopMonitoring(); 2260 } 2261 $(this.element).prop('disabled', false); 2262 2263 var elementParents = $(this.element).parents('[data-drupal-selector]').addBack().toArray(); 2264 2265 var focusChanged = false; 2266 Object.keys(response || {}).forEach(function (i) { 2267 if (response[i].command && _this.commands[response[i].command]) { 2268 _this.commands[response[i].command](_this, response[i], status); 2269 if (response[i].command === 'invoke' && response[i].method === 'focus') { 2270 focusChanged = true; 2271 } 2272 } 2273 }); 2274 2275 if (!focusChanged && this.element && !$(this.element).data('disable-refocus')) { 2276 var target = false;
2277 2278 for (var n = elementParents.length - 1; !target && n >= 0; n--) { 2279 target = document.querySelector('[data-drupal-selector="' + elementParents[n].getAttribute('data-drupal-selector') + '"]'); 2280 } 2281 2282 if (target) { 2283 $(target).trigger('focus'); 2284 } 2285 } 2286 2287 if (this.$form && document.body.contains(this.$form.get(0))) { 2288 var settings = this.settings || drupalSettings; 2289 Drupal.attachBehaviors(this.$form.get(0), settings); 2290 } 2291 2292 this.settings = null; 2293 }; 2294 2295 Drupal.Ajax.prototype.getEffect = function (response) { 2296 var type = response.effect || this.effect; 2297 var speed = response.speed || this.speed; 2298 2299 var effect = {}; 2300 if (type === 'none') { 2301 effect.showEffect = 'show'; 2302 effect.hideEffect = 'hide'; 2303 effect.showSpeed = ''; 2304 } else if (type === 'fade') { 2305 effect.showEffect = 'fadeIn'; 2306 effect.hideEffect = 'fadeOut'; 2307 effect.showSpeed = speed; 2308 } else { 2309 effect.showEffect = type + 'Toggle'; 2310 effect.hideEffect = type + 'Toggle'; 2311 effect.showSpeed = speed; 2312 } 2313 2314 return effect; 2315 }; 2316 2317 Drupal.Ajax.prototype.error = function (xmlhttprequest, uri, customMessage) { 2318 if (this.progress.element) { 2319 $(this.progress.element).remove(); 2320 } 2321 if (this.progress.object) { 2322 this.progress.object.stopMonitoring(); 2323 } 2324 2325 $(this.wrapper).show(); 2326 2327 $(this.element).prop('disabled', false); 2328 2329 if (this.$form && document.body.contains(this.$form.get(0))) { 2330 var settings = this.settings || drupalSettings; 2331 Drupal.attachBehaviors(this.$form.get(0), settings); 2332 } 2333 throw new Drupal.AjaxError(xmlhttprequest, uri, customMessage); 2334 }; 2335 2336 Drupal.theme.ajaxWrapperNewContent = function ($newContent, ajax, response) { 2337 return (response.effect || ajax.effect) !== 'none' && $newContent.filter(function (i) { 2338 return !($newContent[i].nodeName === '#comment' || $newContent[i].nodeName === '#text' && /^(\s|\n|\r)*$/.test($newContent[i].textContent)); 2339 }).length > 1 ? Drupal.theme('ajaxWrapperMultipleRootElements', $newContent) : $newContent; 2340 }; 2341 2342 Drupal.theme.ajaxWrapperMultipleRootElements = function ($elements) { 2343 return $('<div></div>').append($elements); 2344 }; 2345 2346 Drupal.AjaxCommands = function () {}; 2347 Drupal.AjaxCommands.prototype = { 2348 insert: function insert(ajax, response) { 2349 var $wrapper = response.selector ? $(response.selector) : $(ajax.wrapper); 2350 var method = response.method || ajax.method; 2351 var effect = ajax.getEffect(response); 2352 2353 var settings = response.settings || ajax.settings || drupalSettings; 2354 2355 var $newContent = $($.parseHTML(response.data, document, true)); 2356 2357 $newContent = Drupal.theme('ajaxWrapperNewContent', $newContent, ajax, response); 2358 2359 switch (method) { 2360 case 'html': 2361 case 'replaceWith': 2362 case 'replaceAll': 2363 case 'empty': 2364 case 'remove': 2365 Drupal.detachBehaviors($wrapper.get(0), settings); 2366 break; 2367 default: 2368 break; 2369 } 2370 2371 $wrapper[method]($newContent); 2372 2373 if (effect.showEffect !== 'show') { 2374 $newContent.hide(); 2375 } 2376 2377 var $ajaxNewContent = $newContent.find('.ajax-new-content'); 2378 if ($ajaxNewContent.length) { 2379 $ajaxNewContent.hide(); 2380 $newContent.show(); 2381 $ajaxNewContent[effect.showEffect](effect.showSpeed); 2382 } else if (effect.showEffect !== 'show') { 2383 $newContent[effect.showEffect](effect.showSpeed); 2384 } 2385 2386 if ($newContent.parents('html').length) { 2387 $newContent.each(function (index, element) { 2388 if (element.nodeType === Node.ELEMENT_NODE) { 2389 Drupal.attachBehaviors(element, settings); 2390 } 2391 }); 2392 } 2393 }, 2394 remove: function remove(ajax, response, status) { 2395 var settings = response.settings || ajax.settings || drupalSettings; 2396 $(response.selector).each(function () { 2397 Drupal.detachBehaviors(this, settings); 2398 }).remove(); 2399 }, 2400 changed: function changed(ajax, response, status) { 2401 var $element = $(response.selector); 2402 if (!$element.hasClass('ajax-changed')) { 2403 $element.addClass('ajax-changed'); 2404 if (response.asterisk) { 2405 $element.find(response.asterisk).append(' <abbr class="ajax-changed" title="' + Drupal.t('Changed') + '">*</abbr> '); 2406 } 2407 } 2408 }, 2409 alert: function alert(ajax, response, status) { 2410 window.alert(response.text, response.title); 2411 }, 2412 announce: function announce(ajax, response) { 2413 if (response.priority) { 2414 Drupal.announce(response.text, response.priority); 2415 } else { 2416 Drupal.announce(response.text); 2417 } 2418 }, 2419 redirect: function redirect(ajax, response, status) { 2420 window.location = response.url; 2421 }, 2422 css: function css(ajax, response, status) { 2423 $(response.selector).css(response.argument); 2424 }, 2425 settings: function settings(ajax, response, status) { 2426 var ajaxSettings = drupalSettings.ajax; 2427 2428 if (ajaxSettings) {
2429 Drupal.ajax.expired().forEach(function (instance) { 2430 2431 if (instance.selector) { 2432 var selector = instance.selector.replace('#', ''); 2433 if (selector in ajaxSettings) { 2434 delete ajaxSettings[selector]; 2435 } 2436 } 2437 }); 2438 } 2439 2440 if (response.merge) { 2441 $.extend(true, drupalSettings, response.settings); 2442 } else { 2443 ajax.settings = response.settings; 2444 } 2445 }, 2446 data: function data(ajax, response, status) { 2447 $(response.selector).data(response.name, response.value); 2448 }, 2449 invoke: function invoke(ajax, response, status) { 2450 var $element = $(response.selector); 2451 $element[response.method].apply($element, _toConsumableArray(response.args)); 2452 }, 2453 restripe: function restripe(ajax, response, status) { 2454 $(response.selector).find('> tbody > tr:visible, > tr:visible').removeClass('odd even').filter(':even').addClass('odd').end().filter(':odd').addClass('even'); 2455 }, 2456 update_build_id: function update_build_id(ajax, response, status) { 2457 $('input[name="form_build_id"][value="' + response.old + '"]').val(response.new); 2458 }, 2459 add_css: function add_css(ajax, response, status) { 2460 $('head').prepend(response.data); 2461 }, 2462 message: function message(ajax, response) { 2463 var messages = new Drupal.Message(document.querySelector(response.messageWrapperQuerySelector)); 2464 if (response.clearPrevious) { 2465 messages.clear(); 2466 } 2467 messages.add(response.message, response.messageOptions); 2468 } 2469 }; 2470})(jQuery, window, Drupal, drupalSettings);; 2471/** 2472 * @file 2473 * Extends methods from core/misc/ajax.js. 2474 */ 2475 2476(function ($, window, Drupal, drupalSettings) { 2477 2478 /** 2479 * Attempts to find the closest glyphicon progress indicator. 2480 * 2481 * @param {jQuery|Element} element 2482 * A DOM element. 2483 * 2484 * @returns {jQuery} 2485 * A jQuery object. 2486 */ 2487 Drupal.Ajax.prototype.findGlyphicon = function (element) { 2488 return $(element).closest('.form-item').find('.ajax-progress.glyphicon') 2489 }; 2490 2491 /** 2492 * Starts the spinning of the glyphicon progress indicator. 2493 * 2494 * @param {jQuery|Element} element 2495 * A DOM element. 2496 * @param {string} [message] 2497 * An optional message to display (tooltip) for the progress. 2498 * 2499 * @returns {jQuery} 2500 * A jQuery object. 2501 */ 2502 Drupal.Ajax.prototype.glyphiconStart = function (element, message) { 2503 var $glyphicon = this.findGlyphicon(element); 2504 if ($glyphicon[0]) { 2505 $glyphicon.addClass('glyphicon-spin'); 2506 2507 // Add any message as a tooltip to the glyphicon. 2508 if ($.fn.tooltip && drupalSettings.bootstrap.tooltip_enabled) { 2509 $glyphicon 2510 .removeAttr('data-toggle') 2511 .removeAttr('data-original-title') 2512 .removeAttr('title') 2513 .tooltip('destroy') 2514 ; 2515 2516 if (message) { 2517 $glyphicon.attr('data-toggle', 'tooltip').attr('title', message).tooltip(); 2518 } 2519 } 2520 2521 // Append a message for screen readers. 2522 if (message) { 2523 $glyphicon.parent().append('<div class="sr-only message">' + message + '</div>'); 2524 } 2525 } 2526 return $glyphicon; 2527 }; 2528 2529 /** 2530 * Stop the spinning of a glyphicon progress indicator. 2531 * 2532 * @param {jQuery|Element} element 2533 * A DOM element. 2534 */ 2535 Drupal.Ajax.prototype.glyphiconStop = function (element) { 2536 var $glyphicon = this.findGlyphicon(element); 2537 if ($glyphicon[0]) { 2538 $glyphicon.removeClass('glyphicon-spin'); 2539 if ($.fn.tooltip && drupalSettings.bootstrap.tooltip_enabled) { 2540 $glyphicon 2541 .removeAttr('data-toggle') 2542 .removeAttr('data-original-title') 2543 .removeAttr('title') 2544 .tooltip('destroy') 2545 ; 2546 } 2547 } 2548 }; 2549 2550 /** 2551 * Sets the throbber progress indicator. 2552 */ 2553 Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () { 2554 var $element = $(this.element); 2555 2556 // Find an existing glyphicon progress indicator. 2557 var $glyphicon = this.glyphiconStart($element, this.progress.message); 2558 if ($glyphicon[0]) { 2559 this.progress.element = $glyphicon.parent(); 2560 this.progress.glyphicon = true; 2561 return; 2562 } 2563 2564 // Otherwise, add a glyphicon throbber after the element. 2565 if (!this.progress.element) { 2566 this.progress.element = $(Drupal.theme('ajaxThrobber')); 2567 } 2568 if (this.progress.message) { 2569 this.progress.element.after('<div class="message">' + this.progress.message + '</div>'); 2570 } 2571 2572 // If element is an input DOM element type (not :input), append after. 2573 if ($element.is('input')) { 2574 $element.after(this.progress.element); 2575 } 2576 // Otherwise append the throbber inside the element. 2577 else { 2578 $element.append(this.progress.element); 2579 } 2580 }; 2581 2582 2583 /** 2584 * Handler for the form redirection completion. 2585 * 2586 * @param {Array.<Drupal.AjaxCommands~commandDefinition>} response 2587 * @param {number} status 2588 */ 2589 var success = Drupal.Ajax.prototype.success; 2590 Drupal.Ajax.prototype.success = function (response, status) { 2591 if (this.progress.element) { 2592 2593 // Stop a glyphicon throbber. 2594 if (this.progress.glyphicon) { 2595 this.glyphiconStop(this.progress.element); 2596 } 2597 // Remove the progress element. 2598 else { 2599 this.progress.element.remove(); 2600 } 2601 2602 // Remove any message set. 2603 this.progress.element.parent().find('.message').remove(); 2604 } 2605 2606 // Invoke the original success handler. 2607 return success.apply(this, [response, status]); 2608 }; 2609 2610})(jQuery, this, Drupal, drupalSettings); 2611; 2612/** 2613* DO NOT EDIT THIS FILE. 2614* See the following change record for more information, 2615* https://www.drupal.org/node/2815083 2616* @preserve 2617**/ 2618 2619(function ($, Drupal, debounce) { 2620 var offsets = { 2621 top: 0, 2622 right: 0, 2623 bottom: 0, 2624 left: 0 2625 }; 2626 2627 function getRawOffset(el, edge) { 2628 var $el = $(el); 2629 var documentElement = document.documentElement; 2630 var displacement = 0; 2631 var horizontal = edge === 'left' || edge === 'right'; 2632 2633 var placement = $el.offset()[horizontal ? 'left' : 'top']; 2634 2635 placement -= window['scroll' + (horizontal ? 'X' : 'Y')] || document.documentElement['scroll' + (horizontal ? 'Left' : 'Top')] || 0; 2636 2637 switch (edge) { 2638 case 'top': 2639 displacement = placement + $el.outerHeight(); 2640 break; 2641 2642 case 'left': 2643 displacement = placement + $el.outerWidth(); 2644 break; 2645 2646 case 'bottom': 2647 displacement = documentElement.clientHeight - placement; 2648 break; 2649 2650 case 'right': 2651 displacement = documentElement.clientWidth - placement; 2652 break; 2653 2654 default: 2655 displacement = 0; 2656 }
2657 return displacement; 2658 } 2659 2660 function calculateOffset(edge) { 2661 var edgeOffset = 0; 2662 var displacingElements = document.querySelectorAll('[data-offset-' + edge + ']'); 2663 var n = displacingElements.length; 2664 for (var i = 0; i < n; i++) { 2665 var el = displacingElements[i]; 2666 2667 if (el.style.display === 'none') { 2668 continue; 2669 } 2670 2671 var displacement = parseInt(el.getAttribute('data-offset-' + edge), 10); 2672 2673 if (isNaN(displacement)) { 2674 displacement = getRawOffset(el, edge); 2675 } 2676 2677 edgeOffset = Math.max(edgeOffset, displacement); 2678 } 2679 2680 return edgeOffset; 2681 } 2682 2683 function calculateOffsets() { 2684 return { 2685 top: calculateOffset('top'), 2686 right: calculateOffset('right'), 2687 bottom: calculateOffset('bottom'), 2688 left: calculateOffset('left') 2689 }; 2690 } 2691 2692 function displace(broadcast) { 2693 offsets = calculateOffsets(); 2694 Drupal.displace.offsets = offsets; 2695 if (typeof broadcast === 'undefined' || broadcast) { 2696 $(document).trigger('drupalViewportOffsetChange', offsets); 2697 } 2698 return offsets; 2699 } 2700 2701 Drupal.behaviors.drupalDisplace = { 2702 attach: function attach() { 2703 if (this.displaceProcessed) { 2704 return; 2705 } 2706 this.displaceProcessed = true; 2707 2708 $(window).on('resize.drupalDisplace', debounce(displace, 200)); 2709 } 2710 }; 2711 2712 Drupal.displace = displace; 2713 $.extend(Drupal.displace, { 2714 offsets: offsets, 2715 2716 calculateOffset: calculateOffset 2717 }); 2718})(jQuery, Drupal, Drupal.debounce);; 2719/** 2720 * @file 2721 * Bootstrap Modals. 2722 * 2723 * @param {jQuery} $ 2724 * @param {Drupal} Drupal 2725 * @param {Drupal.bootstrap} Bootstrap 2726 * @param {Attributes} Attributes 2727 */ 2728(function ($, Drupal, Bootstrap, Attributes) { 2729 'use strict'; 2730 2731 /** 2732 * Document jQuery object. 2733 * 2734 * @type {jQuery} 2735 */ 2736 var $document = $(document); 2737 2738 /** 2739 * Finds the first available and visible focusable input element. 2740 * 2741 * This is abstracted from the main code below so sub-themes can override 2742 * this method to return their own element if desired. 2743 * 2744 * @param {Modal} modal 2745 * The Bootstrap modal instance. 2746 * 2747 * @return {jQuery} 2748 * A jQuery object containing the element that should be focused. Note: if
2749 * this object contains multiple elements, only the first visible one will 2750 * be used. 2751 */ 2752 Bootstrap.modalFindFocusableElement = function (modal) { 2753 return modal.$dialogBody.find(':input,:button,.btn').not('.visually-hidden,.sr-only'); 2754 }; 2755 2756 $document.on('shown.bs.modal', function (e) { 2757 var $modal = $(e.target); 2758 var modal = $modal.data('bs.modal'); 2759 2760 // Focus the first input element found. 2761 if (modal && modal.options.focusInput) { 2762 var $focusable = Bootstrap.modalFindFocusableElement(modal); 2763 if ($focusable && $focusable[0]) { 2764 var $input = $focusable.filter(':visible:first').focus(); 2765 2766 // Select text if input is text. 2767 if (modal.options.selectText && $input.is(':text')) { 2768 $input[0].setSelectionRange(0, $input[0].value.length) 2769 } 2770 } 2771 else if (modal.$close.is(':visible')) { 2772 modal.$close.focus(); 2773 } 2774 } 2775 }); 2776 2777 /** 2778 * Only process this once. 2779 */ 2780 Bootstrap.once('modal', function (settings) { 2781 2782 /** 2783 * Replace the Bootstrap Modal jQuery plugin definition. 2784 * 2785 * This adds a little bit of functionality so it works better with Drupal. 2786 */ 2787 Bootstrap.replacePlugin('modal', function () { 2788 var BootstrapModal = this; 2789 2790 // Override the Modal constructor. 2791 Bootstrap.Modal = function (element, options) { 2792 this.$body = $(document.body); 2793 this.$element = $(element); 2794 this.$dialog = this.$element.find('.modal-dialog'); 2795 this.$header = this.$dialog.find('.modal-header'); 2796 this.$title = this.$dialog.find('.modal-title'); 2797 this.$close = this.$header.find('.close'); 2798 this.$footer = this.$dialog.find('.modal-footer'); 2799 this.$content = this.$dialog.find('.modal-content'); 2800 this.$dialogBody = this.$dialog.find('.modal-body'); 2801 this.$backdrop = null; 2802 this.isShown = null; 2803 this.originalBodyPad = null; 2804 this.scrollbarWidth = 0; 2805 this.ignoreBackdropClick = false; 2806 this.options = this.mapDialogOptions(options); 2807 }; 2808 2809 // Extend defaults to take into account for theme settings. 2810 Bootstrap.Modal.DEFAULTS = $.extend({}, BootstrapModal.DEFAULTS, { 2811 animation: !!settings.modal_animation, 2812 backdrop: settings.modal_backdrop === 'static' ? 'static' : !!settings.modal_backdrop, 2813 focusInput: !!settings.modal_focus_input, 2814 selectText: !!settings.modal_select_text, 2815 keyboard: !!settings.modal_keyboard, 2816 remote: null, 2817 show: !!settings.modal_show, 2818 size: settings.modal_size 2819 }); 2820 2821 // Copy over the original prototype methods. 2822 Bootstrap.Modal.prototype = BootstrapModal.prototype; 2823 2824 /** 2825 * Handler for $.fn.modal('destroy'). 2826 */ 2827 Bootstrap.Modal.prototype.destroy = function () { 2828 this.hide(); 2829 Drupal.detachBehaviors(this.$element[0]); 2830 this.$element.removeData('bs.modal').remove(); 2831 }; 2832 2833 /** 2834 * Initialize the modal. 2835 */ 2836 Bootstrap.Modal.prototype.init = function () { 2837 if (this.options.remote) { 2838 this.$content.load(this.options.remote, $.proxy(function () { 2839 this.$element.trigger('loaded.bs.modal'); 2840 }, this)); 2841 } 2842 }; 2843 2844 /** 2845 * Map dialog options. 2846 * 2847 * Note: this is primarily for use in modal.jquery.ui.bridge.js. 2848 * 2849 * @param {Object} options 2850 * The passed options. 2851 */ 2852 Bootstrap.Modal.prototype.mapDialogOptions = function (options) { 2853 return options || {}; 2854 } 2855 2856 // Modal jQuery Plugin Definition. 2857 var Plugin = function () { 2858 // Extract the arguments. 2859 var args = Array.prototype.slice.call(arguments); 2860 var method = args[0]; 2861 var options = args[1] || {}; 2862 var relatedTarget = args[2] || null; 2863 // Move arguments down if no method was passed. 2864 if ($.isPlainObject(method)) { 2865 relatedTarget = options || null; 2866 options = method; 2867 method = null; 2868 } 2869 var ret = void 0; 2870 this.each(function () { 2871 var $this = $(this); 2872 var data = $this.data('bs.modal'); 2873 var initialize = false;
2874 2875 // Immediately return if there's no instance to invoke a valid method. 2876 var showMethods = ['open', 'show', 'toggle']; 2877 if (!data && method && showMethods.indexOf(method) === -1) { 2878 return; 2879 } 2880 2881 options = Bootstrap.normalizeObject($.extend({}, Bootstrap.Modal.DEFAULTS, data && data.options, $this.data(), options)); 2882 delete options['bs.modal']; 2883 2884 if (!data) { 2885 $this.data('bs.modal', (data = new Bootstrap.Modal(this, options))); 2886 initialize = true; 2887 } 2888 2889 // Initialize the modal. 2890 if (initialize || (!method && !args.length)) { 2891 data.init(); 2892 } 2893 2894 // Explicit method passed. 2895 if (method) { 2896 if (typeof data[method] === 'function') { 2897 try { 2898 ret = data[method].apply(data, args.slice(1)); 2899 } 2900 catch (e) { 2901 Drupal.throwError(e); 2902 } 2903 } 2904 else { 2905 Bootstrap.unsupported('method', method); 2906 } 2907 } 2908 // No method, set options and open if necessary. 2909 else { 2910 data.option(options); 2911 if (options.show && !data.isShown) { 2912 data.show(relatedTarget); 2913 } 2914 } 2915 }); 2916 2917 // If just one element and there was a result returned for the option passed, 2918 // then return the result. Otherwise, just return the jQuery object. 2919 return this.length === 1 && ret !== void 0 ? ret : this; 2920 }; 2921 2922 // Replace the plugin constructor with the new Modal constructor. 2923 Plugin.Constructor = Bootstrap.Modal; 2924 2925 // Replace the data API so that it calls $.fn.modal rather than Plugin. 2926 // This allows sub-themes to replace the jQuery Plugin if they like with 2927 // out having to redo all this boilerplate. 2928 $document 2929 .off('click.bs.modal.data-api') 2930 .on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { 2931 var $this = $(this); 2932 var href = $this.attr('href'); 2933 var target = $this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, '')); // strip for ie7 2934 var $target = $document.find(target); 2935 var options = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()); 2936 2937 if ($this.is('a')) e.preventDefault(); 2938 2939 $target.one('show.bs.modal', function (showEvent) { 2940 // Only register focus restorer if modal will actually get shown. 2941 if (showEvent.isDefaultPrevented()) return; 2942 $target.one('hidden.bs.modal', function () { 2943 $this.is(':visible') && $this.trigger('focus'); 2944 }); 2945 }); 2946 $target.modal(options, this); 2947 }); 2948 2949 return Plugin; 2950 }); 2951 2952 /** 2953 * Extend Drupal theming functions. 2954 */ 2955 $.extend(Drupal.theme, /** @lend Drupal.theme */ { 2956 /** 2957 * Theme function for a Bootstrap Modal. 2958 * 2959 * @param {Object} [variables] 2960 * An object containing key/value pairs of variables. 2961 * 2962 * @return {string} 2963 * The HTML for the modal. 2964 */ 2965 bootstrapModal: function (variables) { 2966 var output = ''; 2967 var settings = drupalSettings.bootstrap || {}; 2968 var defaults = { 2969 attributes: { 2970 class: ['modal'], 2971 tabindex: -1, 2972 role: 'dialog' 2973 }, 2974 body: '', 2975 closeButton: true, 2976 description: { 2977 attributes: { 2978 class: ['help-block'] 2979 }, 2980 content: null, 2981 position: 'before' 2982 }, 2983 footer: '', 2984 id: 'drupal-modal', 2985 size: settings.modal_size ? settings.modal_size : '', 2986 title: { 2987 attributes: { 2988 class: ['modal-title'] 2989 }, 2990 content: Drupal.t('Loading...'), 2991 html: false, 2992 tag: 'h4' 2993 } 2994 }; 2995 variables = $.extend(true, {}, defaults, variables); 2996 2997 var attributes = Attributes.create(defaults.attributes).merge(variables.attributes); 2998 attributes.set('id', attributes.get('id', variables.id)); 2999 3000 if (settings.modal_animation) { 3001 attributes.addClass('fade'); 3002 } 3003 3004 // Build the modal wrapper. 3005 output += '<div' + attributes + '>'; 3006 3007 // Build the modal-dialog wrapper. 3008 output += Drupal.theme('bootstrapModalDialog', _.omit(variables, 'attributes')); 3009 3010 // Close the modal wrapper. 3011 output += '</div>'; 3012 3013 // Return the constructed modal. 3014 return output; 3015 }, 3016 3017 /** 3018 * Theme function for a Bootstrap Modal dialog markup. 3019 * 3020 * @param {Object} [variables]
3021 * An object containing key/value pairs of variables. 3022 * 3023 * @return {string} 3024 * The HTML for the modal close button. 3025 */ 3026 bootstrapModalDialog: function (variables) { 3027 var output = ''; 3028 3029 var defaults = { 3030 attributes: { 3031 class: ['modal-dialog'], 3032 role: 'document' 3033 }, 3034 id: 'drupal-modal' 3035 }; 3036 variables = $.extend(true, {}, defaults, variables); 3037 3038 var attributes = Attributes.create(defaults.attributes).merge(variables.attributes); 3039 attributes.set('id', attributes.get('id', variables.id + '--dialog')); 3040 3041 if (variables.size) { 3042 attributes.addClass(variables.size); 3043 } 3044 output += '<div' + attributes + '>'; 3045 3046 // Build the modal-content wrapper. 3047 output += Drupal.theme('bootstrapModalContent', _.omit(variables, 'attributes')); 3048 3049 // Close the modal-dialog wrapper. 3050 output += '</div>'; 3051 return output; 3052 }, 3053 3054 /** 3055 * Theme function for a Bootstrap Modal content markup. 3056 * 3057 * @param {Object} [variables] 3058 * An object containing key/value pairs of variables. 3059 * 3060 * @return {string} 3061 * The HTML for the modal close button. 3062 */ 3063 bootstrapModalContent: function (variables) { 3064 var output = ''; 3065 3066 var defaults = { 3067 attributes: { 3068 class: ['modal-content'] 3069 }, 3070 id: 'drupal-modal' 3071 }; 3072 variables = $.extend(true, {}, defaults, variables); 3073 3074 var attributes = Attributes.create(defaults.attributes).merge(variables.attributes); 3075 attributes.set('id', attributes.get('id', variables.id + '--content')); 3076 3077 // Build the modal-content wrapper. 3078 output += '<div' + attributes + '>'; 3079 variables = _.omit(variables, 'attributes'); 3080 3081 // Build the header wrapper and title. 3082 output += Drupal.theme('bootstrapModalHeader', variables); 3083 3084 // Build the body. 3085 output += Drupal.theme('bootstrapModalBody', variables); 3086 3087 // Build the footer. 3088 output += Drupal.theme('bootstrapModalFooter', variables); 3089 3090 // Close the modal-content wrapper. 3091 output += '</div>'; 3092 3093 return output; 3094 }, 3095 3096 /** 3097 * Theme function for a Bootstrap Modal body markup. 3098 * 3099 * @param {Object} [variables] 3100 * An object containing key/value pairs of variables. 3101 * 3102 * @return {string} 3103 * The HTML for the modal close button. 3104 */ 3105 bootstrapModalBody: function (variables) { 3106 var output = ''; 3107 3108 var defaults = { 3109 attributes: { 3110 class: ['modal-body'] 3111 }, 3112 body: '', 3113 description: { 3114 attributes: { 3115 class: ['help-block'] 3116 }, 3117 content: null, 3118 position: 'before' 3119 }, 3120 id: 'drupal-modal' 3121 }; 3122 variables = $.extend(true, {}, defaults, variables); 3123 3124 var attributes = Attributes.create(defaults.attributes).merge(variables.attributes); 3125 attributes.set('id', attributes.get('id', variables.id + '--body')); 3126 3127 output += '<div' + attributes + '>'; 3128 3129 if (typeof variables.description === 'string') { 3130 variables.description = $.extend({}, defaults.description, { content: variables.description }); 3131 } 3132 3133 var description = variables.description; 3134 description.attributes = Attributes.create(defaults.description.attributes).merge(description.attributes); 3135 3136 if (description.content && description.position === 'invisible') { 3137 description.attributes.addClass('sr-only'); 3138 } 3139 3140 if (description.content && description.position === 'before') { 3141 output += '<p' + description.attributes + '>' + description.content + '</p>'; 3142 } 3143 3144 output += variables.body; 3145 3146 if (description.content && (description.position === 'after' || description.position === 'invisible')) { 3147 output += '<p' + description.attributes + '>' + description.content + '</p>'; 3148 } 3149 3150 output += '</div>'; 3151 3152 return output; 3153 }, 3154 3155 /** 3156 * Theme function for a Bootstrap Modal close button. 3157 * 3158 * @param {Object} [variables]
3159 * An object containing key/value pairs of variables. 3160 * 3161 * @return {string} 3162 * The HTML for the modal close button. 3163 */ 3164 bootstrapModalClose: function (variables) { 3165 var defaults = { 3166 attributes: { 3167 'aria-label': Drupal.t('Close'), 3168 class: ['close'], 3169 'data-dismiss': 'modal', 3170 type: 'button' 3171 } 3172 }; 3173 variables = $.extend(true, {}, defaults, variables); 3174 var attributes = Attributes.create(defaults.attributes).merge(variables.attributes); 3175 return '<button' + attributes + '><span aria-hidden="true">×</span></button>'; 3176 }, 3177 3178 /** 3179 * Theme function for a Bootstrap Modal footer. 3180 * 3181 * @param {Object} [variables] 3182 * An object containing key/value pairs of variables. 3183 * @param {boolean} [force] 3184 * Flag to force rendering the footer, regardless if there's content. 3185 * 3186 * @return {string} 3187 * The HTML for the modal footer. 3188 */ 3189 bootstrapModalFooter: function (variables, force) { 3190 var output = ''; 3191 var defaults = { 3192 attributes: { 3193 class: ['modal-footer'] 3194 }, 3195 footer: '', 3196 id: 'drupal-modal' 3197 }; 3198 3199 variables = $.extend(true, {}, defaults, variables); 3200 3201 if (force || variables.footer) { 3202 var attributes = Attributes.create(defaults.attributes).merge(variables.attributes); 3203 attributes.set('id', attributes.get('id', variables.id + '--footer')); 3204 output += '<div' + attributes + '>'; 3205 output += variables.footer; 3206 output += '</div>'; 3207 } 3208 3209 return output; 3210 }, 3211 3212 /** 3213 * Theme function for a Bootstrap Modal header. 3214 * 3215 * @param {Object} [variables] 3216 * An object containing key/value pairs of variables. 3217 * 3218 * @return {string} 3219 * The HTML for the modal header. 3220 */ 3221 bootstrapModalHeader: function (variables) { 3222 var output = ''; 3223 3224 var defaults = { 3225 attributes: { 3226 class: ['modal-header'] 3227 }, 3228 closeButton: true, 3229 id: 'drupal-modal', 3230 title: { 3231 attributes: { 3232 class: ['modal-title'] 3233 }, 3234 content: Drupal.t('Loading...'), 3235 html: false, 3236 tag: 'h4' 3237 } 3238 }; 3239 variables = $.extend(true, {}, defaults, variables); 3240 3241 if (typeof variables.title === 'string') { 3242 variables.title = $.extend({}, defaults.title, { content: variables.title }); 3243 } 3244 3245 var title = Drupal.theme('bootstrapModalTitle', variables.title); 3246 if (title) { 3247 var attributes = Attributes.create(defaults.attributes).merge(variables.attributes); 3248 attributes.set('id', attributes.get('id', variables.id + '--header')); 3249 3250 output += '<div' + attributes + '>'; 3251 3252 if (variables.closeButton) { 3253 output += Drupal.theme('bootstrapModalClose', _.omit(variables, 'attributes')); 3254 } 3255 3256 output += title; 3257 3258 output += '</div>'; 3259 } 3260 3261 return output; 3262 }, 3263 3264 /** 3265 * Theme function for a Bootstrap Modal title. 3266 * 3267 * @param {Object} [variables] 3268 * An object containing key/value pairs of variables. 3269 * 3270 * @return {string} 3271 * The HTML for the modal title. 3272 */ 3273 bootstrapModalTitle: function (variables) { 3274 var output = ''; 3275 3276 var defaults = { 3277 attributes: { 3278 class: ['modal-title'] 3279 }, 3280 closeButton: true, 3281 id: 'drupal-modal', 3282 content: Drupal.t('Loading...'), 3283 html: false, 3284 tag: 'h4' 3285 }; 3286 3287 if (typeof variables === 'string') { 3288 variables = $.extend({}, defaults, { content: title }); 3289 } 3290 3291 variables = $.extend(true, {}, defaults, variables); 3292 3293 var attributes = Attributes.create(defaults.attributes).merge(variables.attributes); 3294 attributes.set('id', attributes.get('id', variables.id + '--title')); 3295 3296 output += '<' + Drupal.checkPlain(variables.tag) + Attributes.create(defaults.attributes).merge(variables.attributes) + '>'; 3297 3298 if (variables.closeButton) { 3299 output += Drupal.theme('bootstrapModalClose', _.omit(variables, 'attributes')); 3300 } 3301 3302 output += (variables.html ? variables.content : Drupal.checkPlain(variables.content)); 3303 3304 output += '</' + Drupal.checkPlain(variables.tag) + '>'; 3305 3306 return output; 3307 } 3308 3309 }) 3310 3311 }); 3312 3313})(window.jQuery, window.Drupal, window.Drupal.bootstrap, window.Attributes); 3314; 3315/** 3316 * @file 3317 * dialog.js 3318 */ 3319(function ($, Drupal, Bootstrap, Attributes) { 3320 3321 Bootstrap.Dialog = Bootstrap.Dialog || {}; 3322 3323 /** 3324 * A collection of Drupal dialog handlers. 3325 * 3326 * @type {Object<String, Drupal.bootstrap.Dialog.Handler>} 3327 */ 3328 Bootstrap.Dialog.handlers = {}; 3329 3330 /** 3331 * @class Drupal.bootstrap.Dialog.Handler 3332 * 3333 * @param type 3334 * @param data 3335 */ 3336 Bootstrap.Dialog.Handler = function (type, data) { 3337 this.ctor = $.fn.modal; 3338 this.extend = null; 3339 this.plugin = 'modal'; 3340 this.prefix = 'modal'; 3341 this.themeHooks = { 3342 modal: 'bootstrapModal', 3343 dialog: 'bootstrapModalDialog', 3344 header: 'bootstrapModalHeader', 3345 title: 'bootstrapModalTitle', 3346 close: 'bootstrapModalClose', 3347 content: 'bootstrapModalContent', 3348 body: 'bootstrapModalBody', 3349 footer: 'bootstrapModalFooter', 3350 }; 3351 this.type = type; 3352 this.selectors = { 3353 dialog: '.modal-dialog', 3354 header: '.modal-header', 3355 title: '.modal-title', 3356 close: '.close', 3357 content: '.modal-content', 3358 body: '.modal-body', 3359 footer: '.modal-footer', 3360 buttons: '.modal-buttons' 3361 }; 3362 3363 // Extend the object with subclassed data. 3364 $.extend(this, data); 3365 3366 // Extend the jQuery plugin. 3367 if (this.extend) { 3368 Bootstrap.extend(this.plugin, this.extend); 3369 } 3370 }; 3371 3372 /** 3373 * Retrieves a Drupal dialog type handler. 3374 * 3375 * @param {String|HTMLElement|jQuery} type 3376 * The dialog type to retrieve. 3377 * 3378 * @return {Drupal.bootstrap.Dialog.Handler} 3379 * A Bootstrap.Dialog.Handler instance. 3380 */ 3381 Bootstrap.Dialog.Handler.get = function (type) { 3382 if (type instanceof $) { 3383 type = type[0]; 3384 } 3385 if (type instanceof HTMLElement) { 3386 type = type.dialogType; 3387 } 3388 if (!type) { 3389 type = 'modal'; 3390 } 3391 if (!Bootstrap.Dialog.handlers[type]) { 3392 Bootstrap.Dialog.handlers[type] = new Bootstrap.Dialog.Handler(); 3393 } 3394 return Bootstrap.Dialog.handlers[type]; 3395 }; 3396 3397 /** 3398 * Registers a Drupal dialog type handler. 3399 * 3400 * @param {String} type 3401 * The dialog type to 3402 * @param {Object} [data] 3403 * Optional. Additional data to use to create the dialog handler. By 3404 * default, this assumes values relative to the Bootstrap Modal plugin. 3405 */ 3406 Bootstrap.Dialog.Handler.register = function (type, data) { 3407 Bootstrap.Dialog.handlers[type] = new Bootstrap.Dialog.Handler(type, data); 3408 }; 3409 3410 Bootstrap.Dialog.Handler.prototype.invoke = function (context) { 3411 var args = Array.prototype.slice.call(arguments); 3412 return this.ctor.apply(context, args.slice(1)); 3413 }; 3414 3415 Bootstrap.Dialog.Handler.prototype.theme = function (hook) { 3416 var args = Array.prototype.slice.call(arguments); 3417 return $(Drupal.theme.apply(Drupal.theme, [this.themeHooks[hook]].concat(args.slice(1)))); 3418 }; 3419 3420 /** 3421 * Ensures a DOM element has the appropriate structure for a modal. 3422 * 3423 * Note: this can get a little tricky. Core potentially already 3424 * semi-processes a "dialog" if was created using an Ajax command 3425 * (i.e. prepareDialogButtons in drupal.ajax.js). Because of this, the 3426 * contents (HTML) of the existing element cannot simply be dumped into a 3427 * newly created modal. This would destroy any existing event bindings. 3428 * Instead, the contents must be "moved" (appended) to the new modal and 3429 * then "moved" again back to the to the existing container as needed. 3430 * 3431 * @param {HTMLElement|jQuery} element 3432 * The element to ensure is a modal structure. 3433 * @param {Object} options 3434 * THe dialog options to use to construct the modal. 3435 */ 3436 Bootstrap.Dialog.Handler.prototype.ensureModalStructure = function (element, options) { 3437 var $element = $(element); 3438 3439 // Immediately return if the modal was already converted into a proper modal. 3440 if ($element.is('[data-drupal-theme="' + this.themeHooks.modal + '"]')) { 3441 return; 3442 } 3443 3444 var attributes = Attributes.create(element).remove('style').set('data-drupal-theme', this.themeHooks.modal); 3445 3446 // Merge in trigger data attributes. 3447 if (options.$trigger && options.$trigger[0]) { 3448 /** @var {HTMLElement} trigger */ 3449 var trigger = options.$trigger[0]; 3450 var data = {}; 3451 for (var i = 0, l = trigger.attributes.length; i < l; i++) { 3452 var name = trigger.attributes[i].name; 3453 if (name && name.substring(0, 5) === 'data-') { 3454 data[name] = trigger.getAttribute(name); 3455 } 3456 } 3457 attributes.merge(data); 3458 } 3459 3460 options = $.extend(true, {}, options, { 3461 attributes: attributes, 3462 }); 3463 3464 // Create a new modal. 3465 var $modal = this.theme('modal', options); 3466 3467 // Store a reference to the content inside the existing element container. 3468 // This references the actual DOM node elements which will allow 3469 // jQuery to "move" then when appending below. Using $.fn.children() 3470 // does not return any text nodes present and $.fn.html() only returns 3471 // a string representation of the content, which effectively destroys 3472 // any prior event bindings or processing. 3473 var $body = $element.find(this.selectors.body); 3474 var $existing = $body[0] ? $body.contents() : $element.contents(); 3475 3476 // Set the attributes of the dialog to that of the newly created modal. 3477 $element.attr(Attributes.create($modal).toPlainObject()); 3478 3479 // Append the newly created modal markup. 3480 $element.append($modal.html()); 3481 3482 // Move the existing HTML into the modal markup that was just appended. 3483 $element.find(this.selectors.body).append($existing); 3484 }; 3485 3486})(jQuery, Drupal, Drupal.bootstrap, Attributes); 3487; 3488/*! jQuery UI - v1.12.1 - 2017-03-31 3489* http://jqueryui.com 3490* Copyright jQuery Foundation and other contributors; Licensed */ 3491!function(a){"function"==typeof define&&define.amd?define(["jquery","./version"],a):a(jQuery)}(function(a){return a.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase())});; 3492/*! jQuery UI - v1.12.1 - 2017-03-31 3493* http://jqueryui.com 3494* Copyright jQuery Foundation and other contributors; Licensed */ 3495!function(a){"function"==typeof define&&define.amd?define(["jquery","../ie","../version","../widget"],a):a(jQuery)}(function(a){var b=!1;return a(document).on("mouseup",function(){b=!1}),a.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var b=this;this.element.on("mousedown."+this.widgetName,function(a){return b._mouseDown(a)}).on("click."+this.widgetName,function(c){if(!0===a.data(c.target,b.widgetName+".preventClickEvent"))return a.removeData(c.target,b.widgetName+".preventClickEvent"),c.stopImmediatePropagation(),!1}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(c){if(!b){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(c),this._mouseDownEvent=c;var d=this,e=1===c.which,f=!("string"!=typeof this.options.cancel||!c.target.nodeName)&&a(c.target).closest(this.options.cancel).length;return!(e&&!f&&this._mouseCapture(c))||(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){d.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(c)&&this._mouseDelayMet(c)&&(this._mouseStarted=this._mouseStart(c)!==!1,!this._mouseStarted)?(c.preventDefault(),!0):(!0===a.data(c.target,this.widgetName+".preventClickEvent")&&a.removeData(c.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(a){return d._mouseMove(a)},this._mouseUpDelegate=function(a){return d._mouseUp(a)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),c.preventDefault(),b=!0,!0))}},_mouseMove:function(b){if(this._mouseMoved){if(a.ui.ie&&(!document.documentMode||document.documentMode<9)&&!b.button)return this._mouseUp(b);if(!b.which)if(b.originalEvent.altKey||b.originalEvent.ctrlKey||b.originalEvent.metaKey||b.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(b)}return(b.which||b.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(b),b.preventDefault()):(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b)),!this._mouseStarted)},_mouseUp:function(c){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,c.target===this._mouseDownEvent.target&&a.data(c.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(c)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,b=!1,c.preventDefault()},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})});;
vendor: 5,705 bytes, lines 3496-3499
3496/*! jQuery UI - v1.12.1 - 2017-03-31 3497* http://jqueryui.com 3498* Copyright jQuery Foundation and other contributors; Licensed */ 3499!function(a){"function"==typeof define&&define.amd?define(["jquery","./mouse","../data","../plugin","../safe-active-element","../safe-blur","../scroll-parent","../version","../widget"],a):a(jQuery)}(function(a){return a.widget("ui.draggable",a.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(a,b){this._super(a,b),"handle"===a&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?void(this.destroyOnClear=!0):(this._removeHandleClassName(),void this._mouseDestroy())},_mouseCapture:function(b){var c=this.options;return!(this.helper||c.disabled||a(b.target).closest(".ui-resizable-handle").length>0)&&(this.handle=this._getHandle(b),!!this.handle&&(this._blurActiveElement(b),this._blockFrames(c.iframeFix===!0?"iframe":c.iframeFix),!0))},_blockFrames:function(b){this.iframeBlocks=this.document.find(b).map(function(){var b=a(this);return a("<div>").css("position","absolute").appendTo(b.parent()).outerWidth(b.outerWidth()).outerHeight(b.outerHeight()).offset(b.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(b){var c=a.ui.safeActiveElement(this.document[0]),d=a(b.target);d.closest(c).length||a.ui.safeBlur(c)},_mouseStart:function(b){var c=this.options;return this.helper=this._createHelper(b),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===a(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(b),this.originalPosition=this.position=this._generatePosition(b,!1),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),this._setContainment(),this._trigger("start",b)===!1?(this._clear(),!1):(this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b),!0)},_refreshOffsets:function(a){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:a.pageX-this.offset.left,top:a.pageY-this.offset.top}},_mouseDrag:function(b,c){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(b,!0),this.positionAbs=this._convertPositionTo("absolute"),!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1)return this._mouseUp(new a.Event("mouseup",b)),!1;this.position=d.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),!1},_mouseStop:function(b){var c=this,d=!1;return a.ui.ddmanager&&!this.options.dropBehaviour&&(d=a.ui.ddmanager.drop(this,b)),this.dropped&&(d=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!d||"valid"===this.options.revert&&d||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d)?a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",b)!==!1&&c._clear()}):this._trigger("stop",b)!==!1&&this._clear(),!1},_mouseUp:function(b){return this._unblockFrames(),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b),this.handleElement.is(b.target)&&this.element.trigger("focus"),a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new a.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(b){return!this.options.handle||!!a(b.target).closest(this.element.find(this.options.handle)).length},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper),e=d?a(c.helper.apply(this.element[0],[b])):"clone"===c.helper?this.element.clone().removeAttr("id"):this.element;return e.parents("body").length||e.appendTo("parent"===c.appendTo?this.element[0].parentNode:c.appendTo),d&&e[0]===this.element[0]&&this._setPositionRelative(),e[0]===this.element[0]||/(fixed|absolute)/.test(e.css("position"))||e.css("position","absolute"),e},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(b){"string"==typeof b&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}
vendor: 4,649 bytes, line 3499
3499),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_isRootNode:function(a){return/(html|body)/i.test(a.tagName)||a===this.document[0]},_getParentOffset:function(){var b=this.offsetParent.offset(),c=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==c&&a.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(b={top:0,left:0}),{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var a=this.element.position(),b=this._isRootNode(this.scrollParent[0]);return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+(b?0:this.scrollParent.scrollTop()),left:a.left-(parseInt(this.helper.css("left"),10)||0)+(b?0:this.scrollParent.scrollLeft())}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b,c,d,e=this.options,f=this.document[0];return this.relativeContainer=null,e.containment?"window"===e.containment?void(this.containment=[a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,a(window).scrollLeft()+a(window).width()-this.helperProportions.width-this.margins.left,a(window).scrollTop()+(a(window).height()||f.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):"document"===e.containment?void(this.containment=[0,0,a(f).width()-this.helperProportions.width-this.margins.left,(a(f).height()||f.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]):e.containment.constructor===Array?void(this.containment=e.containment):("parent"===e.containment&&(e.containment=this.helper[0].parentNode),c=a(e.containment),d=c[0],void(d&&(b=/(scroll|auto)/.test(c.css("overflow")),this.containment=[(parseInt(c.css("borderLeftWidth"),10)||0)+(parseInt(c.css("paddingLeft"),10)||0),(parseInt(c.css("borderTopWidth"),10)||0)+(parseInt(c.css("paddingTop"),10)||0),(b?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(c.css("borderRightWidth"),10)||0)-(parseInt(c.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(b?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(c.css("borderBottomWidth"),10)||0)-(parseInt(c.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=c))):void(this.containment=null)},_convertPositionTo:function(a,b){b||(b=this.position);var c="absolute"===a?1:-1,d=this._isRootNode(this.scrollParent[0]);return{top:b.top+this.offset.relative.top*c+this.offset.parent.top*c-("fixed"===this.cssPosition?-this.offset.scroll.top:d?0:this.offset.scroll.top)*c,left:b.left+this.offset.relative.left*c+this.offset.parent.left*c-("fixed"===this.cssPosition?-this.offset.scroll.left:d?0:this.offset.scroll.left)*c}},_generatePosition:function(a,b){var c,d,e,f,g=this.options,h=this._isRootNode(this.scrollParent[0]),i=a.pageX,j=a.pageY;return h&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),b&&(this.containment&&(this.relativeContainer?(d=this.relativeContainer.offset(),c=[this.containment[0]+d.left,this.containment[1]+d.top,this.containment[2]+d.left,this.containment[3]+d.top]):c=this.containment,a.pageX-this.offset.click.left<c[0]&&(i=c[0]+this.offset.click.left),a.pageY-this.offset.click.top<c[1]&&(j=c[1]+this.offset.click.top),a.pageX-this.offset.click.left>c[2]&&(i=c[2]+this.offset.click.left),a.pageY-this.offset.click.top>c[3]&&(j=c[3]+this.offset.click.top)),g.grid&&(e=g.grid[1]?this.originalPageY+Math.round((j-this.originalPageY)/g.grid[1])*g.grid[1]:this.originalPageY,j=c?e-this.offset.click.top>=c[1]||e-this.offset.click.top>c[3]?e:e-this.offset.click.top>=c[1]?e-g.grid[1]:e+g.grid[1]:e,f=g.grid[0]?this.originalPageX+Math.round((i-this.originalPageX)
vendor: 5,728 bytes, line 3499
3499/g.grid[0])*g.grid[0]:this.originalPageX,i=c?f-this.offset.click.left>=c[0]||f-this.offset.click.left>c[2]?f:f-this.offset.click.left>=c[0]?f-g.grid[0]:f+g.grid[0]:f),"y"===g.axis&&(i=this.originalPageX),"x"===g.axis&&(j=this.originalPageY)),{top:j-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:h?0:this.offset.scroll.top),left:i-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:h?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(b,c,d){return d=d||this._uiHash(),a.ui.plugin.call(this,b,[c,d,this],!0),/^(drag|start|stop)/.test(b)&&(this.positionAbs=this._convertPositionTo("absolute"),d.offset=this.positionAbs),a.Widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),a.ui.plugin.add("draggable","connectToSortable",{start:function(b,c,d){var e=a.extend({},c,{item:d.element});d.sortables=[],a(d.options.connectToSortable).each(function(){var c=a(this).sortable("instance");c&&!c.options.disabled&&(d.sortables.push(c),c.refreshPositions(),c._trigger("activate",b,e))})},stop:function(b,c,d){var e=a.extend({},c,{item:d.element});d.cancelHelperRemoval=!1,a.each(d.sortables,function(){var a=this;a.isOver?(a.isOver=0,d.cancelHelperRemoval=!0,a.cancelHelperRemoval=!1,a._storedCSS={position:a.placeholder.css("position"),top:a.placeholder.css("top"),left:a.placeholder.css("left")},a._mouseStop(b),a.options.helper=a.options._helper):(a.cancelHelperRemoval=!0,a._trigger("deactivate",b,e))})},drag:function(b,c,d){a.each(d.sortables,function(){var e=!1,f=this;f.positionAbs=d.positionAbs,f.helperProportions=d.helperProportions,f.offset.click=d.offset.click,f._intersectsWith(f.containerCache)&&(e=!0,a.each(d.sortables,function(){return this.positionAbs=d.positionAbs,this.helperProportions=d.helperProportions,this.offset.click=d.offset.click,this!==f&&this._intersectsWith(this.containerCache)&&a.contains(f.element[0],this.element[0])&&(e=!1),e})),e?(f.isOver||(f.isOver=1,d._parent=c.helper.parent(),f.currentItem=c.helper.appendTo(f.element).data("ui-sortable-item",!0),f.options._helper=f.options.helper,f.options.helper=function(){return c.helper[0]},b.target=f.currentItem[0],f._mouseCapture(b,!0),f._mouseStart(b,!0,!0),f.offset.click.top=d.offset.click.top,f.offset.click.left=d.offset.click.left,f.offset.parent.left-=d.offset.parent.left-f.offset.parent.left,f.offset.parent.top-=d.offset.parent.top-f.offset.parent.top,d._trigger("toSortable",b),d.dropped=f.element,a.each(d.sortables,function(){this.refreshPositions()}),d.currentItem=d.element,f.fromOutside=d),f.currentItem&&(f._mouseDrag(b),c.position=f.position)):f.isOver&&(f.isOver=0,f.cancelHelperRemoval=!0,f.options._revert=f.options.revert,f.options.revert=!1,f._trigger("out",b,f._uiHash(f)),f._mouseStop(b,!0),f.options.revert=f.options._revert,f.options.helper=f.options._helper,f.placeholder&&f.placeholder.remove(),c.helper.appendTo(d._parent),d._refreshOffsets(b),c.position=d._generatePosition(b,!0),d._trigger("fromSortable",b),d.dropped=!1,a.each(d.sortables,function(){this.refreshPositions()}))})}}),a.ui.plugin.add("draggable","cursor",{start:function(b,c,d){var e=a("body"),f=d.options;e.css("cursor")&&(f._cursor=e.css("cursor")),e.css("cursor",f.cursor)},stop:function(b,c,d){var e=d.options;e._cursor&&a("body").css("cursor",e._cursor)}}),a.ui.plugin.add("draggable","opacity",{start:function(b,c,d){var e=a(c.helper),f=d.options;e.css("opacity")&&(f._opacity=e.css("opacity")),e.css("opacity",f.opacity)},stop:function(b,c,d){var e=d.options;e._opacity&&a(c.helper).css("opacity",e._opacity)}}),a.ui.plugin.add("draggable","scroll",{start:function(a,b,c){c.scrollParentNotHidden||(c.scrollParentNotHidden=c.helper.scrollParent(!1)),c.scrollParentNotHidden[0]!==c.document[0]&&"HTML"!==c.scrollParentNotHidden[0].tagName&&(c.overflowOffset=c.scrollParentNotHidden.offset())},drag:function(b,c,d){var e=d.options,f=!1,g=d.scrollParentNotHidden[0],h=d.document[0];g!==h&&"HTML"!==g.tagName?(e.axis&&"x"===e.axis||(d.overflowOffset.top+g.offsetHeight-b.pageY<e.scrollSensitivity?g.scrollTop=f=g.scrollTop+e.scrollSpeed:b.pageY-d.overflowOffset.top<e.scrollSensitivity&&(g.scrollTop=f=g.scrollTop-e.scrollSpeed)),e.axis&&"y"===e.axis||(d.overflowOffset.left+g.offsetWidth-b.pageX<e.scrollSensitivity?g.scrollLeft=f=g.scrollLeft+e.scrollSpeed:b.pageX-d.overflowOffset.left<e.scrollSensitivity&&(g.scrollLeft=f=g.scrollLeft-e.scrollSpeed))):(e.axis&&"x"===e.axis||(b.pageY-a(h).scrollTop()<e.scrollSensitivity?f=a(h).scrollTop(a(h).scrollTop()-e.scrollSpeed):a(window).height()-(b.pageY-a(h).scrollTop())<e.scrollSensitivity&&(f=a(h).scrollTop(a(h).scrollTop()+e.scrollSpeed))),e.axis&&"y"===e.axis||(b.pageX-a(h).scrollLeft()<e.scrollSensitivity?f=a(h).scrollLeft(a(h).scrollLeft()-e.scrollSpeed):a(window).width()-(b.pageX-a(h).scrollLeft())<e.scrollSensitivity&&(f=a(h).scrollLeft(a(h).scrollLeft()+e.scrollSpeed)))),f!==!1&&a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(d,b)}}),a.ui.plugin.add("draggable","snap",{start:function(b,c,d){var e=d.options;d.snapElements=[],a(e.snap.constructor!==String?e.snap.items||":data(ui-draggable)":e.snap).each(function(){var b=a(this),c=b.offset();this!==d.element[0]&&d.snapElements.push({item:this,width:b.outerWidth(),height:b.outerHeight(),top:c.top,left
vendor: 5,816 bytes, lines 3499-3503
3499:c.left})})},drag:function(b,c,d){var e,f,g,h,i,j,k,l,m,n,o=d.options,p=o.snapTolerance,q=c.offset.left,r=q+d.helperProportions.width,s=c.offset.top,t=s+d.helperProportions.height;for(m=d.snapElements.length-1;m>=0;m--)i=d.snapElements[m].left-d.margins.left,j=i+d.snapElements[m].width,k=d.snapElements[m].top-d.margins.top,l=k+d.snapElements[m].height,r<i-p||q>j+p||t<k-p||s>l+p||!a.contains(d.snapElements[m].item.ownerDocument,d.snapElements[m].item)?(d.snapElements[m].snapping&&d.options.snap.release&&d.options.snap.release.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[m].item})),d.snapElements[m].snapping=!1):("inner"!==o.snapMode&&(e=Math.abs(k-t)<=p,f=Math.abs(l-s)<=p,g=Math.abs(i-r)<=p,h=Math.abs(j-q)<=p,e&&(c.position.top=d._convertPositionTo("relative",{top:k-d.helperProportions.height,left:0}).top),f&&(c.position.top=d._convertPositionTo("relative",{top:l,left:0}).top),g&&(c.position.left=d._convertPositionTo("relative",{top:0,left:i-d.helperProportions.width}).left),h&&(c.position.left=d._convertPositionTo("relative",{top:0,left:j}).left)),n=e||f||g||h,"outer"!==o.snapMode&&(e=Math.abs(k-s)<=p,f=Math.abs(l-t)<=p,g=Math.abs(i-q)<=p,h=Math.abs(j-r)<=p,e&&(c.position.top=d._convertPositionTo("relative",{top:k,left:0}).top),f&&(c.position.top=d._convertPositionTo("relative",{top:l-d.helperProportions.height,left:0}).top),g&&(c.position.left=d._convertPositionTo("relative",{top:0,left:i}).left),h&&(c.position.left=d._convertPositionTo("relative",{top:0,left:j-d.helperProportions.width}).left)),!d.snapElements[m].snapping&&(e||f||g||h||n)&&d.options.snap.snap&&d.options.snap.snap.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[m].item})),d.snapElements[m].snapping=e||f||g||h||n)}}),a.ui.plugin.add("draggable","stack",{start:function(b,c,d){var e,f=d.options,g=a.makeArray(a(f.stack)).sort(function(b,c){return(parseInt(a(b).css("zIndex"),10)||0)-(parseInt(a(c).css("zIndex"),10)||0)});g.length&&(e=parseInt(a(g[0]).css("zIndex"),10)||0,a(g).each(function(b){a(this).css("zIndex",e+b)}),this.css("zIndex",e+g.length))}}),a.ui.plugin.add("draggable","zIndex",{start:function(b,c,d){var e=a(c.helper),f=d.options;e.css("zIndex")&&(f._zIndex=e.css("zIndex")),e.css("zIndex",f.zIndex)},stop:function(b,c,d){var e=d.options;e._zIndex&&a(c.helper).css("zIndex",e._zIndex)}}),a.ui.draggable});; 3500/*! jQuery UI - v1.12.1 - 2017-03-31 3501* http://jqueryui.com 3502* Copyright jQuery Foundation and other contributors; Licensed */ 3503!function(a){"function"==typeof define&&define.amd?define(["jquery","./version"],a):a(jQuery)}(function(a){return function(){function b(a,b,c){return[parseFloat(a[0])*(l.test(a[0])?b/100:1),parseFloat(a[1])*(l.test(a[1])?c/100:1)]}function c(b,c){return parseInt(a.css(b,c),10)||0}function d(b){var c=b[0];return 9===c.nodeType?{width:b.width(),height:b.height(),offset:{top:0,left:0}}:a.isWindow(c)?{width:b.width(),height:b.height(),offset:{top:b.scrollTop(),left:b.scrollLeft()}}:c.preventDefault?{width:0,height:0,offset:{top:c.pageY,left:c.pageX}}:{width:b.outerWidth(),height:b.outerHeight(),offset:b.offset()}}var e,f=Math.max,g=Math.abs,h=/left|center|right/,i=/top|center|bottom/,j=/[\+\-]\d+(\.[\d]+)?%?/,k=/^\w+/,l=/%$/,m=a.fn.position;a.position={scrollbarWidth:function(){if(void 0!==e)return e;var b,c,d=a("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),f=d.children()[0];return a("body").append(d),b=f.offsetWidth,d.css("overflow","scroll"),c=f.offsetWidth,b===c&&(c=d[0].clientWidth),d.remove(),e=b-c},getScrollInfo:function(b){var c=b.isWindow||b.isDocument?"":b.element.css("overflow-x"),d=b.isWindow||b.isDocument?"":b.element.css("overflow-y"),e="scroll"===c||"auto"===c&&b.width<b.element[0].scrollWidth,f="scroll"===d||"auto"===d&&b.height<b.element[0].scrollHeight;return{width:f?a.position.scrollbarWidth():0,height:e?a.position.scrollbarWidth():0}},getWithinInfo:function(b){var c=a(b||window),d=a.isWindow(c[0]),e=!!c[0]&&9===c[0].nodeType,f=!d&&!e;return{element:c,isWindow:d,isDocument:e,offset:f?a(b).offset():{left:0,top:0},scrollLeft:c.scrollLeft(),scrollTop:c.scrollTop(),width:c.outerWidth(),height:c.outerHeight()}}},a.fn.position=function(e){if(!e||!e.of)return m.apply(this,arguments);e=a.extend({},e);var l,n,o,p,q,r,s=a(e.of),t=a.position.getWithinInfo(e.within),u=a.position.getScrollInfo(t),v=(e.collision||"flip").split(" "),w={};return r=d(s),s[0].preventDefault&&(e.at="left top"),n=r.width,o=r.height,p=r.offset,q=a.extend({},p),a.each(["my","at"],function(){var a,b,c=(e[this]||"").split(" ");1===c.length&&(c=h.test(c[0])?c.concat(["center"]):i.test(c[0])?["center"].concat(c):["center","center"]),c[0]=h.test(c[0])?c[0]:"center",c[1]=i.test(c[1])?c[1]:"center",a=j.exec(c[0]),b=j.exec(c[1]),w[this]=[a?a[0]:0,b?b[0]:0],e[this]=[k.exec(c[0])[0],k.exec(c[1])[0]]}),1===v.length&&(v[1]=v[0]),"right"===e.at[0]?q.left+=n:"center"===e.at[0]&&(q.left+=n/2),"bottom"===e.at[1]?q.top+=o:"center"===e.at[1]&&(q.top+=o/2),l=b(w.at,n,o),q.left+=l[0],q.top+=l[1],this.each(function(){var d,h,i=a(this),j=i.outerWidth(),k=i.outerHeight(),m=c(this,"marginLeft"),r=c(this,"marginTop"),x=j+m+c(this,"marginRight")+u.width,y=k+r+c(this,"marginBottom")+u.height,z=a.extend({},q),A=b(w.my,i.outerWidth(),i.outerHeight());"right"===e.my[0]?z.left-=j:"center"===e.my[0]&&(z.left-=j/2),"bottom"===e.my[1]?z.top-=k:"center"===e.my[1]&&(z.top-=k/2),z.left+=A[0],z.top+=A[1],d={marginLeft:m,marginTop:r},a.each(["left","top"],function(b,c){a.ui.position[v[b]]&&a.ui.position[v[b]][c](z,{targetWidth:n,targetHeight:o,elemWidth:j,elemHeight:k,collisionPosition:d,collisionWidth:x,collisionHeight:y,offset:[l[0]+A[0],l[1]+A[1]],my:e.my,at:e.at,within:t,elem:i})}),e.using&&(h=function(a){var b=p.left-z.left,c=b+n-j,d=p.top-z.to
vendor: 1,339 bytes, line 3503
3503p,h=d+o-k,l={target:{element:s,left:p.left,top:p.top,width:n,height:o},element:{element:i,left:z.left,top:z.top,width:j,height:k},horizontal:c<0?"left":b>0?"right":"center",vertical:h<0?"top":d>0?"bottom":"middle"};n<j&&g(b+c)<n&&(l.horizontal="center"),o<k&&g(d+h)<o&&(l.vertical="middle"),f(g(b),g(c))>f(g(d),g(h))?l.important="horizontal":l.important="vertical",e.using.call(this,a,l)}),i.offset(a.extend(z,{using:h}))})},a.ui.position={fit:{left:function(a,b){var c,d=b.within,e=d.isWindow?d.scrollLeft:d.offset.left,g=d.width,h=a.left-b.collisionPosition.marginLeft,i=e-h,j=h+b.collisionWidth-g-e;b.collisionWidth>g?i>0&&j<=0?(c=a.left+i+b.collisionWidth-g-e,a.left+=i-c):j>0&&i<=0?a.left=e:i>j?a.left=e+g-b.collisionWidth:a.left=e:i>0?a.left+=i:j>0?a.left-=j:a.left=f(a.left-h,a.left)},top:function(a,b){var c,d=b.within,e=d.isWindow?d.scrollTop:d.offset.top,g=b.within.height,h=a.top-b.collisionPosition.marginTop,i=e-h,j=h+b.collisionHeight-g-e;b.collisionHeight>g?i>0&&j<=0?(c=a.top+i+b.collisionHeight-g-e,a.top+=i-c):j>0&&i<=0?a.top=e:i>j?a.top=e+g-b.collisionHeight:a.top=e:i>0?a.top+=i:j>0?a.top-=j:a.top=f(a.top-h,a.top)}},flip:{left:function(a,b){var c,d,e=b.within,f=e.offset.left+e.scrollLeft,h=e.width,i=e.isWindow?e.scrollLeft:e.offset.left,j=a.left-b.collisionPosition.marginLeft,k=j-i,l=j+b.collisionWidth-h-i,m="left"
vendor: 5,361 bytes, lines 3503-3507
3503===b.my[0]?-b.elemWidth:"right"===b.my[0]?b.elemWidth:0,n="left"===b.at[0]?b.targetWidth:"right"===b.at[0]?-b.targetWidth:0,o=-2*b.offset[0];k<0?(c=a.left+m+n+o+b.collisionWidth-h-f,(c<0||c<g(k))&&(a.left+=m+n+o)):l>0&&(d=a.left-b.collisionPosition.marginLeft+m+n+o-i,(d>0||g(d)<l)&&(a.left+=m+n+o))},top:function(a,b){var c,d,e=b.within,f=e.offset.top+e.scrollTop,h=e.height,i=e.isWindow?e.scrollTop:e.offset.top,j=a.top-b.collisionPosition.marginTop,k=j-i,l=j+b.collisionHeight-h-i,m="top"===b.my[1],n=m?-b.elemHeight:"bottom"===b.my[1]?b.elemHeight:0,o="top"===b.at[1]?b.targetHeight:"bottom"===b.at[1]?-b.targetHeight:0,p=-2*b.offset[1];k<0?(d=a.top+n+o+p+b.collisionHeight-h-f,(d<0||d<g(k))&&(a.top+=n+o+p)):l>0&&(c=a.top-b.collisionPosition.marginTop+n+o+p-i,(c>0||g(c)<l)&&(a.top+=n+o+p))}},flipfit:{left:function(){a.ui.position.flip.left.apply(this,arguments),a.ui.position.fit.left.apply(this,arguments)},top:function(){a.ui.position.flip.top.apply(this,arguments),a.ui.position.fit.top.apply(this,arguments)}}}}(),a.ui.position});; 3504/*! jQuery UI - v1.12.1 - 2017-03-31 3505* http://jqueryui.com 3506* Copyright jQuery Foundation and other contributors; Licensed */ 3507!function(a){"function"==typeof define&&define.amd?define(["jquery","./mouse","../disable-selection","../plugin","../version","../widget"],a):a(jQuery)}(function(a){return a.widget("ui.resizable",a.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(a){return parseFloat(a)||0},_isNumber:function(a){return!isNaN(parseFloat(a))},_hasScroll:function(b,c){if("hidden"===a(b).css("overflow"))return!1;var d=c&&"left"===c?"scrollLeft":"scrollTop",e=!1;return b[d]>0||(b[d]=1,e=b[d]>0,b[d]=0,e)},_create:function(){var b,c=this.options,d=this;this._addClass("ui-resizable"),a.extend(this,{_aspectRatio:!!c.aspectRatio,aspectRatio:c.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:c.helper||c.ghost||c.animate?c.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(a("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,b={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(b),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(b),this._proportionallyResize()),this._setupHandles(),c.autoHide&&a(this.element).on("mouseenter",function(){c.disabled||(d._removeClass("ui-resizable-autohide"),d._handles.show())}).on("mouseleave",function(){c.disabled||d.resizing||(d._addClass("ui-resizable-autohide"),d._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var b,c=function(b){a(b).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(c(this.element),b=this.element,this.originalElement.css({position:b.css("position"),width:b.outerWidth(),height:b.outerHeight(),top:b.css("top"),left:b.css("left")}).insertAfter(b),b.remove()),this.originalElement.css("resize",this.originalResizeStyle),c(this.originalElement),this},_setOption:function(a,b){switch(this._super(a,b),a){case"handles":this._removeHandles(),this._setupHandles()}},_setupHandles:function(){var b,c,d,e,f,g=this.options,h=this;if(this.handles=g.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=a(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),d=this.handles.split(","),this.handles={},c=0;c<d.length;c++)b=a.trim(d[c]),e="ui-resizable-"+b,f=a("<div>"),this._addClass(f,"ui-resizable-handle "+e),f.css({zIndex:g.zIndex}),this.handles[b]=".ui-resizable-"+b,this.element.append(f);this._renderAxis=function(b){var c,d,e,f;b=b||this.element;for(c in this.handles)this.handles[c].constructor===String?this.handles[c]=this.element.children(this.handles[c]).first().show():(this.handles[c].jquery||this.handles[c].nodeType)&&(this.handles[c]=a(this.handles[c]),this._on(this.handles[c],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(d=a(this.handles[c],this.element),f=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth(),e=["padding",/ne|nw|n
vendor: 4,356 bytes, line 3507
3507/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join(""),b.css(e,f),this._proportionallyResize()),this._handles=this._handles.add(this.handles[c])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(f=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=f&&f[1]?f[1]:"se")}),g.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(b){var c,d,e=!1;for(c in this.handles)d=a(this.handles[c])[0],(d===b.target||a.contains(d,b.target))&&(e=!0);return!this.options.disabled&&e},_mouseStart:function(b){var c,d,e,f=this.options,g=this.element;return this.resizing=!0,this._renderProxy(),c=this._num(this.helper.css("left")),d=this._num(this.helper.css("top")),f.containment&&(c+=a(f.containment).scrollLeft()||0,d+=a(f.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:c,top:d},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:g.width(),height:g.height()},this.originalSize=this._helper?{width:g.outerWidth(),height:g.outerHeight()}:{width:g.width(),height:g.height()},this.sizeDiff={width:g.outerWidth()-g.width(),height:g.outerHeight()-g.height()},this.originalPosition={left:c,top:d},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio="number"==typeof f.aspectRatio?f.aspectRatio:this.originalSize.width/this.originalSize.height||1,e=a(".ui-resizable-"+this.axis).css("cursor"),a("body").css("cursor","auto"===e?this.axis+"-resize":e),this._addClass("ui-resizable-resizing"),this._propagate("start",b),!0},_mouseDrag:function(b){var c,d,e=this.originalMousePosition,f=this.axis,g=b.pageX-e.left||0,h=b.pageY-e.top||0,i=this._change[f];return this._updatePrevProperties(),!!i&&(c=i.apply(this,[b,g,h]),this._updateVirtualBoundaries(b.shiftKey),(this._aspectRatio||b.shiftKey)&&(c=this._updateRatio(c,b)),c=this._respectSize(c,b),this._updateCache(c),this._propagate("resize",b),d=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),a.isEmptyObject(d)||(this._updatePrevProperties(),this._trigger("resize",b,this.ui()),this._applyChanges()),!1)},_mouseStop:function(b){this.resizing=!1;var c,d,e,f,g,h,i,j=this.options,k=this;return this._helper&&(c=this._proportionallyResizeElements,d=c.length&&/textarea/i.test(c[0].nodeName),e=d&&this._hasScroll(c[0],"left")?0:k.sizeDiff.height,f=d?0:k.sizeDiff.width,g={width:k.helper.width()-f,height:k.helper.height()-e},h=parseFloat(k.element.css("left"))+(k.position.left-k.originalPosition.left)||null,i=parseFloat(k.element.css("top"))+(k.position.top-k.originalPosition.top)||null,j.animate||this.element.css(a.extend(g,{top:i,left:h})),k.helper.height(k.size.height),k.helper.width(k.size.width),this._helper&&!j.animate&&this._proportionallyResize()),a("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var a={};return this.position.top!==this.prevPosition.top&&(a.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(a.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(a.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(a.height=this.size.height+"px"),this.helper.css(a),a},_updateVirtualBoundaries:function(a){var b,c,d,e,f,g=this.options;f={minWidth:this._isNumber(g.minWidth)?g.minWidth:0,maxWidth:this._isNumber(g.maxWidth)?g.maxWidth:1/0,minHeight:this._isNumber(g.minHeight)?g.minHeight:0,maxHeight:this._isNumber(g.maxHeight)?g.maxHeight:1/0},(this._aspectRatio||a)&&(b=f.minHeight*this.aspectRatio,d=f.minWidth/this.aspectRatio,c=f.maxHeight*this.aspectRatio,e=f.maxWidth/this.aspectRatio,b>f.minWidth&&(f.minWidth=b),d>f.minHeight&&(f.minHeight=d),c<f.maxWidth&&(f.maxWidth=c),e<f.maxHeight&&(f.maxHeight=e)),this._vBoundaries=f},_updateCache:function(a){this.offset=this.helper.offset(),this._isNumber(a.left)&&(this.position.left
vendor: 9,403 bytes, line 3507
3507=a.left),this._isNumber(a.top)&&(this.position.top=a.top),this._isNumber(a.height)&&(this.size.height=a.height),this._isNumber(a.width)&&(this.size.width=a.width)},_updateRatio:function(a){var b=this.position,c=this.size,d=this.axis;return this._isNumber(a.height)?a.width=a.height*this.aspectRatio:this._isNumber(a.width)&&(a.height=a.width/this.aspectRatio),"sw"===d&&(a.left=b.left+(c.width-a.width),a.top=null),"nw"===d&&(a.top=b.top+(c.height-a.height),a.left=b.left+(c.width-a.width)),a},_respectSize:function(a){var b=this._vBoundaries,c=this.axis,d=this._isNumber(a.width)&&b.maxWidth&&b.maxWidth<a.width,e=this._isNumber(a.height)&&b.maxHeight&&b.maxHeight<a.height,f=this._isNumber(a.width)&&b.minWidth&&b.minWidth>a.width,g=this._isNumber(a.height)&&b.minHeight&&b.minHeight>a.height,h=this.originalPosition.left+this.originalSize.width,i=this.originalPosition.top+this.originalSize.height,j=/sw|nw|w/.test(c),k=/nw|ne|n/.test(c);return f&&(a.width=b.minWidth),g&&(a.height=b.minHeight),d&&(a.width=b.maxWidth),e&&(a.height=b.maxHeight),f&&j&&(a.left=h-b.minWidth),d&&j&&(a.left=h-b.maxWidth),g&&k&&(a.top=i-b.minHeight),e&&k&&(a.top=i-b.maxHeight),a.width||a.height||a.left||!a.top?a.width||a.height||a.top||!a.left||(a.left=null):a.top=null,a},_getPaddingPlusBorderDimensions:function(a){for(var b=0,c=[],d=[a.css("borderTopWidth"),a.css("borderRightWidth"),a.css("borderBottomWidth"),a.css("borderLeftWidth")],e=[a.css("paddingTop"),a.css("paddingRight"),a.css("paddingBottom"),a.css("paddingLeft")];b<4;b++)c[b]=parseFloat(d[b])||0,c[b]+=parseFloat(e[b])||0;return{height:c[0]+c[2],width:c[1]+c[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var a,b=0,c=this.helper||this.element;b<this._proportionallyResizeElements.length;b++)a=this._proportionallyResizeElements[b],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(a)),a.css({height:c.height()-this.outerDimensions.height||0,width:c.width()-this.outerDimensions.width||0})},_renderProxy:function(){var b=this.element,c=this.options;this.elementOffset=b.offset(),this._helper?(this.helper=this.helper||a("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(a,b){return{width:this.originalSize.width+b}},w:function(a,b){var c=this.originalSize,d=this.originalPosition;return{left:d.left+b,width:c.width-b}},n:function(a,b,c){var d=this.originalSize,e=this.originalPosition;return{top:e.top+c,height:d.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),"resize"!==b&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.ui.plugin.add("resizable","animate",{stop:function(b){var c=a(this).resizable("instance"),d=c.options,e=c._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&c._hasScroll(e[0],"left")?0:c.sizeDiff.height,h=f?0:c.sizeDiff.width,i={width:c.size.width-h,height:c.size.height-g},j=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,k=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null;c.element.animate(a.extend(i,k&&j?{top:k,left:j}:{}),{duration:d.animateDuration,easing:d.animateEasing,step:function(){var d={width:parseFloat(c.element.css("width")),height:parseFloat(c.element.css("height")),top:parseFloat(c.element.css("top")),left:parseFloat(c.element.css("left"))};e&&e.length&&a(e[0]).css({width:d.width,height:d.height}),c._updateCache(d),c._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(){var b,c,d,e,f,g,h,i=a(this).resizable("instance"),j=i.options,k=i.element,l=j.containment,m=l instanceof a?l.get(0):/parent/.test(l)?k.parent().get(0):l;m&&(i.containerElement=a(m),/document/.test(l)||l===document?(i.containerOffset={left:0,top:0},i.containerPosition={left:0,top:0},i.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight}):(b=a(m),c=[],a(["Top","Right","Left","Bottom"]).each(function(a,d){c[a]=i._num(b.css("padding"+d))}),i.containerOffset=b.offset(),i.containerPosition=b.position(),i.containerSize={height:b.innerHeight()-c[3],width:b.innerWidth()-c[1]},d=i.containerOffset,e=i.containerSize.height,f=i.containerSize.width,g=i._hasScroll(m,"left")?m.scrollWidth:f,h=i._hasScroll(m)?m.scrollHeight:e,i.parentData={element:m,left:d.left,top:d.top,width:g,height:h}))},resize:function(b){var c,d,e,f,g=a(this).resizable("instance"),h=g.options,i=g.containerOffset,j=g.position,k=g._aspectRatio||b.shiftKey,l={top:0,left:0},m=g.containerElement,n=!0;m[0]!==document&&/static/.test(m.css("position"))&&(l=i),j.left<(g._helper?i.left:0)&&(g.size.width=g.size.width+(g._helper?g.position.left-i.left:g.position.left-l.left),k&&(g.size.height=g.size.width/g.aspectRatio,n=!1),g.position.left=h.helper?i.left:0),j.top<(g._helper?i.top:0)&&(g.size.height=g.size.height+(g._helper?g.position.top-i.top:g.position.top),k&&(g.size.width=g.size.height*g.aspectRatio,n=!1),g.position.top=g._helper?i.top:0),e=g.containerElement.get(0)===g.element.parent().get(0),f=/relative|absolute/.test(g.containerElement.css("position")),e&&f?(g.offset.left=g.parentData.left+g.position.left,g.offset.top=g.parentData.top+g.position.top):(g.offset.left=g.element.offset().left,g.offset.top=g.element.offset().top),c=Math.abs(g.sizeDiff.width+(g._helper?g.offset.left-l.left:g.offset.left-i.left)),d=Math.abs(g.sizeDiff.height+(g._helper?g.offset.top-l.top:g.offset.top-i.top)),c+g.size.width>=g.parentData.width&&(g.size.width=g.parentData.width-c,k&&(g.size.height=g.size.width/g.aspectRatio,n=!1)),d+g.size.height>=g.parentData.height&&(g.size.height=g.parentData.height-d,k&&(g.size.width=g.size.height*g.aspectRatio,n=!1)),n||(g.position.left=g.prevPosition.left,g.position.top=g.prevPosition.top,g.size.width=g.prevSize.width,g.size.height=g.prevSize.height)},stop:function(){var b=a(this).resizable("instance"),c=b.options,d=b.containerOffset,e=b.containerPosition,f=b.containerElement,g=a(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width,j=g.outerHeight()-b.sizeDiff.height;b._helper&&!c.animate&&/relative/.test(f.css("position"))&&a(this).css({left:h.left-e.left-d.left,width:i,height:j}),b._helper&&!c.animate&&/static/.test(f.css("position"))&&a(this).css({left:h.left-e.left-d.left,width:i,height:j})}}),a.ui.plugin.add("resizable","alsoResize",{start:function(){var b=a(this).resizable("instance"),c=b.options;a(c.alsoResize).each(function(){var b=a(this);b.data("ui-resizable-alsoresize",{width:parseFloat(b.width()),height:parseFloat(b.height()),left:parseFloat(b.css("left")),top:parseFloat(b.css("top"))})})},resize:function(b,c){var d=a(this).resizable("instance"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0};a(e.alsoResize).each(function(){var b=a(this),d=a(this).data("ui-resizable-alsoresize"),e={},f=b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(f,function(a,b){var c=(d[b]||0)+(h[b]||0);c&&c>=0&&(e[b]=c||null)}),b.css(e)})},stop:function(){a(this).removeData("ui-resizable-alsoresize")}}),a.ui.plugin.add("resizable","ghost",{start:function(){var b=a(this).resizable("instance"),c=b.size;b.ghost=b.originalElement.clone(),b.ghost.css({opacity:.25,display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}),b._addClass(b.ghost,"ui-resizable-ghost"),a.uiBackCompat!==!1&&"string"==typeof b.options.ghost&&b.ghost.addClass(this.options.ghost),b.ghost.appendTo(b.helper)},resize:function(){var b=a(this).resizable("instance");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=a(this).resizable("instance");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(){var b,c=a(this).resizable("instance"),d=c.options,e=c.size,f=c.originalSize,g=c.originalPosition,h=c.axis,i="number"==typeof d.grid?[d.grid,d.grid]:d.grid,j=i[0]||1,k=i[1]||1,l=Math.round((e.width-f.width)/j)*j,m=Math.round((e.height-f.height)/k)*k,n=f.width+l,o=f.height+m,p=d.maxWidth&&d.maxWidth<n,q=d.maxHeight&&d.maxHeight<o,r=d.minWidth&&d.minWidth>n,s=d.minHeight&&d.minHeight>o;d.grid=i,r&&(n+=j),s&&(o+=k),p&&(n-=j),q&&(o-=k),/^(se|s|e)$/.test(h)?(c.size.width=n,c.size.height=o
3507):/^(ne)$/.test(h)?(c.size.width=n,c.size.height=o,c.position.top=g.top-m):/^(sw)$/.test(h)?(c.size.width=n,c.size.height=o,c.position.left=g.left-l):((o-k<=0||n-j<=0)&&(b=c._getPaddingPlusBorderDimensions(this)),o-k>0?(c.size.height=o,c.position.top=g.top-m):(o=k-b.height,c.size.height=o,c.position.top=g.top+f.height-o),n-j>0?(c.size.width=n,c.position.left=g.left-l):(n=j-b.width,c.size.width=n,c.position.left=g.left+f.width-n))}}),a.ui.resizable});; 3508/** 3509 * @file 3510 * Bootstrap Modals. 3511 * 3512 * @param {jQuery} $ 3513 * @param {Drupal} Drupal 3514 * @param {Drupal.bootstrap} Bootstrap 3515 * @param {Attributes} Attributes 3516 * @param {drupalSettings} drupalSettings 3517 */ 3518(function ($, Drupal, Bootstrap, Attributes, drupalSettings) { 3519 'use strict'; 3520 3521 /** 3522 * Only process this once. 3523 */ 3524 Bootstrap.once('modal.jquery.ui.bridge', function (settings) { 3525 // RTL support. 3526 var rtl = document.documentElement.getAttribute('dir').toLowerCase() === 'rtl'; 3527 3528 // Override drupal.dialog button classes. This must be done on DOM ready 3529 // since core/drupal.dialog technically depends on this file and has not 3530 // yet set their default settings. 3531 $(function () { 3532 drupalSettings.dialog.buttonClass = 'btn'; 3533 drupalSettings.dialog.buttonPrimaryClass = 'btn-primary'; 3534 }); 3535 3536 // Create the "dialog" plugin bridge. 3537 Bootstrap.Dialog.Bridge = function (options) { 3538 var args = Array.prototype.slice.call(arguments); 3539 var $element = $(this); 3540 var type = options && options.dialogType || $element[0].dialogType || 'modal'; 3541 3542 $element[0].dialogType = type; 3543 3544 var handler = Bootstrap.Dialog.Handler.get(type); 3545 3546 // When only options are passed, jQuery UI dialog treats this like a 3547 // initialization method. Destroy any existing Bootstrap modal and 3548 // recreate it using the contents of the dialog HTML. 3549 if (args.length === 1 && typeof options === 'object') { 3550 this.each(function () { 3551 handler.ensureModalStructure(this, options); 3552 }); 3553 3554 // Proxy to the Bootstrap Modal plugin, indicating that this is a 3555 // jQuery UI dialog bridge. 3556 return handler.invoke(this, { 3557 dialogOptions: options, 3558 jQueryUiBridge: true 3559 }); 3560 } 3561 3562 // Otherwise, proxy all arguments to the Bootstrap Modal plugin. 3563 var ret; 3564 try { 3565 ret = handler.invoke.apply(handler, [this].concat(args)); 3566 } 3567 catch (e) { 3568 Bootstrap.warn(e); 3569 } 3570 3571 // If just one element and there was a result returned for the option passed, 3572 // then return the result. Otherwise, just return the jQuery object. 3573 return this.length === 1 && ret !== void 0 ? ret : this; 3574 }; 3575 3576 // Assign the jQuery "dialog" plugin to use to the bridge. 3577 Bootstrap.createPlugin('dialog', Bootstrap.Dialog.Bridge); 3578 3579 // Create the "modal" plugin bridge. 3580 Bootstrap.Modal.Bridge = function () { 3581 var Modal = this; 3582 3583 return { 3584 DEFAULTS: { 3585 // By default, this option is disabled. It's only flagged when a modal 3586 // was created using $.fn.dialog above. 3587 jQueryUiBridge: false 3588 }, 3589 prototype: { 3590 3591 /** 3592 * Handler for $.fn.dialog('close'). 3593 */ 3594 close: function () { 3595 var _this = this; 3596 3597 this.hide.apply(this, arguments); 3598 3599 // For some reason (likely due to the transition event not being 3600 // registered properly), the backdrop doesn't always get removed 3601 // after the above "hide" method is invoked . Instead, ensure the 3602 // backdrop is removed after the transition duration by manually 3603 // invoking the internal "hideModal" method shortly thereafter. 3604 setTimeout(function () { 3605 if (!_this.isShown && _this.$backdrop) { 3606 _this.hideModal(); 3607 } 3608 }, (Modal.TRANSITION_DURATION !== void 0 ? Modal.TRANSITION_DURATION : 300) + 10); 3609 }, 3610 3611 /** 3612 * Creates any necessary buttons from dialog options. 3613 */ 3614 createButtons: function () { 3615 var handler = Bootstrap.Dialog.Handler.get(this.$element); 3616 this.$footer.find(handler.selectors.buttons).remove(); 3617 3618 // jQuery UI supports both objects and arrays. Unfortunately 3619 // developers have misunderstood and abused this by simply placing 3620 // the objects that should be in an array inside an object with 3621 // arbitrary keys (likely to target specific buttons as a hack). 3622 var buttons = this.options.dialogOptions && this.options.dialogOptions.buttons || []; 3623 if (!Array.isArray(buttons)) { 3624 var array = []; 3625 for (var k in buttons) {
3626 // Support the proper object values: label => click callback. 3627 if (typeof buttons[k] === 'function') { 3628 array.push({ 3629 label: k, 3630 click: buttons[k], 3631 }); 3632 } 3633 // Support nested objects, but log a warning. 3634 else if (buttons[k].text || buttons[k].label) { 3635 Bootstrap.warn('Malformed jQuery UI dialog button: @key. The button object should be inside an array.', { 3636 '@key': k 3637 }); 3638 array.push(buttons[k]); 3639 } 3640 else { 3641 Bootstrap.unsupported('button', k, buttons[k]); 3642 } 3643 } 3644 buttons = array; 3645 } 3646 3647 if (buttons.length) { 3648 var $buttons = $('<div class="modal-buttons"/>').appendTo(this.$footer); 3649 for (var i = 0, l = buttons.length; i < l; i++) { 3650 var button = buttons[i]; 3651 var $button = $(Drupal.theme('bootstrapModalDialogButton', button)); 3652 3653 // Invoke the "create" method for jQuery UI buttons. 3654 if (typeof button.create === 'function') { 3655 button.create.call($button[0]); 3656 } 3657 3658 // Bind the "click" method for jQuery UI buttons to the modal. 3659 if (typeof button.click === 'function') { 3660 $button.on('click', button.click.bind(this.$element)); 3661 } 3662 3663 $buttons.append($button); 3664 } 3665 } 3666 3667 // Toggle footer visibility based on whether it has child elements. 3668 this.$footer[this.$footer.children()[0] ? 'show' : 'hide'](); 3669 }, 3670 3671 /** 3672 * Initializes the Bootstrap Modal. 3673 */ 3674 init: function () { 3675 var handler = Bootstrap.Dialog.Handler.get(this.$element); 3676 if (!this.$dialog) { 3677 this.$dialog = this.$element.find(handler.selectors.dialog); 3678 } 3679 this.$dialog.addClass('js-drupal-dialog'); 3680 3681 if (!this.$header) { 3682 this.$header = this.$dialog.find(handler.selectors.header); 3683 } 3684 if (!this.$title) { 3685 this.$title = this.$dialog.find(handler.selectors.title); 3686 } 3687 if (!this.$close) { 3688 this.$close = this.$header.find(handler.selectors.close); 3689 } 3690 if (!this.$footer) { 3691 this.$footer = this.$dialog.find(handler.selectors.footer); 3692 } 3693 if (!this.$content) { 3694 this.$content = this.$dialog.find(handler.selectors.content); 3695 } 3696 if (!this.$dialogBody) { 3697 this.$dialogBody = this.$dialog.find(handler.selectors.body); 3698 } 3699 3700 // Relay necessary events. 3701 if (this.options.jQueryUiBridge) { 3702 this.$element.on('hide.bs.modal', Bootstrap.relayEvent(this.$element, 'dialogbeforeclose', false)); 3703 this.$element.on('hidden.bs.modal', Bootstrap.relayEvent(this.$element, 'dialogclose', false)); 3704 this.$element.on('show.bs.modal', Bootstrap.relayEvent(this.$element, 'dialogcreate', false)); 3705 this.$element.on('shown.bs.modal', Bootstrap.relayEvent(this.$element, 'dialogopen', false)); 3706 } 3707 3708 // Create a footer if one doesn't exist. 3709 // This is necessary in case dialog.ajax.js decides to add buttons. 3710 if (!this.$footer[0]) { 3711 this.$footer = handler.theme('footer', {}, true).insertAfter(this.$dialogBody); 3712 } 3713 3714 // Map the initial options. 3715 $.extend(true, this.options, this.mapDialogOptions(this.options)); 3716 3717 // Update buttons. 3718 this.createButtons(); 3719 3720 // Now call the parent init method. 3721 this.super(); 3722 3723 // Handle autoResize option (this is a drupal.dialog option). 3724 if (this.options.dialogOptions && this.options.dialogOptions.autoResize && this.options.dialogOptions.position) { 3725 this.position(this.options.dialogOptions.position); 3726 } 3727 3728 // If show is enabled and currently not shown, show it. 3729 if (this.options.jQueryUiBridge && this.options.show && !this.isShown) { 3730 this.show(); 3731 } 3732 }, 3733 3734 /** 3735 * Handler for $.fn.dialog('instance'). 3736 */ 3737 instance: function () { 3738 Bootstrap.unsupported('method', 'instance', arguments); 3739 }, 3740 3741 /** 3742 * Handler for $.fn.dialog('isOpen'). 3743 */ 3744 isOpen: function () { 3745 return !!this.isShown; 3746 }, 3747 3748 /** 3749 * Maps dialog options to the modal. 3750 * 3751 * @param {Object} options 3752 * The options to map. 3753 */ 3754 mapDialogOptions: function (options) { 3755 // Retrieve the dialog handler for this type. 3756 var handler = Bootstrap.Dialog.Handler.get(this.$element); 3757 3758 var mappedOptions = {}; 3759 var dialogOptions = options.dialogOptions || {}; 3760 3761 // Remove any existing dialog options. 3762 delete options.dialogOptions; 3763 3764 // Separate Bootstrap modal options from jQuery UI dialog options. 3765 for (var k in options) { 3766 if (Modal.DEFAULTS.hasOwnProperty(k)) { 3767 mappedOptions[k] = options[k]; 3768 } 3769 else { 3770 dialogOptions[k] = options[k]; 3771 } 3772 } 3773 3774 3775 // Handle CSS properties. 3776 var cssUnitRegExp = /^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)?$/; 3777 var parseCssUnit = function (value, defaultUnit) { 3778 var parts = ('' + value).match(cssUnitRegExp); 3779 return parts && parts[1] !== void 0 ? parts[1] + (parts[2] || defaultUnit || 'px') : null; 3780 }; 3781 var styles = {}; 3782 var cssProperties = ['height', 'maxHeight', 'maxWidth', 'minHeight', 'minWidth', 'width']; 3783 for (var i = 0, l = cssProperties.length; i < l; i++) { 3784 var prop = cssProperties[i]; 3785 if (dialogOptions[prop] !== void 0) { 3786 var value = parseCssUnit(dialogOptions[prop]); 3787 if (value) { 3788 styles[prop] = value; 3789 3790 // If there's a defined height of some kind, enforce the modal 3791 // to use flex (on modern browsers). This will ensure that 3792 // the core autoResize calculations don't cause the content 3793 // to overflow. 3794 if (dialogOptions.autoResize && (prop === 'height' || prop === 'maxHeight')) { 3795 styles.display = 'flex'; 3796 styles.flexDirection = 'column'; 3797 this.$dialogBody.css('overflow', 'scroll'); 3798 } 3799 } 3800 } 3801 } 3802
3803 // Apply mapped CSS styles to the modal-content container. 3804 this.$content.css(styles); 3805 3806 // Handle deprecated "dialogClass" option by merging it with "classes". 3807 var classesMap = { 3808 'ui-dialog': 'modal-content', 3809 'ui-dialog-titlebar': 'modal-header', 3810 'ui-dialog-title': 'modal-title', 3811 'ui-dialog-titlebar-close': 'close', 3812 'ui-dialog-content': 'modal-body', 3813 'ui-dialog-buttonpane': 'modal-footer' 3814 }; 3815 if (dialogOptions.dialogClass) { 3816 if (dialogOptions.classes === void 0) { 3817 dialogOptions.classes = {}; 3818 } 3819 if (dialogOptions.classes['ui-dialog'] === void 0) { 3820 dialogOptions.classes['ui-dialog'] = ''; 3821 } 3822 var dialogClass = dialogOptions.classes['ui-dialog'].split(' '); 3823 dialogClass.push(dialogOptions.dialogClass); 3824 dialogOptions.classes['ui-dialog'] = dialogClass.join(' '); 3825 delete dialogOptions.dialogClass; 3826 } 3827 3828 // Add jQuery UI classes to elements in case developers target them 3829 // in callbacks. 3830 for (k in classesMap) { 3831 this.$element.find('.' + classesMap[k]).addClass(k); 3832 } 3833 3834 // Bind events. 3835 var events = [ 3836 'beforeClose', 'close', 3837 'create', 3838 'drag', 'dragStart', 'dragStop', 3839 'focus', 3840 'open', 3841 'resize', 'resizeStart', 'resizeStop' 3842 ]; 3843 for (i = 0, l = events.length; i < l; i++) { 3844 var event = events[i].toLowerCase(); 3845 if (dialogOptions[event] === void 0 || typeof dialogOptions[event] !== 'function') continue; 3846 this.$element.on('dialog' + event, dialogOptions[event]); 3847 } 3848 3849 // Support title attribute on the modal. 3850 var title; 3851 if ((dialogOptions.title === null || dialogOptions.title === void 0) && (title = this.$element.attr('title'))) { 3852 dialogOptions.title = title; 3853 } 3854 3855 // Handle the reset of the options. 3856 for (var name in dialogOptions) { 3857 if (!dialogOptions.hasOwnProperty(name) || dialogOptions[name] === void 0) continue; 3858 3859 switch (name) { 3860 case 'appendTo': 3861 Bootstrap.unsupported('option', name, dialogOptions.appendTo); 3862 break; 3863 3864 case 'autoOpen': 3865 mappedOptions.show = dialogOptions.show = !!dialogOptions.autoOpen; 3866 break; 3867 3868 case 'classes': 3869 if (dialogOptions.classes) { 3870 for (var key in dialogOptions.classes) { 3871 if (dialogOptions.classes.hasOwnProperty(key) && classesMap[key] !== void 0) { 3872 // Run through Attributes to sanitize classes. 3873 var attributes = Attributes.create().addClass(dialogOptions.classes[key]).toPlainObject(); 3874 var selector = '.' + classesMap[key]; 3875 this.$element.find(selector).addClass(attributes['class']); 3876 } 3877 } 3878 } 3879 break; 3880 3881 case 'closeOnEscape': 3882 mappedOptions.keyboard = !!dialogOptions.closeOnEscape; 3883 if (!dialogOptions.closeOnEscape && dialogOptions.modal) { 3884 mappedOptions.backdrop = 'static'; 3885 } 3886 break; 3887 3888 case 'closeText': 3889 Bootstrap.unsupported('option', name, dialogOptions.closeText); 3890 break; 3891 3892 case 'draggable': 3893 this.$content 3894 .draggable({ 3895 handle: handler.selectors.header, 3896 drag: Bootstrap.relayEvent(this.$element, 'dialogdrag'), 3897 start: Bootstrap.relayEvent(this.$element, 'dialogdragstart'), 3898 end: Bootstrap.relayEvent(this.$element, 'dialogdragend') 3899 }) 3900 .draggable(dialogOptions.draggable ? 'enable' : 'disable'); 3901 break; 3902 3903 case 'hide': 3904 if (dialogOptions.hide === false || dialogOptions.hide === true) { 3905 this.$element[dialogOptions.hide ? 'addClass' : 'removeClass']('fade'); 3906 mappedOptions.animation = dialogOptions.hide; 3907 } 3908 else { 3909 Bootstrap.unsupported('option', name + ' (complex animation)', dialogOptions.hide); 3910 } 3911 break; 3912 3913 case 'modal': 3914 if (!dialogOptions.closeOnEscape && dialogOptions.modal) { 3915 mappedOptions.backdrop = 'static'; 3916 } 3917 else { 3918 mappedOptions.backdrop = dialogOptions.modal; 3919 } 3920
3921 // If not a modal and no initial position, center it. 3922 if (!dialogOptions.modal && !dialogOptions.position) { 3923 this.position({ my: 'center', of: window }); 3924 } 3925 break; 3926 3927 case 'position': 3928 this.position(dialogOptions.position); 3929 break; 3930 3931 // Resizable support (must initialize first). 3932 case 'resizable': 3933 this.$content 3934 .resizable({ 3935 resize: Bootstrap.relayEvent(this.$element, 'dialogresize'), 3936 start: Bootstrap.relayEvent(this.$element, 'dialogresizestart'), 3937 end: Bootstrap.relayEvent(this.$element, 'dialogresizeend') 3938 }) 3939 .resizable(dialogOptions.resizable ? 'enable' : 'disable'); 3940 break; 3941 3942 case 'show': 3943 if (dialogOptions.show === false || dialogOptions.show === true) { 3944 this.$element[dialogOptions.show ? 'addClass' : 'removeClass']('fade'); 3945 mappedOptions.animation = dialogOptions.show; 3946 } 3947 else { 3948 Bootstrap.unsupported('option', name + ' (complex animation)', dialogOptions.show); 3949 } 3950 break; 3951 3952 case 'title': 3953 this.$title.text(dialogOptions.title); 3954 break; 3955 3956 } 3957 } 3958 3959 // Add the supported dialog options to the mapped options. 3960 mappedOptions.dialogOptions = dialogOptions; 3961 3962 return mappedOptions; 3963 }, 3964 3965 /** 3966 * Handler for $.fn.dialog('moveToTop'). 3967 */ 3968 moveToTop: function () { 3969 Bootstrap.unsupported('method', 'moveToTop', arguments); 3970 }, 3971 3972 /** 3973 * Handler for $.fn.dialog('option'). 3974 */ 3975 option: function () { 3976 var clone = {options: {}}; 3977 3978 // Apply the parent option method to the clone of current options. 3979 this.super.apply(clone, arguments); 3980 3981 // Merge in the cloned mapped options. 3982 $.extend(true, this.options, this.mapDialogOptions(clone.options)); 3983 3984 // Update buttons. 3985 this.createButtons(); 3986 }, 3987 3988 position: function(position) { 3989 // Reset modal styling. 3990 this.$element.css({ 3991 bottom: 'initial', 3992 overflow: 'visible', 3993 right: 'initial' 3994 }); 3995 3996 // Position the modal. 3997 this.$element.position(position); 3998 }, 3999 4000 /** 4001 * Handler for $.fn.dialog('open'). 4002 */ 4003 open: function () { 4004 this.show.apply(this, arguments); 4005 }, 4006 4007 /** 4008 * Handler for $.fn.dialog('widget'). 4009 */ 4010 widget: function () { 4011 return this.$element; 4012 } 4013 } 4014 }; 4015 }; 4016 4017 // Extend the Bootstrap Modal plugin constructor class. 4018 Bootstrap.extendPlugin('modal', Bootstrap.Modal.Bridge); 4019 4020 // Register default core dialog type handlers. 4021 Bootstrap.Dialog.Handler.register('dialog'); 4022 Bootstrap.Dialog.Handler.register('modal'); 4023 4024 /** 4025 * Extend Drupal theming functions. 4026 */ 4027 $.extend(Drupal.theme, /** @lend Drupal.theme */ { 4028 4029 /** 4030 * Renders a jQuery UI Dialog compatible button element. 4031 * 4032 * @param {Object} button 4033 * The button object passed in the dialog options. 4034 * 4035 * @return {String} 4036 * The modal dialog button markup. 4037 * 4038 * @see http://api.jqueryui.com/dialog/#option-buttons 4039 * @see http://api.jqueryui.com/button/ 4040 */ 4041 bootstrapModalDialogButton: function (button) { 4042 var attributes = Attributes.create(); 4043 4044 var icon = ''; 4045 var iconPosition = button.iconPosition || 'beginning'; 4046 iconPosition = (iconPosition === 'end' && !rtl) || (iconPosition === 'beginning' && rtl) ? 'after' : 'before'; 4047 4048 // Handle Bootstrap icons differently. 4049 if (button.bootstrapIcon) { 4050 icon = Drupal.theme('icon', 'bootstrap', button.icon); 4051 } 4052 // Otherwise, assume it's a jQuery UI icon. 4053 // @todo Map jQuery UI icons to Bootstrap icons? 4054 else if (button.icon) { 4055 var iconAttributes = Attributes.create() 4056 .addClass(['ui-icon', button.icon]) 4057 .set('aria-hidden', 'true'); 4058 icon = '<span' + iconAttributes + '></span>'; 4059 } 4060 4061 // Label. Note: jQuery UI dialog has an inconsistency where it uses 4062 // "text" instead of "label", so both need to be supported. 4063 var value = button.label || button.text; 4064 4065 // Show/hide label. 4066 if (icon && ((button.showLabel !== void 0 && !button.showLabel) || (button.text !== void 0 && !button.text))) { 4067 value = '<span' + Attributes.create().addClass('sr-only') + '>
4067' + value + '</span>'; 4068 } 4069 attributes.set('value', iconPosition === 'before' ? icon + value : value + icon); 4070 4071 // Handle disabled. 4072 attributes[button.disabled ? 'set' :'remove']('disabled', 'disabled'); 4073 4074 if (button.classes) { 4075 attributes.addClass(Object.keys(button.classes).map(function(key) { return button.classes[key]; })); 4076 } 4077 if (button['class']) { 4078 attributes.addClass(button['class']); 4079 } 4080 if (button.primary) { 4081 attributes.addClass('btn-primary'); 4082 } 4083 4084 return Drupal.theme('button', attributes); 4085 } 4086 4087 }); 4088 4089 }); 4090 4091 4092})(window.jQuery, window.Drupal, window.Drupal.bootstrap, window.Attributes, window.drupalSettings); 4093; 4094/** 4095* DO NOT EDIT THIS FILE. 4096* See the following change record for more information, 4097* https://www.drupal.org/node/2815083 4098* @preserve 4099**/ 4100 4101(function ($, Drupal, drupalSettings) { 4102 drupalSettings.dialog = { 4103 autoOpen: true, 4104 dialogClass: '', 4105 4106 buttonClass: 'button', 4107 buttonPrimaryClass: 'button--primary', 4108 close: function close(event) { 4109 Drupal.dialog(event.target).close(); 4110 Drupal.detachBehaviors(event.target, null, 'unload'); 4111 } 4112 }; 4113 4114 Drupal.dialog = function (element, options) { 4115 var undef = void 0; 4116 var $element = $(element); 4117 var dialog = { 4118 open: false, 4119 returnValue: undef 4120 }; 4121 4122 function openDialog(settings) { 4123 settings = $.extend({}, drupalSettings.dialog, options, settings); 4124 4125 $(window).trigger('dialog:beforecreate', [dialog, $element, settings]); 4126 $element.dialog(settings); 4127 dialog.open = true; 4128 $(window).trigger('dialog:aftercreate', [dialog, $element, settings]); 4129 } 4130 4131 function closeDialog(value) { 4132 $(window).trigger('dialog:beforeclose', [dialog, $element]); 4133 $element.dialog('close'); 4134 dialog.returnValue = value; 4135 dialog.open = false; 4136 $(window).trigger('dialog:afterclose', [dialog, $element]); 4137 } 4138 4139 dialog.show = function () { 4140 openDialog({ modal: false }); 4141 }; 4142 dialog.showModal = function () { 4143 openDialog({ modal: true }); 4144 }; 4145 dialog.close = closeDialog; 4146 4147 return dialog; 4148 }; 4149})(jQuery, Drupal, drupalSettings);; 4150/** 4151* DO NOT EDIT THIS FILE. 4152* See the following change record for more information, 4153* https://www.drupal.org/node/2815083 4154* @preserve 4155**/ 4156 4157(function ($, Drupal, drupalSettings, debounce, displace) { 4158 drupalSettings.dialog = $.extend({ autoResize: true, maxHeight: '95%' }, drupalSettings.dialog); 4159 4160 function resetPosition(options) { 4161 var offsets = displace.offsets; 4162 var left = offsets.left - offsets.right; 4163 var top = offsets.top - offsets.bottom; 4164 4165 var leftString = (left > 0 ? '+' : '-') + Math.abs(Math.round(left / 2)) + 'px'; 4166 var topString = (top > 0 ? '+' : '-') + Math.abs(Math.round(top / 2)) + 'px'; 4167 options.position = { 4168 my: 'center' + (left !== 0 ? leftString : '') + ' center' + (top !== 0 ? topString : ''), 4169 of: window 4170 }; 4171 return options; 4172 } 4173 4174 function resetSize(event) { 4175 var positionOptions = ['width', 'height', 'minWidth', 'minHeight', 'maxHeight', 'maxWidth', 'position']; 4176 var adjustedOptions = {}; 4177 var windowHeight = $(window).height(); 4178 var option = void 0; 4179 var optionValue = void 0; 4180 var adjustedValue = void 0; 4181 for (var n = 0; n < positionOptions.length; n++) { 4182 option = positionOptions[n]; 4183 optionValue = event.data.settings[option]; 4184 if (optionValue) { 4185 if (typeof optionValue === 'string' && /%$/.test(optionValue) && /height/i.test(option)) { 4186 windowHeight -= displace.offsets.top + displace.offsets.bottom; 4187 adjustedValue = parseInt(0.01 * parseInt(optionValue, 10) * windowHeight, 10); 4188 4189 if (option === 'height' && event.data.$element.parent().outerHeight() < adjustedValue) { 4190 adjustedValue = 'auto'; 4191 } 4192 adjustedOptions[option] = adjustedValue; 4193 } 4194 } 4195 } 4196 4197 if (!event.data.settings.modal) { 4198 adjustedOptions = resetPosition(adjustedOptions); 4199 } 4200 event.data.$element.dialog('option', adjustedOptions).trigger('dialogContentResize'); 4201 } 4202 4203 $(window).on({ 4204 'dialog:aftercreate': function dialogAftercreate(event, dialog, $element, settings) { 4205 var autoResize = debounce(resetSize, 20); 4206 var eventData = { settings: settings, $element: $element }; 4207 if (settings.autoResize === true || settings.autoResize === 'true') { 4208 $element.dialog('option', { resizable: false, draggable: false }).dialog('widget').css('position', 'fixed'); 4209 $(window).on('resize.dialogResize scroll.dialogResize', eventData, autoResize).trigger('resize.dialogResize'); 4210 $(document).on('drupalViewportOffsetChange.dialogResize', eventData, autoResize); 4211 } 4212 }, 4213 'dialog:beforeclose': function dialogBeforeclose(event, dialog, $element) { 4214 $(window).off('.dialogResize'); 4215 $(document).off('.dialogResize'); 4216 } 4217 }); 4218})(jQuery, Drupal, drupalSettings, Drupal.debounce, Drupal.displace);; 4219/** 4220* DO NOT EDIT THIS FILE. 4221* See the following change record for more information, 4222* https://www.drupal.org/node/2815083 4223* @preserve 4224**/ 4225 4226(function ($, Drupal) { 4227 Drupal.behaviors.dialog = { 4228 attach: function attach(context, settings) { 4229 var $context = $(context); 4230 4231 if (!$('#drupal-modal').length) { 4232 $('<div id="drupal-modal" class="ui-front"></div>').hide().appendTo('body'); 4233 } 4234 4235 var $dialog = $context.closest('.ui-dialog-content'); 4236 if ($dialog.length) { 4237 if ($dialog.dialog('option', 'drupalAutoButtons')) { 4238 $dialog.trigger('dialogButtonsChange'); 4239 } 4240 4241 $dialog.dialog('widget').trigger('focus'); 4242 } 4243 4244 var originalClose = settings.dialog.close; 4245 4246 settings.dialog.close = function (event) { 4247 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 4248 args[_key - 1] = arguments[_key]; 4249 } 4250 4251 originalClose.apply(settings.dialog, [event].concat(args)); 4252 $(event.target).remove(); 4253 }; 4254 }, 4255 prepareDialogButtons: function prepareDialogButtons($dialog) { 4256 var buttons = []; 4257 var $buttons = $dialog.find('.form-actions input[type=submit], .form-actions a.button'); 4258 $buttons.each(function () { 4259 var $originalButton = $(this).css({ display: 'none' }); 4260 buttons.push({ 4261 text: $originalButton.html() || $originalButton.attr('value'), 4262 class: $originalButton.attr('class'), 4263 click: function click(e) { 4264 if ($originalButton.is('a')) { 4265 $originalButton[0].click(); 4266 } else { 4267 $originalButton.trigger('mousedown').trigger('mouseup').trigger('click'); 4268 e.preventDefault(); 4269 } 4270 } 4271 }); 4272 }); 4273 return buttons; 4274 } 4275 }; 4276 4277 Drupal.AjaxCommands.prototype.openDialog = function (ajax, response, status) { 4278 if (!response.selector) { 4279 return false;
4280 } 4281 var $dialog = $(response.selector); 4282 if (!$dialog.length) { 4283 $dialog = $('<div id="' + response.selector.replace(/^#/, '') + '" class="ui-front"></div>').appendTo('body'); 4284 } 4285 4286 if (!ajax.wrapper) { 4287 ajax.wrapper = $dialog.attr('id'); 4288 } 4289 4290 response.command = 'insert'; 4291 response.method = 'html'; 4292 ajax.commands.insert(ajax, response, status); 4293 4294 if (!response.dialogOptions.buttons) { 4295 response.dialogOptions.drupalAutoButtons = true; 4296 response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); 4297 } 4298 4299 $dialog.on('dialogButtonsChange', function () { 4300 var buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); 4301 $dialog.dialog('option', 'buttons', buttons); 4302 }); 4303 4304 response.dialogOptions = response.dialogOptions || {}; 4305 var dialog = Drupal.dialog($dialog.get(0), response.dialogOptions); 4306 if (response.dialogOptions.modal) { 4307 dialog.showModal(); 4308 } else { 4309 dialog.show(); 4310 } 4311 4312 $dialog.parent().find('.ui-dialog-buttonset').addClass('form-actions'); 4313 }; 4314 4315 Drupal.AjaxCommands.prototype.closeDialog = function (ajax, response, status) { 4316 var $dialog = $(response.selector); 4317 if ($dialog.length) { 4318 Drupal.dialog($dialog.get(0)).close(); 4319 if (!response.persist) { 4320 $dialog.remove(); 4321 } 4322 } 4323 4324 $dialog.off('dialogButtonsChange'); 4325 }; 4326 4327 Drupal.AjaxCommands.prototype.setDialogOption = function (ajax, response, status) { 4328 var $dialog = $(response.selector); 4329 if ($dialog.length) { 4330 $dialog.dialog('option', response.optionName, response.optionValue); 4331 } 4332 }; 4333 4334 $(window).on('dialog:aftercreate', function (e, dialog, $element, settings) { 4335 $element.on('click.dialog', '.dialog-cancel', function (e) { 4336 dialog.close('cancel'); 4337 e.preventDefault(); 4338 e.stopPropagation(); 4339 }); 4340 }); 4341 4342 $(window).on('dialog:beforeclose', function (e, dialog, $element) { 4343 $element.off('.dialog'); 4344 }); 4345})(jQuery, Drupal);; 4346/** 4347 * @file 4348 * dialog.ajax.js 4349 */ 4350(function ($, Drupal, Bootstrap) { 4351 4352 Drupal.behaviors.dialog.ajaxCurrentButton = null; 4353 Drupal.behaviors.dialog.ajaxOriginalButton = null; 4354 4355 // Intercept the success event to add the dialog type to commands. 4356 var success = Drupal.Ajax.prototype.success; 4357 Drupal.Ajax.prototype.success = function (response, status) { 4358 if (this.dialogType) { 4359 for (var i = 0, l = response.length; i < l; i++) { 4360 if (response[i].dialogOptions) { 4361 response[i].dialogType = response[i].dialogOptions.dialogType = this.dialogType; 4362 response[i].$trigger = response[i].dialogOptions.$trigger = $(this.element); 4363 } 4364 } 4365 } 4366 return success.apply(this, [response, status]); 4367 }; 4368 4369 var beforeSerialize = Drupal.Ajax.prototype.beforeSerialize; 4370 Drupal.Ajax.prototype.beforeSerialize = function (element, options) { 4371 // Add the dialog type currently in use. 4372 if (this.dialogType) { 4373 options.data['ajax_page_state[dialogType]'] = this.dialogType; 4374 4375 // Add the dialog element ID if it can be found (useful for closing it). 4376 var id = $(this.element).parents('.js-drupal-dialog:first').attr('id'); 4377 if (id) { 4378 options.data['ajax_page_state[dialogId]'] = id; 4379 } 4380 } 4381 return beforeSerialize.apply(this, arguments); 4382 }; 4383 4384 /** 4385 * Synchronizes a faux button with its original counterpart. 4386 * 4387 * @param {Boolean} [reset = false] 4388 * Whether to reset the current and original buttons after synchronizing. 4389 */ 4390 Drupal.behaviors.dialog.ajaxUpdateButtons = function (reset) { 4391 if (this.ajaxCurrentButton && this.ajaxOriginalButton) { 4392 this.ajaxCurrentButton.html(this.ajaxOriginalButton.html()); 4393 this.ajaxCurrentButton.prop('disabled', this.ajaxOriginalButton.prop('disabled')); 4394 } 4395 if (reset) { 4396 this.ajaxCurrentButton = null; 4397 this.ajaxOriginalButton = null; 4398 } 4399 }; 4400 4401 $(document) 4402 .ajaxSend(function () { 4403 Drupal.behaviors.dialog.ajaxUpdateButtons(); 4404 }) 4405 .ajaxComplete(function () { 4406 Drupal.behaviors.dialog.ajaxUpdateButtons(true); 4407 }) 4408 ; 4409 4410 /** 4411 * {@inheritdoc} 4412 */ 4413 Drupal.behaviors.dialog.prepareDialogButtons = function prepareDialogButtons($dialog) { 4414 var _this = this; 4415 var buttons = []; 4416 var $buttons = $dialog.find('.form-actions').find('button, input[type=submit], a.button, .btn'); 4417 $buttons.each(function () { 4418 var $originalButton = $(this) 4419 // Prevent original button from being tabbed to. 4420 .attr('tabindex', -1) 4421 // Visually make the original button invisible, but don't actually hide 4422 // or remove it from the DOM because the click needs to be proxied from 4423 // the faux button created in the footer to its original counterpart. 4424 .css({ 4425 display: 'block', 4426 width: 0, 4427 height: 0, 4428 padding: 0, 4429 border: 0, 4430 overflow: 'hidden' 4431 }); 4432 4433 buttons.push({ 4434 // Strip all HTML from the actual text value. This value is escaped. 4435 // It actual HTML value will be synced with the original button's HTML 4436 // below in the "create" method.
4437 text: Bootstrap.stripHtml($originalButton), 4438 class: $originalButton.attr('class').replace('use-ajax-submit', ''), 4439 click: function click(e) { 4440 e.preventDefault(); 4441 e.stopPropagation(); 4442 _this.ajaxCurrentButton = $(e.target); 4443 _this.ajaxOriginalButton = $originalButton; 4444 // Some core JS binds dialog buttons to the mousedown or mouseup 4445 // events instead of click; all three events must be simulated here. 4446 // @see https://www.drupal.org/project/bootstrap/issues/3016254 4447 Bootstrap.simulate($originalButton, ['mousedown', 'mouseup', 'click']); 4448 }, 4449 create: function () { 4450 _this.ajaxCurrentButton = $(this); 4451 _this.ajaxOriginalButton = $originalButton; 4452 _this.ajaxUpdateButtons(true); 4453 } 4454 }); 4455 }); 4456 4457 return buttons; 4458 }; 4459 4460})(window.jQuery, window.Drupal, window.Drupal.bootstrap); 4461; 4462/** 4463 * @file entity_browser.common.js 4464 * 4465 * Common helper functions used by various parts of entity browser. 4466 */ 4467 4468(function ($, Drupal, drupalSettings) { 4469 4470 'use strict'; 4471 4472 Drupal.entityBrowser = {}; 4473 4474 /** 4475 * Command to refresh an entity_browser_entity_reference field widget. 4476 * 4477 * @param {Drupal.Ajax} [ajax] 4478 * The ajax object. 4479 * @param {object} response 4480 * Object holding the server response. 4481 * @param {string} response.details_id 4482 * The ID for the details element. 4483 * @param {number} [status] 4484 * The HTTP status code. 4485 */ 4486 Drupal.AjaxCommands.prototype.entity_browser_value_updated = function (ajax, response, status) { 4487 $('#' + response.details_id) 4488 .find('input[type="hidden"][name$="[target_id]"]') 4489 .trigger('entity_browser_value_updated'); 4490 }; 4491 4492 /** 4493 * Reacts on "entities selected" event. 4494 * 4495 * @param {object} event 4496 * Event object. 4497 * @param {string} uuid 4498 * Entity browser UUID. 4499 * @param {array} entities 4500 * Array of selected entities. 4501 */ 4502 Drupal.entityBrowser.selectionCompleted = function (event, uuid, entities) { 4503 var selected_entities = $.map(entities, function (item) { 4504 return item[2] + ':' + item[0]; 4505 }); 4506 // @todo Use uuid here. But for this to work we need to move eb uuid 4507 // generation from display to eb directly. When we do this, we can change 4508 // \Drupal\entity_browser\Plugin\Field\FieldWidget\EntityReferenceBrowserWidget::formElement 4509 // also. 4510 // Checking if cardinality is set - assume unlimited. 4511 var cardinality = isNaN(parseInt(drupalSettings['entity_browser'][uuid]['cardinality'])) ? -1 : parseInt(drupalSettings['entity_browser'][uuid]['cardinality']); 4512 4513 // Get field widget selection mode. 4514 var selection_mode = drupalSettings['entity_browser'][uuid]['selection_mode']; 4515 4516 // Update value form element with new entity IDs. 4517 var selector = drupalSettings['entity_browser'][uuid]['selector'] ? $(drupalSettings['entity_browser'][uuid]['selector']) : $(this).parent().parent().find('input[type*=hidden]'); 4518 var entity_ids = selector.val(); 4519 var existing_entities = (entity_ids.length !== 0) ? entity_ids.split(' ') : []; 4520 4521 entity_ids = Drupal.entityBrowser.updateEntityIds( 4522 existing_entities, 4523 selected_entities, 4524 selection_mode, 4525 cardinality 4526 ); 4527 4528 selector.val(entity_ids); 4529 selector.trigger('entity_browser_value_updated'); 4530 }; 4531 4532 /** 4533 * Updates the list of selected entities. 4534 * 4535 * It uses existing selection and selected entities in entity browser. Also 4536 * considers cardinality and used selection mode. 4537 * 4538 * Note: Selection modes are defined in EntityBrowserElement class and same 4539 * options should be used here to determine what action will be performed. 4540 * Default action is append ('selection_append'). 4541 * 4542 * @param {Array} existing_entities 4543 * List of existing entity IDs. 4544 * @param {Array} selected_entities 4545 * The entities that are selected and entity browser. 4546 * @param {string} selection_mode 4547 * Selection mode defined by entity browser field widget. 4548 * @param {int} cardinality 4549 * The maximal amount of items the field can store. 4550 * 4551 * @return {string}
4552 * List of entities as a string, separated by space. 4553 */ 4554 Drupal.entityBrowser.updateEntityIds = function (existing_entities, selected_entities, selection_mode, cardinality) { 4555 var combined_entities; 4556 4557 if (selection_mode === 'selection_edit') { 4558 // Propagate new selected entities. 4559 combined_entities = selected_entities; 4560 } 4561 else if (selection_mode === 'selection_prepend') { 4562 // Prepend selected entities to existing list of entities. 4563 combined_entities = selected_entities.concat(existing_entities); 4564 } 4565 else { 4566 // Append selected entities to existing list of entities. 4567 combined_entities = existing_entities.concat(selected_entities); 4568 } 4569 4570 // Having more elements than cardinality should never happen, because 4571 // server side authentication should prevent it, but we handle it here 4572 // anyway. 4573 if (cardinality > 0 && combined_entities.length > cardinality) { 4574 combined_entities = combined_entities.slice(0, cardinality); 4575 } 4576 4577 return combined_entities.join(' '); 4578 }; 4579 4580 /** 4581 * Reacts on "entities selected" event. 4582 * 4583 * @param {object} element 4584 * Element to bind on. 4585 * @param {array} callbacks 4586 * List of callbacks. 4587 * @param {string} event_name 4588 * Name of event to bind to. 4589 */ 4590 Drupal.entityBrowser.registerJsCallbacks = function (element, callbacks, event_name) { 4591 // JS callbacks are registred as strings. We need to split their names and 4592 // find actual functions. 4593 for (var i = 0; i < callbacks.length; i++) { 4594 var callback = callbacks[i].split('.'); 4595 var fn = window; 4596 4597 for (var j = 0; j < callback.length; j++) { 4598 fn = fn[callback[j]]; 4599 } 4600 4601 if (typeof fn === 'function') { 4602 $(element).bind(event_name, fn); 4603 } 4604 } 4605 }; 4606 4607}(jQuery, Drupal, drupalSettings)); 4608; 4609'use strict'; 4610 4611(function($) { 4612 /* 4613 * Centrar el modal del selector de imagen, ya que al desplegar las opciones 4614 * de recorte, el contenido puede extenderse mas que la ventana. 4615 */ 4616 4617 Drupal.behaviors.centerCropModal = { 4618 4619 attach: function(context, settings) { 4620 4621 jQuery('details[data-drupal-selector=edit-image-crop-crop-wrapper] > summary').click(function() { 4622 4623 setTimeout(function() { 4624 // centrar modal verticalmente 4625 4626 var modal = jQuery('.ui-dialog'); 4627 4628 modal.css('left', window.innerWidth / 2 - modal.outerWidth() / 2 + 'px'); 4629 modal.css('top', window.innerHeight / 2 - modal.outerHeight() / 2 + 'px'); 4630 }, 0); 4631 }); 4632 } 4633 }; 4634 4635 Drupal.behaviors.cmsTweaksFileUploadModal = { 4636 4637 attach: function(context) { 4638 if (context != document) { 4639 return; 4640 } 4641 4642 var uploadForm = jQuery('#cms-tweaks-file-upload-form'); 4643 4644 if (!uploadForm.length) { 4645 return; 4646 } 4647 4648 // recargar pagina al subir archivo 4649 4650 uploadForm.find('#edit-browser-target').on('entity_browser_value_updated', function() { 4651 location.reload(true); 4652 }); 4653 4654 // asignar tid de carpeta al subir archivos 4655 4656 jQuery(window).on('dialog:aftercreate', function(e, modal, elements, dialogOptions) { 4657 var dialogElement = jQuery(elements[0].parentElement); 4658 var frameElement = dialogElement.find('iframe'); 4659 4660 function applyFolderId(element) { 4661 element.find('input[name=folder]').val( 4662 jQuery('input[name=folder]').val() 4663 ); 4664 } 4665 4666 if (frameElement.length) { 4667 frameElement.on('load', function() { 4668 applyFolderId(frameElement.contents()); 4669 }); 4670 4671 } else { 4672 applyFolderId(dialogElement); 4673 } 4674 }); 4675 4676 // tabular arbol de carpetas 4677 4678 jQuery('.folders-filter [data-depth]').each(function(u, element) { 4679 var linkElement = jQuery(element); 4680 var termDepth = parseInt(linkElement.data('depth')); 4681 4682 linkElement.css('margin-left', (termDepth * 10) + 'px'); 4683 }); 4684 4685 // cambiar view filter al seleccionar carpeta 4686 4687 jQuery('.folders-filter').on('click', 'a', function(event) { 4688 var termId = jQuery(event.target).data('value'); 4689 4690 jQuery('input[name=folder]').val(termId); 4691 jQuery('.views-exposed-form').submit(); 4692 }); 4693 4694 } 4695 }; 4696 4697 /* 4698 * Mantener dialogos de jQuery UI fijos (independiente del scroll), 4699 * y corregir desfazaje del tamaño del contenido interior con el marco exterior 4700 * al cambiar tamaño. 4701 */ 4702 4703 Drupal.behaviors.cmsTweaksFixateDialogPosition = { 4704 4705 attach: function(context) { 4706 if (context != document) { 4707 return; 4708 } 4709 4710 jQuery(window).on('dialog:beforecreate', function(e, modal, elements, dialogOptions) { 4711 4712 if (dialogOptions.modal) { 4713 return; 4714 } 4715 4716 dialogOptions.resize = function() { 4717 var contentElement = jQuery(this); 4718 contentElement.outerWidth(contentElement.parent().width()); 4719 4720 // TODO: en algunos casos el altura es menor que el espacio disponible 4721 }; 4722 }); 4723 4724 jQuery(window).on('dialog:aftercreate', function(e, modal, elements, dialogOptions) { 4725 4726 if (dialogOptions.modal) { 4727 return; 4728 } 4729 4730 var dialogElement = jQuery(elements[0].parentElement); 4731 var dialogY = dialogElement.offset().top - window.pageYOffset; 4732 4733 dialogElement.css('position', 'fixed'); 4734 dialogElement.css('top', dialogY); 4735 4736 // habilitar el scroll ya que EntityBrowser lo deshabilita 4737 4738 setTimeout(function() { 4739 jQuery(document.body).css('overflow', 'inherit'); 4740 }, 0); 4741 4742 }); 4743 } 4744 }; 4745 4746 /* 4747 * Resaltar el campo donde se inserta un token. 4748 */ 4749 4750 Drupal.behaviors.cmsTweaksHighlightTokenWidget = { 4751 4752 attach: function(context) { 4753 if (context != document) { 4754 return; 4755 } 4756 4757 var highlightedElement = null; 4758 var highlightTimer = null; 4759 var highlightCssClass = 'widget-highlight';
4760 4761 function getBodyVerticalOffset() { 4762 // TODO: calcular altura de toolbar 4763 return 80; 4764 } 4765 4766 function scrollToElement(element) { 4767 var verticalOffset = getBodyVerticalOffset(); 4768 var rect = element[0].getBoundingClientRect(); 4769 4770 if (rect.y > verticalOffset && rect.bottom < window.innerHeight) { 4771 return; 4772 } 4773 4774 // centrar scroll en el elemento 4775 window.scroll(0, element.offset().top - window.innerHeight / 2); 4776 } 4777 4778 function hightlightElement(element) { 4779 4780 if (highlightedElement) { 4781 highlightedElement.removeClass(highlightCssClass); 4782 } 4783 4784 if (highlightTimer) { 4785 clearTimeout(highlightTimer); 4786 highlightTimer = null; 4787 } 4788 4789 if (element) { 4790 element.addClass(highlightCssClass); 4791 4792 // quitar resaltado luego de unos segundos 4793 4794 highlightTimer = setTimeout(function() { 4795 highlightTimer = null; 4796 hightlightElement(null); 4797 }, 5000); 4798 4799 // asegurar que el elemento sea visible 4800 scrollToElement(element); 4801 } 4802 4803 highlightedElement = element; 4804 } 4805 4806 /* 4807 * interceptar creacion de modals de Drupal, y modificarlo en caso de que 4808 * sea el de insercion de tokens. 4809 */ 4810 4811 jQuery(window).on('dialog:aftercreate', function(e, modal, elements, dialogOptions) { 4812 var contentElement = jQuery(elements[0]); 4813 4814 if (!contentElement.find('table.token-tree').length) { 4815 // no es el modal de tokens 4816 return; 4817 } 4818 4819 /* 4820 * usar evento mouseup en vez de click ya que el JS de token desactiva 4821 * la propagacion 4822 */ 4823 4824 contentElement.mouseup(function(e) { 4825 var linkElement = jQuery(e.target); 4826 4827 if (linkElement[0].tagName != 'A' 4828 || !linkElement.parent().hasClass('token-key')) { 4829 4830 return; 4831 } 4832 4833 var ckEditor = window.CKEDITOR; 4834 4835 if (ckEditor && ckEditor.currentInstance) { 4836 4837 // resaltar contenedor de CKEditor 4838 hightlightElement(jQuery(ckEditor.currentInstance.container.$)); 4839 4840 } else if (drupalSettings.tokenFocusedField) { 4841 4842 // resaltar input 4843 hightlightElement(jQuery(drupalSettings.tokenFocusedField)); 4844 } 4845 }); 4846 4847 /* 4848 * deshabilitar foco en link de apertura del dialogo 4849 * 4850 * esto es para prevenir que al cerrar el dialog jQuery UI haga foco 4851 * en el link, ya que esto puede causar un salto de scroll 4852 * 4853 * este comportamiento de jQuery UI no puede desactivarse 4854 * https://bugs.jqueryui.com/ticket/10686 4855 */ 4856 4857 jQuery('a.token-dialog.use-ajax').each(function(u, domElement) { 4858 var element = jQuery(domElement); 4859 4860 element.data('href', element.attr('href')); 4861 element.attr('href', null); 4862 4863 // adicionalmente, prevenir que se puedan abrir dialogos adicionales 4864 element.css('pointer-events', 'none') 4865 }); 4866 }); 4867 4868 jQuery(window).on('dialog:afterclose', function() { 4869 4870 // restaurar links de apertura 4871 4872 jQuery('a.token-dialog.use-ajax').each(function(u, domElement) { 4873 var element = jQuery(domElement); 4874 4875 element.attr('href', element.data('href')); 4876 element.css('pointer-events', ''); 4877 }); 4878 }); 4879 4880 } 4881 }; 4882 4883 /* 4884 * Corregir funciones de tabledrag BCRCMS-153. 4885 * 4886 * Se previene resalte de fila (e indicacion de cambios aplicados) en los 4887 * tabledrag si se arrastra y suelta una fila en el mismo lugar donde estaba. 4888 */ 4889 4890 Drupal.behaviors.cmsTweaksFixTableDrag = { 4891 4892 applied: false, 4893 originalDragStart: null, 4894 originalDropRow: null, 4895 4896 attach: function() { 4897 // se espera a que se incluya tabledrag.js 4898 4899 if (this.applied) { 4900 // ignorar llamada si fue previamente aplicado 4901 return; 4902 } 4903 4904 setTimeout(function() { 4905 var self = Drupal.behaviors.cmsTweaksFixTableDrag; 4906 var target = Drupal.tableDrag; 4907 4908 if (self.applied || !target) {
4909 // ya aplicado o tabledrag aun no fue incluido 4910 return; 4911 } 4912 4913 self.applied = true; 4914 self.originalDragStart = target.prototype.dragStart; 4915 self.originalDropRow = target.prototype.dropRow; 4916 4917 // parchar dragStart 4918 4919 target.prototype.dragStart = function(event, selfObject, item) { 4920 4921 // llamar funcion original 4922 self.originalDragStart.call(this, event, selfObject, item); 4923 4924 // guardar ubicacion inicial 4925 selfObject.dragObject.originalIndent = selfObject.rowObject.indents; 4926 selfObject.dragObject.originalIndex = jQuery(item).index(); 4927 }; 4928 4929 // parchar dropRow 4930 4931 target.prototype.dropRow = function(event, selfObject) { 4932 4933 if (selfObject.rowObject !== null 4934 && selfObject.rowObject.changed === true) { 4935 4936 var rowObject = selfObject.rowObject; 4937 var dragObject = selfObject.dragObject; 4938 4939 if (rowObject.indents == dragObject.originalIndent 4940 && jQuery(rowObject.element).index() == dragObject.originalIndex) { 4941 4942 // prevenir resaltado si se ubico en el mismo lugar 4943 rowObject.changed = false; 4944 } 4945 } 4946 4947 // llamar funcion original 4948 self.originalDropRow.call(this, event, selfObject); 4949 }; 4950 4951 }, 0); 4952 } 4953 4954 }; 4955 4956 /* 4957 * Toogles the next element based on boolean changes. 4958 */ 4959 4960 Drupal.behaviors.cmsTweaksConditionalFormFields = { 4961 attach: function() { 4962 var booleans = [ 4963 $(".field--name-field-opt-link-download > div > input"), 4964 $(".field--name-field-opt-link-history > div > input"), 4965 $(".field--name-field-bulletin-show-list > div > input"), 4966 $(".field--name-field-opt-show-article > div > input"), 4967 $(".field--name-field-opt-show-list > div > input"), 4968 ]; 4969 4970 $.each(booleans, function (i) { 4971 booleans[i].once('cmsTweaksConditionalFormFields'+i).each(function(z){ 4972 $(this).on('change', function(){ 4973 $(this).parent().parent().next().toggle(); 4974 }); 4975 4976 if ($(this)[0].checked) { 4977 $(this).parent().parent().next().show(); 4978 } else { 4979 $(this).parent().parent().next().hide(); 4980 } 4981 4982 // Alter styles. 4983 $(this).parent().parent().css({ 4984 'marginBottom': '0', 4985 }); 4986 $(this).parent().parent().next().find('fieldset').css({ 4987 'paddingTop': '0', 4988 'paddingBottom': '0', 4989 'marginTop': '0', 4990 }).find('legend').remove(); 4991 }); 4992 }); 4993 } 4994 }; 4995 4996 Drupal.behaviors.taxonomyTreeSelect = { 4997 attach: function(context) { 4998 4999 $('input.taxonomytree-select', context) 5000 .once('taxonomytree-select') 5001 .each(function(u, element) { 5002 var isLoading = true; 5003 var isVisible = false; 5004 var settings = $(element).data('settings'); 5005 var extraOptions = settings.extraOptions; 5006 5007 function getExtraOptionById(id) { 5008 return extraOptions.find(function(option) { 5009 return option.id == id; 5010 }); 5011 } 5012 5013 function getExtraOptionByValue(value) { 5014 return extraOptions.find(function(option) { 5015 return option.value == value; 5016 }); 5017 } 5018 5019 function makeExtraOptionsNodes(parent) { 5020 return extraOptions.map(function(option) { 5021 var node = { 5022 id: option.id, 5023 text: option.label, 5024 state: { 5025 selected: element.value == option.value 5026 } 5027 }; 5028 5029 if (parent) { 5030 node.parent = parent; 5031 } 5032 5033 return node; 5034 }); 5035 } 5036 5037 function show() { 5038 if (isVisible || isLoading) { 5039 return; 5040 } 5041 5042 isVisible = true; 5043 5044 searchElement.value = ''; 5045 $treeElement.jstree(true).clear_search(); 5046 5047 dropdownElement.classList.add('open'); 5048 5049 searchElement.focus(); 5050 } 5051 5052 function hide() { 5053 if (!isVisible) { 5054 return; 5055 } 5056 5057 isVisible = false;
5058 5059 dropdownElement.classList.remove('open'); 5060 } 5061 5062 function toggleVisible() { 5063 if (isVisible) { 5064 hide(); 5065 } else { 5066 show(); 5067 } 5068 } 5069 5070 if ($(element).data('emptyoption')) { 5071 extraOptions.push({ 5072 id: '_empty', 5073 value: '', 5074 label: $(element).data('emptyoption') 5075 }); 5076 } 5077 5078 var root = document.createElement('div'); 5079 var labelElement = document.createElement('div'); 5080 var dropdownElement = document.createElement('div'); 5081 var searchElement = document.createElement('input'); 5082 var treeElement = document.createElement('div'); 5083 5084 labelElement.classList.add('taxonomytree-label'); 5085 labelElement.textContent = 'Cargando...'; 5086 labelElement.addEventListener('click', function() { 5087 toggleVisible(); 5088 }); 5089 5090 searchElement.type = 'text'; 5091 searchElement.tabIndex = -1; 5092 searchElement.classList.add('taxonomytree-search'); 5093 5094 var $treeElement = $(treeElement); 5095 5096 var doSearch = _.debounce(function doSearch() { 5097 $treeElement.jstree(true).search(searchElement.value); 5098 }, 800); 5099 5100 searchElement.addEventListener('input', function() { 5101 doSearch(); 5102 }); 5103 5104 $treeElement.jstree({ 5105 plugins : ["search"], 5106 core: { 5107 multiple: false, 5108 worker: false, 5109 data: function(node, callback) { 5110 var finalQueryUrl = settings.queryUrl; 5111 5112 if (node.id == '#') { 5113 // terminos raiz 5114 5115 var multilevelLoad = !getExtraOptionByValue(element.value); 5116 5117 if (multilevelLoad) { 5118 finalQueryUrl += '&selected=' + element.value; 5119 } 5120 5121 $.getJSON(finalQueryUrl).then(function(json) { 5122 isLoading = false; 5123 root.classList.remove('loading'); 5124 5125 callback(makeExtraOptionsNodes(multilevelLoad ? '#' : undefined).concat(json)); 5126 5127 var selected = $treeElement.jstree(true).get_selected(); 5128 5129 if (selected.length) { 5130 labelElement.textContent = $treeElement.jstree(true).get_node(selected[0]).text; 5131 } 5132 }); 5133 5134 } else { 5135 // consultar subterminos 5136 $.getJSON(finalQueryUrl + '&parent=' + node.id).then(callback); 5137 } 5138 }, 5139 themes: { 5140 icons: false 5141 } 5142 }, 5143 search: { 5144 show_only_matches: true, 5145 ajax: function(query, callback) { 5146 $.getJSON(settings.queryUrl + '&search=' + encodeURIComponent(query)).then(function(json) { 5147 callback.call(this, json); 5148 }); 5149 } 5150 } 5151 }); 5152 5153 treeElement.tabIndex = -1; 5154 5155 $treeElement.on('select_node.jstree', function(event, data) { 5156 var nodeId = data.node.id; 5157 var option = getExtraOptionById(nodeId); 5158 5159 if (option) { 5160 // es una opcion extra: usar su valor 5161 element.value = option.value; 5162 5163 } else { 5164 // termino regular 5165 element.value = nodeId; 5166 } 5167 5168 labelElement.textContent = data.node.text; 5169 hide(); 5170 }); 5171 5172 dropdownElement.classList.add('taxonomytree-dropdown'); 5173 dropdownElement.appendChild(searchElement); 5174 dropdownElement.appendChild(treeElement); 5175 5176 root.tabIndex = 0; 5177 root.classList.add('taxonomytree'); 5178 root.classList.add('loading'); 5179 root.appendChild(labelElement); 5180 root.appendChild(dropdownElement); 5181 5182 root.addEventListener('focusout', function(event) { 5183 if (!event.relatedTarget || !root.contains(event.relatedTarget)) { 5184 hide(); 5185 } 5186 }); 5187 5188 root.addEventListener('keyup', function(event) { 5189 switch (event.code) { 5190 case 'Enter': 5191 toggleVisible(); 5192 break; 5193 5194 case 'Escape': 5195 hide(); 5196 break; 5197 5198 case 'Space': 5199 show(); 5200 break; 5201 5202 default: 5203 return; 5204 } 5205 5206 event.preventDefault(); 5207 }); 5208 5209 $(root).insertAfter($(element)); 5210 }); 5211 }, 5212 5213 detach: function(context, trigger) { 5214 if (trigger === 'unload') { 5215 $('input.taxonomytree-select', context) 5216 .removeOnce('taxonomytree-select') 5217 .each(function(index, element) { 5218 var $element = $(element); 5219 5220 $element.find('.jstree').jstree(true).destroy(); 5221 $element.next('.taxonomytree').remove(); 5222 }); 5223 } 5224 } 5225 }; 5226 5227 Drupal.behaviors.cmsTweaksFolderTree = { 5228 5229 attach: function(context) { 5230 if (context !== document) { 5231 return; 5232 } 5233 5234 var treeElement = $('.view-file-entity-files .tree-container'); 5235 5236 if (!treeElement.length) { 5237 return; 5238 } 5239 5240 treeElement.jstree({ 5241 core: { 5242 multiple: false, 5243 worker: false, 5244 data: function(node, callback) { 5245 if (node.id == '#') { 5246 callback(drupalSettings.cms_tweaks.folders_tree_data); 5247 5248 } else { 5249 $.getJSON('/es/api/folder?parent=' + node.id).then(callback); 5250 } 5251 }, 5252 themes: { 5253 icons: false 5254 } 5255 } 5256 }); 5257 5258 treeElement.on('select_node.jstree', function(event, data) { 5259 var termId = data.node.id; 5260 5261 $('input[name=folder]').val(termId == 'root' ? '' : termId); 5262 $('.views-exposed-form').submit(); 5263 }); 5264 } 5265 5266 }; 5267 5268 Drupal.behaviors.cmsTweaksFolderTreeAdmin = { 5269 5270 attach: function(context) { 5271 if (context !== document) { 5272 return; 5273 } 5274 5275 var treeElement = $('.term-folder'); 5276 5277 if (!treeElement.length) { 5278 return; 5279 } 5280 5281 treeElement.jstree({ 5282 core: { 5283 check_callback: true, 5284 multiple: false, 5285 worker: true, 5286 data: function(node, callback) { 5287 $.getJSON('/es/api/folder?parent=' + node.id).then(callback); 5288 }, 5289 themes: { 5290 icons: true 5291 }, 5292 }, 5293 plugins : [ "dnd" ], 5294 dnd : { 5295 is_draggable : function(node) { 5296 return true; 5297 } 5298 } 5299 }).bind("move_node.jstree", function(e, data) { 5300 var parent = data.instance.get_node(data.parent); 5301 5302 var queryParameters = {"id": data.node.id, "parent_id": data.parent}; 5303 5304 if ((data.position +1) >= parent.children.length) { // Por si el elemento va al final. 5305 queryParameters.before = null; 5306 } else { 5307 var previous = data.instance.get_node(parent.children[data.position + 1]); 5308 queryParameters.before = previous.id; 5309 } 5310 5311 5312 // Aca debo ejecutar un callback al metodo post para actualizar el term. 5313 var queryPath = 'admin/structure/taxonomy/manage/folder/post'; 5314 5315 jQuery.ajax({ 5316 url: drupalSettings.path.baseUrl + queryPath, 5317 type: 'POST', 5318 dataType: 'json', 5319 headers: { 5320 'Content-Type':'application/json' 5321 }, 5322 data: JSON.stringify(queryParameters), 5323 error: function (XMLHttpRequest, textStatus, errorThrown) 5324 { 5325 console.log(JSON.stringify(XMLHttpRequest)); 5326 console.log(JSON.stringify(textStatus)); 5327 console.log(JSON.stringify(errorThrown)); 5328 }, 5329 success: function (data) 5330 { 5331 console.log('success:' + data); 5332 } 5333 }); 5334 5335 }); 5336 } 5337 }; 5338 5339 Drupal.behaviors.cmsTweaksDatePicker = { 5340 5341 attach: function(context) { 5342 5343 if (!drupalSettings.path.currentPathIsAdmin) { 5344 // solo aplicar a paginas administrativas 5345 return; 5346 } 5347 5348 $('input[type=date]', context) 5349 .once('cms-tweaks-datepicker') 5350 .each(function(u, dateElement) { 5351 /* 5352 * Se crea un input de tipo texto para el datepicker con las mismas 5353 * clases css que el original y se lo ubica junto al mismo. 5354 */ 5355 5356 var value = dateElement.valueAsDate; 5357 5358 var pickerElement = $(document.createElement('input')) 5359 .attr('required', dateElement.getAttribute('required')) 5360 .attr('class', dateElement.getAttribute('class')) 5361 .insertBefore(dateElement); 5362 5363 dateElement.classList.add('hidden'); 5364 5365 pickerElement.datepicker({ 5366 altField: dateElement, 5367 altFormat: 'yy-mm-dd', 5368 dateFormat: 'dd/mm/yy', 5369 changeYear: true, 5370 changeMonth: true 5371 }); 5372 5373 pickerElement.on('change', function(){ 5374 if (this.value.length < 1) { 5375 pickerElement.datepicker('setDate', null); 5376 } 5377 }); 5378 5379 if (value) { 5380 /* 5381 * corregir fecha ya que jQuery UI toma un objeto Date corrido a 5382 * la zona horaria local (en vez de UTC). 5383 */ 5384 5385 var adjustedValue = new Date(value); 5386 5387 adjustedValue.setMinutes( 5388 value.getMinutes() + value.getTimezoneOffset() 5389 ); 5390 5391 pickerElement.datepicker('setDate', adjustedValue); 5392 } 5393 }); 5394 } 5395 5396 }; 5397 5398 Drupal.behaviors.cmsTweaksFixToolbar = { 5399 attach: function(context) { 5400 if (context !== document) { 5401 return; 5402 } 5403 5404 _.delay(function() { 5405 if (!Drupal.toolbar) { 5406 return; 5407 } 5408 5409 var view = Drupal.toolbar.views.toolbarVisualView; 5410 5411 if ($(view.model.get('activeTab')).is(':hidden')) { 5412 var tabs = $('#toolbar-bar').find('[data-toolbar-tray]:visible'); 5413 5414 if (tabs.length) { 5415 view.model.set('activeTab', tabs[0]); 5416 } 5417 } 5418 }); 5419 } 5420 }; 5421 5422 // autocompletado para articulos 5423 5424 Drupal.behaviors.cmsTweaksArticleAutocomplete = { 5425 5426 attach: function(context) { 5427 5428 $(context) 5429 .find('fieldset[data-article-autocomplete]') 5430 .once('article-autocomplete') 5431 .each(function(index, section) { 5432 5433 var $section = $(section); 5434 var $widgets = $section.find('input.form-text'); 5435 5436 var queryOptions = $section.data('article-autocomplete'); 5437 var selectedIds; 5438 5439 function updateSelectedList() { 5440 selectedIds = _.compact(_.map($widgets, function(element) { 5441 var match = element.value.match(/\((\d+)\)\s*$/); 5442 return match ? match[1] : null; 5443 })); 5444 } 5445 5446 updateSelectedList(); 5447 5448 $widgets.on('input', function() { 5449 updateSelectedList(); 5450 }); 5451 5452 $widgets.autocomplete({ 5453 source: function(request, response) { 5454 var search = request.term.trim(); 5455 5456 if (search) { 5457 queryOptions.q = search; 5458 queryOptions.exclude = selectedIds; 5459 5460 $.getJSON( 5461 '/es/api/bulletin-autocomplete', queryOptions 5462 ).then(response); 5463 5464 } else { 5465 response([]); 5466 } 5467 } 5468 }); 5469 5470 }); 5471 }, 5472 5473 detach: function(context, settings, trigger) { 5474 if (trigger === 'unload') { 5475 $(context).find('fieldset[data-article-autocomplete]') 5476 .removeOnce('article-autocomplete') 5477 .find('input.form-text') 5478 .each(function(index, element) { 5479 $(element).autocomplete('destroy'); 5480 }); 5481 } 5482 } 5483 5484 }; 5485 5486 // Cambiar titulos de campo cabecera y footer (field image dentro de paragraph). 5487 Drupal.behaviors.addLabelInFields = { 5488 attach: function() { 5489 $('.field--name-field-sitemap-header .paragraph-type-title').html("Cabecera"); 5490 $('.field--name-field-sitemap-footer .paragraph-type-title').html("Pie"); 5491 } 5492 }; 5493 5494 // corregir error al importar libreria spectrum.js desde modulo color_field 5495 5496 if (!drupalSettings.color_field) { 5497 drupalSettings.color_field = {}; 5498 } 5499 5500 Drupal.behaviors.cmsTweaksTranslateInputRequired = { 5501 attach: function(context) { 5502 var input_required = $("input[type!='hidden']", context); 5503 for (var i = 0; i < input_required.length; i++) { 5504 input_required[i].oninvalid = function(e) { 5505 e.target.setCustomValidity(''); 5506 if (!e.target.validity.valid) { 5507 e.target.setCustomValidity('Por favor complete este campo.'); 5508 } 5509 }; 5510 input_required[i].oninput = function(e) { 5511 e.target.setCustomValidity(''); 5512 }; 5513 } 5514 } 5515 }; 5516 5517 jQuery('#article-title-and-date').length && jQuery('#edit-group-article').append( jQuery('#article-title-and-date') ); 5518 5519 5520})(jQuery); 5521; 5522/** 5523 * @file 5524 * JavaScript behaviors for message element integration. 5525 */ 5526 5527(function ($, Drupal) { 5528 5529 'use strict'; 5530 5531 // Determine if local storage exists and is enabled. 5532 // This approach is copied from Modernizr. 5533 // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 5534 var hasLocalStorage = (function () { 5535 try { 5536 localStorage.setItem('webform', 'webform'); 5537 localStorage.removeItem('webform'); 5538 return true; 5539 } 5540 catch (e) { 5541 return false;
5542 } 5543 }()); 5544 5545 // Determine if session storage exists and is enabled. 5546 // This approach is copied from Modernizr. 5547 // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 5548 var hasSessionStorage = (function () { 5549 try { 5550 sessionStorage.setItem('webform', 'webform'); 5551 sessionStorage.removeItem('webform'); 5552 return true; 5553 } 5554 catch (e) { 5555 return false; 5556 } 5557 }()); 5558 5559 /** 5560 * Behavior for handler message close. 5561 * 5562 * @type {Drupal~behavior} 5563 */ 5564 Drupal.behaviors.webformMessageClose = { 5565 attach: function (context) { 5566 $(context).find('.js-webform-message--close').once('webform-message--close').each(function () { 5567 var $element = $(this); 5568 5569 var id = $element.attr('data-message-id'); 5570 var storage = $element.attr('data-message-storage'); 5571 var effect = $element.attr('data-message-close-effect') || 'hide'; 5572 switch (effect) { 5573 case 'slide': effect = 'slideUp'; break; 5574 5575 case 'fade': effect = 'fadeOut'; break; 5576 } 5577 5578 // Check storage status. 5579 if (isClosed($element, storage, id)) { 5580 return; 5581 } 5582 5583 // Only show element if it's style is not set to 'display: none'. 5584 if ($element.attr('style') !== 'display: none;') { 5585 $element.show(); 5586 } 5587 5588 $element.find('.js-webform-message__link').on('click', function (event) { 5589 $element[effect](); 5590 setClosed($element, storage, id); 5591 $element.trigger('close'); 5592 event.preventDefault(); 5593 }); 5594 }); 5595 } 5596 }; 5597 5598 function isClosed($element, storage, id) { 5599 if (!id || !storage) { 5600 return false; 5601 } 5602 5603 switch (storage) { 5604 case 'local': 5605 if (hasLocalStorage) { 5606 return localStorage.getItem('Drupal.webform.message.' + id) || false; 5607 } 5608 return false; 5609 5610 case 'session': 5611 if (hasSessionStorage) { 5612 return sessionStorage.getItem('Drupal.webform.message.' + id) || false; 5613 } 5614 return false; 5615 5616 default: 5617 return false; 5618 } 5619 } 5620 5621 function setClosed($element, storage, id) { 5622 if (!id || !storage) { 5623 return; 5624 } 5625 5626 switch (storage) { 5627 case 'local': 5628 if (hasLocalStorage) { 5629 localStorage.setItem('Drupal.webform.message.' + id, true); 5630 } 5631 break; 5632 5633 case 'session': 5634 if (hasSessionStorage) { 5635 sessionStorage.setItem('Drupal.webform.message.' + id, true); 5636 } 5637 break; 5638 5639 case 'user': 5640 case 'state': 5641 case 'custom': 5642 $.get($element.find('.js-webform-message__link').attr('href')); 5643 return true; 5644 } 5645 } 5646 5647})(jQuery, Drupal); 5648; 5649(function ($) { 5650 'use strict'; 5651 5652 Drupal.form_placeholder = {}; 5653 5654 Drupal.form_placeholder.elementIsSupported = function ($element) { 5655 var supportedElement = $element.is('input[type=number], input[type=text], input[type=date], input[type=email], input[type=url], input[type=tel], input[type=password], textarea'); 5656 var hasId = $element.attr('id'); 5657 return supportedElement && hasId; 5658 }; 5659 5660 Drupal.form_placeholder.placeholderIsSupported = function () { 5661 // Opera Mini v7 doesnât support placeholder although its DOM seems to 5662 // indicate so. 5663 var isOperaMini = Object.prototype.toString.call(window.operamini) == '[object OperaMini]'; 5664 return 'placeholder' in document.createElement('input') && !isOperaMini; 5665 }; 5666 5667 Drupal.behaviors.form_placeholder = { 5668 attach: function (context, settings) { 5669 // In some cases settings after ajax form submit could contain only 5670 // settings from response but not all Drupal.settings data. 5671 if (!settings.hasOwnProperty('form_placeholder')) { 5672 settings = Drupal.settings; 5673 } 5674 var include = settings.form_placeholder.include; 5675 if (include) { 5676 include += ', '; 5677 } 5678 include += '.form-placeholder-include-children *'; 5679 include += ', .form-placeholder-include'; 5680 var exclude = settings.form_placeholder.exclude; 5681 if (exclude) { 5682 exclude += ', '; 5683 } 5684 exclude += '.form-placeholder-exclude-children *'; 5685 exclude += ', .form-placeholder-exclude'; 5686 5687 var required_indicator = settings.form_placeholder.required_indicator; 5688 5689 $(include, context).not(exclude).each(function () { 5690 var $textfield = $(this); 5691 var elementSupported = Drupal.form_placeholder.elementIsSupported($textfield); 5692 var placeholderSupported = Drupal.form_placeholder.placeholderIsSupported() || $().placeholder; 5693 5694 // Placeholder is supported. 5695 if (elementSupported && placeholderSupported) { 5696 var $form = $textfield.closest('form'); 5697 var $label = $form.find('label[for=' + this.id + ']'); 5698 var placeholder = $.trim($label.text()); 5699 5700 // Handle required field marker. 5701 if ($label.hasClass('form-required')) { 5702 switch (required_indicator) { 5703 case 'append': 5704 $textfield.after('<span class="form-required"></span>'); 5705 break; 5706 case 'remove': 5707 // It's removed anyway, so we don't have to do anything. 5708 break; 5709 case 'leave': 5710 placeholder += ' *'; 5711 break; 5712 case 'text': 5713 placeholder += ' (' + Drupal.t('required') + ')'; 5714 break; 5715 } 5716 } 5717 else if (required_indicator === 'optional') { 5718 placeholder += ' (' + Drupal.t('optional') + ')'; 5719 } 5720 5721 if (!$textfield.attr('placeholder')) { 5722 $textfield.attr('placeholder', placeholder); 5723 $label.addClass('visually-hidden'); 5724 } 5725 5726 // Fallback support for older browsers. 5727 if (!Drupal.form_placeholder.placeholderIsSupported() && $().placeholder) { 5728 $textfield.placeholder(); 5729 } 5730 } 5731 }); 5732 } 5733 }; 5734 5735})(jQuery); 5736;
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.