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(function ($, Drupal) { 8 Drupal.theme.progressBar = function (id) { 9 return "<div id=\"".concat(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>'; 10 }; 11 Drupal.ProgressBar = function (id, updateCallback, method, errorCallback) { 12 this.id = id; 13 this.method = method || 'GET'; 14 this.updateCallback = updateCallback; 15 this.errorCallback = errorCallback; 16 this.element = $(Drupal.theme('progressBar', id)); 17 }; 18 $.extend(Drupal.ProgressBar.prototype, { 19 setProgress: function setProgress(percentage, message, label) { 20 if (percentage >= 0 && percentage <= 100) { 21 $(this.element).find('div.progress__bar').css('width', "".concat(percentage, "%")); 22 $(this.element).find('div.progress__percentage').html("".concat(percentage, "%")); 23 } 24 $('div.progress__description', this.element).html(message); 25 $('div.progress__label', this.element).html(label); 26 if (this.updateCallback) { 27 this.updateCallback(percentage, message, this); 28 } 29 }, 30 startMonitoring: function startMonitoring(uri, delay) { 31 this.delay = delay; 32 this.uri = uri; 33 this.sendPing(); 34 }, 35 stopMonitoring: function stopMonitoring() { 36 clearTimeout(this.timer); 37 this.uri = null; 38 }, 39 sendPing: function sendPing() { 40 if (this.timer) { 41 clearTimeout(this.timer); 42 } 43 if (this.uri) { 44 var pb = this; 45 var uri = this.uri; 46 if (uri.indexOf('?') === -1) { 47 uri += '?'; 48 } else { 49 uri += '&'; 50 } 51 uri += '_format=json'; 52 $.ajax({ 53 type: this.method, 54 url: uri, 55 data: '', 56 dataType: 'json', 57 success: function success(progress) { 58 if (progress.status === 0) { 59 pb.displayError(progress.data); 60 return; 61 } 62 pb.setProgress(progress.percentage, progress.message, progress.label); 63 pb.timer = setTimeout(function () { 64 pb.sendPing(); 65 }, pb.delay); 66 }, 67 error: function error(xmlhttp) { 68 var e = new Drupal.AjaxError(xmlhttp, pb.uri); 69 pb.displayError("<pre>".concat(e.message, "</pre>")); 70 } 71 }); 72 } 73 }, 74 displayError: function displayError(string) { 75 var error = $('<div class="messages messages--error"></div>').html(string); 76 $(this.element).before(error).hide(); 77 if (this.errorCallback) { 78 this.errorCallback(this); 79 } 80 } 81 }); 82})(jQuery, Drupal);; 83loadjs=function(){var h=function(){},c={},u={},f={};function o(e,n){if(e){var r=f[e];if(u[e]=n,r)for(;r.length;)r[0](e,n),r.splice(0,1)}}function l(e,n){e.call&&(e={success:e}),n.length?(e.error||h)(n):(e.success||h)(e)}function d(r,t,s,i){var c,o,e=document,n=s.async,u=(s.numRetries||0)+1,f=s.before||h,l=r.replace(/[\?|#].*$/,""),a=r.replace(/^(css|img)!/,"");i=i||0,/(^css!|\.css$)/.test(l)?((o=e.createElement("link")).rel="stylesheet",o.href=a,(c="hideFocus"in o)&&o.relList&&(c=0,o.rel="preload",o.as="style")):/(^img!|\.(png|gif|jpg|svg|webp)$)/.test(l)?(o=e.createElement("img")).src=a:((o=e.createElement("script")).src=r,o.async=void 0===n||n),!(o.onload=o.onerror=o.onbeforeload=function(e){var n=e.type[0];if(c)try{o.sheet.cssText.length||(n="e")}catch(e){18!=e.code&&(n="e")}if("e"==n){if((i+=1)<u)return d(r,t,s,i)}else if("preload"==o.rel&&"style"==o.as)return o.rel="stylesheet";t(r,n,e.defaultPrevented)})!==f(r,o)&&e.head.appendChild(o)}function r(e,n,r){var t,s;if(n&&n.trim&&(t=n),s=(t?r:n)||{},t){if(t in c)throw"LoadJS";c[t]=!0}function i(n,r){!function(e,t,n){var r,s,i=(e=e.push?e:[e]).length,c=i,o=[];for(r=function(e,n,r){if("e"==n&&o.push(e),"b"==n){if(!r)return;o.push(e)}--i||t(o)},s=0;s<c;s++)d(e[s],r,n)}(e,function(e){l(s,e),n&&l({success:n,error:r},e),o(t,e)},s)}if(s.returnPromise)return new Promise(i);i()}return r.ready=function(e,n){return function(e,r){e=e.push?e:[e];var n,t,s,i=[],c=e.length,o=c;
83for(n=function(e,n){n.length&&i.push(e),--o||r(i)};c--;)t=e[c],(s=u[t])?n(t,s):(f[t]=f[t]||[]).push(n)}(e,function(e){l(n,e)}),r},r.done=function(e){o(e,[])},r.reset=function(){c={},u={},f={}},r.isDefined=function(e){return e in c},r}();; 84/** 85* DO NOT EDIT THIS FILE. 86* See the following change record for more information, 87* https://www.drupal.org/node/2815083 88* @preserve 89**/ 90function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } 91function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } 92function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } 93function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } 94function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } 95function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } 96(function ($, window, Drupal, drupalSettings, loadjs, _ref) { 97 var isFocusable = _ref.isFocusable, 98 tabbable = _ref.tabbable; 99 Drupal.behaviors.AJAX = { 100 attach: function attach(context, settings) { 101 function loadAjaxBehavior(base) { 102 var elementSettings = settings.ajax[base]; 103 if (typeof elementSettings.selector === 'undefined') { 104 elementSettings.selector = "#".concat(base); 105 } 106 once('drupal-ajax', $(elementSettings.selector)).forEach(function (el) { 107 elementSettings.element = el; 108 elementSettings.base = base; 109 Drupal.ajax(elementSettings); 110 }); 111 } 112 Object.keys(settings.ajax || {}).forEach(function (base) { 113 return loadAjaxBehavior(base); 114 }); 115 Drupal.ajax.bindAjaxLinks(document.body); 116 once('ajax', '.use-ajax-submit').forEach(function (el) { 117 var elementSettings = {}; 118 elementSettings.url = $(el.form).attr('action'); 119 elementSettings.setClick = true; 120 elementSettings.event = 'click'; 121 elementSettings.progress = { 122 type: 'throbber' 123 }; 124 elementSettings.base = el.id; 125 elementSettings.element = el; 126 Drupal.ajax(elementSettings); 127 }); 128 }, 129 detach: function detach(context, settings, trigger) { 130 if (trigger === 'unload') { 131 Drupal.ajax.expired().forEach(function (instance) { 132 Drupal.ajax.instances[instance.instanceIndex] = null; 133 }); 134 } 135 } 136 }; 137 Drupal.AjaxError = function (xmlhttp, uri, customMessage) { 138 var statusCode; 139 var statusText; 140 var responseText; 141 if (xmlhttp.status) { 142 statusCode = "\n".concat(Drupal.t('An AJAX HTTP error occurred.'), "\n").concat(Drupal.t('HTTP Result Code: !status', { 143 '!status': xmlhttp.status 144 })); 145 } else { 146 statusCode = "\n".concat(Drupal.t('An AJAX HTTP request terminated abnormally.')); 147 } 148 statusCode += "\n".concat(Drupal.t('Debugging information follows.')); 149 var pathText = "\n".concat(Drupal.t('Path: !uri', { 150 '!uri': uri 151 })); 152 statusText = ''; 153 try { 154 statusText = "\n".concat(Drupal.t('StatusText: !statusText', { 155 '!statusText': xmlhttp.statusText.trim() 156 })); 157 } catch (e) {} 158 responseText = ''; 159 try { 160 responseText = "\n".concat(Drupal.t('ResponseText: !responseText', { 161 '!responseText': xmlhttp.responseText.trim() 162 })); 163 } catch (e) {} 164 responseText = responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi, ''); 165 responseText = responseText.replace(/[\n]+\s+/g, '\n'); 166 var readyStateText = xmlhttp.status === 0 ? "\n".concat(Drupal.t('ReadyState: !readyState', { 167 '!readyState': xmlhttp.readyState 168 })) : ''; 169 customMessage = customMessage ? "\n".concat(Drupal.t('CustomMessage: !customMessage', { 170 '!customMessage': customMessage 171 })) : ''; 172 this.message = statusCode + pathText + statusText + customMessage + responseText + readyStateText; 173 this.name = 'AjaxError'; 174 }; 175 Drupal.AjaxError.prototype = new Error(); 176 Drupal.AjaxError.prototype.constructor = Drupal.AjaxError; 177 Drupal.ajax = function (settings) { 178 if (arguments.length !== 1) { 179 throw new Error('Drupal.ajax() function must be called with one configuration object only'); 180 } 181 var base = settings.base || false; 182 var element = settings.element || false; 183 delete settings.base; 184 delete settings.element; 185 if (!settings.progress && !element) { 186 settings.progress = false;
187 } 188 var ajax = new Drupal.Ajax(base, element, settings); 189 ajax.instanceIndex = Drupal.ajax.instances.length; 190 Drupal.ajax.instances.push(ajax); 191 return ajax; 192 }; 193 Drupal.ajax.instances = []; 194 Drupal.ajax.expired = function () { 195 return Drupal.ajax.instances.filter(function (instance) { 196 return instance && instance.element !== false && !document.body.contains(instance.element); 197 }); 198 }; 199 Drupal.ajax.bindAjaxLinks = function (element) { 200 once('ajax', '.use-ajax', element).forEach(function (ajaxLink) { 201 var $linkElement = $(ajaxLink); 202 var elementSettings = { 203 progress: { 204 type: 'throbber' 205 }, 206 dialogType: $linkElement.data('dialog-type'), 207 dialog: $linkElement.data('dialog-options'), 208 dialogRenderer: $linkElement.data('dialog-renderer'), 209 base: $linkElement.attr('id'), 210 element: ajaxLink 211 }; 212 var href = $linkElement.attr('href'); 213 if (href) { 214 elementSettings.url = href; 215 elementSettings.event = 'click'; 216 } 217 Drupal.ajax(elementSettings); 218 }); 219 }; 220 Drupal.Ajax = function (base, element, elementSettings) { 221 var defaults = { 222 event: element ? 'mousedown' : null, 223 keypress: true, 224 selector: base ? "#".concat(base) : null, 225 effect: 'none', 226 speed: 'none', 227 method: 'replaceWith', 228 progress: { 229 type: 'throbber', 230 message: Drupal.t('Please wait...') 231 }, 232 submit: { 233 js: true 234 } 235 }; 236 $.extend(this, defaults, elementSettings); 237 this.commands = new Drupal.AjaxCommands(); 238 this.instanceIndex = false; 239 if (this.wrapper) { 240 this.wrapper = "#".concat(this.wrapper); 241 } 242 this.element = element; 243 this.element_settings = elementSettings; 244 this.elementSettings = elementSettings; 245 if (this.element && this.element.form) { 246 this.$form = $(this.element.form); 247 } 248 if (!this.url) { 249 var $element = $(this.element); 250 if ($element.is('a')) { 251 this.url = $element.attr('href'); 252 } else if (this.element && element.form) { 253 this.url = this.$form.attr('action'); 254 } 255 } 256 var originalUrl = this.url; 257 this.url = this.url.replace(/\/nojs(\/|$|\?|#)/, '/ajax$1'); 258 if (drupalSettings.ajaxTrustedUrl[originalUrl]) { 259 drupalSettings.ajaxTrustedUrl[this.url] = true; 260 } 261 var ajax = this; 262 ajax.options = { 263 url: ajax.url, 264 data: ajax.submit, 265 isInProgress: function isInProgress() { 266 return ajax.ajaxing; 267 }, 268 beforeSerialize: function beforeSerialize(elementSettings, options) { 269 return ajax.beforeSerialize(elementSettings, options); 270 }, 271 beforeSubmit: function beforeSubmit(formValues, elementSettings, options) { 272 ajax.ajaxing = true; 273 return ajax.beforeSubmit(formValues, elementSettings, options); 274 }, 275 beforeSend: function beforeSend(xmlhttprequest, options) { 276 ajax.ajaxing = true; 277 return ajax.beforeSend(xmlhttprequest, options); 278 }, 279 success: function success(response, status, xmlhttprequest) { 280 var _this = this; 281 if (typeof response === 'string') { 282 response = $.parseJSON(response); 283 } 284 if (response !== null && !drupalSettings.ajaxTrustedUrl[ajax.url]) { 285 if (xmlhttprequest.getResponseHeader('X-Drupal-Ajax-Token') !== '1') { 286 var customMessage = Drupal.t('The response failed verification so will not be processed.'); 287 return ajax.error(xmlhttprequest, ajax.url, customMessage); 288 } 289 } 290 return Promise.resolve(ajax.success(response, status)).then(function () { 291 ajax.ajaxing = false; 292 $(document).trigger('ajaxSuccess', [xmlhttprequest, _this]); 293 $(document).trigger('ajaxComplete', [xmlhttprequest, _this]); 294 if (--$.active === 0) { 295 $(document).trigger('ajaxStop'); 296 } 297 }); 298 }, 299 error: function error(xmlhttprequest, status, _error) { 300 ajax.ajaxing = false; 301 }, 302 complete: function complete(xmlhttprequest, status) { 303 if (status === 'error' || status === 'parsererror') { 304 return ajax.error(xmlhttprequest, ajax.url); 305 } 306 }, 307 dataType: 'json', 308 jsonp: false, 309 type: 'POST' 310 }; 311 if (elementSettings.dialog) { 312 ajax.options.data.dialogOptions = elementSettings.dialog; 313 } 314 if (ajax.options.url.indexOf('?') === -1) { 315 ajax.options.url += '?'; 316 } else { 317 ajax.options.url += '&'; 318 } 319 var wrapper = "drupal_".concat(elementSettings.dialogType || 'ajax'); 320 if (elementSettings.dialogRenderer) { 321 wrapper += ".".concat(elementSettings.dialogRenderer); 322 } 323 ajax.options.url += "".concat(Drupal.ajax.WRAPPER_FORMAT, "=").concat(wrapper); 324 $(ajax.element).on(elementSettings.event, function (event) { 325 if (!drupalSettings.ajaxTrustedUrl[ajax.url] && !Drupal.url.isLocal(ajax.url)) { 326 throw new Error(Drupal.t('The callback URL is not local and n
326ot trusted: !url', { 327 '!url': ajax.url 328 })); 329 } 330 return ajax.eventResponse(this, event); 331 }); 332 if (elementSettings.keypress) { 333 $(ajax.element).on('keypress', function (event) { 334 return ajax.keypressResponse(this, event); 335 }); 336 } 337 if (elementSettings.prevent) { 338 $(ajax.element).on(elementSettings.prevent, false); 339 } 340 }; 341 Drupal.ajax.WRAPPER_FORMAT = '_wrapper_format'; 342 Drupal.Ajax.AJAX_REQUEST_PARAMETER = '_drupal_ajax'; 343 Drupal.Ajax.prototype.execute = function () { 344 if (this.ajaxing) { 345 return; 346 } 347 try { 348 this.beforeSerialize(this.element, this.options); 349 return $.ajax(this.options); 350 } catch (e) { 351 this.ajaxing = false; 352 window.alert("An error occurred while attempting to process ".concat(this.options.url, ": ").concat(e.message)); 353 return $.Deferred().reject(); 354 } 355 }; 356 Drupal.Ajax.prototype.keypressResponse = function (element, event) { 357 var ajax = this; 358 if (event.which === 13 || event.which === 32 && element.type !== 'text' && element.type !== 'textarea' && element.type !== 'tel' && element.type !== 'number') { 359 event.preventDefault(); 360 event.stopPropagation(); 361 $(element).trigger(ajax.elementSettings.event); 362 } 363 }; 364 Drupal.Ajax.prototype.eventResponse = function (element, event) { 365 event.preventDefault(); 366 event.stopPropagation(); 367 var ajax = this; 368 if (ajax.ajaxing) { 369 return; 370 } 371 try { 372 if (ajax.$form) { 373 if (ajax.setClick) { 374 element.form.clk = element; 375 } 376 ajax.$form.ajaxSubmit(ajax.options); 377 } else { 378 ajax.beforeSerialize(ajax.element, ajax.options); 379 $.ajax(ajax.options); 380 } 381 } catch (e) { 382 ajax.ajaxing = false; 383 window.alert("An error occurred while attempting to process ".concat(ajax.options.url, ": ").concat(e.message)); 384 } 385 }; 386 Drupal.Ajax.prototype.beforeSerialize = function (element, options) { 387 if (this.$form && document.body.contains(this.$form.get(0))) { 388 var settings = this.settings || drupalSettings; 389 Drupal.detachBehaviors(this.$form.get(0), settings, 'serialize'); 390 } 391 options.data[Drupal.Ajax.AJAX_REQUEST_PARAMETER] = 1; 392 var pageState = drupalSettings.ajaxPageState; 393 options.data['ajax_page_state[theme]'] = pageState.theme; 394 options.data['ajax_page_state[theme_token]'] = pageState.theme_token; 395 options.data['ajax_page_state[libraries]'] = pageState.libraries; 396 }; 397 Drupal.Ajax.prototype.beforeSubmit = function (formValues, element, options) {}; 398 Drupal.Ajax.prototype.beforeSend = function (xmlhttprequest, options) { 399 if (this.$form) { 400 options.extraData = options.extraData || {}; 401 options.extraData.ajax_iframe_upload = '1'; 402 var v = $.fieldValue(this.element); 403 if (v !== null) { 404 options.extraData[this.element.name] = v; 405 } 406 } 407 $(this.element).prop('disabled', true); 408 if (!this.progress || !this.progress.type) { 409 return; 410 } 411 var progressIndicatorMethod = "setProgressIndicator".concat(this.progress.type.slice(0, 1).toUpperCase()).concat(this.progress.type.slice(1).toLowerCase()); 412 if (progressIndicatorMethod in this && typeof this[progressIndicatorMethod] === 'function') { 413 this[progressIndicatorMethod].call(this); 414 } 415 }; 416 Drupal.theme.ajaxProgressThrobber = function (message) { 417 var messageMarkup = typeof message === 'string' ? Drupal.theme('ajaxProgressMessage', message) : ''; 418 var throbber = '<div class="throbber"> </div>'; 419 return "<div class=\"ajax-progress ajax-progress-throbber\">".concat(throbber).concat(messageMarkup, "</div>"); 420 }; 421 Drupal.theme.ajaxProgressIndicatorFullscreen = function () { 422 return '<div class="ajax-progress ajax-progress-fullscreen"> </div>'; 423 }; 424 Drupal.theme.ajaxProgressMessage = function (message) { 425 return "<div class=\"message\">".concat(message, "</div>"); 426 }; 427 Drupal.theme.ajaxProgressBar = function ($element) { 428 return $('<div class="ajax-progress ajax-progress-bar"></div>').append($element); 429 }; 430 Drupal.Ajax.prototype.setProgressIndicatorBar = function () { 431 var progressBar = new Drupal.ProgressBar("ajax-progress-".concat(this.element.i
431d), $.noop, this.progress.method, $.noop); 432 if (this.progress.message) { 433 progressBar.setProgress(-1, this.progress.message); 434 } 435 if (this.progress.url) { 436 progressBar.startMonitoring(this.progress.url, this.progress.interval || 1500); 437 } 438 this.progress.element = $(Drupal.theme('ajaxProgressBar', progressBar.element)); 439 this.progress.object = progressBar; 440 $(this.element).after(this.progress.element); 441 }; 442 Drupal.Ajax.prototype.setProgressIndicatorThrobber = function () { 443 this.progress.element = $(Drupal.theme('ajaxProgressThrobber', this.progress.message)); 444 $(this.element).after(this.progress.element); 445 }; 446 Drupal.Ajax.prototype.setProgressIndicatorFullscreen = function () { 447 this.progress.element = $(Drupal.theme('ajaxProgressIndicatorFullscreen')); 448 $('body').append(this.progress.element); 449 }; 450 Drupal.Ajax.prototype.commandExecutionQueue = function (response, status) { 451 var _this2 = this; 452 var ajaxCommands = this.commands; 453 return Object.keys(response || {}).reduce(function (executionQueue, key) { 454 return executionQueue.then(function () { 455 var command = response[key].command; 456 if (command && ajaxCommands[command]) { 457 return ajaxCommands[command](_this2, response[key], status); 458 } 459 }); 460 }, Promise.resolve()); 461 }; 462 Drupal.Ajax.prototype.success = function (response, status) { 463 var _this3 = this; 464 if (this.progress.element) { 465 $(this.progress.element).remove(); 466 } 467 if (this.progress.object) { 468 this.progress.object.stopMonitoring(); 469 } 470 $(this.element).prop('disabled', false); 471 var elementParents = $(this.element).parents('[data-drupal-selector]').addBack().toArray(); 472 var focusChanged = Object.keys(response || {}).some(function (key) { 473 var _response$key = response[key], 474 command = _response$key.command, 475 method = _response$key.method; 476 return command === 'focusFirst' || command === 'invoke' && method === 'focus'; 477 }); 478 return this.commandExecutionQueue(response, status).then(function () { 479 if (!focusChanged && _this3.element && !$(_this3.element).data('disable-refocus')) { 480 var target = false;
481 for (var n = elementParents.length - 1; !target && n >= 0; n--) { 482 target = document.querySelector("[data-drupal-selector=\"".concat(elementParents[n].getAttribute('data-drupal-selector'), "\"]")); 483 } 484 if (target) { 485 $(target).trigger('focus'); 486 } 487 } 488 if (_this3.$form && document.body.contains(_this3.$form.get(0))) { 489 var settings = _this3.settings || drupalSettings; 490 Drupal.attachBehaviors(_this3.$form.get(0), settings); 491 } 492 _this3.settings = null; 493 }).catch(function (error) { 494 return console.error(Drupal.t('An error occurred during the execution of the Ajax response: !error', { 495 '!error': error 496 })); 497 }); 498 }; 499 Drupal.Ajax.prototype.getEffect = function (response) { 500 var type = response.effect || this.effect; 501 var speed = response.speed || this.speed; 502 var effect = {}; 503 if (type === 'none') { 504 effect.showEffect = 'show'; 505 effect.hideEffect = 'hide'; 506 effect.showSpeed = ''; 507 } else if (type === 'fade') { 508 effect.showEffect = 'fadeIn'; 509 effect.hideEffect = 'fadeOut'; 510 effect.showSpeed = speed; 511 } else { 512 effect.showEffect = "".concat(type, "Toggle"); 513 effect.hideEffect = "".concat(type, "Toggle"); 514 effect.showSpeed = speed; 515 } 516 return effect; 517 }; 518 Drupal.Ajax.prototype.error = function (xmlhttprequest, uri, customMessage) { 519 if (this.progress.element) { 520 $(this.progress.element).remove(); 521 } 522 if (this.progress.object) { 523 this.progress.object.stopMonitoring(); 524 } 525 $(this.wrapper).show(); 526 $(this.element).prop('disabled', false); 527 if (this.$form && document.body.contains(this.$form.get(0))) { 528 var settings = this.settings || drupalSettings; 529 Drupal.attachBehaviors(this.$form.get(0), settings); 530 } 531 throw new Drupal.AjaxError(xmlhttprequest, uri, customMessage); 532 }; 533 Drupal.theme.ajaxWrapperNewContent = function ($newContent, ajax, response) { 534 return (response.effect || ajax.effect) !== 'none' && $newContent.filter(function (i) { 535 return !($newContent[i].nodeName === '#comment' || $newContent[i].nodeName === '#text' && /^(\s|\n|\r)*$/.test($newContent[i].textContent)); 536 }).length > 1 ? Drupal.theme('ajaxWrapperMultipleRootElements', $newContent) : $newContent; 537 }; 538 Drupal.theme.ajaxWrapperMultipleRootElements = function ($elements) { 539 return $('<div></div>').append($elements); 540 }; 541 Drupal.AjaxCommands = function () {}; 542 Drupal.AjaxCommands.prototype = { 543 insert: function insert(ajax, response) { 544 var $wrapper = response.selector ? $(response.selector) : $(ajax.wrapper); 545 var method = response.method || ajax.method; 546 var effect = ajax.getEffect(response); 547 var settings = response.settings || ajax.settings || drupalSettings; 548 var $newContent = $($.parseHTML(response.data, document, true)); 549 $newContent = Drupal.theme('ajaxWrapperNewContent', $newContent, ajax, response); 550 switch (method) { 551 case 'html': 552 case 'replaceWith': 553 case 'replaceAll': 554 case 'empty': 555 case 'remove': 556 Drupal.detachBehaviors($wrapper.get(0), settings); 557 break; 558 default: 559 break; 560 } 561 $wrapper[method]($newContent); 562 if (effect.showEffect !== 'show') { 563 $newContent.hide(); 564 } 565 var $ajaxNewContent = $newContent.find('.ajax-new-content'); 566 if ($ajaxNewContent.length) { 567 $ajaxNewContent.hide(); 568 $newContent.show(); 569 $ajaxNewContent[effect.showEffect](effect.showSpeed); 570 } else if (effect.showEffect !== 'show') { 571 $newContent[effect.showEffect](effect.showSpeed); 572 } 573 if ($newContent.parents('html').length) { 574 $newContent.each(function (index, element) { 575 if (element.nodeType === Node.ELEMENT_NODE) { 576 Drupal.attachBehaviors(element, settings); 577 } 578 }); 579 } 580 }, 581 remove: function remove(ajax, response, status) { 582 var settings = response.settings || ajax.settings || drupalSettings; 583 $(response.selector).each(function () { 584 Drupal.detachBehaviors(this, settings); 585 }).remove(); 586 }, 587 changed: function changed(ajax, response, status) { 588 var $element = $(response.selector); 589 if (!$element.hasClass('ajax-changed')) { 590 $element.addClass('ajax-changed'); 591 if (response.asterisk) { 592 $element.find(response.asterisk).append(" <abbr class=\"ajax-changed\" title=\"".concat(Drupal.t('Changed'), "\">*</abbr> ")); 593 } 594 } 595 }, 596 alert: function alert(ajax, response, status) { 597 window.alert(response.text); 598 }, 599 announce: function announce(ajax, response) { 600 if (response.priority) { 601 Drupal.announce(response.text, response.priority); 602 } else { 603 Drupal.announce(response.text); 604 } 605 }, 606 redirect: function redirect(ajax, response, status) { 607 window.location = response.url; 608 }, 609 css: function css(ajax, response, status) { 610 $(response.selector).css(response.argument); 611 }, 612 settings: function settings(ajax, response, status) { 613 var ajaxSettings = drupalSettings.ajax; 614 if (ajaxSettings) {
615 Drupal.ajax.expired().forEach(function (instance) { 616 if (instance.selector) { 617 var selector = instance.selector.replace('#', ''); 618 if (selector in ajaxSettings) { 619 delete ajaxSettings[selector]; 620 } 621 } 622 }); 623 } 624 if (response.merge) { 625 $.extend(true, drupalSettings, response.settings); 626 } else { 627 ajax.settings = response.settings; 628 } 629 }, 630 data: function data(ajax, response, status) { 631 $(response.selector).data(response.name, response.value); 632 }, 633 focusFirst: function focusFirst(ajax, response, status) { 634 var focusChanged = false; 635 var container = document.querySelector(response.selector); 636 if (container) { 637 var tabbableElements = tabbable(container); 638 if (tabbableElements.length) { 639 tabbableElements[0].focus(); 640 focusChanged = true; 641 } else if (isFocusable(container)) { 642 container.focus(); 643 focusChanged = true; 644 } 645 } 646 if (ajax.hasOwnProperty('element') && !focusChanged) { 647 ajax.element.focus(); 648 } 649 }, 650 invoke: function invoke(ajax, response, status) { 651 var $element = $(response.selector); 652 $element[response.method].apply($element, _toConsumableArray(response.args)); 653 }, 654 restripe: function restripe(ajax, response, status) { 655 $(response.selector).find('> tbody > tr:visible, > tr:visible').removeClass('odd even').filter(':even').addClass('odd').end().filter(':odd').addClass('even'); 656 }, 657 update_build_id: function update_build_id(ajax, response, status) { 658 document.querySelectorAll("input[name=\"form_build_id\"][value=\"".concat(response.old, "\"]")).forEach(function (item) { 659 item.value = response.new; 660 }); 661 }, 662 add_css: function add_css(ajax, response, status) { 663 $('head').prepend(response.data); 664 }, 665 message: function message(ajax, response) { 666 var messages = new Drupal.Message(document.querySelector(response.messageWrapperQuerySelector)); 667 if (response.clearPrevious) { 668 messages.clear(); 669 } 670 messages.add(response.message, response.messageOptions); 671 }, 672 add_js: function add_js(ajax, response, status) { 673 var parentEl = document.querySelector(response.selector || 'body'); 674 var settings = ajax.settings || drupalSettings; 675 var allUniqueBundleIds = response.data.map(function (script) { 676 var uniqueBundleId = script.src + ajax.instanceIndex; 677 loadjs(script.src, uniqueBundleId, { 678 async: false, 679 before: function before(path, scriptEl) { 680 Object.keys(script).forEach(function (attributeKey) { 681 scriptEl.setAttribute(attributeKey, script[attributeKey]); 682 }); 683 parentEl.appendChild(scriptEl); 684 return false; 685 } 686 }); 687 return uniqueBundleId; 688 }); 689 return new Promise(function (resolve, reject) { 690 loadjs.ready(allUniqueBundleIds, { 691 success: function success() { 692 Drupal.attachBehaviors(parentEl, settings); 693 resolve(); 694 }, 695 error: function error(depsNotFound) { 696 var message = Drupal.t("The following files could not be loaded: @dependencies", { 697 '@dependencies': depsNotFound.join(', ') 698 }); 699 reject(message); 700 } 701 }); 702 }); 703 } 704 }; 705 var stopEvent = function stopEvent(xhr, settings) { 706 return xhr.getResponseHeader('X-Drupal-Ajax-Token') === '1' && settings.isInProgress && settings.isInProgress(); 707 }; 708 $.extend(true, $.event.special, { 709 ajaxSuccess: { 710 trigger: function trigger(event, xhr, settings) { 711 if (stopEvent(xhr, settings)) { 712 return false; 713 } 714 } 715 }, 716 ajaxComplete: { 717 trigger: function trigger(event, xhr, settings) { 718 if (stopEvent(xhr, settings)) { 719 $.active++; 720 return false; 721 } 722 } 723 } 724 }); 725})(jQuery, window, Drupal, drupalSettings, loadjs, window.tabbable);; 726/** 727* DO NOT EDIT THIS FILE. 728* See the following change record for more information, 729* https://www.drupal.org/node/2815083 730* @preserve 731**/ 732(function (Drupal) { 733 Drupal.theme.ajaxProgressBar = function ($element) { 734 return $element.addClass('ajax-progress ajax-progress-bar'); 735 }; 736})(Drupal);; 737(function (Drupal) { 738 739 /** 740 * Command to attach data using jQuery's data API. 741 * 742 * @param {Drupal.Ajax} [ajax] 743 * {@link Drupal.Ajax} object created by {@link Drupal.ajax}. 744 * @param {object} response 745 * The response from the Ajax request. 746 * @param {string} response.event_name 747 * The event name 748 * @param {object} response.data 749 * The value of the event. 750 */ 751 Drupal.AjaxCommands.prototype.gtagEvent = function (ajax, response) { 752 gtag('event', response.event_name, response.data) 753 } 754})(Drupal); 755; 756function ctSetCookie(cookies) 757{ 758 759 let useCookies, useAltCookies 760 761 if ('undefined' !== typeof ct_use_cookies) { 762 useCookies = ct_use_cookies; 763 } else { 764 useCookies = false;
765 } 766 767 if ('undefined' !== typeof ct_use_alt_cookies) { 768 useAltCookies = ct_use_alt_cookies; 769 } else { 770 useAltCookies = false 771 } 772 773 if (useCookies) { 774 if (useAltCookies && useAltCookies === 1) { 775 let xhr = new XMLHttpRequest(); 776 777 let json = JSON.stringify(cookies); 778 779 xhr.open("POST", '/admin/config/cleantalk/set_alt_cookies') 780 xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8'); 781 782 xhr.send(json); 783 } else { 784 cookies.forEach( 785 function (e) { 786 let ctSecure = location.protocol === "https:" ? "; secure" : ""; 787 document.cookie = e.name + "=" + encodeURIComponent(e.value) + "; path=/; expires=0; samesite=lax" + ctSecure; 788 } 789 ) 790 } 791 } 792} 793; 794var d = new Date(), 795 ctTimeMs = new Date().getTime(), 796 ctMouseEventTimerFlag = true, //Reading interval flag 797 ctMouseData = "[", 798 ctMouseDataCounter = 0, 799 ctScrollCollected = false; 800 801ctSetCookie( 802 [ 803 { 804 'name' : 'ct_check_js', 805 'value' : ct_check_js_val 806 }, 807 { 808 'name' : 'ct_ps_timestamp', 809 'value' : Math.floor(new Date().getTime()/1000) 810 }, 811 { 812 'name' : 'ct_fkp_timestamp', 813 'value' : '0' 814 }, 815 { 816 'name' : 'ct_pointer_data', 817 'value' : '0' 818 }, 819 { 820 'name' : 'ct_timezone', 821 'value' : d.getTimezoneOffset()/60*(-1) 822 }, 823 { 824 'name' : 'apbct_antibot', 825 'value' : drupal_ac_antibot_cookie_value 826 }, 827 { 828 'name' : 'ct_has_scrolled', 829 'value' : false 830 } 831 ] 832); 833 834//Reading interval 835 836var ctMouseReadInterval = setInterval( 837 function () { 838 ctMouseEventTimerFlag = true; 839 }, 150 840); 841 842//Writting interval 843 844var ctMouseWriteDataInterval = setInterval( 845 function () { 846 if(typeof ct_use_alt_cookies !== "undefined" && ct_use_alt_cookies === 1) { 847 return; 848 } 849 var ctMouseDataToSend = ctMouseData.slice(0,-1).concat("]"); 850 ctSetCookie( 851 [ 852 { 853 'name' : 'ct_pointer_data', 854 'value' : ctMouseDataToSend 855 } 856 ] 857 ); 858 }, 1200 859); 860 861//Stop observing function 862 863function ctMouseStopData() 864{ 865 if(typeof window.addEventListener == "function") { 866 window.removeEventListener("mousemove", ctFunctionMouseMove); 867 } else { 868 window.detachEvent("onmousemove", ctFunctionMouseMove); 869 } 870 clearInterval(ctMouseReadInterval); 871 clearInterval(ctMouseWriteDataInterval); 872} 873 874//Logging mouse position each 300 ms 875 876var ctFunctionMouseMove = function output(event) 877{ 878 if (ctMouseEventTimerFlag == true) { 879 var mouseDate = new Date(); 880 ctMouseData += "[" + Math.round(event.pageY) + "," + Math.round(event.pageX) + "," + Math.round(mouseDate.getTime() - ctTimeMs) + "],"; 881 ctMouseDataCounter++; 882 ctMouseEventTimerFlag = false; 883 if(ctMouseDataCounter >= 100) { 884 ctMouseStopData(); 885 } 886 } 887}; 888 889/** 890 * Set scrolling cookie 891 */ 892function ctSetHasScrolled() 893{ 894 if(! ctScrollCollected ) { 895 ctSetCookie( 896 [ 897 { 898 'name' : 'ct_has_scrolled', 899 'value' : true 900 } 901 ] 902 ); 903 ctScrollCollected = true; 904 } 905} 906 907//Stop key listening function 908 909function ctKeyStopStopListening() 910{ 911 if (typeof window.addEventListener == "function") { 912 window.removeEventListener("mousedown", ctFunctionFirstKey); 913 window.removeEventListener("keydown", ctFunctionFirstKey); 914 } 915 else { 916 window.detachEvent("mousedown", ctFunctionFirstKey); 917 window.detachEvent("keydown", ctFunctionFirstKey); 918 } 919} 920 921//Writing first key press timestamp 922 923var ctFunctionFirstKey = function output(event) 924{ 925 var KeyTimestamp = Math.floor(new Date().getTime()/1000); 926 ctSetCookie( 927 [ 928 { 929 'name' : 'ct_fkp_timestamp', 930 'value' : KeyTimestamp 931 } 932 ] 933 ); 934 ctKeyStopStopListening(); 935}; 936 937if (typeof window.addEventListener == "function") { 938 window.addEventListener("mousemove", ctFunctionMouseMove); 939 window.addEventListener("mousedown", ctFunctionFirstKey); 940 window.addEventListener("keydown", ctFunctionFirstKey); 941 window.addEventListener("scroll", ctSetHasScrolled); 942} 943else { 944 window.attachEvent("onmousemove", ctFunctionMouseMove); 945 window.attachEvent("mousedown", ctFunctionFirstKey); 946 window.attachEvent("keydown", ctFunctionFirstKey); 947 window.attachEvent("scroll", ctSetHasScrolled); 948} 949 950function apbct_collect_visible_fields( form ) 951{ 952 953 // Get only fields 954 var inputs = [], 955 inputs_visible = '', 956 inputs_visible_count = 0, 957 inputs_invisible = '', 958 inputs_invisible_count = 0, 959 inputs_with_duplicate_names = []; 960 961 for(var key in form.elements){ 962 if(!isNaN(+key)) { 963 inputs[key] = form.elements[key]; 964 } 965 } 966 967 // Filter fields
968 inputs = inputs.filter( 969 function (elem) { 970 971 // Filter already added fields 972 if(inputs_with_duplicate_names.indexOf(elem.getAttribute('name')) !== -1 ) { 973 return false; 974 } 975 // Filter inputs with same names for type == radio 976 if(-1 !== ['radio', 'checkbox'].indexOf(elem.getAttribute("type"))) { 977 inputs_with_duplicate_names.push(elem.getAttribute('name')); 978 return false; 979 } 980 return true; 981 } 982 ); 983 984 // Visible fields 985 inputs.forEach( 986 function (elem, i, elements) { 987 // Unnecessary fields 988 if(elem.getAttribute("type") === "submit" // type == submit 989 || elem.getAttribute('name') === null 990 || elem.getAttribute('name') === 'ct_checkjs' 991 ) { 992 return; 993 } 994 // Invisible fields 995 if(getComputedStyle(elem).display === "none" // hidden 996 || getComputedStyle(elem).visibility === "hidden" // hidden 997 || getComputedStyle(elem).opacity === "0" // hidden 998 || elem.getAttribute("type") === "hidden" // type == hidden 999 ) { 1000 if(elem.classList.contains("wp-editor-area") ) { 1001 inputs_visible += " " + elem.getAttribute("name"); 1002 inputs_visible_count++; 1003 } else { 1004 inputs_invisible += " " + elem.getAttribute("name"); 1005 inputs_invisible_count++; 1006 } 1007 } 1008 // Visible fields 1009 else { 1010 inputs_visible += " " + elem.getAttribute("name"); 1011 inputs_visible_count++; 1012 } 1013 1014 } 1015 ); 1016 1017 inputs_invisible = inputs_invisible.trim(); 1018 inputs_visible = inputs_visible.trim(); 1019 1020 return { 1021 visible_fields : inputs_visible, 1022 visible_fields_count : inputs_visible_count, 1023 invisible_fields : inputs_invisible, 1024 invisible_fields_count : inputs_invisible_count, 1025 } 1026 1027} 1028 1029function apbct_visible_fields_set_cookie( visible_fields_collection ) 1030{ 1031 1032 var collection = typeof visible_fields_collection === 'object' && visible_fields_collection !== null ? visible_fields_collection : {}; 1033 1034 ctSetCookie( 1035 [ 1036 { 1037 'name' : 'apbct_visible_fields', 1038 'value' : JSON.stringify(collection) 1039 } 1040 ] 1041 ) 1042} 1043; 1044(function ($, undefined) { 1045 1046 'use strict'; 1047 1048 /** 1049   * Provides enhanced functionality for Pay Portal Paragraphs admin. 1050   * 1051   * @type {Drupal~behavior} 1052   * 1053   * @prop {Drupal~behaviorAttach} attach 1054   *  Adds administrative effects and enhancements for the various 1055 * Paragraphs components that act as the base for this module. 1056   */ 1057 Drupal.behaviors.payportal_admin = { 1058 attach: function (context, settings) { 1059 1060 var 1061 $settings = settings.payportal_admin, 1062 $keys = Object.keys($settings) 1063 ; 1064 1065 // The top level object literal is keyed by the deltas for 1066 // each Pay Portal paragraph instance. 1067 for (var i = 0, c = $keys.length; i < c; i++) { 1068 var $delta = $keys[i]; 1069 1070 // If an Add More set of elements is present for this delta... 1071 if ($settings[$delta]['payprovider_add_more'] !== undefined) { 1072 1073 // Update Add More button text based on the value 1074 // selected in the Add More select. 1075 $($settings[$delta]['payprovider_add_more']['select']).each(function () { 1076 var $this = this; 1077 1078 // Add event handler only once per element per behaviors attachment. 1079 $($this).once('payportal_admin_' + $delta).each(function () { 1080 1081 // Update button text when pay provider select option changes. 1082 $($this).on('change', function () { 1083 var $pattern = $settings[$delta]['payprovider_add_more']['pattern']; 1084 var $text = Drupal.t($pattern, {'@pp': this[this.selectedIndex].innerHTML}); 1085 $($settings[$delta]['payprovider_add_more']['button'], context) 1086 .prop('value', $text) 1087 .text($text); 1088 }); 1089 }); 1090 }); 1091 } 1092 } 1093 } 1094 }; 1095})(jQuery);; 1096/** 1097* DO NOT EDIT THIS FILE. 1098* See the following change record for more information, 1099* https://www.drupal.org/node/2815083 1100* @preserve 1101**/ 1102Drupal.debounce = function (func, wait, immediate) { 1103 var timeout; 1104 var result; 1105 return function () { 1106 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 1107 args[_key] = arguments[_key]; 1108 } 1109 var context = this; 1110 var later = function later() { 1111 timeout = null; 1112 if (!immediate) {
1113 result = func.apply(context, args); 1114 } 1115 }; 1116 var callNow = immediate && !timeout; 1117 clearTimeout(timeout); 1118 timeout = setTimeout(later, wait); 1119 if (callNow) { 1120 result = func.apply(context, args); 1121 } 1122 return result; 1123 }; 1124};; 1125/** 1126* DO NOT EDIT THIS FILE. 1127* See the following change record for more information, 1128* https://www.drupal.org/node/2815083 1129* @preserve 1130**/ 1131(function ($, Drupal, debounce) { 1132 $.fn.drupalGetSummary = function () { 1133 var callback = this.data('summaryCallback'); 1134 return this[0] && callback ? callback(this[0]).trim() : ''; 1135 }; 1136 $.fn.drupalSetSummary = function (callback) { 1137 var self = this; 1138 if (typeof callback !== 'function') { 1139 var val = callback; 1140 callback = function callback() { 1141 return val; 1142 }; 1143 } 1144 return this.data('summaryCallback', callback).off('formUpdated.summary').on('formUpdated.summary', function () { 1145 self.trigger('summaryUpdated'); 1146 }).trigger('summaryUpdated'); 1147 }; 1148 Drupal.behaviors.formSingleSubmit = { 1149 attach: function attach() { 1150 function onFormSubmit(e) { 1151 var $form = $(e.currentTarget); 1152 var formValues = $form.serialize(); 1153 var previousValues = $form.attr('data-drupal-form-submit-last'); 1154 if (previousValues === formValues) { 1155 e.preventDefault(); 1156 } else { 1157 $form.attr('data-drupal-form-submit-last', formValues); 1158 } 1159 } 1160 $(once('form-single-submit', 'body')).on('submit.singleSubmit', 'form:not([method~="GET"])', onFormSubmit); 1161 } 1162 }; 1163 function triggerFormUpdated(element) { 1164 $(element).trigger('formUpdated'); 1165 } 1166 function fieldsList(form) { 1167 return [].map.call(form.querySelectorAll('[name][id]'), function (el) { 1168 return el.id; 1169 }); 1170 } 1171 Drupal.behaviors.formUpdated = { 1172 attach: function attach(context) { 1173 var $context = $(context); 1174 var contextIsForm = $context.is('form'); 1175 var $forms = $(once('form-updated', contextIsForm ? $context : $context.find('form'))); 1176 var formFields; 1177 if ($forms.length) { 1178 $.makeArray($forms).forEach(function (form) { 1179 var events = 'change.formUpdated input.formUpdated '; 1180 var eventHandler = debounce(function (event) { 1181 triggerFormUpdated(event.target); 1182 }, 300); 1183 formFields = fieldsList(form).join(','); 1184 form.setAttribute('data-drupal-form-fields', formFields); 1185 $(form).on(events, eventHandler); 1186 }); 1187 } 1188 if (contextIsForm) { 1189 formFields = fieldsList(context).join(','); 1190 var currentFields = $(context).attr('data-drupal-form-fields'); 1191 if (formFields !== currentFields) { 1192 triggerFormUpdated(context); 1193 } 1194 } 1195 }, 1196 detach: function detach(context, settings, trigger) { 1197 var $context = $(context); 1198 var contextIsForm = $context.is('form'); 1199 if (trigger === 'unload') { 1200 once.remove('form-updated', contextIsForm ? $context : $context.find('form')).forEac
1200h(function (form) { 1201 form.removeAttribute('data-drupal-form-fields'); 1202 $(form).off('.formUpdated'); 1203 }); 1204 } 1205 } 1206 }; 1207 Drupal.behaviors.fillUserInfoFromBrowser = { 1208 attach: function attach(context, settings) { 1209 var userInfo = ['name', 'mail', 'homepage']; 1210 var $forms = $(once('user-info-from-browser', '[data-user-info-from-browser]')); 1211 if ($forms.length) { 1212 userInfo.forEach(function (info) { 1213 var $element = $forms.find("[name=".concat(info, "]")); 1214 var browserData = localStorage.getItem("Drupal.visitor.".concat(info)); 1215 if (!$element.length) { 1216 return; 1217 } 1218 var emptyValue = $element[0].value === ''; 1219 var defaultValue = $element.attr('data-drupal-default-value') === $element[0].value; 1220 if (browserData && (emptyValue || defaultValue)) { 1221 $element.each(function (index, item) { 1222 item.value = browserData; 1223 }); 1224 } 1225 }); 1226 } 1227 $forms.on('submit', function () { 1228 userInfo.forEach(function (info) { 1229 var $element = $forms.find("[name=".concat(info, "]")); 1230 if ($element.length) { 1231 localStorage.setItem("Drupal.visitor.".concat(info), $element[0].value); 1232 } 1233 }); 1234 }); 1235 } 1236 }; 1237 var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e) { 1238 var url; 1239 if (e.type === 'click') { 1240 url = e.currentTarget.location ? e.currentTarget.location : e.currentTarget; 1241 } else { 1242 url = window.location; 1243 } 1244 var hash = url.hash.substr(1); 1245 if (hash) { 1246 var $target = $("#".concat(hash)); 1247 $('body').trigger('formFragmentLinkClickOrHashChange', [$target]); 1248 setTimeout(function () { 1249 return $target.trigger('focus'); 1250 }, 300); 1251 } 1252 }; 1253 var debouncedHandleFragmentLinkClickOrHashChange = debounce(handleFragmentLinkClickOrHashChange, 300, true); 1254 $(window).on('hashchange.form-fragment', debouncedHandleFragmentLinkClickOrHashChange); 1255 $(document).on('click.form-fragment', 'a[href*="#"]', debouncedHandleFragmentLinkClickOrHashChange); 1256})(jQuery, Drupal, Drupal.debounce);; 1257/** 1258 * @file 1259 * Webform behaviors. 1260 */ 1261 1262(function ($, Drupal) { 1263 1264 'use strict'; 1265 1266 // Trigger Drupal's attaching of behaviors after the page is 1267 // completely loaded. 1268 // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button 1269 // @see https://stackoverflow.com/questions/20899274/how-to-refresh-page-on-back-button-click/20899422#20899422 1270 var isChrome = (/chrom(e|ium)/.test(window.navigator.userAgent.toLowerCase())); 1271 if (isChrome) { 1272 // Track back button in navigation. 1273 // @see https://stackoverflow.com/questions/37838430/detect-if-page-is-load-from-back-button 1274 var backButton = false; 1275 if (window.performance) { 1276 var navEntries = window.performance.getEntriesByType('navigation'); 1277 if (navEntries.length > 0 && navEntries[0].type === 'back_forward') { 1278 backButton = true; 1279 } 1280 else if (window.performance.navigation 1281 && window.performance.navigation.type === window.performance.navigation.TYPE_BACK_FORWARD) { 1282 backButton = true; 1283 } 1284 } 1285 1286 // If the back button is pressed, delay Drupal's attaching of behaviors. 1287 if (backButton) { 1288 var attachBehaviors = Drupal.attachBehaviors; 1289 Drupal.attachBehaviors = function (context, settings) { 1290 setTimeout(function (context, settings) { 1291 attachBehaviors(context, settings); 1292 }, 300); 1293 }; 1294 } 1295 } 1296 1297})(jQuery, Drupal); 1298; 1299/** 1300* DO NOT EDIT THIS FILE. 1301* See the following change record for more information, 1302* https://www.drupal.org/node/2815083 1303* @preserve 1304**/ 1305(function ($, Drupal) { 1306 var states = { 1307 postponed: [] 1308 }; 1309 Drupal.states = states; 1310 function invert(a, invertState) { 1311 return invertState && typeof a !== 'undefined' ? !a : a; 1312 } 1313 function _compare2(a, b) { 1314 if (a === b) { 1315 return typeof a === 'undefined' ? a : true; 1316 } 1317 return typeof a === 'undefined' || typeof b === 'undefined'; 1318 } 1319 function ternary(a, b) { 1320 if (typeof a === 'undefined') { 1321 return b; 1322 } 1323 if (typeof b === 'undefined') { 1324 return a; 1325 } 1326 return a && b; 1327 } 1328 Drupal.behaviors.states = { 1329 attach: function attach(context, settings) { 1330 var $states = $(context).find('[data-drupal-states]'); 1331 var il = $states.length; 1332 var _loop = function _loop(i) { 1333 var config = JSON.parse($states[i].getAttribute('data-drupal-states')); 1334 Object.keys(config || {}
1334).forEach(function (state) { 1335 new states.Dependent({ 1336 element: $($states[i]), 1337 state: states.State.sanitize(state), 1338 constraints: config[state] 1339 }); 1340 }); 1341 }; 1342 for (var i = 0; i < il; i++) { 1343 _loop(i); 1344 } 1345 while (states.postponed.length) { 1346 states.postponed.shift()(); 1347 } 1348 } 1349 }; 1350 states.Dependent = function (args) { 1351 var _this = this; 1352 $.extend(this, { 1353 values: {}, 1354 oldValue: null 1355 }, args); 1356 this.dependees = this.getDependees(); 1357 Object.keys(this.dependees || {}).forEach(function (selector) { 1358 _this.initializeDependee(selector, _this.dependees[selector]); 1359 }); 1360 }; 1361 states.Dependent.comparisons = { 1362 RegExp: function RegExp(reference, value) { 1363 return reference.test(value); 1364 }, 1365 Function: function Function(reference, value) { 1366 return reference(value); 1367 }, 1368 Number: function Number(reference, value) { 1369 return typeof value === 'string' ? _compare2(reference.toString(), value) : _compare2(reference, value); 1370 } 1371 }; 1372 states.Dependent.prototype = { 1373 initializeDependee: function initializeDependee(selector, dependeeStates) { 1374 var _this2 = this; 1375 this.values[selector] = {}; 1376 Object.keys(dependeeStates).forEach(function (i) { 1377 var state = dependeeStates[i]; 1378 if ($.inArray(state, dependeeStates) === -1) { 1379 return; 1380 } 1381 state = states.State.sanitize(state); 1382 _this2.values[selector][state.name] = null; 1383 $(selector).on("state:".concat(state), { 1384 selector: selector, 1385 state: state 1386 }, function (e) { 1387 _this2.update(e.data.selector, e.data.state, e.value); 1388 }); 1389 new states.Trigger({ 1390 selector: selector, 1391 state: state 1392 }); 1393 }); 1394 }, 1395 compare: function compare(reference, selector, state) { 1396 var value = this.values[selector][state.name]; 1397 if (reference.constructor.name in states.Dependent.comparisons) { 1398 return states.Dependent.comparisons[reference.constructor.name](reference, value); 1399 } 1400 return _compare2(reference, value); 1401 }, 1402 update: function update(selector, state, value) { 1403 if (value !== this.values[selector][state.name]) { 1404 this.values[selector][state.name] = value; 1405 this.reevaluate(); 1406 } 1407 }, 1408 reevaluate: function reevaluate() { 1409 var value = this.verifyConstraints(this.constraints); 1410 if (value !== this.oldValue) { 1411 this.oldValue = value; 1412 value = invert(value, this.state.invert); 1413 this.element.trigger({ 1414 type: "state:".concat(this.state), 1415 value: value, 1416 trigger: true 1417 }); 1418 } 1419 }, 1420 verifyConstraints: function verifyConstraints(constraints, selector) { 1421 var result; 1422 if ($.isArray(constraints)) { 1423 var hasXor = $.inArray('xor', constraints) === -1; 1424 var len = constraints.length; 1425 for (var i = 0; i < len; i++) { 1426 if (constraints[i] !== 'xor') { 1427 var constraint = this.checkConstraints(constraints[i], selector, i); 1428 if (constraint && (hasXor || result)) { 1429 return hasXor; 1430 } 1431 result = result || constraint; 1432 } 1433 } 1434 } else if ($.isPlainObject(constraints)) { 1435 for (var n in constraints) { 1436 if (constraints.hasOwnProperty(n)) { 1437 result = ternary(result, this.checkConstraints(constraints[n], selector, n)); 1438 if (result === false) { 1439 return false; 1440 } 1441 } 1442 } 1443 } 1444 return result; 1445 }, 1446 checkConstraints: function checkConstraints(value, selector, state) { 1447 if (typeof state !== 'string' || /[0-9]/.test(state[0])) { 1448 state = null; 1449 } else if (typeof selector === 'undefined') { 1450 selector = state; 1451 state = null; 1452 } 1453 if (state !== null) { 1454 state = states.State.sanitize(state); 1455 return invert(this.compare(value, selector, state), state.invert); 1456 } 1457 return this.verifyConstraints(value, selector); 1458 }, 1459 getDependees: function getDependees() { 1460 var cache = {}; 1461 var _compare = this.compare; 1462 this.compare = function (reference, selector, state) { 1463 (cache[selector] || (cache[selector] = [])).push(state.name); 1464 }; 1465 this.verifyConstraints(this.constraints); 1466 this.compare = _compare; 1467 return cache; 1468 } 1469 }; 1470 states.Trigger = function (args) { 1471 $.extend(this, args); 1472 if (this.state in states.Trigger.states) { 1473 this.element = $(this.selector); 1474 if (!this.element.data("trigger:".concat(this.state))) { 1475 this.initialize(); 1476 } 1477 } 1478 }; 1479 states.Trigger.prototype = { 1480 initialize: function initialize() { 1481 var _this3 = this; 1482 var trigger = states.Trigger.states[this.state]; 1483 if (typeof trigger === 'function') { 1484 trigger.call(window, this.element); 1485 } else { 1486 Object.keys(trigger || {}
1486).forEach(function (event) { 1487 _this3.defaultTrigger(event, trigger[event]); 1488 }); 1489 } 1490 this.element.data("trigger:".concat(this.state), true); 1491 }, 1492 defaultTrigger: function defaultTrigger(event, valueFn) { 1493 var oldValue = valueFn.call(this.element); 1494 this.element.on(event, $.proxy(function (e) { 1495 var value = valueFn.call(this.element, e); 1496 if (oldValue !== value) { 1497 this.element.trigger({ 1498 type: "state:".concat(this.state), 1499 value: value, 1500 oldValue: oldValue 1501 }); 1502 oldValue = value; 1503 } 1504 }, this)); 1505 states.postponed.push($.proxy(function () { 1506 this.element.trigger({ 1507 type: "state:".concat(this.state), 1508 value: oldValue, 1509 oldValue: null 1510 }); 1511 }, this)); 1512 } 1513 }; 1514 states.Trigger.states = { 1515 empty: { 1516 keyup: function keyup() { 1517 return this.val() === ''; 1518 }, 1519 change: function change() { 1520 return this.val() === ''; 1521 } 1522 }, 1523 checked: { 1524 change: function change() { 1525 var checked = false; 1526 this.each(function () { 1527 checked = $(this).prop('checked'); 1528 return !checked; 1529 }); 1530 return checked; 1531 } 1532 }, 1533 value: { 1534 keyup: function keyup() { 1535 if (this.length > 1) { 1536 return this.filter(':checked').val() || false; 1537 } 1538 return this.val(); 1539 }, 1540 change: function change() { 1541 if (this.length > 1) { 1542 return this.filter(':checked').val() || false; 1543 } 1544 return this.val(); 1545 } 1546 }, 1547 collapsed: { 1548 collapsed: function collapsed(e) { 1549 return typeof e !== 'undefined' && 'value' in e ? e.value : !this.is('[open]'); 1550 } 1551 } 1552 }; 1553 states.State = function (state) { 1554 this.pristine = state; 1555 this.name = state; 1556 var process = true; 1557 do { 1558 while (this.name.charAt(0) === '!') { 1559 this.name = this.name.substring(1); 1560 this.invert = !this.invert; 1561 } 1562 if (this.name in states.State.aliases) { 1563 this.name = states.State.aliases[this.name]; 1564 } else { 1565 process = false; 1566 } 1567 } while (process); 1568 }; 1569 states.State.sanitize = function (state) { 1570 if (state instanceof states.State) { 1571 return state; 1572 } 1573 return new states.State(state); 1574 }; 1575 states.State.aliases = { 1576 enabled: '!disabled', 1577 invisible: '!visible', 1578 invalid: '!valid', 1579 untouched: '!touched', 1580 optional: '!required', 1581 filled: '!empty', 1582 unchecked: '!checked', 1583 irrelevant: '!relevant', 1584 expanded: '!collapsed', 1585 open: '!collapsed', 1586 closed: 'collapsed', 1587 readwrite: '!readonly' 1588 }; 1589 states.State.prototype = { 1590 invert: false, 1591 toString: function toString() { 1592 return this.name; 1593 } 1594 }; 1595 var $document = $(document); 1596 $document.on('state:disabled', function (e) { 1597 if (e.trigger) { 1598 $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value).find('select, input, textarea').prop('disabled', e.value); 1599 } 1600 }); 1601 $document.on('state:required', function (e) { 1602 if (e.trigger) { 1603 if (e.value) { 1604 var label = "label".concat(e.target.id ? "[for=".concat(e.target.id, "]") : ''); 1605 var $label = $(e.target).attr({ 1606 required: 'required', 1607 'aria-required': 'true' 1608 }).closest('.js-form-item, .js-form-wrapper').find(label); 1609 if (!$label.hasClass('js-form-required').length) { 1610 $label.addClass('js-form-required form-required'); 1611 } 1612 } else { 1613 $(e.target).removeAttr('required aria-required').closest('.js-form-item, .js-form-wrapper').find('label.js-form-required').removeClass('js-form-required form-required'); 1614 } 1615 } 1616 }); 1617 $document.on('state:visible', function (e) { 1618 if (e.trigger) { 1619 $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggle(e.value); 1620 } 1621 }); 1622 $document.on('state:checked', function (e) { 1623 if (e.trigger) { 1624 $(e.target).closest('.js-form-item, .js-form-wrapper').find('input').prop('checked', e.value).trigger('change'); 1625 } 1626 }); 1627 $document.on('state:collapsed', function (e) { 1628 if (e.trigger) { 1629 if ($(e.target).is('[open]') === e.value) { 1630 $(e.target).find('> summary').trigger('click'); 1631 } 1632 } 1633 }); 1634})(jQuery, Drupal);; 1635/** 1636 * @file 1637 * JavaScript behaviors for custom webform #states. 1638 */ 1639 1640(function ($, Drupal, once) { 1641 1642 'use strict'; 1643 1644 Drupal.webform = Drupal.webform || {}; 1645 Drupal.webform.states = Drupal.webform.states || {}; 1646 Drupal.webform.states.slideDown = Drupal.webform.states.slideDown || {}; 1647 Drupal.webform.states.slideDown.duration = 'slow'; 1648 Drupal.webform.states.slideUp = Drupal.webform.states.slideUp || {}; 1649 Drupal.webform.states.slideUp.duration = 'fast'; 1650 1651 /* ************************************************************************ */ 1652 // jQuery functions. 1653 /* ************************************************************************ */ 1654 1655 /** 1656 * Check if an element has a specified data attribute. 1657 * 1658 * @param {string} data 1659 * The data attribute name. 1660 * 1661 * @return {boolean} 1662 * TRUE if an element has a specified data attribute. 1663 */ 1664 $.fn.hasData = function (data) { 1665 return (typeof this.data(data) !== 'undefined'); 1666 }; 1667 1668 /**
1669 * Check if element is within the webform or not. 1670 * 1671 * @return {boolean} 1672 * TRUE if element is within the webform. 1673 */ 1674 $.fn.isWebform = function () { 1675 return $(this).closest('form.webform-submission-form, form[id^="webform"], form[data-is-webform]').length ? true : false; 1676 }; 1677 1678 /** 1679 * Check if element is to be treated as a webform element. 1680 * 1681 * @return {boolean} 1682 * TRUE if element is to be treated as a webform element. 1683 */ 1684 $.fn.isWebformElement = function () { 1685 return ($(this).isWebform() || $(this).closest('[data-is-webform-element]').length) ? true : false; 1686 }; 1687 1688 /* ************************************************************************ */ 1689 // Trigger. 1690 /* ************************************************************************ */ 1691 1692 // The change event is triggered by cut-n-paste and select menus. 1693 // Issue #2445271: #states element empty check not triggered on mouse 1694 // based paste. 1695 // @see https://www.drupal.org/node/2445271 1696 Drupal.states.Trigger.states.empty.change = function change() { 1697 return this.val() === ''; 1698 }; 1699 1700 /* ************************************************************************ */ 1701 // Dependents. 1702 /* ************************************************************************ */ 1703 1704 // Apply solution included in #1962800 patch. 1705 // Issue #1962800: Form #states not working with literal integers as 1706 // values in IE11. 1707 // @see https://www.drupal.org/project/drupal/issues/1962800 1708 // @see https://www.drupal.org/files/issues/core-states-not-working-with-integers-ie11_1962800_46.patch 1709 // 1710 // This issue causes pattern, less than, and greater than support to break. 1711 // @see https://www.drupal.org/project/webform/issues/2981724 1712 var states = Drupal.states; 1713 Drupal.states.Dependent.prototype.compare = function compare(reference, selector, state) { 1714 var value = this.values[selector][state.name]; 1715 1716 var name = reference.constructor.name; 1717 if (!name) { 1718 name = $.type(reference); 1719 1720 name = name.charAt(0).toUpperCase() + name.slice(1); 1721 } 1722 if (name in states.Dependent.comparisons) { 1723 return states.Dependent.comparisons[name](reference, value); 1724 } 1725 1726 if (reference.constructor.name in states.Dependent.comparisons) { 1727 return states.Dependent.comparisons[reference.constructor.name](reference, value); 1728 } 1729 1730 return _compare2(reference, value); 1731 }; 1732 function _compare2(a, b) { 1733 if (a === b) { 1734 return typeof a === 'undefined' ? a : true; 1735 } 1736 1737 return typeof a === 'undefined' || typeof b === 'undefined'; 1738 } 1739 1740 // Adds pattern, less than, and greater than support to #state API. 1741 // @see http://drupalsun.com/julia-evans/2012/03/09/extending-form-api-states-regular-expressions 1742 Drupal.states.Dependent.comparisons.Object = function (reference, value) { 1743 if ('pattern' in reference) { 1744 return (new RegExp(reference['pattern'])).test(value); 1745 } 1746 else if ('!pattern' in reference) { 1747 return !((new RegExp(reference['!pattern'])).test(value)); 1748 } 1749 else if ('less' in reference) { 1750 return (value !== '' && parseFloat(reference['less']) > parseFloat(value)); 1751 } 1752 else if ('less_equal' in reference) { 1753 return (value !== '' && parseFloat(reference['less_equal']) >= parseFloat(value)); 1754 } 1755 else if ('greater' in reference) { 1756 return (value !== '' && parseFloat(reference['greater']) < parseFloat(value)); 1757 } 1758 else if ('greater_equal' in reference) { 1759 return (value !== '' && parseFloat(reference['greater_equal']) <= parseFloat(value)); 1760 } 1761 else if ('between' in reference || '!between' in reference) { 1762 if (value === '') { 1763 return false; 1764 } 1765 1766 var between = reference['between'] || reference['!between']; 1767 var betweenParts = between.split(':'); 1768 var greater = betweenParts[0]; 1769 var less = (typeof betweenParts[1] !== 'undefined') ? betweenParts[1] : null; 1770 var isGreaterThan = (greater === null || greater === '' || parseFloat(value) >= parseFloat(greater)); 1771 var isLessThan = (less === null || less === '' || parseFloat(value) <= parseFloat(less)); 1772 var result = (isGreaterThan && isLessThan); 1773 return (reference['!between']) ? !result : result; 1774 } 1775 else { 1776 return reference.indexOf(value) !== false; 1777 } 1778 }; 1779 1780 /* ************************************************************************ */ 1781 // States events. 1782 /* ************************************************************************ */ 1783 1784 var $document = $(document); 1785 1786 $document.on('state:required', function (e) { 1787 if (e.trigger && $(e.target).isWebformElement()) { 1788 var $target = $(e.target); 1789 // Fix #required file upload. 1790 // @see Issue #2860529: Conditional required File upload field don't work. 1791 toggleRequired($target.find('input[type="file"]'), e.value); 1792 1793 // Fix #required for radios and likert. 1794 // @see Issue #2856795: If radio buttons are required but not filled form is nevertheless submitted. 1795 if ($target.is('.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other, .js-webform-type-webform-entity-radios, .webform-likert-table')) { 1796 $target.toggleClass('required', e.value); 1797 toggleRequired($target.find('input[type="radio"]'), e.value); 1798 } 1799 1800 // Fix #required for checkboxes. 1801 // @see Issue #2938414: Checkboxes don't support #states required. 1802 // @see checkboxRequiredhandler 1803 if ($target.is('.js-form-type-checkboxes, .js-form-type-webform-checkboxes-other, .js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other')) { 1804 $target.toggleClass('required', e.value); 1805 var $checkboxes = $target.find('input[type="checkbox"]'); 1806 if (e.value) { 1807 // Add event handler. 1808 $checkboxes.on('click', statesCheckboxesRequiredEventHandler); 1809 // Initialize and add required attribute. 1810 checkboxesRequired($target); 1811 } 1812 else { 1813 // Remove event handler. 1814 $checkboxes.off('click', statesCheckboxesRequiredEventHandler); 1815 // Remove required attribute. 1816 toggleRequired($checkboxes, false); 1817 } 1818 } 1819 1820 // Fix #required for tableselect. 1821 // @see Issue #3212581: Table select does not trigger client side validation 1822 if ($target.is('.js-webform-tableselect')) { 1823 $target.toggleClass('required', e.value); 1824 var isMultiple = $target.is('[multiple]'); 1825 if (isMultiple) { 1826 // Checkboxes. 1827 var $tbody = $target.find('tbody'); 1828 var $checkboxes = $tbody.find('input[type="checkbox"]'); 1829 copyRequireMessage($target, $checkboxes); 1830 if (e.value) { 1831 $checkboxes.on('click change', statesCheckboxesRequiredEventHandler); 1832 checkboxesRequired($tbody); 1833 } 1834 else { 1835 $checkboxes.off('click change ', statesCheckboxesRequiredEventHandler); 1836 toggleRequired($tbody, false); 1837 } 1838 } 1839 else { 1840 // Radios. 1841 var $radios = $target.find('input[type="radio"]'); 1842 copyRequireMessage($target, $radios); 1843 toggleRequired($radios, e.value); 1844 } 1845 } 1846 1847 // Fix required label for elements without the for attribute. 1848 // @see Issue #3145300: Conditional Visible Select Other not working. 1849 if ($target.is('.js-form-type-webform-select-other, .js-webform-type-webform-select-other')) { 1850 var $select = $target.find('select'); 1851 toggleRequired($select, e.value); 1852 copyRequireMessage($target, $select); 1853 } 1854 if ($target.find('> label:not([for])').length) { 1855 $target.find('> label').toggleClass('js-form-required form-required', e.value); 1856 } 1857 1858 // Fix required label for checkboxes and radios. 1859 // @see Issue #2938414: Checkboxes don't support #states required 1860 // @see Issue #2731991: Setting required on radios marks all options required. 1861 // @see Issue #2856315: Conditional Logic - Requiring Radios in a Fieldset. 1862 // Fix #required for fieldsets. 1863 // @see Issue #2977569: Hidden fieldsets that become visible with conditional logic cannot be made required. 1864 if ($target.is('.js-webform-type-radios, .js-webform-type-checkboxes, fieldset')) { 1865 $target.find('legend span.fieldset-legend:not(.visually-hidden),legend span.fieldset__label:not(.visually-hidden)').toggleClass('js-form-required form-required', e.value); 1866 } 1867 1868 // Issue #2986017: Fieldsets shouldn't have required attribute. 1869 if ($target.is('fieldset')) { 1870 $target.removeAttr('required aria-required'); 1871 } 1872 } 1873 }); 1874 1875 $document.on('state:checked', function (e) { 1876 if (e.trigger) { 1877 $(e.target).trigger('change'); 1878 } 1879 }); 1880 1881 $document.on('state:readonly', function (e) { 1882 if (e.trigger && $(e.target).isWebformElement()) { 1883 $(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); 1884 1885 // Trigger webform:readonly. 1886 $(e.target).trigger('webform:readonly') 1887 .find('select, input, textarea, button').trigger('webform:readonly'); 1888 } 1889 }); 1890 1891 $document.on('state:visible state:visible-slide', function (e) { 1892 if (e.trigger && $(e.target).isWebformElement()) { 1893 if (e.value) { 1894 $(':input', e.target).addBack().each(function () { 1895 restoreValueAndRequired(this); 1896 triggerEventHandlers(this); 1897 }); 1898 } 1899 else { 1900 // @see https://www.sitepoint.com/jquery-function-clear-form-data/ 1901 $(':input', e.target).addBack().each(function () { 1902 backupValueAndRequired(this); 1903 clearValueAndRequired(this); 1904 triggerEventHandlers(this); 1905 }); 1906 } 1907 } 1908 }); 1909 1910 $document.on('state:visible-slide', function (e) { 1911 if (e.trigger && $(e.target).isWebformElement()) { 1912 var effect = e.value ? 'slideDown' : 'slideUp'; 1913 var duration = Drupal.webform.states[effect].duration; 1914 $(e.target).closest('.js-form-item, .js-form-submit, .js-form-wrapper')[effect](duration); 1915 } 1916 }); 1917 Drupal.states.State.aliases['invisible-slide'] = '!visible-slide'; 1918 1919 $document.on('state:disabled', function (e) { 1920 if (e.trigger && $(e.target).isWebformElement()) { 1921 // Make sure disabled property is set before triggering webform:disabled. 1922 // Copied from: core/misc/states.js 1923 $(e.target) 1924 .prop('disabled', e.value) 1925 .closest('.js-form-item, .js-form-submit, .js-form-wrapper').toggleClass('form-disabled', e.value) 1926 .find('select, input, textarea, button').prop('disabled', e.value); 1927 1928 // Never disable hidden file[fids] because the existing values will 1929 // be completely lost when the webform is submitted. 1930 var fileElements = $(e.target) 1931 .find(':input[type="hidden"][name$="[fids]"]'); 1932 if (fileElements.length) { 1933 // Remove 'disabled' attribute from fieldset which will block 1934 // all disabled elements from being submitted. 1935 if ($(e.target).is('fieldset')) { 1936 $(e.target).prop('disabled', false); 1937 } 1938 fileElements.removeAttr('disabled'); 1939 } 1940 1941 // Trigger webform:disabled. 1942 $(e.target).trigger('webform:disabled') 1943 .find('select, input, textarea, button').trigger('webform:disabled'); 1944 } 1945 }); 1946 1947 /* ************************************************************************ */ 1948 // Behaviors. 1949 /* ************************************************************************ */ 1950 1951 /** 1952 * Adds HTML5 validation to required checkboxes. 1953 * 1954 * @type {Drupal~behavior} 1955 * 1956 * @see https://www.drupal.org/project/webform/issues/3068998 1957 */ 1958 Drupal.behaviors.webformCheckboxesRequired = { 1959 attach: function (context) { 1960 $(once('webform-checkboxes-required', '.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)) 1961 .each(function () { 1962 var $element = $(this); 1963 $element.find('input[type="checkbox"]').on('click', statesCheckboxesRequiredEventHandler); 1964 setTimeout(function () {checkboxesRequired($element);}); 1965 }); 1966 } 1967 }; 1968 1969 /** 1970 * Adds HTML5 validation to required radios. 1971 * 1972 * @type {Drupal~behavior} 1973 * 1974 * @see https://www.drupal.org/project/webform/issues/2856795 1975 */ 1976 Drupal.behaviors.webformRadiosRequired = { 1977 attach: function (context) { 1978 $(once('webform-radios-required', '.js-form-type-radios, .js-form-type-webform-radios-other, .js-webform-type-radios, .js-webform-type-webform-radios-other, .js-webform-type-webform-entity-radios, .js-webform-type-webform-scale', context)) 1979 .each(function () { 1980 var $element = $(this); 1981 setTimeout(function () {radiosRequired($element);}); 1982 }); 1983 } 1984 }; 1985 1986 /** 1987 * Adds HTML5 validation to required table select. 1988 * 1989 * @type {Drupal~behavior} 1990 * 1991 * @see https://www.drupal.org/project/webform/issues/2856795 1992 */ 1993 Drupal.behaviors.webformTableSelectRequired = { 1994 attach: function (context) { 1995 $(once('webform-tableselect-required','.js-webform-tableselect.required', context)) 1996 .each(function () { 1997 var $element = $(this); 1998 var $tbody = $element.find('tbody'); 1999 var isMultiple = $element.is('[multiple]'); 2000 2001 if (isMultiple) { 2002 // Check all checkbox triggers checkbox 'change' event on 2003 // select and deselect all. 2004 // @see Drupal.tableSelect 2005 $tbody.find('input[type="checkbox"]').on('click change', function () { 2006 checkboxesRequired($tbody); 2007 }); 2008 } 2009 2010 setTimeout(function () { 2011 isMultiple ? checkboxesRequired($tbody) : radiosRequired($element); 2012 }); 2013 }); 2014 } 2015 }; 2016 2017 /** 2018 * Add HTML5 multiple checkboxes required validation. 2019 * 2020 * @param {jQuery} $element
2021 * An jQuery object containing HTML5 radios. 2022 * 2023 * @see https://stackoverflow.com/a/37825072/145846 2024 */ 2025 function checkboxesRequired($element) { 2026 var $firstCheckbox = $element.find('input[type="checkbox"]').first(); 2027 var isChecked = $element.find('input[type="checkbox"]').is(':checked'); 2028 toggleRequired($firstCheckbox, !isChecked); 2029 copyRequireMessage($element, $firstCheckbox); 2030 } 2031 2032 /** 2033 * Add HTML5 radios required validation. 2034 * 2035 * @param {jQuery} $element 2036 * An jQuery object containing HTML5 radios. 2037 * 2038 * @see https://www.drupal.org/project/webform/issues/2856795 2039 */ 2040 function radiosRequired($element) { 2041 var $radios = $element.find('input[type="radio"]'); 2042 var isRequired = $element.hasClass('required'); 2043 toggleRequired($radios, isRequired); 2044 copyRequireMessage($element, $radios); 2045 } 2046 2047 /* ************************************************************************ */ 2048 // Event handlers. 2049 /* ************************************************************************ */ 2050 2051 /** 2052 * Trigger #states API HTML5 multiple checkboxes required validation. 2053 * 2054 * @see https://stackoverflow.com/a/37825072/145846 2055 */ 2056 function statesCheckboxesRequiredEventHandler() { 2057 var $element = $(this).closest('.js-webform-type-checkboxes, .js-webform-type-webform-checkboxes-other'); 2058 checkboxesRequired($element); 2059 } 2060 2061 /** 2062 * Trigger an input's event handlers. 2063 * 2064 * @param {element} input 2065 * An input. 2066 */ 2067 function triggerEventHandlers(input) { 2068 var $input = $(input); 2069 var type = input.type; 2070 var tag = input.tagName.toLowerCase(); 2071 // Add 'webform.states' as extra parameter to event handlers. 2072 // @see Drupal.behaviors.webformUnsaved 2073 var extraParameters = ['webform.states']; 2074 if (type === 'checkbox' || type === 'radio') { 2075 $input 2076 .trigger('change', extraParameters) 2077 .trigger('blur', extraParameters); 2078 } 2079 else if (tag === 'select') { 2080 // Do not trigger the onchange event for Address element's country code 2081 // when it is initialized. 2082 // @see \Drupal\address\Element\Country 2083 if ($input.closest('.webform-type-address').length) { 2084 if (!$input.data('webform-states-address-initialized') 2085 && $input.attr('autocomplete') === 'country' 2086 && $input.val() === $input.find("option[selected]").attr('value')) { 2087 return; 2088 } 2089 $input.data('webform-states-address-initialized', true); 2090 } 2091 2092 $input 2093 .trigger('change', extraParameters) 2094 .trigger('blur', extraParameters); 2095 } 2096 else if (type !== 'submit' && type !== 'button' && type !== 'file') { 2097 // Make sure input mask is removed and then reset when value is restored. 2098 // @see https://www.drupal.org/project/webform/issues/3124155 2099 // @see https://www.drupal.org/project/webform/issues/3202795 2100 var hasInputMask = ($.fn.inputmask && $input.hasClass('js-webform-input-mask')); 2101 hasInputMask && $input.inputmask('remove'); 2102 2103 $input 2104 .trigger('input', extraParameters) 2105 .trigger('change', extraParameters) 2106 .trigger('keydown', extraParameters) 2107 .trigger('keyup', extraParameters) 2108 .trigger('blur', extraParameters); 2109 2110 hasInputMask && $input.inputmask(); 2111 } 2112 } 2113 2114 /* ************************************************************************ */ 2115 // Backup and restore value functions. 2116 /* ************************************************************************ */ 2117 2118 /** 2119 * Backup an input's current value and required attribute 2120 * 2121 * @param {element} input 2122 * An input. 2123 */ 2124 function backupValueAndRequired(input) { 2125 var $input = $(input); 2126 var type = input.type; 2127 var tag = input.tagName.toLowerCase(); // Normalize case. 2128 2129 // Backup required. 2130 if ($input.prop('required') && !$input.hasData('webform-required')) { 2131 $input.data('webform-required', true); 2132 } 2133 2134 // Backup value. 2135 if (!$input.hasData('webform-value')) { 2136 if (type === 'checkbox' || type === 'radio') { 2137 $input.data('webform-value', $input.prop('checked')); 2138 } 2139 else if (tag === 'select') { 2140 var values = []; 2141 $input.find('option:selected').each(function (i, option) { 2142 values[i] = option.value; 2143 }); 2144 $input.data('webform-value', values); 2145 } 2146 else if (type !== 'submit' && type !== 'button') { 2147 $input.data('webform-value', input.value); 2148 } 2149 } 2150 } 2151 2152 /** 2153 * Restore an input's value and required attribute. 2154 * 2155 * @param {element} input 2156 * An input. 2157 */ 2158 function restoreValueAndRequired(input) { 2159 var $input = $(input); 2160 2161 // Restore value. 2162 var value = $input.data('webform-value'); 2163 if (typeof value !== 'undefined') { 2164 var type = input.type; 2165 var tag = input.tagName.toLowerCase(); // Normalize case. 2166 2167 if (type === 'checkbox' || type === 'radio') { 2168 $input.prop('checked', value); 2169 } 2170 else if (tag === 'select') { 2171 $.each(value, function (i, option_value) { 2172 // Prevent "Syntax error, unrecognized expression" error by 2173 // escaping single quotes. 2174 // @see https://forum.jquery.com/topic/escape-characters-prior-to-using-selector 2175 option_value = option_value.replace(/'/g, "\\\'"); 2176 $input.find("option[value='" + option_value + "']").prop('selected', true); 2177 }); 2178 } 2179 else if (type !== 'submit' && type !== 'button') { 2180 input.value = value; 2181 } 2182 $input.removeData('webform-value'); 2183 } 2184 2185 // Restore required. 2186 var required = $input.data('webform-required'); 2187 if (typeof required !== 'undefined') { 2188 if (required) { 2189 $input.prop('required', true); 2190 } 2191 $input.removeData('webform-required'); 2192 } 2193 } 2194 2195 /** 2196 * Clear an input's value and required attributes. 2197 * 2198 * @param {element} input 2199 * An input. 2200 */ 2201 function clearValueAndRequired(input) { 2202 var $input = $(input); 2203 2204 // Check for #states no clear attribute.
2205 // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/ 2206 if ($input.closest('[data-webform-states-no-clear]').length) { 2207 return; 2208 } 2209 2210 // Clear value. 2211 var type = input.type; 2212 var tag = input.tagName.toLowerCase(); // Normalize case. 2213 if (type === 'checkbox' || type === 'radio') { 2214 $input.prop('checked', false); 2215 } 2216 else if (tag === 'select') { 2217 if ($input.find('option[value=""]').length) { 2218 $input.val(''); 2219 } 2220 else { 2221 input.selectedIndex = -1; 2222 } 2223 } 2224 else if (type !== 'submit' && type !== 'button') { 2225 input.value = (type === 'color') ? '#000000' : ''; 2226 } 2227 2228 // Clear required. 2229 $input.prop('required', false); 2230 } 2231 2232 /* ************************************************************************ */ 2233 // Helper functions. 2234 /* ************************************************************************ */ 2235 2236 /** 2237 * Toggle an input's required attributes. 2238 * 2239 * @param {element} $input 2240 * An input. 2241 * @param {boolean} required 2242 * Is input required. 2243 */ 2244 function toggleRequired($input, required) { 2245 var isCheckboxOrRadio = ($input.attr('type') === 'radio' || $input.attr('type') === 'checkbox'); 2246 if (required) { 2247 if (isCheckboxOrRadio) { 2248 $input.attr({'required': 'required'}); 2249 } 2250 else { 2251 $input.attr({'required': 'required', 'aria-required': 'true'}); 2252 } 2253 } 2254 else { 2255 if (isCheckboxOrRadio) { 2256 $input.removeAttr('required'); 2257 } 2258 else { 2259 $input.removeAttr('required aria-required'); 2260 } 2261 } 2262 } 2263 2264 /** 2265 * Copy the clientside_validation.module's message. 2266 * 2267 * @param {jQuery} $source 2268 * The source element. 2269 * @param {jQuery} $destination 2270 * The destination element. 2271 */ 2272 function copyRequireMessage($source, $destination) { 2273 if ($source.attr('data-msg-required')) { 2274 $destination.attr('data-msg-required', $source.attr('data-msg-required')); 2275 } 2276 } 2277 2278})(jQuery, Drupal, once); 2279; 2280/** 2281 * @file 2282 * JavaScript behaviors for webforms. 2283 */ 2284 2285(function ($, Drupal, once) { 2286 2287 'use strict'; 2288 2289 /** 2290 * Remove single submit event listener. 2291 * 2292 * @type {Drupal~behavior} 2293 * 2294 * @prop {Drupal~behaviorAttach} attach 2295 * Attaches the behavior for removing single submit event listener. 2296 * 2297 * @see Drupal.behaviors.formSingleSubmit 2298 */ 2299 Drupal.behaviors.webformRemoveFormSingleSubmit = { 2300 attach: function attach() { 2301 function onFormSubmit(e) { 2302 var $form = $(e.currentTarget); 2303 $form.removeAttr('data-drupal-form-submit-last'); 2304 } 2305 $(once('webform-single-submit', 'body')) 2306 .on('submit.singleSubmit', 'form.webform-remove-single-submit', onFormSubmit); 2307 } 2308 }; 2309 2310 /** 2311 * Prevent webform autosubmit on wizard pages. 2312 * 2313 * @type {Drupal~behavior} 2314 * 2315 * @prop {Drupal~behaviorAttach} attach 2316 * Attaches the behavior for disabling webform autosubmit. 2317 * Wizard pages need to be progressed with the Previous or Next buttons, 2318 * not by pressing Enter. 2319 */ 2320 Drupal.behaviors.webformDisableAutoSubmit = { 2321 attach: function (context) { 2322 // Not using context so that inputs loaded via Ajax will have autosubmit 2323 // disabled. 2324 // @see http://stackoverflow.com/questions/11235622/jquery-disable-form-submit-on-enter 2325 $(once('webform-disable-autosubmit', $('.js-webform-disable-autosubmit input').not(':button, :submit, :reset, :image, :file'))) 2326 .on('keyup keypress', function (e) { 2327 if (e.which === 13) { 2328 e.preventDefault(); 2329 return false; 2330 } 2331 }); 2332 } 2333 }; 2334 2335 /** 2336 * Custom required and pattern validation error messages. 2337 * 2338 * @type {Drupal~behavior} 2339 * 2340 * @prop {Drupal~behaviorAttach} attach 2341 * Attaches the behavior for the webform custom required and pattern 2342 * validation error messages. 2343 * 2344 * @see http://stackoverflow.com/questions/5272433/html5-form-required-attribute-set-custom-validation-message 2345 **/ 2346 Drupal.behaviors.webformRequiredError = { 2347 attach: function (context) { 2348 $(once('webform-required-error', $(context).find(':input[data-webform-required-error], :input[data-webform-pattern-error]'))) 2349 .on('invalid', function () { 2350 this.setCustomValidity(''); 2351 if (this.valid) { 2352 return; 2353 } 2354 2355 if (this.validity.patternMismatch && $(this).attr('data-webform-pattern-error')) { 2356 this.setCustomValidity($(this).attr('data-webform-pattern-error')); 2357 } 2358 else if (this.validity.valueMissing && $(this).attr('data-webform-required-error')) { 2359 this.setCustomValidity($(this).attr('data-webform-required-error')); 2360 } 2361 }) 2362 .on('input change', function () { 2363 // Find all related elements by name and reset custom validity. 2364 // This specifically applies to required radios and checkboxes. 2365 var name = $(this).attr('name'); 2366 $(this.form).find(':input[name="' + name + '"]').each(function () { 2367 this.setCustomValidity(''); 2368 }); 2369 }); 2370 } 2371 }; 2372 2373 // When #state:required is triggered we need to reset the target elements 2374 // custom validity. 2375 $(document).on('state:required', function (e) { 2376 $(e.target).filter(':input[data-webform-required-error]') 2377 .each(function () {this.setCustomValidity('');}); 2378 }); 2379 2380})(jQuery, Drupal, once); 2381; 2382/** 2383 * @file 2384 * JavaScript behaviors for details element. 2385 */ 2386 2387(function ($, Drupal, once) { 2388 2389 'use strict'; 2390 2391 // Determine if local storage exists and is enabled. 2392 // This approach is copied from Modernizr. 2393 // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 2394 var hasLocalStorage = (function () { 2395 try { 2396 localStorage.setItem('webform', 'webform'); 2397 localStorage.removeItem('webform'); 2398 return true; 2399 } 2400 catch (e) { 2401 return false;
2402 } 2403 }()); 2404 2405 /** 2406 * Attach handler to save details open/close state. 2407 * 2408 * @type {Drupal~behavior} 2409 */ 2410 Drupal.behaviors.webformDetailsSave = { 2411 attach: function (context) { 2412 if (!hasLocalStorage) { 2413 return; 2414 } 2415 2416 // Summary click event handler. 2417 $(once('webform-details-summary-save', 'details > summary', context)).on('click', function () { 2418 var $details = $(this).parent(); 2419 2420 // @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/ 2421 if ($details[0].hasAttribute('data-webform-details-nosave')) { 2422 return; 2423 } 2424 2425 var name = Drupal.webformDetailsSaveGetName($details); 2426 if (!name) { 2427 return; 2428 } 2429 2430 var open = ($details.attr('open') !== 'open') ? '1' : '0'; 2431 localStorage.setItem(name, open); 2432 }); 2433 2434 // Initialize details open state via local storage. 2435 $(once('webform-details-save', 'details', context)).each(function () { 2436 var $details = $(this); 2437 2438 var name = Drupal.webformDetailsSaveGetName($details); 2439 if (!name) { 2440 return; 2441 } 2442 2443 var open = localStorage.getItem(name); 2444 if (open === null) { 2445 return; 2446 } 2447 2448 if (open === '1') { 2449 $details.attr('open', 'open'); 2450 } 2451 else { 2452 $details.removeAttr('open'); 2453 } 2454 }); 2455 } 2456 2457 }; 2458 2459 /** 2460 * Get the name used to store the state of details element. 2461 * 2462 * @param {jQuery} $details 2463 * A details element. 2464 * 2465 * @return {string} 2466 * The name used to store the state of details element. 2467 */ 2468 Drupal.webformDetailsSaveGetName = function ($details) { 2469 if (!hasLocalStorage) { 2470 return ''; 2471 } 2472 2473 // Ignore details that are vertical tabs pane. 2474 if ($details.hasClass('vertical-tabs__pane')) { 2475 return ''; 2476 } 2477 2478 // Any details element not included a webform must have define its own id. 2479 var webformId = $details.attr('data-webform-element-id'); 2480 if (webformId) { 2481 return 'Drupal.webform.' + webformId.replace('--', '.'); 2482 } 2483 2484 var detailsId = $details.attr('id'); 2485 if (!detailsId) { 2486 return ''; 2487 } 2488 2489 var $form = $details.parents('form'); 2490 if (!$form.length || !$form.attr('id')) { 2491 return ''; 2492 } 2493 2494 var formId = $form.attr('id'); 2495 if (!formId) { 2496 return ''; 2497 } 2498 2499 // ISSUE: When Drupal renders a webform in a modal dialog it appends a unique 2500 // identifier to webform ids and details ids. (i.e. my-form--FeSFISegTUI) 2501 // WORKAROUND: Remove the unique id that delimited using double dashes. 2502 formId = formId.replace(/--.+?$/, '').replace(/-/g, '_'); 2503 detailsId = detailsId.replace(/--.+?$/, '').replace(/-/g, '_'); 2504 return 'Drupal.webform.' + formId + '.' + detailsId; 2505 }; 2506 2507})(jQuery, Drupal, once); 2508; 2509/** 2510* DO NOT EDIT THIS FILE. 2511* See the following change record for more information, 2512* https://www.drupal.org/node/2815083 2513* @preserve 2514**/ 2515(function (Drupal, debounce) { 2516 var liveElement; 2517 var announcements = []; 2518 Drupal.behaviors.drupalAnnounce = { 2519 attach: function attach(context) { 2520 if (!liveElement) { 2521 liveElement = document.createElement('div'); 2522 liveElement.id = 'drupal-live-announce'; 2523 liveElement.className = 'visually-hidden'; 2524 liveElement.setAttribute('aria-live', 'polite'); 2525 liveElement.setAttribute('aria-busy', 'false'); 2526 document.body.appendChild(liveElement); 2527 } 2528 } 2529 }; 2530 function announce() { 2531 var text = []; 2532 var priority = 'polite'; 2533 var announcement; 2534 var il = announcements.length; 2535 for (var i = 0; i < il; i++) { 2536 announcement = announcements.pop(); 2537 text.unshift(announcement.text); 2538 if (announcement.priority === 'assertive') { 2539 priority = 'assertive'; 2540 } 2541 } 2542 if (text.length) { 2543 liveElement.innerHTML = ''; 2544 liveElement.setAttribute('aria-busy', 'true'); 2545 liveElement.setAttribute('aria-live', priority); 2546 liveElement.innerHTML = text.join('\n'); 2547 liveElement.setAttribute('aria-busy', 'false'); 2548 } 2549 } 2550 Drupal.announce = function (text, priority) { 2551 announcements.push({ 2552 text: text, 2553 priority: priority 2554 }); 2555 return debounce(announce, 200)(); 2556 }; 2557})(Drupal, Drupal.debounce);; 2558/** 2559 * @file 2560 * JavaScript behaviors for details element. 2561 */ 2562 2563(function ($, Drupal, once) { 2564 2565 'use strict'; 2566 2567 Drupal.webform = Drupal.webform || {}; 2568 Drupal.webform.detailsToggle = Drupal.webform.detailsToggle || {}; 2569 Drupal.webform.detailsToggle.options = Drupal.webform.detailsToggle.options || {}; 2570 2571 /** 2572 * Attach handler to toggle details open/close state. 2573 * 2574 * @type {Drupal~behavior} 2575 */ 2576 Drupal.behaviors.webformDetailsToggle = { 2577 attach: function (context) { 2578 $(once('webform-details-toggle', '.js-webform-details-toggle', context)).each(function () { 2579 var $form = $(this); 2580 var $tabs = $form.find('.webform-tabs'); 2581 2582 // Get only the main details elements and ignore all nested details. 2583 var selector = ($tabs.length) ? '.webform-tab' : '.js-webform-details-toggle, .webform-elements'; 2584 var $details = $form.find('details').filter(function () { 2585 var $parents = $(this).parentsUntil(selector); 2586 return ($parents.find('details').length === 0); 2587 }); 2588 2589 // Toggle is only useful when there are two or more details elements. 2590 if ($details.length < 2) { 2591 return; 2592 } 2593 2594 var options = $.extend({ 2595 button: '<button type="button" class="webform-details-toggle-state"></button>' 2596 }, Drupal.webform.detailsToggle.options); 2597 2598 // Create toggle buttons. 2599 var $toggle = $(options.button) 2600 .attr('title', Drupal.t('Toggle details widget state.')) 2601 .on('click', function (e) { 2602 // Get details that are not vertical tabs pane. 2603 var $details = $form.find('details:not(.vertical-tabs__pane)'); 2604 var open; 2605 if (Drupal.webform.detailsToggle.isFormDetailsOpen($form)) { 2606 $details.removeAttr('open'); 2607 open = 0; 2608 } 2609 else { 2610 $details.attr('open', 'open'); 2611 open = 1; 2612 } 2613 Drupal.webform.detailsToggle.setDetailsToggleLabel($form); 2614 2615 // Set the saved states for all the details elements. 2616 // @see webform.element.details.save.js 2617 if (Drupal.webformDetailsSaveGetName) { 2618 $details.each(function () { 2619 // Note: Drupal.webformDetailsSaveGetName checks if localStorage 2620 // exists and is enabled. 2621 // @see webform.element.details.save.js 2622 var name = Drupal.webformDetailsSaveGetName($(this)); 2623 if (name) {
2624 localStorage.setItem(name, open); 2625 } 2626 }); 2627 } 2628 }) 2629 .wrap('<div class="webform-details-toggle-state-wrapper"></div>') 2630 .parent(); 2631 2632 if ($tabs.length) { 2633 // Add toggle state before the tabs. 2634 $tabs.find('.item-list:first-child').eq(0).before($toggle); 2635 } 2636 else { 2637 // Add toggle state link to first details element. 2638 $details.eq(0).before($toggle); 2639 } 2640 2641 Drupal.webform.detailsToggle.setDetailsToggleLabel($form); 2642 }); 2643 } 2644 }; 2645 2646 /** 2647 * Determine if a webform's details are all opened. 2648 * 2649 * @param {jQuery} $form 2650 * A webform. 2651 * 2652 * @return {boolean} 2653 * TRUE if a webform's details are all opened. 2654 */ 2655 Drupal.webform.detailsToggle.isFormDetailsOpen = function ($form) { 2656 return ($form.find('details[open]').length === $form.find('details').length); 2657 }; 2658 2659 /** 2660 * Set a webform's details toggle state widget label. 2661 * 2662 * @param {jQuery} $form 2663 * A webform. 2664 */ 2665 Drupal.webform.detailsToggle.setDetailsToggleLabel = function ($form) { 2666 var isOpen = Drupal.webform.detailsToggle.isFormDetailsOpen($form); 2667 2668 var label = (isOpen) ? Drupal.t('Collapse all') : Drupal.t('Expand all'); 2669 $form.find('.webform-details-toggle-state').html(label); 2670 2671 var text = (isOpen) ? Drupal.t('All details have been expanded.') : Drupal.t('All details have been collapsed.'); 2672 Drupal.announce(text); 2673 }; 2674 2675})(jQuery, Drupal, once); 2676; 2677/** 2678 * @file 2679 * JavaScript behaviors for message element integration. 2680 */ 2681 2682(function ($, Drupal, once) { 2683 2684 'use strict'; 2685 2686 // Determine if local storage exists and is enabled. 2687 // This approach is copied from Modernizr. 2688 // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 2689 var hasLocalStorage = (function () { 2690 try { 2691 localStorage.setItem('webform', 'webform'); 2692 localStorage.removeItem('webform'); 2693 return true; 2694 } 2695 catch (e) { 2696 return false; 2697 } 2698 }()); 2699 2700 // Determine if session storage exists and is enabled. 2701 // This approach is copied from Modernizr. 2702 // @see https://github.com/Modernizr/Modernizr/blob/c56fb8b09515f629806ca44742932902ac145302/modernizr.js#L696-731 2703 var hasSessionStorage = (function () { 2704 try { 2705 sessionStorage.setItem('webform', 'webform'); 2706 sessionStorage.removeItem('webform'); 2707 return true; 2708 } 2709 catch (e) { 2710 return false; 2711 } 2712 }()); 2713 2714 /** 2715 * Behavior for handler message close. 2716 * 2717 * @type {Drupal~behavior} 2718 */ 2719 Drupal.behaviors.webformMessageClose = { 2720 attach: function (context) { 2721 $(once('webform-message--close', '.js-webform-message--close', context)).each(function () { 2722 var $element = $(this); 2723 2724 var id = $element.attr('data-message-id'); 2725 var storage = $element.attr('data-message-storage'); 2726 var effect = $element.attr('data-message-close-effect') || 'hide'; 2727 switch (effect) { 2728 case 'slide': effect = 'slideUp'; break; 2729 2730 case 'fade': effect = 'fadeOut'; break; 2731 } 2732 2733 // Check storage status. 2734 if (isClosed($element, storage, id)) { 2735 return; 2736 } 2737 2738 // Only show element if it's style is not set to 'display: none' 2739 // and it is not hidden via .js-webform-states-hidden. 2740 if ($element.attr('style') !== 'display: none;' && !$element.hasClass('js-webform-states-hidden')) { 2741 $element.show(); 2742 } 2743 2744 $element.find('.js-webform-message__link').on('click', function (event) { 2745 $element[effect](); 2746 setClosed($element, storage, id); 2747 $element.trigger('close'); 2748 event.preventDefault(); 2749 }); 2750 }); 2751 } 2752 }; 2753 2754 function isClosed($element, storage, id) { 2755 if (!id || !storage) { 2756 return false; 2757 } 2758 2759 switch (storage) { 2760 case 'local': 2761 if (hasLocalStorage) { 2762 return localStorage.getItem('Drupal.webform.message.' + id) || false; 2763 } 2764 return false; 2765 2766 case 'session': 2767 if (hasSessionStorage) { 2768 return sessionStorage.getItem('Drupal.webform.message.' + id) || false; 2769 } 2770 return false;
2771 2772 default: 2773 return false; 2774 } 2775 } 2776 2777 function setClosed($element, storage, id) { 2778 if (!id || !storage) { 2779 return; 2780 } 2781 2782 switch (storage) { 2783 case 'local': 2784 if (hasLocalStorage) { 2785 localStorage.setItem('Drupal.webform.message.' + id, true); 2786 } 2787 break; 2788 2789 case 'session': 2790 if (hasSessionStorage) { 2791 sessionStorage.setItem('Drupal.webform.message.' + id, true); 2792 } 2793 break; 2794 2795 case 'user': 2796 case 'state': 2797 case 'custom': 2798 $.get($element.find('.js-webform-message__link').attr('href')); 2799 return true; 2800 } 2801 } 2802 2803})(jQuery, Drupal, once); 2804; 2805/** 2806 * @file 2807 * JavaScript behaviors for select menu. 2808 */ 2809 2810(function ($, Drupal, once) { 2811 2812 'use strict'; 2813 2814 /** 2815 * Disable select menu options using JavaScript. 2816 * 2817 * @type {Drupal~behavior} 2818 */ 2819 Drupal.behaviors.webformSelectOptionsDisabled = { 2820 attach: function (context) { 2821 $(once('webform-select-options-disabled', 'select[data-webform-select-options-disabled]', context)).each(function () { 2822 var $select = $(this); 2823 var disabled = $select.attr('data-webform-select-options-disabled').split(/\s*,\s*/); 2824 $select.find('option').filter(function isDisabled() { 2825 return ($.inArray(this.value, disabled) !== -1); 2826 }).attr('disabled', 'disabled'); 2827 }); 2828 } 2829 }; 2830 2831})(jQuery, Drupal, once); 2832;
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.